diff --git a/.github/actions/delete-deployments/action.yml b/.github/actions/delete-deployments/action.yml
new file mode 100644
index 00000000000..20b7d0eefe5
--- /dev/null
+++ b/.github/actions/delete-deployments/action.yml
@@ -0,0 +1,59 @@
+name: Delete Deployments
+description: Delete deployments by env and ref
+inputs:
+ environment:
+ required: true
+ description: The Github environment to filter deployments by
+ ref:
+ required: true
+ description: The ref to filter deployments by
+ dry-run:
+ required: false
+ description: Whether to actually delete deployments or not
+ github-token:
+ description: "The Github token to use for authentication"
+ required: true
+ default: ${{ github.token }}
+ num-of-pages:
+ required: false
+ description: The number of pages (of 100 per page) to fetch deployments from, set to 'all' to fetch all deployments
+ default: "all"
+ starting-page:
+ required: false
+ description: The page to start fetching deployments from, only valid if num-of-pages is set to a number
+ repository:
+ required: false
+ description: The owner and repository name to delete deployments from, defaults to the current repository, ex. 'smartcontractkit/chainlink'
+ default: ${{ github.repository }}
+
+runs:
+ using: composite
+ steps:
+ - uses: pnpm/action-setup@c3b53f6a16e57305370b4ae5a540c2077a1d50dd #v2.2.4
+ with:
+ version: ^8.0.0
+
+ - uses: actions/setup-node@v3
+ with:
+ node-version: "18"
+ cache: "pnpm"
+ cache-dependency-path: "./.github/actions/delete-deployments/pnpm-lock.yaml"
+
+ - name: Install dependencies
+ shell: bash
+ run: pnpm i --prod
+ working-directory: "./.github/actions/delete-deployments"
+
+ - name: Run deployment deleter
+ shell: bash
+ run: pnpm start
+ env:
+ NUM_OF_PAGES: ${{ inputs.num-of-pages }}
+ STARTING_PAGE: ${{ inputs.starting-page }}
+ GITHUB_TOKEN: ${{ inputs.github-token }}
+ ENVIRONMENT: ${{ inputs.environment }}
+ REF: ${{ inputs.ref }}
+ DRY_RUN: ${{ inputs.dry-run }}
+ OWNER: ${{ inputs.owner }}
+ REPOSITORY: ${{ inputs.repository }}
+ working-directory: "./.github/actions/delete-deployments"
diff --git a/.github/actions/delete-deployments/index.ts b/.github/actions/delete-deployments/index.ts
new file mode 100644
index 00000000000..e38f1957d21
--- /dev/null
+++ b/.github/actions/delete-deployments/index.ts
@@ -0,0 +1,232 @@
+import { Octokit } from "@octokit/action";
+import { info, warning, isDebug } from "@actions/core";
+import { throttling } from "@octokit/plugin-throttling";
+import { retry } from "@octokit/plugin-retry";
+
+async function main() {
+ const {
+ dryRun,
+ environment,
+ numOfPages,
+ owner,
+ ref,
+ repo,
+ debug,
+ startingPage,
+ } = getInputs();
+ const octokit = getOctokit(debug);
+
+ const deployments = await getDeployments({
+ octokit,
+ owner,
+ repo,
+ environment,
+ ref,
+ paginateOptions: {
+ numOfPages,
+ startingPage,
+ },
+ });
+ const deploymentIds = deployments.map((d) => d.id);
+ if (dryRun) {
+ info(`Dry run: would delete deployments (${deploymentIds.length})`);
+ return;
+ }
+
+ info(`Deleting deployments (${deploymentIds.length})`);
+ const deleteDeployments = deploymentIds.map(async (id) => {
+ const sharedArgs = {
+ owner,
+ repo,
+ deployment_id: id,
+ request: {
+ retries: 0,
+ },
+ };
+
+ const setStatus = await octokit.repos
+ .createDeploymentStatus({
+ ...sharedArgs,
+ state: "inactive",
+ })
+ .then(() => true)
+ .catch((e) => {
+ warning(
+ `Marking deployment id ${id} to "inactive" failed: ${e.message}`
+ );
+ return false;
+ });
+ if (!setStatus) return false;
+
+ return octokit.repos
+ .deleteDeployment({
+ ...sharedArgs,
+ })
+ .then(() => true)
+ .catch((e) => {
+ warning(`Deleting deployment id ${id} failed: ${e.message}`);
+ return false;
+ });
+ });
+
+ const processed = await Promise.all(deleteDeployments);
+ const succeeded = processed.filter((p) => !!p);
+ info(
+ `Successfully deleted ${succeeded.length}/${processed.length} deployments`
+ );
+}
+main();
+
+function getInputs() {
+ const debug = !!(process.env.DEBUG || isDebug());
+
+ const dryRun = process.env.DRY_RUN === "true";
+
+ const environment = process.env.ENVIRONMENT;
+ if (!environment) throw new Error("ENVIRONMENT not set");
+
+ const ref = process.env.REF;
+
+ const repository = process.env.REPOSITORY;
+ if (!repository) throw new Error("REPOSITORY not set");
+ const [owner, repo] = repository.split("/");
+
+ const rawStartingPage = process.env.STARTING_PAGE;
+
+ let startingPage: number | undefined;
+ if (rawStartingPage) {
+ startingPage = parseInt(rawStartingPage);
+ if (isNaN(startingPage)) {
+ throw new Error(`STARTING_PAGE is not a number: ${rawStartingPage}`);
+ }
+ if (startingPage < 0) {
+ throw new Error(
+ `STARTING_PAGE must be a positive integer or zero: ${rawStartingPage}`
+ );
+ }
+ info(`Starting from page ${startingPage}`);
+ }
+
+ const rawNumOfPages = process.env.NUM_OF_PAGES;
+ let numOfPages: "all" | number = "all";
+ if (rawNumOfPages === "all") {
+ info("Fetching all pages of deployments");
+ } else {
+ const parsedPages = parseInt(rawNumOfPages || "");
+ if (isNaN(parsedPages)) {
+ throw new Error(`NUM_OF_PAGES is not a number: ${rawNumOfPages}`);
+ }
+ if (parsedPages < 1) {
+ throw new Error(`NUM_OF_PAGES must be greater than 0: ${rawNumOfPages}`);
+ }
+ numOfPages = parsedPages;
+ }
+
+ if (numOfPages === "all" && startingPage) {
+ throw new Error(`Cannot use STARTING_PAGE with NUM_OF_PAGES=all`);
+ }
+
+ const parsedInputs = {
+ environment,
+ ref,
+ owner,
+ repo,
+ numOfPages,
+ startingPage,
+ dryRun,
+ debug,
+ };
+ info(`Configuration: ${JSON.stringify(parsedInputs)}`);
+ return parsedInputs;
+}
+
+function getOctokit(debug: boolean) {
+ const OctokitAPI = Octokit.plugin(throttling, retry);
+ const octokit = new OctokitAPI({
+ log: debug ? console : undefined,
+ throttle: {
+ onRateLimit: (retryAfter, options, octokit, retryCount) => {
+ octokit.log.warn(
+ // Types are busted from octokit
+ //@ts-expect-error
+ `Request quota exhausted for request ${options.method} ${options.url}`
+ );
+
+ octokit.log.info(`Retrying after ${retryAfter} seconds!`);
+ return true;
+ },
+ onSecondaryRateLimit: (_retryAfter, options, octokit) => {
+ octokit.log.warn(
+ // Types are busted from octokit
+ //@ts-expect-error
+ `SecondaryRateLimit detected for request ${options.method} ${options.url}`
+ );
+ return true;
+ },
+ },
+ });
+
+ return octokit;
+}
+
+async function getDeployments({
+ octokit,
+ owner,
+ repo,
+ environment,
+ ref,
+ paginateOptions,
+}: {
+ octokit: ReturnType;
+ owner: string;
+ repo: string;
+ environment: string;
+ ref?: string;
+ paginateOptions: {
+ numOfPages: number | "all";
+ startingPage?: number;
+ };
+}) {
+ const listDeploymentsSharedArgs: Parameters<
+ typeof octokit.repos.listDeployments
+ >[0] = {
+ owner,
+ repo,
+ environment,
+ ref,
+ per_page: 100,
+ request: {
+ retries: 20,
+ },
+ };
+
+ if (paginateOptions.numOfPages === "all") {
+ info(`Fetching all deployments`);
+ const deployments = await octokit.paginate(octokit.repos.listDeployments, {
+ ...listDeploymentsSharedArgs,
+ });
+
+ return deployments;
+ } else {
+ info(
+ `Fetching ${
+ paginateOptions.numOfPages * listDeploymentsSharedArgs.per_page!
+ } deployments`
+ );
+ const deployments: Awaited<
+ ReturnType
+ >["data"] = [];
+
+ const offset = paginateOptions.startingPage || 0;
+ for (let i = offset; i < paginateOptions.numOfPages + offset; i++) {
+ const deploymentPage = await octokit.repos.listDeployments({
+ ...listDeploymentsSharedArgs,
+ page: i,
+ });
+
+ deployments.push(...deploymentPage.data);
+ }
+
+ return deployments;
+ }
+}
diff --git a/.github/actions/delete-deployments/package.json b/.github/actions/delete-deployments/package.json
new file mode 100644
index 00000000000..7045cb35797
--- /dev/null
+++ b/.github/actions/delete-deployments/package.json
@@ -0,0 +1,25 @@
+{
+ "name": "delete-deployments",
+ "version": "1.0.0",
+ "description": "",
+ "main": "index.ts",
+ "scripts": {
+ "start": "ts-node -T .",
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "keywords": [],
+ "author": "",
+ "license": "ISC",
+ "dependencies": {
+ "@actions/core": "^1.10.1",
+ "@octokit/action": "^6.0.5",
+ "@octokit/plugin-retry": "^6.0.0",
+ "@octokit/plugin-throttling": "^7.0.0",
+ "ts-node": "^10.9.1"
+ },
+ "devDependencies": {
+ "@octokit/types": "^11.1.0",
+ "@types/node": "^18",
+ "typescript": "^5.2.2"
+ }
+}
diff --git a/.github/actions/delete-deployments/pnpm-lock.yaml b/.github/actions/delete-deployments/pnpm-lock.yaml
new file mode 100644
index 00000000000..a5553eb3dee
--- /dev/null
+++ b/.github/actions/delete-deployments/pnpm-lock.yaml
@@ -0,0 +1,350 @@
+lockfileVersion: '6.0'
+
+settings:
+ autoInstallPeers: true
+ excludeLinksFromLockfile: false
+
+dependencies:
+ '@actions/core':
+ specifier: ^1.10.1
+ version: 1.10.1
+ '@octokit/action':
+ specifier: ^6.0.5
+ version: 6.0.5
+ '@octokit/plugin-retry':
+ specifier: ^6.0.0
+ version: 6.0.0(@octokit/core@5.0.0)
+ '@octokit/plugin-throttling':
+ specifier: ^7.0.0
+ version: 7.0.0(@octokit/core@5.0.0)
+ ts-node:
+ specifier: ^10.9.1
+ version: 10.9.1(@types/node@18.17.15)(typescript@5.2.2)
+
+devDependencies:
+ '@octokit/types':
+ specifier: ^11.1.0
+ version: 11.1.0
+ '@types/node':
+ specifier: ^18
+ version: 18.17.15
+ typescript:
+ specifier: ^5.2.2
+ version: 5.2.2
+
+packages:
+
+ /@actions/core@1.10.1:
+ resolution: {integrity: sha512-3lBR9EDAY+iYIpTnTIXmWcNbX3T2kCkAEQGIQx4NVQ0575nk2k3GRZDTPQG+vVtS2izSLmINlxXf0uLtnrTP+g==}
+ dependencies:
+ '@actions/http-client': 2.1.1
+ uuid: 8.3.2
+ dev: false
+
+ /@actions/http-client@2.1.1:
+ resolution: {integrity: sha512-qhrkRMB40bbbLo7gF+0vu+X+UawOvQQqNAA/5Unx774RS8poaOhThDOG6BGmxvAnxhQnDp2BG/ZUm65xZILTpw==}
+ dependencies:
+ tunnel: 0.0.6
+ dev: false
+
+ /@cspotcode/source-map-support@0.8.1:
+ resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==}
+ engines: {node: '>=12'}
+ dependencies:
+ '@jridgewell/trace-mapping': 0.3.9
+ dev: false
+
+ /@jridgewell/resolve-uri@3.1.1:
+ resolution: {integrity: sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==}
+ engines: {node: '>=6.0.0'}
+ dev: false
+
+ /@jridgewell/sourcemap-codec@1.4.15:
+ resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==}
+ dev: false
+
+ /@jridgewell/trace-mapping@0.3.9:
+ resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==}
+ dependencies:
+ '@jridgewell/resolve-uri': 3.1.1
+ '@jridgewell/sourcemap-codec': 1.4.15
+ dev: false
+
+ /@octokit/action@6.0.5:
+ resolution: {integrity: sha512-jcCZb+jR4nzHgj86wlUvbTv92hiZ4OWpI9dIoWRilbtT4HuVVNFZvQih8X/YE2GMVrLCVbBD0xkjeq+1m8Rcpw==}
+ engines: {node: '>= 18'}
+ dependencies:
+ '@octokit/auth-action': 4.0.0
+ '@octokit/core': 5.0.0
+ '@octokit/plugin-paginate-rest': 8.0.0(@octokit/core@5.0.0)
+ '@octokit/plugin-rest-endpoint-methods': 9.0.0(@octokit/core@5.0.0)
+ '@octokit/types': 11.1.0
+ undici: 5.24.0
+ dev: false
+
+ /@octokit/auth-action@4.0.0:
+ resolution: {integrity: sha512-sMm9lWZdiX6e89YFaLrgE9EFs94k58BwIkvjOtozNWUqyTmsrnWFr/M5LolaRzZ7Kmb5FbhF9hi7FEeE274SoQ==}
+ engines: {node: '>= 18'}
+ dependencies:
+ '@octokit/auth-token': 4.0.0
+ '@octokit/types': 11.1.0
+ dev: false
+
+ /@octokit/auth-token@4.0.0:
+ resolution: {integrity: sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==}
+ engines: {node: '>= 18'}
+ dev: false
+
+ /@octokit/core@5.0.0:
+ resolution: {integrity: sha512-YbAtMWIrbZ9FCXbLwT9wWB8TyLjq9mxpKdgB3dUNxQcIVTf9hJ70gRPwAcqGZdY6WdJPZ0I7jLaaNDCiloGN2A==}
+ engines: {node: '>= 18'}
+ dependencies:
+ '@octokit/auth-token': 4.0.0
+ '@octokit/graphql': 7.0.1
+ '@octokit/request': 8.1.1
+ '@octokit/request-error': 5.0.0
+ '@octokit/types': 11.1.0
+ before-after-hook: 2.2.3
+ universal-user-agent: 6.0.0
+ dev: false
+
+ /@octokit/endpoint@9.0.0:
+ resolution: {integrity: sha512-szrQhiqJ88gghWY2Htt8MqUDO6++E/EIXqJ2ZEp5ma3uGS46o7LZAzSLt49myB7rT+Hfw5Y6gO3LmOxGzHijAQ==}
+ engines: {node: '>= 18'}
+ dependencies:
+ '@octokit/types': 11.1.0
+ is-plain-object: 5.0.0
+ universal-user-agent: 6.0.0
+ dev: false
+
+ /@octokit/graphql@7.0.1:
+ resolution: {integrity: sha512-T5S3oZ1JOE58gom6MIcrgwZXzTaxRnxBso58xhozxHpOqSTgDS6YNeEUvZ/kRvXgPrRz/KHnZhtb7jUMRi9E6w==}
+ engines: {node: '>= 18'}
+ dependencies:
+ '@octokit/request': 8.1.1
+ '@octokit/types': 11.1.0
+ universal-user-agent: 6.0.0
+ dev: false
+
+ /@octokit/openapi-types@18.0.0:
+ resolution: {integrity: sha512-V8GImKs3TeQRxRtXFpG2wl19V7444NIOTDF24AWuIbmNaNYOQMWRbjcGDXV5B+0n887fgDcuMNOmlul+k+oJtw==}
+
+ /@octokit/plugin-paginate-rest@8.0.0(@octokit/core@5.0.0):
+ resolution: {integrity: sha512-2xZ+baZWUg+qudVXnnvXz7qfrTmDeYPCzangBVq/1gXxii/OiS//4shJp9dnCCvj1x+JAm9ji1Egwm1BA47lPQ==}
+ engines: {node: '>= 18'}
+ peerDependencies:
+ '@octokit/core': '>=5'
+ dependencies:
+ '@octokit/core': 5.0.0
+ '@octokit/types': 11.1.0
+ dev: false
+
+ /@octokit/plugin-rest-endpoint-methods@9.0.0(@octokit/core@5.0.0):
+ resolution: {integrity: sha512-KquMF/VB1IkKNiVnzJKspY5mFgGyLd7HzdJfVEGTJFzqu9BRFNWt+nwTCMuUiWc72gLQhRWYubTwOkQj+w/1PA==}
+ engines: {node: '>= 18'}
+ peerDependencies:
+ '@octokit/core': '>=5'
+ dependencies:
+ '@octokit/core': 5.0.0
+ '@octokit/types': 11.1.0
+ dev: false
+
+ /@octokit/plugin-retry@6.0.0(@octokit/core@5.0.0):
+ resolution: {integrity: sha512-a1/A4A+PB1QoAHQfLJxGHhLfSAT03bR1jJz3GgQJZvty2ozawFWs93MiBQXO7SL2YbO7CIq0Goj4qLOBj8JeMQ==}
+ engines: {node: '>= 18'}
+ peerDependencies:
+ '@octokit/core': '>=5'
+ dependencies:
+ '@octokit/core': 5.0.0
+ '@octokit/request-error': 5.0.0
+ '@octokit/types': 11.1.0
+ bottleneck: 2.19.5
+ dev: false
+
+ /@octokit/plugin-throttling@7.0.0(@octokit/core@5.0.0):
+ resolution: {integrity: sha512-KL2k/d0uANc8XqP5S64YcNFCudR3F5AaKO39XWdUtlJIjT9Ni79ekWJ6Kj5xvAw87udkOMEPcVf9xEge2+ahew==}
+ engines: {node: '>= 18'}
+ peerDependencies:
+ '@octokit/core': ^5.0.0
+ dependencies:
+ '@octokit/core': 5.0.0
+ '@octokit/types': 11.1.0
+ bottleneck: 2.19.5
+ dev: false
+
+ /@octokit/request-error@5.0.0:
+ resolution: {integrity: sha512-1ue0DH0Lif5iEqT52+Rf/hf0RmGO9NWFjrzmrkArpG9trFfDM/efx00BJHdLGuro4BR/gECxCU2Twf5OKrRFsQ==}
+ engines: {node: '>= 18'}
+ dependencies:
+ '@octokit/types': 11.1.0
+ deprecation: 2.3.1
+ once: 1.4.0
+ dev: false
+
+ /@octokit/request@8.1.1:
+ resolution: {integrity: sha512-8N+tdUz4aCqQmXl8FpHYfKG9GelDFd7XGVzyN8rc6WxVlYcfpHECnuRkgquzz+WzvHTK62co5di8gSXnzASZPQ==}
+ engines: {node: '>= 18'}
+ dependencies:
+ '@octokit/endpoint': 9.0.0
+ '@octokit/request-error': 5.0.0
+ '@octokit/types': 11.1.0
+ is-plain-object: 5.0.0
+ universal-user-agent: 6.0.0
+ dev: false
+
+ /@octokit/types@11.1.0:
+ resolution: {integrity: sha512-Fz0+7GyLm/bHt8fwEqgvRBWwIV1S6wRRyq+V6exRKLVWaKGsuy6H9QFYeBVDV7rK6fO3XwHgQOPxv+cLj2zpXQ==}
+ dependencies:
+ '@octokit/openapi-types': 18.0.0
+
+ /@tsconfig/node10@1.0.9:
+ resolution: {integrity: sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==}
+ dev: false
+
+ /@tsconfig/node12@1.0.11:
+ resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==}
+ dev: false
+
+ /@tsconfig/node14@1.0.3:
+ resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==}
+ dev: false
+
+ /@tsconfig/node16@1.0.4:
+ resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==}
+ dev: false
+
+ /@types/node@18.17.15:
+ resolution: {integrity: sha512-2yrWpBk32tvV/JAd3HNHWuZn/VDN1P+72hWirHnvsvTGSqbANi+kSeuQR9yAHnbvaBvHDsoTdXV0Fe+iRtHLKA==}
+
+ /acorn-walk@8.2.0:
+ resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==}
+ engines: {node: '>=0.4.0'}
+ dev: false
+
+ /acorn@8.10.0:
+ resolution: {integrity: sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==}
+ engines: {node: '>=0.4.0'}
+ hasBin: true
+ dev: false
+
+ /arg@4.1.3:
+ resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==}
+ dev: false
+
+ /before-after-hook@2.2.3:
+ resolution: {integrity: sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==}
+ dev: false
+
+ /bottleneck@2.19.5:
+ resolution: {integrity: sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw==}
+ dev: false
+
+ /busboy@1.6.0:
+ resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==}
+ engines: {node: '>=10.16.0'}
+ dependencies:
+ streamsearch: 1.1.0
+ dev: false
+
+ /create-require@1.1.1:
+ resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==}
+ dev: false
+
+ /deprecation@2.3.1:
+ resolution: {integrity: sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==}
+ dev: false
+
+ /diff@4.0.2:
+ resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==}
+ engines: {node: '>=0.3.1'}
+ dev: false
+
+ /is-plain-object@5.0.0:
+ resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==}
+ engines: {node: '>=0.10.0'}
+ dev: false
+
+ /make-error@1.3.6:
+ resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==}
+ dev: false
+
+ /once@1.4.0:
+ resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
+ dependencies:
+ wrappy: 1.0.2
+ dev: false
+
+ /streamsearch@1.1.0:
+ resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==}
+ engines: {node: '>=10.0.0'}
+ dev: false
+
+ /ts-node@10.9.1(@types/node@18.17.15)(typescript@5.2.2):
+ resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==}
+ hasBin: true
+ peerDependencies:
+ '@swc/core': '>=1.2.50'
+ '@swc/wasm': '>=1.2.50'
+ '@types/node': '*'
+ typescript: '>=2.7'
+ peerDependenciesMeta:
+ '@swc/core':
+ optional: true
+ '@swc/wasm':
+ optional: true
+ dependencies:
+ '@cspotcode/source-map-support': 0.8.1
+ '@tsconfig/node10': 1.0.9
+ '@tsconfig/node12': 1.0.11
+ '@tsconfig/node14': 1.0.3
+ '@tsconfig/node16': 1.0.4
+ '@types/node': 18.17.15
+ acorn: 8.10.0
+ acorn-walk: 8.2.0
+ arg: 4.1.3
+ create-require: 1.1.1
+ diff: 4.0.2
+ make-error: 1.3.6
+ typescript: 5.2.2
+ v8-compile-cache-lib: 3.0.1
+ yn: 3.1.1
+ dev: false
+
+ /tunnel@0.0.6:
+ resolution: {integrity: sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==}
+ engines: {node: '>=0.6.11 <=0.7.0 || >=0.7.3'}
+ dev: false
+
+ /typescript@5.2.2:
+ resolution: {integrity: sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==}
+ engines: {node: '>=14.17'}
+ hasBin: true
+
+ /undici@5.24.0:
+ resolution: {integrity: sha512-OKlckxBjFl0oXxcj9FU6oB8fDAaiRUq+D8jrFWGmOfI/gIyjk/IeS75LMzgYKUaeHzLUcYvf9bbJGSrUwTfwwQ==}
+ engines: {node: '>=14.0'}
+ dependencies:
+ busboy: 1.6.0
+ dev: false
+
+ /universal-user-agent@6.0.0:
+ resolution: {integrity: sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==}
+ dev: false
+
+ /uuid@8.3.2:
+ resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==}
+ hasBin: true
+ dev: false
+
+ /v8-compile-cache-lib@3.0.1:
+ resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==}
+ dev: false
+
+ /wrappy@1.0.2:
+ resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
+ dev: false
+
+ /yn@3.1.1:
+ resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==}
+ engines: {node: '>=6'}
+ dev: false
diff --git a/.github/actions/delete-deployments/test.sh b/.github/actions/delete-deployments/test.sh
new file mode 100755
index 00000000000..18b77260886
--- /dev/null
+++ b/.github/actions/delete-deployments/test.sh
@@ -0,0 +1,9 @@
+#!/bin/sh
+export NUM_OF_PAGES=all
+export ENVIRONMENT=integration
+export DRY_RUN=false
+export REPOSITORY=smartcontractkit/chainlink
+export REF=fix/golint
+export GITHUB_ACTION=true
+
+pnpm start
diff --git a/.github/actions/delete-deployments/tsconfig.json b/.github/actions/delete-deployments/tsconfig.json
new file mode 100644
index 00000000000..4b36d4a178c
--- /dev/null
+++ b/.github/actions/delete-deployments/tsconfig.json
@@ -0,0 +1,104 @@
+{
+ "compilerOptions": {
+ /* Visit https://aka.ms/tsconfig to read more about this file */
+
+ /* Projects */
+ // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
+ // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
+ // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */
+ // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */
+ // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
+ // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
+
+ /* Language and Environment */
+ "target": "ESNext" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */,
+ // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
+ // "jsx": "preserve", /* Specify what JSX code is generated. */
+ // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */
+ // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
+ // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
+ // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
+ // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
+ // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
+ // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
+ // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
+ // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
+
+ /* Modules */
+ "module": "NodeNext" /* Specify what module code is generated. */,
+ // "rootDir": "./", /* Specify the root folder within your source files. */
+ "moduleResolution": "NodeNext" /* Specify how TypeScript looks up a file from a given module specifier. */,
+ // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
+ // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
+ // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
+ // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */
+ // "types": [], /* Specify type package names to be included without being referenced in a source file. */
+ // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
+ // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
+ // "resolveJsonModule": true, /* Enable importing .json files. */
+ // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */
+
+ /* JavaScript Support */
+ // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
+ // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
+ // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
+
+ /* Emit */
+ // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
+ // "declarationMap": true, /* Create sourcemaps for d.ts files. */
+ // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
+ // "sourceMap": true, /* Create source map files for emitted JavaScript files. */
+ // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
+ // "outDir": "./", /* Specify an output folder for all emitted files. */
+ // "removeComments": true, /* Disable emitting comments. */
+ "noEmit": true /* Disable emitting files from a compilation. */,
+ // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
+ // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */
+ // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
+ // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
+ // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
+ // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
+ // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
+ // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
+ // "newLine": "crlf", /* Set the newline character for emitting files. */
+ // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */
+ // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */
+ // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
+ // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */
+ // "declarationDir": "./", /* Specify the output directory for generated declaration files. */
+ // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
+
+ /* Interop Constraints */
+ // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
+ // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
+ "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */,
+ // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
+ "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */,
+
+ /* Type Checking */
+ "strict": true /* Enable all strict type-checking options. */,
+ // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
+ // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */
+ // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
+ // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
+ // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
+ // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */
+ // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */
+ // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
+ // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */
+ // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */
+ // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
+ // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
+ // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
+ // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */
+ // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
+ // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */
+ // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
+ // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
+
+ /* Completeness */
+ // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
+ "skipLibCheck": false /* Skip type checking all .d.ts files. */
+ },
+ "include": ["src", "test"]
+}
diff --git a/.github/actions/setup-postgres/wait-for-healthy-postgres.sh b/.github/actions/setup-postgres/wait-for-healthy-postgres.sh
index 3f0efd66f3b..438cfbaff3d 100755
--- a/.github/actions/setup-postgres/wait-for-healthy-postgres.sh
+++ b/.github/actions/setup-postgres/wait-for-healthy-postgres.sh
@@ -2,10 +2,24 @@
RETRIES=10
until [ $RETRIES -eq 0 ]; do
- if docker compose ps postgres --status running --format json | jq >/dev/null -e 'if (.[0].Health == "healthy") then true else false end'; then
+ DOCKER_OUTPUT=$(docker compose ps postgres --status running --format json)
+ JSON_TYPE=$(echo "$DOCKER_OUTPUT" | jq -r 'type')
+
+ if [ "$JSON_TYPE" == "array" ]; then
+ HEALTH_STATUS=$(echo "$DOCKER_OUTPUT" | jq -r '.[0].Health')
+ elif [ "$JSON_TYPE" == "object" ]; then
+ HEALTH_STATUS=$(echo "$DOCKER_OUTPUT" | jq -r '.Health')
+ else
+ HEALTH_STATUS="Unknown JSON type: $JSON_TYPE"
+ fi
+
+ echo "postgres health status: $HEALTH_STATUS"
+ if [ "$HEALTH_STATUS" == "healthy" ]; then
exit 0
fi
+
echo "Waiting for postgres server, $((RETRIES--)) remaining attempts..."
sleep 2
done
+
exit 1
diff --git a/.github/actions/split-tests/.npmrc b/.github/actions/split-tests/.npmrc
new file mode 100644
index 00000000000..4c2f52b3be7
--- /dev/null
+++ b/.github/actions/split-tests/.npmrc
@@ -0,0 +1,2 @@
+auto-install-peers=true
+strict-peer-dependencies=false
diff --git a/.github/actions/split-tests/package.json b/.github/actions/split-tests/package.json
index 5aa41ae791f..1624bda7b37 100644
--- a/.github/actions/split-tests/package.json
+++ b/.github/actions/split-tests/package.json
@@ -21,6 +21,6 @@
"@types/node": "^18.8.2",
"jest": "^29.1.2",
"ts-jest": "^29.0.3",
- "typescript": "^4.8.4"
+ "typescript": "^5.2.2"
}
}
diff --git a/.github/actions/split-tests/pnpm-lock.yaml b/.github/actions/split-tests/pnpm-lock.yaml
index 86334f734c6..9b5deb258dc 100644
--- a/.github/actions/split-tests/pnpm-lock.yaml
+++ b/.github/actions/split-tests/pnpm-lock.yaml
@@ -1,43 +1,53 @@
-lockfileVersion: 5.4
-
-specifiers:
- '@actions/core': ^1.10.0
- '@types/jest': ^29.1.2
- '@types/node': ^18.8.2
- jest: ^29.1.2
- ts-jest: ^29.0.3
- ts-node: ^10.9.1
- typescript: ^4.8.4
- zx: ^7.0.8
+lockfileVersion: '6.0'
+
+settings:
+ autoInstallPeers: true
+ excludeLinksFromLockfile: false
dependencies:
- '@actions/core': 1.10.0
- ts-node: 10.9.1_p2zphemn5bk5inasc666rmprwi
- zx: 7.0.8
+ '@actions/core':
+ specifier: ^1.10.0
+ version: 1.10.0
+ ts-node:
+ specifier: ^10.9.1
+ version: 10.9.1(@types/node@18.8.2)(typescript@5.2.2)
+ zx:
+ specifier: ^7.0.8
+ version: 7.0.8
devDependencies:
- '@types/jest': 29.1.2
- '@types/node': 18.8.2
- jest: 29.1.2_texb6yekbdrurkf2spvwkwkdam
- ts-jest: 29.0.3_2gcdg7c5hzdfd67o3khlosdlhu
- typescript: 4.8.4
+ '@types/jest':
+ specifier: ^29.1.2
+ version: 29.1.2
+ '@types/node':
+ specifier: ^18.8.2
+ version: 18.8.2
+ jest:
+ specifier: ^29.1.2
+ version: 29.1.2(@types/node@18.8.2)(ts-node@10.9.1)
+ ts-jest:
+ specifier: ^29.0.3
+ version: 29.0.3(@babel/core@7.19.3)(jest@29.1.2)(typescript@5.2.2)
+ typescript:
+ specifier: ^5.2.2
+ version: 5.2.2
packages:
- /@actions/core/1.10.0:
+ /@actions/core@1.10.0:
resolution: {integrity: sha512-2aZDDa3zrrZbP5ZYg159sNoLRb61nQ7awl5pSvIq5Qpj81vwDzdMRKzkWJGJuwVvWpvZKx7vspJALyvaaIQyug==}
dependencies:
'@actions/http-client': 2.0.1
uuid: 8.3.2
dev: false
- /@actions/http-client/2.0.1:
+ /@actions/http-client@2.0.1:
resolution: {integrity: sha512-PIXiMVtz6VvyaRsGY268qvj57hXQEpsYogYOu2nrQhlf+XCGmZstmuZBbAybUl1nQGnvS1k1eEsQ69ZoD7xlSw==}
dependencies:
tunnel: 0.0.6
dev: false
- /@ampproject/remapping/2.2.0:
+ /@ampproject/remapping@2.2.0:
resolution: {integrity: sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==}
engines: {node: '>=6.0.0'}
dependencies:
@@ -45,26 +55,26 @@ packages:
'@jridgewell/trace-mapping': 0.3.15
dev: true
- /@babel/code-frame/7.18.6:
+ /@babel/code-frame@7.18.6:
resolution: {integrity: sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==}
engines: {node: '>=6.9.0'}
dependencies:
'@babel/highlight': 7.18.6
dev: true
- /@babel/compat-data/7.19.3:
+ /@babel/compat-data@7.19.3:
resolution: {integrity: sha512-prBHMK4JYYK+wDjJF1q99KK4JLL+egWS4nmNqdlMUgCExMZ+iZW0hGhyC3VEbsPjvaN0TBhW//VIFwBrk8sEiw==}
engines: {node: '>=6.9.0'}
dev: true
- /@babel/core/7.19.3:
+ /@babel/core@7.19.3:
resolution: {integrity: sha512-WneDJxdsjEvyKtXKsaBGbDeiyOjR5vYq4HcShxnIbG0qixpoHjI3MqeZM9NDvsojNCEBItQE4juOo/bU6e72gQ==}
engines: {node: '>=6.9.0'}
dependencies:
'@ampproject/remapping': 2.2.0
'@babel/code-frame': 7.18.6
'@babel/generator': 7.19.3
- '@babel/helper-compilation-targets': 7.19.3_@babel+core@7.19.3
+ '@babel/helper-compilation-targets': 7.19.3(@babel/core@7.19.3)
'@babel/helper-module-transforms': 7.19.0
'@babel/helpers': 7.19.0
'@babel/parser': 7.19.3
@@ -80,7 +90,7 @@ packages:
- supports-color
dev: true
- /@babel/generator/7.19.3:
+ /@babel/generator@7.19.3:
resolution: {integrity: sha512-fqVZnmp1ncvZU757UzDheKZpfPgatqY59XtW2/j/18H7u76akb8xqvjw82f+i2UKd/ksYsSick/BCLQUUtJ/qQ==}
engines: {node: '>=6.9.0'}
dependencies:
@@ -89,7 +99,7 @@ packages:
jsesc: 2.5.2
dev: true
- /@babel/helper-compilation-targets/7.19.3_@babel+core@7.19.3:
+ /@babel/helper-compilation-targets@7.19.3(@babel/core@7.19.3):
resolution: {integrity: sha512-65ESqLGyGmLvgR0mst5AdW1FkNlj9rQsCKduzEoEPhBCDFGXvz2jW6bXFG6i0/MrV2s7hhXjjb2yAzcPuQlLwg==}
engines: {node: '>=6.9.0'}
peerDependencies:
@@ -102,12 +112,12 @@ packages:
semver: 6.3.0
dev: true
- /@babel/helper-environment-visitor/7.18.9:
+ /@babel/helper-environment-visitor@7.18.9:
resolution: {integrity: sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==}
engines: {node: '>=6.9.0'}
dev: true
- /@babel/helper-function-name/7.19.0:
+ /@babel/helper-function-name@7.19.0:
resolution: {integrity: sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==}
engines: {node: '>=6.9.0'}
dependencies:
@@ -115,21 +125,21 @@ packages:
'@babel/types': 7.19.3
dev: true
- /@babel/helper-hoist-variables/7.18.6:
+ /@babel/helper-hoist-variables@7.18.6:
resolution: {integrity: sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==}
engines: {node: '>=6.9.0'}
dependencies:
'@babel/types': 7.19.3
dev: true
- /@babel/helper-module-imports/7.18.6:
+ /@babel/helper-module-imports@7.18.6:
resolution: {integrity: sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==}
engines: {node: '>=6.9.0'}
dependencies:
'@babel/types': 7.19.3
dev: true
- /@babel/helper-module-transforms/7.19.0:
+ /@babel/helper-module-transforms@7.19.0:
resolution: {integrity: sha512-3HBZ377Fe14RbLIA+ac3sY4PTgpxHVkFrESaWhoI5PuyXPBBX8+C34qblV9G89ZtycGJCmCI/Ut+VUDK4bltNQ==}
engines: {node: '>=6.9.0'}
dependencies:
@@ -145,41 +155,41 @@ packages:
- supports-color
dev: true
- /@babel/helper-plugin-utils/7.19.0:
+ /@babel/helper-plugin-utils@7.19.0:
resolution: {integrity: sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw==}
engines: {node: '>=6.9.0'}
dev: true
- /@babel/helper-simple-access/7.18.6:
+ /@babel/helper-simple-access@7.18.6:
resolution: {integrity: sha512-iNpIgTgyAvDQpDj76POqg+YEt8fPxx3yaNBg3S30dxNKm2SWfYhD0TGrK/Eu9wHpUW63VQU894TsTg+GLbUa1g==}
engines: {node: '>=6.9.0'}
dependencies:
'@babel/types': 7.19.3
dev: true
- /@babel/helper-split-export-declaration/7.18.6:
+ /@babel/helper-split-export-declaration@7.18.6:
resolution: {integrity: sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==}
engines: {node: '>=6.9.0'}
dependencies:
'@babel/types': 7.19.3
dev: true
- /@babel/helper-string-parser/7.18.10:
+ /@babel/helper-string-parser@7.18.10:
resolution: {integrity: sha512-XtIfWmeNY3i4t7t4D2t02q50HvqHybPqW2ki1kosnvWCwuCMeo81Jf0gwr85jy/neUdg5XDdeFE/80DXiO+njw==}
engines: {node: '>=6.9.0'}
dev: true
- /@babel/helper-validator-identifier/7.19.1:
+ /@babel/helper-validator-identifier@7.19.1:
resolution: {integrity: sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==}
engines: {node: '>=6.9.0'}
dev: true
- /@babel/helper-validator-option/7.18.6:
+ /@babel/helper-validator-option@7.18.6:
resolution: {integrity: sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==}
engines: {node: '>=6.9.0'}
dev: true
- /@babel/helpers/7.19.0:
+ /@babel/helpers@7.19.0:
resolution: {integrity: sha512-DRBCKGwIEdqY3+rPJgG/dKfQy9+08rHIAJx8q2p+HSWP87s2HCrQmaAMMyMll2kIXKCW0cO1RdQskx15Xakftg==}
engines: {node: '>=6.9.0'}
dependencies:
@@ -190,7 +200,7 @@ packages:
- supports-color
dev: true
- /@babel/highlight/7.18.6:
+ /@babel/highlight@7.18.6:
resolution: {integrity: sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==}
engines: {node: '>=6.9.0'}
dependencies:
@@ -199,7 +209,7 @@ packages:
js-tokens: 4.0.0
dev: true
- /@babel/parser/7.19.3:
+ /@babel/parser@7.19.3:
resolution: {integrity: sha512-pJ9xOlNWHiy9+FuFP09DEAFbAn4JskgRsVcc169w2xRBC3FRGuQEwjeIMMND9L2zc0iEhO/tGv4Zq+km+hxNpQ==}
engines: {node: '>=6.0.0'}
hasBin: true
@@ -207,7 +217,7 @@ packages:
'@babel/types': 7.19.3
dev: true
- /@babel/plugin-syntax-async-generators/7.8.4_@babel+core@7.19.3:
+ /@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.19.3):
resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==}
peerDependencies:
'@babel/core': ^7.0.0-0
@@ -216,7 +226,7 @@ packages:
'@babel/helper-plugin-utils': 7.19.0
dev: true
- /@babel/plugin-syntax-bigint/7.8.3_@babel+core@7.19.3:
+ /@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.19.3):
resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==}
peerDependencies:
'@babel/core': ^7.0.0-0
@@ -225,7 +235,7 @@ packages:
'@babel/helper-plugin-utils': 7.19.0
dev: true
- /@babel/plugin-syntax-class-properties/7.12.13_@babel+core@7.19.3:
+ /@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.19.3):
resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==}
peerDependencies:
'@babel/core': ^7.0.0-0
@@ -234,7 +244,7 @@ packages:
'@babel/helper-plugin-utils': 7.19.0
dev: true
- /@babel/plugin-syntax-import-meta/7.10.4_@babel+core@7.19.3:
+ /@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.19.3):
resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==}
peerDependencies:
'@babel/core': ^7.0.0-0
@@ -243,7 +253,7 @@ packages:
'@babel/helper-plugin-utils': 7.19.0
dev: true
- /@babel/plugin-syntax-json-strings/7.8.3_@babel+core@7.19.3:
+ /@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.19.3):
resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==}
peerDependencies:
'@babel/core': ^7.0.0-0
@@ -252,7 +262,7 @@ packages:
'@babel/helper-plugin-utils': 7.19.0
dev: true
- /@babel/plugin-syntax-jsx/7.18.6_@babel+core@7.19.3:
+ /@babel/plugin-syntax-jsx@7.18.6(@babel/core@7.19.3):
resolution: {integrity: sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==}
engines: {node: '>=6.9.0'}
peerDependencies:
@@ -262,7 +272,7 @@ packages:
'@babel/helper-plugin-utils': 7.19.0
dev: true
- /@babel/plugin-syntax-logical-assignment-operators/7.10.4_@babel+core@7.19.3:
+ /@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.19.3):
resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==}
peerDependencies:
'@babel/core': ^7.0.0-0
@@ -271,7 +281,7 @@ packages:
'@babel/helper-plugin-utils': 7.19.0
dev: true
- /@babel/plugin-syntax-nullish-coalescing-operator/7.8.3_@babel+core@7.19.3:
+ /@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.19.3):
resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==}
peerDependencies:
'@babel/core': ^7.0.0-0
@@ -280,7 +290,7 @@ packages:
'@babel/helper-plugin-utils': 7.19.0
dev: true
- /@babel/plugin-syntax-numeric-separator/7.10.4_@babel+core@7.19.3:
+ /@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.19.3):
resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==}
peerDependencies:
'@babel/core': ^7.0.0-0
@@ -289,7 +299,7 @@ packages:
'@babel/helper-plugin-utils': 7.19.0
dev: true
- /@babel/plugin-syntax-object-rest-spread/7.8.3_@babel+core@7.19.3:
+ /@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.19.3):
resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==}
peerDependencies:
'@babel/core': ^7.0.0-0
@@ -298,7 +308,7 @@ packages:
'@babel/helper-plugin-utils': 7.19.0
dev: true
- /@babel/plugin-syntax-optional-catch-binding/7.8.3_@babel+core@7.19.3:
+ /@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.19.3):
resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==}
peerDependencies:
'@babel/core': ^7.0.0-0
@@ -307,7 +317,7 @@ packages:
'@babel/helper-plugin-utils': 7.19.0
dev: true
- /@babel/plugin-syntax-optional-chaining/7.8.3_@babel+core@7.19.3:
+ /@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.19.3):
resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==}
peerDependencies:
'@babel/core': ^7.0.0-0
@@ -316,7 +326,7 @@ packages:
'@babel/helper-plugin-utils': 7.19.0
dev: true
- /@babel/plugin-syntax-top-level-await/7.14.5_@babel+core@7.19.3:
+ /@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.19.3):
resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==}
engines: {node: '>=6.9.0'}
peerDependencies:
@@ -326,7 +336,7 @@ packages:
'@babel/helper-plugin-utils': 7.19.0
dev: true
- /@babel/plugin-syntax-typescript/7.18.6_@babel+core@7.19.3:
+ /@babel/plugin-syntax-typescript@7.18.6(@babel/core@7.19.3):
resolution: {integrity: sha512-mAWAuq4rvOepWCBid55JuRNvpTNf2UGVgoz4JV0fXEKolsVZDzsa4NqCef758WZJj/GDu0gVGItjKFiClTAmZA==}
engines: {node: '>=6.9.0'}
peerDependencies:
@@ -336,7 +346,7 @@ packages:
'@babel/helper-plugin-utils': 7.19.0
dev: true
- /@babel/template/7.18.10:
+ /@babel/template@7.18.10:
resolution: {integrity: sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==}
engines: {node: '>=6.9.0'}
dependencies:
@@ -345,7 +355,7 @@ packages:
'@babel/types': 7.19.3
dev: true
- /@babel/traverse/7.19.3:
+ /@babel/traverse@7.19.3:
resolution: {integrity: sha512-qh5yf6149zhq2sgIXmwjnsvmnNQC2iw70UFjp4olxucKrWd/dvlUsBI88VSLUsnMNF7/vnOiA+nk1+yLoCqROQ==}
engines: {node: '>=6.9.0'}
dependencies:
@@ -363,7 +373,7 @@ packages:
- supports-color
dev: true
- /@babel/types/7.19.3:
+ /@babel/types@7.19.3:
resolution: {integrity: sha512-hGCaQzIY22DJlDh9CH7NOxgKkFjBk0Cw9xDO1Xmh2151ti7wiGfQ3LauXzL4HP1fmFlTX6XjpRETTpUcv7wQLw==}
engines: {node: '>=6.9.0'}
dependencies:
@@ -372,17 +382,17 @@ packages:
to-fast-properties: 2.0.0
dev: true
- /@bcoe/v8-coverage/0.2.3:
+ /@bcoe/v8-coverage@0.2.3:
resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==}
dev: true
- /@cspotcode/source-map-support/0.8.1:
+ /@cspotcode/source-map-support@0.8.1:
resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==}
engines: {node: '>=12'}
dependencies:
'@jridgewell/trace-mapping': 0.3.9
- /@istanbuljs/load-nyc-config/1.1.0:
+ /@istanbuljs/load-nyc-config@1.1.0:
resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==}
engines: {node: '>=8'}
dependencies:
@@ -393,12 +403,12 @@ packages:
resolve-from: 5.0.0
dev: true
- /@istanbuljs/schema/0.1.3:
+ /@istanbuljs/schema@0.1.3:
resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==}
engines: {node: '>=8'}
dev: true
- /@jest/console/29.1.2:
+ /@jest/console@29.1.2:
resolution: {integrity: sha512-ujEBCcYs82BTmRxqfHMQggSlkUZP63AE5YEaTPj7eFyJOzukkTorstOUC7L6nE3w5SYadGVAnTsQ/ZjTGL0qYQ==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
@@ -410,7 +420,7 @@ packages:
slash: 3.0.0
dev: true
- /@jest/core/29.1.2_ts-node@10.9.1:
+ /@jest/core@29.1.2(ts-node@10.9.1):
resolution: {integrity: sha512-sCO2Va1gikvQU2ynDN8V4+6wB7iVrD2CvT0zaRst4rglf56yLly0NQ9nuRRAWFeimRf+tCdFsb1Vk1N9LrrMPA==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
peerDependencies:
@@ -431,7 +441,7 @@ packages:
exit: 0.1.2
graceful-fs: 4.2.10
jest-changed-files: 29.0.0
- jest-config: 29.1.2_texb6yekbdrurkf2spvwkwkdam
+ jest-config: 29.1.2(@types/node@18.8.2)(ts-node@10.9.1)
jest-haste-map: 29.1.2
jest-message-util: 29.1.2
jest-regex-util: 29.0.0
@@ -452,7 +462,7 @@ packages:
- ts-node
dev: true
- /@jest/environment/29.1.2:
+ /@jest/environment@29.1.2:
resolution: {integrity: sha512-rG7xZ2UeOfvOVzoLIJ0ZmvPl4tBEQ2n73CZJSlzUjPw4or1oSWC0s0Rk0ZX+pIBJ04aVr6hLWFn1DFtrnf8MhQ==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
@@ -462,14 +472,14 @@ packages:
jest-mock: 29.1.2
dev: true
- /@jest/expect-utils/29.1.2:
+ /@jest/expect-utils@29.1.2:
resolution: {integrity: sha512-4a48bhKfGj/KAH39u0ppzNTABXQ8QPccWAFUFobWBaEMSMp+sB31Z2fK/l47c4a/Mu1po2ffmfAIPxXbVTXdtg==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
jest-get-type: 29.0.0
dev: true
- /@jest/expect/29.1.2:
+ /@jest/expect@29.1.2:
resolution: {integrity: sha512-FXw/UmaZsyfRyvZw3M6POgSNqwmuOXJuzdNiMWW9LCYo0GRoRDhg+R5iq5higmRTHQY7hx32+j7WHwinRmoILQ==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
@@ -479,7 +489,7 @@ packages:
- supports-color
dev: true
- /@jest/fake-timers/29.1.2:
+ /@jest/fake-timers@29.1.2:
resolution: {integrity: sha512-GppaEqS+QQYegedxVMpCe2xCXxxeYwQ7RsNx55zc8f+1q1qevkZGKequfTASI7ejmg9WwI+SJCrHe9X11bLL9Q==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
@@ -491,7 +501,7 @@ packages:
jest-util: 29.1.2
dev: true
- /@jest/globals/29.1.2:
+ /@jest/globals@29.1.2:
resolution: {integrity: sha512-uMgfERpJYoQmykAd0ffyMq8wignN4SvLUG6orJQRe9WAlTRc9cdpCaE/29qurXixYJVZWUqIBXhSk8v5xN1V9g==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
@@ -503,7 +513,7 @@ packages:
- supports-color
dev: true
- /@jest/reporters/29.1.2:
+ /@jest/reporters@29.1.2:
resolution: {integrity: sha512-X4fiwwyxy9mnfpxL0g9DD0KcTmEIqP0jUdnc2cfa9riHy+I6Gwwp5vOZiwyg0vZxfSDxrOlK9S4+340W4d+DAA==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
peerDependencies:
@@ -541,14 +551,14 @@ packages:
- supports-color
dev: true
- /@jest/schemas/29.0.0:
+ /@jest/schemas@29.0.0:
resolution: {integrity: sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
'@sinclair/typebox': 0.24.44
dev: true
- /@jest/source-map/29.0.0:
+ /@jest/source-map@29.0.0:
resolution: {integrity: sha512-nOr+0EM8GiHf34mq2GcJyz/gYFyLQ2INDhAylrZJ9mMWoW21mLBfZa0BUVPPMxVYrLjeiRe2Z7kWXOGnS0TFhQ==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
@@ -557,7 +567,7 @@ packages:
graceful-fs: 4.2.10
dev: true
- /@jest/test-result/29.1.2:
+ /@jest/test-result@29.1.2:
resolution: {integrity: sha512-jjYYjjumCJjH9hHCoMhA8PCl1OxNeGgAoZ7yuGYILRJX9NjgzTN0pCT5qAoYR4jfOP8htIByvAlz9vfNSSBoVg==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
@@ -567,7 +577,7 @@ packages:
collect-v8-coverage: 1.0.1
dev: true
- /@jest/test-sequencer/29.1.2:
+ /@jest/test-sequencer@29.1.2:
resolution: {integrity: sha512-fU6dsUqqm8sA+cd85BmeF7Gu9DsXVWFdGn9taxM6xN1cKdcP/ivSgXh5QucFRFz1oZxKv3/9DYYbq0ULly3P/Q==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
@@ -577,7 +587,7 @@ packages:
slash: 3.0.0
dev: true
- /@jest/transform/29.1.2:
+ /@jest/transform@29.1.2:
resolution: {integrity: sha512-2uaUuVHTitmkx1tHF+eBjb4p7UuzBG7SXIaA/hNIkaMP6K+gXYGxP38ZcrofzqN0HeZ7A90oqsOa97WU7WZkSw==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
@@ -600,7 +610,7 @@ packages:
- supports-color
dev: true
- /@jest/types/29.1.2:
+ /@jest/types@29.1.2:
resolution: {integrity: sha512-DcXGtoTykQB5jiwCmVr8H4vdg2OJhQex3qPkG+ISyDO7xQXbt/4R6dowcRyPemRnkH7JoHvZuxPBdlq+9JxFCg==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
@@ -612,7 +622,7 @@ packages:
chalk: 4.1.2
dev: true
- /@jridgewell/gen-mapping/0.1.1:
+ /@jridgewell/gen-mapping@0.1.1:
resolution: {integrity: sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==}
engines: {node: '>=6.0.0'}
dependencies:
@@ -620,7 +630,7 @@ packages:
'@jridgewell/sourcemap-codec': 1.4.14
dev: true
- /@jridgewell/gen-mapping/0.3.2:
+ /@jridgewell/gen-mapping@0.3.2:
resolution: {integrity: sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==}
engines: {node: '>=6.0.0'}
dependencies:
@@ -629,32 +639,32 @@ packages:
'@jridgewell/trace-mapping': 0.3.15
dev: true
- /@jridgewell/resolve-uri/3.1.0:
+ /@jridgewell/resolve-uri@3.1.0:
resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==}
engines: {node: '>=6.0.0'}
- /@jridgewell/set-array/1.1.2:
+ /@jridgewell/set-array@1.1.2:
resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==}
engines: {node: '>=6.0.0'}
dev: true
- /@jridgewell/sourcemap-codec/1.4.14:
+ /@jridgewell/sourcemap-codec@1.4.14:
resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==}
- /@jridgewell/trace-mapping/0.3.15:
+ /@jridgewell/trace-mapping@0.3.15:
resolution: {integrity: sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g==}
dependencies:
'@jridgewell/resolve-uri': 3.1.0
'@jridgewell/sourcemap-codec': 1.4.14
dev: true
- /@jridgewell/trace-mapping/0.3.9:
+ /@jridgewell/trace-mapping@0.3.9:
resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==}
dependencies:
'@jridgewell/resolve-uri': 3.1.0
'@jridgewell/sourcemap-codec': 1.4.14
- /@nodelib/fs.scandir/2.1.5:
+ /@nodelib/fs.scandir@2.1.5:
resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
engines: {node: '>= 8'}
dependencies:
@@ -662,12 +672,12 @@ packages:
run-parallel: 1.2.0
dev: false
- /@nodelib/fs.stat/2.0.5:
+ /@nodelib/fs.stat@2.0.5:
resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==}
engines: {node: '>= 8'}
dev: false
- /@nodelib/fs.walk/1.2.8:
+ /@nodelib/fs.walk@1.2.8:
resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
engines: {node: '>= 8'}
dependencies:
@@ -675,35 +685,35 @@ packages:
fastq: 1.13.0
dev: false
- /@sinclair/typebox/0.24.44:
+ /@sinclair/typebox@0.24.44:
resolution: {integrity: sha512-ka0W0KN5i6LfrSocduwliMMpqVgohtPFidKdMEOUjoOFCHcOOYkKsPRxfs5f15oPNHTm6ERAm0GV/+/LTKeiWg==}
dev: true
- /@sinonjs/commons/1.8.3:
+ /@sinonjs/commons@1.8.3:
resolution: {integrity: sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==}
dependencies:
type-detect: 4.0.8
dev: true
- /@sinonjs/fake-timers/9.1.2:
+ /@sinonjs/fake-timers@9.1.2:
resolution: {integrity: sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==}
dependencies:
'@sinonjs/commons': 1.8.3
dev: true
- /@tsconfig/node10/1.0.9:
+ /@tsconfig/node10@1.0.9:
resolution: {integrity: sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==}
- /@tsconfig/node12/1.0.11:
+ /@tsconfig/node12@1.0.11:
resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==}
- /@tsconfig/node14/1.0.3:
+ /@tsconfig/node14@1.0.3:
resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==}
- /@tsconfig/node16/1.0.3:
+ /@tsconfig/node16@1.0.3:
resolution: {integrity: sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==}
- /@types/babel__core/7.1.19:
+ /@types/babel__core@7.1.19:
resolution: {integrity: sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw==}
dependencies:
'@babel/parser': 7.19.3
@@ -713,134 +723,134 @@ packages:
'@types/babel__traverse': 7.18.2
dev: true
- /@types/babel__generator/7.6.4:
+ /@types/babel__generator@7.6.4:
resolution: {integrity: sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==}
dependencies:
'@babel/types': 7.19.3
dev: true
- /@types/babel__template/7.4.1:
+ /@types/babel__template@7.4.1:
resolution: {integrity: sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==}
dependencies:
'@babel/parser': 7.19.3
'@babel/types': 7.19.3
dev: true
- /@types/babel__traverse/7.18.2:
+ /@types/babel__traverse@7.18.2:
resolution: {integrity: sha512-FcFaxOr2V5KZCviw1TnutEMVUVsGt4D2hP1TAfXZAMKuHYW3xQhe3jTxNPWutgCJ3/X1c5yX8ZoGVEItxKbwBg==}
dependencies:
'@babel/types': 7.19.3
dev: true
- /@types/fs-extra/9.0.13:
+ /@types/fs-extra@9.0.13:
resolution: {integrity: sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==}
dependencies:
'@types/node': 18.8.2
dev: false
- /@types/graceful-fs/4.1.5:
+ /@types/graceful-fs@4.1.5:
resolution: {integrity: sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==}
dependencies:
'@types/node': 18.8.2
dev: true
- /@types/istanbul-lib-coverage/2.0.4:
+ /@types/istanbul-lib-coverage@2.0.4:
resolution: {integrity: sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==}
dev: true
- /@types/istanbul-lib-report/3.0.0:
+ /@types/istanbul-lib-report@3.0.0:
resolution: {integrity: sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==}
dependencies:
'@types/istanbul-lib-coverage': 2.0.4
dev: true
- /@types/istanbul-reports/3.0.1:
+ /@types/istanbul-reports@3.0.1:
resolution: {integrity: sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==}
dependencies:
'@types/istanbul-lib-report': 3.0.0
dev: true
- /@types/jest/29.1.2:
+ /@types/jest@29.1.2:
resolution: {integrity: sha512-y+nlX0h87U0R+wsGn6EBuoRWYyv3KFtwRNP3QWp9+k2tJ2/bqcGS3UxD7jgT+tiwJWWq3UsyV4Y+T6rsMT4XMg==}
dependencies:
expect: 29.1.2
pretty-format: 29.1.2
dev: true
- /@types/minimist/1.2.2:
+ /@types/minimist@1.2.2:
resolution: {integrity: sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==}
dev: false
- /@types/node/18.8.2:
+ /@types/node@18.8.2:
resolution: {integrity: sha512-cRMwIgdDN43GO4xMWAfJAecYn8wV4JbsOGHNfNUIDiuYkUYAR5ec4Rj7IO2SAhFPEfpPtLtUTbbny/TCT7aDwA==}
- /@types/prettier/2.7.1:
+ /@types/prettier@2.7.1:
resolution: {integrity: sha512-ri0UmynRRvZiiUJdiz38MmIblKK+oH30MztdBVR95dv/Ubw6neWSb8u1XpRb72L4qsZOhz+L+z9JD40SJmfWow==}
dev: true
- /@types/ps-tree/1.1.2:
+ /@types/ps-tree@1.1.2:
resolution: {integrity: sha512-ZREFYlpUmPQJ0esjxoG1fMvB2HNaD3z+mjqdSosZvd3RalncI9NEur73P8ZJz4YQdL64CmV1w0RuqoRUlhQRBw==}
dev: false
- /@types/stack-utils/2.0.1:
+ /@types/stack-utils@2.0.1:
resolution: {integrity: sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==}
dev: true
- /@types/which/2.0.1:
+ /@types/which@2.0.1:
resolution: {integrity: sha512-Jjakcv8Roqtio6w1gr0D7y6twbhx6gGgFGF5BLwajPpnOIOxFkakFhCq+LmyyeAz7BX6ULrjBOxdKaCDy+4+dQ==}
dev: false
- /@types/yargs-parser/21.0.0:
+ /@types/yargs-parser@21.0.0:
resolution: {integrity: sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==}
dev: true
- /@types/yargs/17.0.13:
+ /@types/yargs@17.0.13:
resolution: {integrity: sha512-9sWaruZk2JGxIQU+IhI1fhPYRcQ0UuTNuKuCW9bR5fp7qi2Llf7WDzNa17Cy7TKnh3cdxDOiyTu6gaLS0eDatg==}
dependencies:
'@types/yargs-parser': 21.0.0
dev: true
- /acorn-walk/8.2.0:
+ /acorn-walk@8.2.0:
resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==}
engines: {node: '>=0.4.0'}
- /acorn/8.8.0:
+ /acorn@8.8.0:
resolution: {integrity: sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==}
engines: {node: '>=0.4.0'}
hasBin: true
- /ansi-escapes/4.3.2:
+ /ansi-escapes@4.3.2:
resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==}
engines: {node: '>=8'}
dependencies:
type-fest: 0.21.3
dev: true
- /ansi-regex/5.0.1:
+ /ansi-regex@5.0.1:
resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
engines: {node: '>=8'}
dev: true
- /ansi-styles/3.2.1:
+ /ansi-styles@3.2.1:
resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==}
engines: {node: '>=4'}
dependencies:
color-convert: 1.9.3
dev: true
- /ansi-styles/4.3.0:
+ /ansi-styles@4.3.0:
resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
engines: {node: '>=8'}
dependencies:
color-convert: 2.0.1
dev: true
- /ansi-styles/5.2.0:
+ /ansi-styles@5.2.0:
resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==}
engines: {node: '>=10'}
dev: true
- /anymatch/3.1.2:
+ /anymatch@3.1.2:
resolution: {integrity: sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==}
engines: {node: '>= 8'}
dependencies:
@@ -848,16 +858,16 @@ packages:
picomatch: 2.3.1
dev: true
- /arg/4.1.3:
+ /arg@4.1.3:
resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==}
- /argparse/1.0.10:
+ /argparse@1.0.10:
resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==}
dependencies:
sprintf-js: 1.0.3
dev: true
- /babel-jest/29.1.2_@babel+core@7.19.3:
+ /babel-jest@29.1.2(@babel/core@7.19.3):
resolution: {integrity: sha512-IuG+F3HTHryJb7gacC7SQ59A9kO56BctUsT67uJHp1mMCHUOMXpDwOHWGifWqdWVknN2WNkCVQELPjXx0aLJ9Q==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
peerDependencies:
@@ -867,7 +877,7 @@ packages:
'@jest/transform': 29.1.2
'@types/babel__core': 7.1.19
babel-plugin-istanbul: 6.1.1
- babel-preset-jest: 29.0.2_@babel+core@7.19.3
+ babel-preset-jest: 29.0.2(@babel/core@7.19.3)
chalk: 4.1.2
graceful-fs: 4.2.10
slash: 3.0.0
@@ -875,7 +885,7 @@ packages:
- supports-color
dev: true
- /babel-plugin-istanbul/6.1.1:
+ /babel-plugin-istanbul@6.1.1:
resolution: {integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==}
engines: {node: '>=8'}
dependencies:
@@ -888,7 +898,7 @@ packages:
- supports-color
dev: true
- /babel-plugin-jest-hoist/29.0.2:
+ /babel-plugin-jest-hoist@29.0.2:
resolution: {integrity: sha512-eBr2ynAEFjcebVvu8Ktx580BD1QKCrBG1XwEUTXJe285p9HA/4hOhfWCFRQhTKSyBV0VzjhG7H91Eifz9s29hg==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
@@ -898,27 +908,27 @@ packages:
'@types/babel__traverse': 7.18.2
dev: true
- /babel-preset-current-node-syntax/1.0.1_@babel+core@7.19.3:
+ /babel-preset-current-node-syntax@1.0.1(@babel/core@7.19.3):
resolution: {integrity: sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==}
peerDependencies:
'@babel/core': ^7.0.0
dependencies:
'@babel/core': 7.19.3
- '@babel/plugin-syntax-async-generators': 7.8.4_@babel+core@7.19.3
- '@babel/plugin-syntax-bigint': 7.8.3_@babel+core@7.19.3
- '@babel/plugin-syntax-class-properties': 7.12.13_@babel+core@7.19.3
- '@babel/plugin-syntax-import-meta': 7.10.4_@babel+core@7.19.3
- '@babel/plugin-syntax-json-strings': 7.8.3_@babel+core@7.19.3
- '@babel/plugin-syntax-logical-assignment-operators': 7.10.4_@babel+core@7.19.3
- '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3_@babel+core@7.19.3
- '@babel/plugin-syntax-numeric-separator': 7.10.4_@babel+core@7.19.3
- '@babel/plugin-syntax-object-rest-spread': 7.8.3_@babel+core@7.19.3
- '@babel/plugin-syntax-optional-catch-binding': 7.8.3_@babel+core@7.19.3
- '@babel/plugin-syntax-optional-chaining': 7.8.3_@babel+core@7.19.3
- '@babel/plugin-syntax-top-level-await': 7.14.5_@babel+core@7.19.3
- dev: true
-
- /babel-preset-jest/29.0.2_@babel+core@7.19.3:
+ '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.19.3)
+ '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.19.3)
+ '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.19.3)
+ '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.19.3)
+ '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.19.3)
+ '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.19.3)
+ '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.19.3)
+ '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.19.3)
+ '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.19.3)
+ '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.19.3)
+ '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.19.3)
+ '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.19.3)
+ dev: true
+
+ /babel-preset-jest@29.0.2(@babel/core@7.19.3):
resolution: {integrity: sha512-BeVXp7rH5TK96ofyEnHjznjLMQ2nAeDJ+QzxKnHAAMs0RgrQsCywjAN8m4mOm5Di0pxU//3AoEeJJrerMH5UeA==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
peerDependencies:
@@ -926,27 +936,27 @@ packages:
dependencies:
'@babel/core': 7.19.3
babel-plugin-jest-hoist: 29.0.2
- babel-preset-current-node-syntax: 1.0.1_@babel+core@7.19.3
+ babel-preset-current-node-syntax: 1.0.1(@babel/core@7.19.3)
dev: true
- /balanced-match/1.0.2:
+ /balanced-match@1.0.2:
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
dev: true
- /brace-expansion/1.1.11:
+ /brace-expansion@1.1.11:
resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==}
dependencies:
balanced-match: 1.0.2
concat-map: 0.0.1
dev: true
- /braces/3.0.2:
+ /braces@3.0.2:
resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==}
engines: {node: '>=8'}
dependencies:
fill-range: 7.0.1
- /browserslist/4.21.4:
+ /browserslist@4.21.4:
resolution: {integrity: sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==}
engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
hasBin: true
@@ -954,46 +964,46 @@ packages:
caniuse-lite: 1.0.30001418
electron-to-chromium: 1.4.275
node-releases: 2.0.6
- update-browserslist-db: 1.0.10_browserslist@4.21.4
+ update-browserslist-db: 1.0.10(browserslist@4.21.4)
dev: true
- /bs-logger/0.2.6:
+ /bs-logger@0.2.6:
resolution: {integrity: sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==}
engines: {node: '>= 6'}
dependencies:
fast-json-stable-stringify: 2.1.0
dev: true
- /bser/2.1.1:
+ /bser@2.1.1:
resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==}
dependencies:
node-int64: 0.4.0
dev: true
- /buffer-from/1.1.2:
+ /buffer-from@1.1.2:
resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==}
dev: true
- /callsites/3.1.0:
+ /callsites@3.1.0:
resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
engines: {node: '>=6'}
dev: true
- /camelcase/5.3.1:
+ /camelcase@5.3.1:
resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==}
engines: {node: '>=6'}
dev: true
- /camelcase/6.3.0:
+ /camelcase@6.3.0:
resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==}
engines: {node: '>=10'}
dev: true
- /caniuse-lite/1.0.30001418:
+ /caniuse-lite@1.0.30001418:
resolution: {integrity: sha512-oIs7+JL3K9JRQ3jPZjlH6qyYDp+nBTCais7hjh0s+fuBwufc7uZ7hPYMXrDOJhV360KGMTcczMRObk0/iMqZRg==}
dev: true
- /chalk/2.4.2:
+ /chalk@2.4.2:
resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==}
engines: {node: '>=4'}
dependencies:
@@ -1002,7 +1012,7 @@ packages:
supports-color: 5.5.0
dev: true
- /chalk/4.1.2:
+ /chalk@4.1.2:
resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
engines: {node: '>=10'}
dependencies:
@@ -1010,25 +1020,25 @@ packages:
supports-color: 7.2.0
dev: true
- /chalk/5.0.1:
+ /chalk@5.0.1:
resolution: {integrity: sha512-Fo07WOYGqMfCWHOzSXOt2CxDbC6skS/jO9ynEcmpANMoPrD+W1r1K6Vx7iNm+AQmETU1Xr2t+n8nzkV9t6xh3w==}
engines: {node: ^12.17.0 || ^14.13 || >=16.0.0}
dev: false
- /char-regex/1.0.2:
+ /char-regex@1.0.2:
resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==}
engines: {node: '>=10'}
dev: true
- /ci-info/3.4.0:
+ /ci-info@3.4.0:
resolution: {integrity: sha512-t5QdPT5jq3o262DOQ8zA6E1tlH2upmUc4Hlvrbx1pGYJuiiHl7O7rvVNI+l8HTVhd/q3Qc9vqimkNk5yiXsAug==}
dev: true
- /cjs-module-lexer/1.2.2:
+ /cjs-module-lexer@1.2.2:
resolution: {integrity: sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==}
dev: true
- /cliui/8.0.1:
+ /cliui@8.0.1:
resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==}
engines: {node: '>=12'}
dependencies:
@@ -1037,50 +1047,50 @@ packages:
wrap-ansi: 7.0.0
dev: true
- /co/4.6.0:
+ /co@4.6.0:
resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==}
engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'}
dev: true
- /collect-v8-coverage/1.0.1:
+ /collect-v8-coverage@1.0.1:
resolution: {integrity: sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==}
dev: true
- /color-convert/1.9.3:
+ /color-convert@1.9.3:
resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==}
dependencies:
color-name: 1.1.3
dev: true
- /color-convert/2.0.1:
+ /color-convert@2.0.1:
resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
engines: {node: '>=7.0.0'}
dependencies:
color-name: 1.1.4
dev: true
- /color-name/1.1.3:
+ /color-name@1.1.3:
resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==}
dev: true
- /color-name/1.1.4:
+ /color-name@1.1.4:
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
dev: true
- /concat-map/0.0.1:
+ /concat-map@0.0.1:
resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=}
dev: true
- /convert-source-map/1.8.0:
+ /convert-source-map@1.8.0:
resolution: {integrity: sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==}
dependencies:
safe-buffer: 5.1.2
dev: true
- /create-require/1.1.1:
+ /create-require@1.1.1:
resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==}
- /cross-spawn/7.0.3:
+ /cross-spawn@7.0.3:
resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==}
engines: {node: '>= 8'}
dependencies:
@@ -1089,12 +1099,12 @@ packages:
which: 2.0.2
dev: true
- /data-uri-to-buffer/4.0.0:
+ /data-uri-to-buffer@4.0.0:
resolution: {integrity: sha512-Vr3mLBA8qWmcuschSLAOogKgQ/Jwxulv3RNE4FXnYWRGujzrRWQI4m12fQqRkwX06C0KanhLr4hK+GydchZsaA==}
engines: {node: '>= 12'}
dev: false
- /debug/4.3.4:
+ /debug@4.3.4:
resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==}
engines: {node: '>=6.0'}
peerDependencies:
@@ -1106,81 +1116,81 @@ packages:
ms: 2.1.2
dev: true
- /dedent/0.7.0:
+ /dedent@0.7.0:
resolution: {integrity: sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==}
dev: true
- /deepmerge/4.2.2:
+ /deepmerge@4.2.2:
resolution: {integrity: sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==}
engines: {node: '>=0.10.0'}
dev: true
- /detect-newline/3.1.0:
+ /detect-newline@3.1.0:
resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==}
engines: {node: '>=8'}
dev: true
- /diff-sequences/29.0.0:
+ /diff-sequences@29.0.0:
resolution: {integrity: sha512-7Qe/zd1wxSDL4D/X/FPjOMB+ZMDt71W94KYaq05I2l0oQqgXgs7s4ftYYmV38gBSrPz2vcygxfs1xn0FT+rKNA==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dev: true
- /diff/4.0.2:
+ /diff@4.0.2:
resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==}
engines: {node: '>=0.3.1'}
- /dir-glob/3.0.1:
+ /dir-glob@3.0.1:
resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==}
engines: {node: '>=8'}
dependencies:
path-type: 4.0.0
dev: false
- /duplexer/0.1.2:
+ /duplexer@0.1.2:
resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==}
dev: false
- /electron-to-chromium/1.4.275:
+ /electron-to-chromium@1.4.275:
resolution: {integrity: sha512-aJeQQ+Hl9Jyyzv4chBqYJwmVRY46N5i2BEX5Cuyk/5gFCUZ5F3i7Hnba6snZftWla7Gglwc5pIgcd+E7cW+rPg==}
dev: true
- /emittery/0.10.2:
+ /emittery@0.10.2:
resolution: {integrity: sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw==}
engines: {node: '>=12'}
dev: true
- /emoji-regex/8.0.0:
+ /emoji-regex@8.0.0:
resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
dev: true
- /error-ex/1.3.2:
+ /error-ex@1.3.2:
resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==}
dependencies:
is-arrayish: 0.2.1
dev: true
- /escalade/3.1.1:
+ /escalade@3.1.1:
resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==}
engines: {node: '>=6'}
dev: true
- /escape-string-regexp/1.0.5:
+ /escape-string-regexp@1.0.5:
resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==}
engines: {node: '>=0.8.0'}
dev: true
- /escape-string-regexp/2.0.0:
+ /escape-string-regexp@2.0.0:
resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==}
engines: {node: '>=8'}
dev: true
- /esprima/4.0.1:
+ /esprima@4.0.1:
resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==}
engines: {node: '>=4'}
hasBin: true
dev: true
- /event-stream/3.3.4:
+ /event-stream@3.3.4:
resolution: {integrity: sha512-QHpkERcGsR0T7Qm3HNJSyXKEEj8AHNxkY3PK8TS2KJvQ7NiSHe3DDpwVKKtoYprL/AreyzFBeIkBIWChAqn60g==}
dependencies:
duplexer: 0.1.2
@@ -1192,7 +1202,7 @@ packages:
through: 2.3.8
dev: false
- /execa/5.1.1:
+ /execa@5.1.1:
resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==}
engines: {node: '>=10'}
dependencies:
@@ -1207,12 +1217,12 @@ packages:
strip-final-newline: 2.0.0
dev: true
- /exit/0.1.2:
+ /exit@0.1.2:
resolution: {integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==}
engines: {node: '>= 0.8.0'}
dev: true
- /expect/29.1.2:
+ /expect@29.1.2:
resolution: {integrity: sha512-AuAGn1uxva5YBbBlXb+2JPxJRuemZsmlGcapPXWNSBNsQtAULfjioREGBWuI0EOvYUKjDnrCy8PW5Zlr1md5mw==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
@@ -1223,7 +1233,7 @@ packages:
jest-util: 29.1.2
dev: true
- /fast-glob/3.2.12:
+ /fast-glob@3.2.12:
resolution: {integrity: sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==}
engines: {node: '>=8.6.0'}
dependencies:
@@ -1234,23 +1244,23 @@ packages:
micromatch: 4.0.5
dev: false
- /fast-json-stable-stringify/2.1.0:
+ /fast-json-stable-stringify@2.1.0:
resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==}
dev: true
- /fastq/1.13.0:
+ /fastq@1.13.0:
resolution: {integrity: sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==}
dependencies:
reusify: 1.0.4
dev: false
- /fb-watchman/2.0.2:
+ /fb-watchman@2.0.2:
resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==}
dependencies:
bser: 2.1.1
dev: true
- /fetch-blob/3.2.0:
+ /fetch-blob@3.2.0:
resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==}
engines: {node: ^12.20 || >= 14.13}
dependencies:
@@ -1258,13 +1268,13 @@ packages:
web-streams-polyfill: 3.2.1
dev: false
- /fill-range/7.0.1:
+ /fill-range@7.0.1:
resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==}
engines: {node: '>=8'}
dependencies:
to-regex-range: 5.0.1
- /find-up/4.1.0:
+ /find-up@4.1.0:
resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==}
engines: {node: '>=8'}
dependencies:
@@ -1272,18 +1282,18 @@ packages:
path-exists: 4.0.0
dev: true
- /formdata-polyfill/4.0.10:
+ /formdata-polyfill@4.0.10:
resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==}
engines: {node: '>=12.20.0'}
dependencies:
fetch-blob: 3.2.0
dev: false
- /from/0.1.7:
+ /from@0.1.7:
resolution: {integrity: sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==}
dev: false
- /fs-extra/10.1.0:
+ /fs-extra@10.1.0:
resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==}
engines: {node: '>=12'}
dependencies:
@@ -1292,11 +1302,11 @@ packages:
universalify: 2.0.0
dev: false
- /fs.realpath/1.0.0:
+ /fs.realpath@1.0.0:
resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
dev: true
- /fsevents/2.3.2:
+ /fsevents@2.3.2:
resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==}
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
os: [darwin]
@@ -1304,38 +1314,38 @@ packages:
dev: true
optional: true
- /function-bind/1.1.1:
+ /function-bind@1.1.1:
resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==}
dev: true
- /gensync/1.0.0-beta.2:
+ /gensync@1.0.0-beta.2:
resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==}
engines: {node: '>=6.9.0'}
dev: true
- /get-caller-file/2.0.5:
+ /get-caller-file@2.0.5:
resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==}
engines: {node: 6.* || 8.* || >= 10.*}
dev: true
- /get-package-type/0.1.0:
+ /get-package-type@0.1.0:
resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==}
engines: {node: '>=8.0.0'}
dev: true
- /get-stream/6.0.1:
+ /get-stream@6.0.1:
resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==}
engines: {node: '>=10'}
dev: true
- /glob-parent/5.1.2:
+ /glob-parent@5.1.2:
resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
engines: {node: '>= 6'}
dependencies:
is-glob: 4.0.3
dev: false
- /glob/7.2.3:
+ /glob@7.2.3:
resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==}
dependencies:
fs.realpath: 1.0.0
@@ -1346,12 +1356,12 @@ packages:
path-is-absolute: 1.0.1
dev: true
- /globals/11.12.0:
+ /globals@11.12.0:
resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==}
engines: {node: '>=4'}
dev: true
- /globby/13.1.2:
+ /globby@13.1.2:
resolution: {integrity: sha512-LKSDZXToac40u8Q1PQtZihbNdTYSNMuWe+K5l+oa6KgDzSvVrHXlJy40hUP522RjAIoNLJYBJi7ow+rbFpIhHQ==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
dependencies:
@@ -1362,41 +1372,41 @@ packages:
slash: 4.0.0
dev: false
- /graceful-fs/4.2.10:
+ /graceful-fs@4.2.10:
resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==}
- /has-flag/3.0.0:
+ /has-flag@3.0.0:
resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==}
engines: {node: '>=4'}
dev: true
- /has-flag/4.0.0:
+ /has-flag@4.0.0:
resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
engines: {node: '>=8'}
dev: true
- /has/1.0.3:
+ /has@1.0.3:
resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==}
engines: {node: '>= 0.4.0'}
dependencies:
function-bind: 1.1.1
dev: true
- /html-escaper/2.0.2:
+ /html-escaper@2.0.2:
resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==}
dev: true
- /human-signals/2.1.0:
+ /human-signals@2.1.0:
resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==}
engines: {node: '>=10.17.0'}
dev: true
- /ignore/5.2.0:
+ /ignore@5.2.0:
resolution: {integrity: sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==}
engines: {node: '>= 4'}
dev: false
- /import-local/3.1.0:
+ /import-local@3.1.0:
resolution: {integrity: sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==}
engines: {node: '>=8'}
hasBin: true
@@ -1405,72 +1415,72 @@ packages:
resolve-cwd: 3.0.0
dev: true
- /imurmurhash/0.1.4:
+ /imurmurhash@0.1.4:
resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==}
engines: {node: '>=0.8.19'}
dev: true
- /inflight/1.0.6:
+ /inflight@1.0.6:
resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==}
dependencies:
once: 1.4.0
wrappy: 1.0.2
dev: true
- /inherits/2.0.4:
+ /inherits@2.0.4:
resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
dev: true
- /is-arrayish/0.2.1:
+ /is-arrayish@0.2.1:
resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==}
dev: true
- /is-core-module/2.10.0:
+ /is-core-module@2.10.0:
resolution: {integrity: sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==}
dependencies:
has: 1.0.3
dev: true
- /is-extglob/2.1.1:
+ /is-extglob@2.1.1:
resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
engines: {node: '>=0.10.0'}
dev: false
- /is-fullwidth-code-point/3.0.0:
+ /is-fullwidth-code-point@3.0.0:
resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
engines: {node: '>=8'}
dev: true
- /is-generator-fn/2.1.0:
+ /is-generator-fn@2.1.0:
resolution: {integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==}
engines: {node: '>=6'}
dev: true
- /is-glob/4.0.3:
+ /is-glob@4.0.3:
resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
engines: {node: '>=0.10.0'}
dependencies:
is-extglob: 2.1.1
dev: false
- /is-number/7.0.0:
+ /is-number@7.0.0:
resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
engines: {node: '>=0.12.0'}
- /is-stream/2.0.1:
+ /is-stream@2.0.1:
resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==}
engines: {node: '>=8'}
dev: true
- /isexe/2.0.0:
+ /isexe@2.0.0:
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
- /istanbul-lib-coverage/3.2.0:
+ /istanbul-lib-coverage@3.2.0:
resolution: {integrity: sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==}
engines: {node: '>=8'}
dev: true
- /istanbul-lib-instrument/5.2.1:
+ /istanbul-lib-instrument@5.2.1:
resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==}
engines: {node: '>=8'}
dependencies:
@@ -1483,7 +1493,7 @@ packages:
- supports-color
dev: true
- /istanbul-lib-report/3.0.0:
+ /istanbul-lib-report@3.0.0:
resolution: {integrity: sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==}
engines: {node: '>=8'}
dependencies:
@@ -1492,7 +1502,7 @@ packages:
supports-color: 7.2.0
dev: true
- /istanbul-lib-source-maps/4.0.1:
+ /istanbul-lib-source-maps@4.0.1:
resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==}
engines: {node: '>=10'}
dependencies:
@@ -1503,7 +1513,7 @@ packages:
- supports-color
dev: true
- /istanbul-reports/3.1.5:
+ /istanbul-reports@3.1.5:
resolution: {integrity: sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==}
engines: {node: '>=8'}
dependencies:
@@ -1511,7 +1521,7 @@ packages:
istanbul-lib-report: 3.0.0
dev: true
- /jest-changed-files/29.0.0:
+ /jest-changed-files@29.0.0:
resolution: {integrity: sha512-28/iDMDrUpGoCitTURuDqUzWQoWmOmOKOFST1mi2lwh62X4BFf6khgH3uSuo1e49X/UDjuApAj3w0wLOex4VPQ==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
@@ -1519,7 +1529,7 @@ packages:
p-limit: 3.1.0
dev: true
- /jest-circus/29.1.2:
+ /jest-circus@29.1.2:
resolution: {integrity: sha512-ajQOdxY6mT9GtnfJRZBRYS7toNIJayiiyjDyoZcnvPRUPwJ58JX0ci0PKAKUo2C1RyzlHw0jabjLGKksO42JGA==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
@@ -1546,7 +1556,7 @@ packages:
- supports-color
dev: true
- /jest-cli/29.1.2_texb6yekbdrurkf2spvwkwkdam:
+ /jest-cli@29.1.2(@types/node@18.8.2)(ts-node@10.9.1):
resolution: {integrity: sha512-vsvBfQ7oS2o4MJdAH+4u9z76Vw5Q8WBQF5MchDbkylNknZdrPTX1Ix7YRJyTlOWqRaS7ue/cEAn+E4V1MWyMzw==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
hasBin: true
@@ -1556,14 +1566,14 @@ packages:
node-notifier:
optional: true
dependencies:
- '@jest/core': 29.1.2_ts-node@10.9.1
+ '@jest/core': 29.1.2(ts-node@10.9.1)
'@jest/test-result': 29.1.2
'@jest/types': 29.1.2
chalk: 4.1.2
exit: 0.1.2
graceful-fs: 4.2.10
import-local: 3.1.0
- jest-config: 29.1.2_texb6yekbdrurkf2spvwkwkdam
+ jest-config: 29.1.2(@types/node@18.8.2)(ts-node@10.9.1)
jest-util: 29.1.2
jest-validate: 29.1.2
prompts: 2.4.2
@@ -1574,7 +1584,7 @@ packages:
- ts-node
dev: true
- /jest-config/29.1.2_texb6yekbdrurkf2spvwkwkdam:
+ /jest-config@29.1.2(@types/node@18.8.2)(ts-node@10.9.1):
resolution: {integrity: sha512-EC3Zi86HJUOz+2YWQcJYQXlf0zuBhJoeyxLM6vb6qJsVmpP7KcCP1JnyF0iaqTaXdBP8Rlwsvs7hnKWQWWLwwA==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
peerDependencies:
@@ -1590,7 +1600,7 @@ packages:
'@jest/test-sequencer': 29.1.2
'@jest/types': 29.1.2
'@types/node': 18.8.2
- babel-jest: 29.1.2_@babel+core@7.19.3
+ babel-jest: 29.1.2(@babel/core@7.19.3)
chalk: 4.1.2
ci-info: 3.4.0
deepmerge: 4.2.2
@@ -1609,12 +1619,12 @@ packages:
pretty-format: 29.1.2
slash: 3.0.0
strip-json-comments: 3.1.1
- ts-node: 10.9.1_p2zphemn5bk5inasc666rmprwi
+ ts-node: 10.9.1(@types/node@18.8.2)(typescript@5.2.2)
transitivePeerDependencies:
- supports-color
dev: true
- /jest-diff/29.1.2:
+ /jest-diff@29.1.2:
resolution: {integrity: sha512-4GQts0aUopVvecIT4IwD/7xsBaMhKTYoM4/njE/aVw9wpw+pIUVp8Vab/KnSzSilr84GnLBkaP3JLDnQYCKqVQ==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
@@ -1624,14 +1634,14 @@ packages:
pretty-format: 29.1.2
dev: true
- /jest-docblock/29.0.0:
+ /jest-docblock@29.0.0:
resolution: {integrity: sha512-s5Kpra/kLzbqu9dEjov30kj1n4tfu3e7Pl8v+f8jOkeWNqM6Ds8jRaJfZow3ducoQUrf2Z4rs2N5S3zXnb83gw==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
detect-newline: 3.1.0
dev: true
- /jest-each/29.1.2:
+ /jest-each@29.1.2:
resolution: {integrity: sha512-AmTQp9b2etNeEwMyr4jc0Ql/LIX/dhbgP21gHAizya2X6rUspHn2gysMXaj6iwWuOJ2sYRgP8c1P4cXswgvS1A==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
@@ -1642,7 +1652,7 @@ packages:
pretty-format: 29.1.2
dev: true
- /jest-environment-node/29.1.2:
+ /jest-environment-node@29.1.2:
resolution: {integrity: sha512-C59yVbdpY8682u6k/lh8SUMDJPbOyCHOTgLVVi1USWFxtNV+J8fyIwzkg+RJIVI30EKhKiAGNxYaFr3z6eyNhQ==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
@@ -1654,12 +1664,12 @@ packages:
jest-util: 29.1.2
dev: true
- /jest-get-type/29.0.0:
+ /jest-get-type@29.0.0:
resolution: {integrity: sha512-83X19z/HuLKYXYHskZlBAShO7UfLFXu/vWajw9ZNJASN32li8yHMaVGAQqxFW1RCFOkB7cubaL6FaJVQqqJLSw==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dev: true
- /jest-haste-map/29.1.2:
+ /jest-haste-map@29.1.2:
resolution: {integrity: sha512-xSjbY8/BF11Jh3hGSPfYTa/qBFrm3TPM7WU8pU93m2gqzORVLkHFWvuZmFsTEBPRKndfewXhMOuzJNHyJIZGsw==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
@@ -1678,7 +1688,7 @@ packages:
fsevents: 2.3.2
dev: true
- /jest-leak-detector/29.1.2:
+ /jest-leak-detector@29.1.2:
resolution: {integrity: sha512-TG5gAZJpgmZtjb6oWxBLf2N6CfQ73iwCe6cofu/Uqv9iiAm6g502CAnGtxQaTfpHECBdVEMRBhomSXeLnoKjiQ==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
@@ -1686,7 +1696,7 @@ packages:
pretty-format: 29.1.2
dev: true
- /jest-matcher-utils/29.1.2:
+ /jest-matcher-utils@29.1.2:
resolution: {integrity: sha512-MV5XrD3qYSW2zZSHRRceFzqJ39B2z11Qv0KPyZYxnzDHFeYZGJlgGi0SW+IXSJfOewgJp/Km/7lpcFT+cgZypw==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
@@ -1696,7 +1706,7 @@ packages:
pretty-format: 29.1.2
dev: true
- /jest-message-util/29.1.2:
+ /jest-message-util@29.1.2:
resolution: {integrity: sha512-9oJ2Os+Qh6IlxLpmvshVbGUiSkZVc2FK+uGOm6tghafnB2RyjKAxMZhtxThRMxfX1J1SOMhTn9oK3/MutRWQJQ==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
@@ -1711,7 +1721,7 @@ packages:
stack-utils: 2.0.5
dev: true
- /jest-mock/29.1.2:
+ /jest-mock@29.1.2:
resolution: {integrity: sha512-PFDAdjjWbjPUtQPkQufvniXIS3N9Tv7tbibePEjIIprzjgo0qQlyUiVMrT4vL8FaSJo1QXifQUOuPH3HQC/aMA==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
@@ -1720,7 +1730,7 @@ packages:
jest-util: 29.1.2
dev: true
- /jest-pnp-resolver/1.2.2_jest-resolve@29.1.2:
+ /jest-pnp-resolver@1.2.2(jest-resolve@29.1.2):
resolution: {integrity: sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==}
engines: {node: '>=6'}
peerDependencies:
@@ -1732,12 +1742,12 @@ packages:
jest-resolve: 29.1.2
dev: true
- /jest-regex-util/29.0.0:
+ /jest-regex-util@29.0.0:
resolution: {integrity: sha512-BV7VW7Sy0fInHWN93MMPtlClweYv2qrSCwfeFWmpribGZtQPWNvRSq9XOVgOEjU1iBGRKXUZil0o2AH7Iy9Lug==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dev: true
- /jest-resolve-dependencies/29.1.2:
+ /jest-resolve-dependencies@29.1.2:
resolution: {integrity: sha512-44yYi+yHqNmH3OoWZvPgmeeiwKxhKV/0CfrzaKLSkZG9gT973PX8i+m8j6pDrTYhhHoiKfF3YUFg/6AeuHw4HQ==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
@@ -1747,14 +1757,14 @@ packages:
- supports-color
dev: true
- /jest-resolve/29.1.2:
+ /jest-resolve@29.1.2:
resolution: {integrity: sha512-7fcOr+k7UYSVRJYhSmJHIid3AnDBcLQX3VmT9OSbPWsWz1MfT7bcoerMhADKGvKCoMpOHUQaDHtQoNp/P9JMGg==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
chalk: 4.1.2
graceful-fs: 4.2.10
jest-haste-map: 29.1.2
- jest-pnp-resolver: 1.2.2_jest-resolve@29.1.2
+ jest-pnp-resolver: 1.2.2(jest-resolve@29.1.2)
jest-util: 29.1.2
jest-validate: 29.1.2
resolve: 1.22.1
@@ -1762,7 +1772,7 @@ packages:
slash: 3.0.0
dev: true
- /jest-runner/29.1.2:
+ /jest-runner@29.1.2:
resolution: {integrity: sha512-yy3LEWw8KuBCmg7sCGDIqKwJlULBuNIQa2eFSVgVASWdXbMYZ9H/X0tnXt70XFoGf92W2sOQDOIFAA6f2BG04Q==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
@@ -1791,7 +1801,7 @@ packages:
- supports-color
dev: true
- /jest-runtime/29.1.2:
+ /jest-runtime@29.1.2:
resolution: {integrity: sha512-jr8VJLIf+cYc+8hbrpt412n5jX3tiXmpPSYTGnwcvNemY+EOuLNiYnHJ3Kp25rkaAcTWOEI4ZdOIQcwYcXIAZw==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
@@ -1821,14 +1831,14 @@ packages:
- supports-color
dev: true
- /jest-snapshot/29.1.2:
+ /jest-snapshot@29.1.2:
resolution: {integrity: sha512-rYFomGpVMdBlfwTYxkUp3sjD6usptvZcONFYNqVlaz4EpHPnDvlWjvmOQ9OCSNKqYZqLM2aS3wq01tWujLg7gg==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
'@babel/core': 7.19.3
'@babel/generator': 7.19.3
- '@babel/plugin-syntax-jsx': 7.18.6_@babel+core@7.19.3
- '@babel/plugin-syntax-typescript': 7.18.6_@babel+core@7.19.3
+ '@babel/plugin-syntax-jsx': 7.18.6(@babel/core@7.19.3)
+ '@babel/plugin-syntax-typescript': 7.18.6(@babel/core@7.19.3)
'@babel/traverse': 7.19.3
'@babel/types': 7.19.3
'@jest/expect-utils': 29.1.2
@@ -1836,7 +1846,7 @@ packages:
'@jest/types': 29.1.2
'@types/babel__traverse': 7.18.2
'@types/prettier': 2.7.1
- babel-preset-current-node-syntax: 1.0.1_@babel+core@7.19.3
+ babel-preset-current-node-syntax: 1.0.1(@babel/core@7.19.3)
chalk: 4.1.2
expect: 29.1.2
graceful-fs: 4.2.10
@@ -1853,7 +1863,7 @@ packages:
- supports-color
dev: true
- /jest-util/29.1.2:
+ /jest-util@29.1.2:
resolution: {integrity: sha512-vPCk9F353i0Ymx3WQq3+a4lZ07NXu9Ca8wya6o4Fe4/aO1e1awMMprZ3woPFpKwghEOW+UXgd15vVotuNN9ONQ==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
@@ -1865,7 +1875,7 @@ packages:
picomatch: 2.3.1
dev: true
- /jest-validate/29.1.2:
+ /jest-validate@29.1.2:
resolution: {integrity: sha512-k71pOslNlV8fVyI+mEySy2pq9KdXdgZtm7NHrBX8LghJayc3wWZH0Yr0mtYNGaCU4F1OLPXRkwZR0dBm/ClshA==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
@@ -1877,7 +1887,7 @@ packages:
pretty-format: 29.1.2
dev: true
- /jest-watcher/29.1.2:
+ /jest-watcher@29.1.2:
resolution: {integrity: sha512-6JUIUKVdAvcxC6bM8/dMgqY2N4lbT+jZVsxh0hCJRbwkIEnbr/aPjMQ28fNDI5lB51Klh00MWZZeVf27KBUj5w==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
@@ -1891,7 +1901,7 @@ packages:
string-length: 4.0.2
dev: true
- /jest-worker/29.1.2:
+ /jest-worker@29.1.2:
resolution: {integrity: sha512-AdTZJxKjTSPHbXT/AIOjQVmoFx0LHFcVabWu0sxI7PAy7rFf8c0upyvgBKgguVXdM4vY74JdwkyD4hSmpTW8jA==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
@@ -1901,7 +1911,7 @@ packages:
supports-color: 8.1.1
dev: true
- /jest/29.1.2_texb6yekbdrurkf2spvwkwkdam:
+ /jest@29.1.2(@types/node@18.8.2)(ts-node@10.9.1):
resolution: {integrity: sha512-5wEIPpCezgORnqf+rCaYD1SK+mNN7NsstWzIsuvsnrhR/hSxXWd82oI7DkrbJ+XTD28/eG8SmxdGvukrGGK6Tw==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
hasBin: true
@@ -1911,21 +1921,21 @@ packages:
node-notifier:
optional: true
dependencies:
- '@jest/core': 29.1.2_ts-node@10.9.1
+ '@jest/core': 29.1.2(ts-node@10.9.1)
'@jest/types': 29.1.2
import-local: 3.1.0
- jest-cli: 29.1.2_texb6yekbdrurkf2spvwkwkdam
+ jest-cli: 29.1.2(@types/node@18.8.2)(ts-node@10.9.1)
transitivePeerDependencies:
- '@types/node'
- supports-color
- ts-node
dev: true
- /js-tokens/4.0.0:
+ /js-tokens@4.0.0:
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
dev: true
- /js-yaml/3.14.1:
+ /js-yaml@3.14.1:
resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==}
hasBin: true
dependencies:
@@ -1933,23 +1943,23 @@ packages:
esprima: 4.0.1
dev: true
- /jsesc/2.5.2:
+ /jsesc@2.5.2:
resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==}
engines: {node: '>=4'}
hasBin: true
dev: true
- /json-parse-even-better-errors/2.3.1:
+ /json-parse-even-better-errors@2.3.1:
resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==}
dev: true
- /json5/2.2.1:
+ /json5@2.2.1:
resolution: {integrity: sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==}
engines: {node: '>=6'}
hasBin: true
dev: true
- /jsonfile/6.1.0:
+ /jsonfile@6.1.0:
resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==}
dependencies:
universalify: 2.0.0
@@ -1957,103 +1967,103 @@ packages:
graceful-fs: 4.2.10
dev: false
- /kleur/3.0.3:
+ /kleur@3.0.3:
resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==}
engines: {node: '>=6'}
dev: true
- /leven/3.1.0:
+ /leven@3.1.0:
resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==}
engines: {node: '>=6'}
dev: true
- /lines-and-columns/1.2.4:
+ /lines-and-columns@1.2.4:
resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
dev: true
- /locate-path/5.0.0:
+ /locate-path@5.0.0:
resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==}
engines: {node: '>=8'}
dependencies:
p-locate: 4.1.0
dev: true
- /lodash.memoize/4.1.2:
+ /lodash.memoize@4.1.2:
resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==}
dev: true
- /lru-cache/6.0.0:
+ /lru-cache@6.0.0:
resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==}
engines: {node: '>=10'}
dependencies:
yallist: 4.0.0
dev: true
- /make-dir/3.1.0:
+ /make-dir@3.1.0:
resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==}
engines: {node: '>=8'}
dependencies:
semver: 6.3.0
dev: true
- /make-error/1.3.6:
+ /make-error@1.3.6:
resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==}
- /makeerror/1.0.12:
+ /makeerror@1.0.12:
resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==}
dependencies:
tmpl: 1.0.5
dev: true
- /map-stream/0.1.0:
+ /map-stream@0.1.0:
resolution: {integrity: sha512-CkYQrPYZfWnu/DAmVCpTSX/xHpKZ80eKh2lAkyA6AJTef6bW+6JpbQZN5rofum7da+SyN1bi5ctTm+lTfcCW3g==}
dev: false
- /merge-stream/2.0.0:
+ /merge-stream@2.0.0:
resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==}
dev: true
- /merge2/1.4.1:
+ /merge2@1.4.1:
resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
engines: {node: '>= 8'}
dev: false
- /micromatch/4.0.5:
+ /micromatch@4.0.5:
resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==}
engines: {node: '>=8.6'}
dependencies:
braces: 3.0.2
picomatch: 2.3.1
- /mimic-fn/2.1.0:
+ /mimic-fn@2.1.0:
resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==}
engines: {node: '>=6'}
dev: true
- /minimatch/3.1.2:
+ /minimatch@3.1.2:
resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
dependencies:
brace-expansion: 1.1.11
dev: true
- /minimist/1.2.6:
+ /minimist@1.2.6:
resolution: {integrity: sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==}
dev: false
- /ms/2.1.2:
+ /ms@2.1.2:
resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==}
dev: true
- /natural-compare/1.4.0:
+ /natural-compare@1.4.0:
resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
dev: true
- /node-domexception/1.0.0:
+ /node-domexception@1.0.0:
resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==}
engines: {node: '>=10.5.0'}
dev: false
- /node-fetch/3.2.8:
+ /node-fetch@3.2.8:
resolution: {integrity: sha512-KtpD1YhGszhntMpBDyp5lyagk8KIMopC1LEb7cQUAh7zcosaX5uK8HnbNb2i3NTQK3sIawCItS0uFC3QzcLHdg==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
dependencies:
@@ -2062,66 +2072,66 @@ packages:
formdata-polyfill: 4.0.10
dev: false
- /node-int64/0.4.0:
+ /node-int64@0.4.0:
resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==}
dev: true
- /node-releases/2.0.6:
+ /node-releases@2.0.6:
resolution: {integrity: sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==}
dev: true
- /normalize-path/3.0.0:
+ /normalize-path@3.0.0:
resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
engines: {node: '>=0.10.0'}
dev: true
- /npm-run-path/4.0.1:
+ /npm-run-path@4.0.1:
resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==}
engines: {node: '>=8'}
dependencies:
path-key: 3.1.1
dev: true
- /once/1.4.0:
+ /once@1.4.0:
resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
dependencies:
wrappy: 1.0.2
dev: true
- /onetime/5.1.2:
+ /onetime@5.1.2:
resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==}
engines: {node: '>=6'}
dependencies:
mimic-fn: 2.1.0
dev: true
- /p-limit/2.3.0:
+ /p-limit@2.3.0:
resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==}
engines: {node: '>=6'}
dependencies:
p-try: 2.2.0
dev: true
- /p-limit/3.1.0:
+ /p-limit@3.1.0:
resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
engines: {node: '>=10'}
dependencies:
yocto-queue: 0.1.0
dev: true
- /p-locate/4.1.0:
+ /p-locate@4.1.0:
resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==}
engines: {node: '>=8'}
dependencies:
p-limit: 2.3.0
dev: true
- /p-try/2.2.0:
+ /p-try@2.2.0:
resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==}
engines: {node: '>=6'}
dev: true
- /parse-json/5.2.0:
+ /parse-json@5.2.0:
resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==}
engines: {node: '>=8'}
dependencies:
@@ -2131,57 +2141,57 @@ packages:
lines-and-columns: 1.2.4
dev: true
- /path-exists/4.0.0:
+ /path-exists@4.0.0:
resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
engines: {node: '>=8'}
dev: true
- /path-is-absolute/1.0.1:
+ /path-is-absolute@1.0.1:
resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==}
engines: {node: '>=0.10.0'}
dev: true
- /path-key/3.1.1:
+ /path-key@3.1.1:
resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
engines: {node: '>=8'}
dev: true
- /path-parse/1.0.7:
+ /path-parse@1.0.7:
resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
dev: true
- /path-type/4.0.0:
+ /path-type@4.0.0:
resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==}
engines: {node: '>=8'}
dev: false
- /pause-stream/0.0.11:
+ /pause-stream@0.0.11:
resolution: {integrity: sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==}
dependencies:
through: 2.3.8
dev: false
- /picocolors/1.0.0:
+ /picocolors@1.0.0:
resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==}
dev: true
- /picomatch/2.3.1:
+ /picomatch@2.3.1:
resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
engines: {node: '>=8.6'}
- /pirates/4.0.5:
+ /pirates@4.0.5:
resolution: {integrity: sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==}
engines: {node: '>= 6'}
dev: true
- /pkg-dir/4.2.0:
+ /pkg-dir@4.2.0:
resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==}
engines: {node: '>=8'}
dependencies:
find-up: 4.1.0
dev: true
- /pretty-format/29.1.2:
+ /pretty-format@29.1.2:
resolution: {integrity: sha512-CGJ6VVGXVRP2o2Dorl4mAwwvDWT25luIsYhkyVQW32E4nL+TgW939J7LlKT/npq5Cpq6j3s+sy+13yk7xYpBmg==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
@@ -2190,7 +2200,7 @@ packages:
react-is: 18.2.0
dev: true
- /prompts/2.4.2:
+ /prompts@2.4.2:
resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==}
engines: {node: '>= 6'}
dependencies:
@@ -2198,7 +2208,7 @@ packages:
sisteransi: 1.0.5
dev: true
- /ps-tree/1.2.0:
+ /ps-tree@1.2.0:
resolution: {integrity: sha512-0VnamPPYHl4uaU/nSFeZZpR21QAWRz+sRv4iW9+v/GS/J5U5iZB5BNN6J0RMoOvdx2gWM2+ZFMIm58q24e4UYA==}
engines: {node: '>= 0.10'}
hasBin: true
@@ -2206,37 +2216,37 @@ packages:
event-stream: 3.3.4
dev: false
- /queue-microtask/1.2.3:
+ /queue-microtask@1.2.3:
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
dev: false
- /react-is/18.2.0:
+ /react-is@18.2.0:
resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==}
dev: true
- /require-directory/2.1.1:
+ /require-directory@2.1.1:
resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
engines: {node: '>=0.10.0'}
dev: true
- /resolve-cwd/3.0.0:
+ /resolve-cwd@3.0.0:
resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==}
engines: {node: '>=8'}
dependencies:
resolve-from: 5.0.0
dev: true
- /resolve-from/5.0.0:
+ /resolve-from@5.0.0:
resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==}
engines: {node: '>=8'}
dev: true
- /resolve.exports/1.1.0:
+ /resolve.exports@1.1.0:
resolution: {integrity: sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==}
engines: {node: '>=10'}
dev: true
- /resolve/1.22.1:
+ /resolve@1.22.1:
resolution: {integrity: sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==}
hasBin: true
dependencies:
@@ -2245,27 +2255,27 @@ packages:
supports-preserve-symlinks-flag: 1.0.0
dev: true
- /reusify/1.0.4:
+ /reusify@1.0.4:
resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==}
engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
dev: false
- /run-parallel/1.2.0:
+ /run-parallel@1.2.0:
resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
dependencies:
queue-microtask: 1.2.3
dev: false
- /safe-buffer/5.1.2:
+ /safe-buffer@5.1.2:
resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==}
dev: true
- /semver/6.3.0:
+ /semver@6.3.0:
resolution: {integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==}
hasBin: true
dev: true
- /semver/7.3.8:
+ /semver@7.3.8:
resolution: {integrity: sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==}
engines: {node: '>=10'}
hasBin: true
@@ -2273,72 +2283,72 @@ packages:
lru-cache: 6.0.0
dev: true
- /shebang-command/2.0.0:
+ /shebang-command@2.0.0:
resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
engines: {node: '>=8'}
dependencies:
shebang-regex: 3.0.0
dev: true
- /shebang-regex/3.0.0:
+ /shebang-regex@3.0.0:
resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
engines: {node: '>=8'}
dev: true
- /signal-exit/3.0.7:
+ /signal-exit@3.0.7:
resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==}
dev: true
- /sisteransi/1.0.5:
+ /sisteransi@1.0.5:
resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==}
dev: true
- /slash/3.0.0:
+ /slash@3.0.0:
resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==}
engines: {node: '>=8'}
dev: true
- /slash/4.0.0:
+ /slash@4.0.0:
resolution: {integrity: sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==}
engines: {node: '>=12'}
dev: false
- /source-map-support/0.5.13:
+ /source-map-support@0.5.13:
resolution: {integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==}
dependencies:
buffer-from: 1.1.2
source-map: 0.6.1
dev: true
- /source-map/0.6.1:
+ /source-map@0.6.1:
resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
engines: {node: '>=0.10.0'}
dev: true
- /split/0.3.3:
+ /split@0.3.3:
resolution: {integrity: sha512-wD2AeVmxXRBoX44wAycgjVpMhvbwdI2aZjCkvfNcH1YqHQvJVa1duWc73OyVGJUc05fhFaTZeQ/PYsrmyH0JVA==}
dependencies:
through: 2.3.8
dev: false
- /sprintf-js/1.0.3:
+ /sprintf-js@1.0.3:
resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==}
dev: true
- /stack-utils/2.0.5:
+ /stack-utils@2.0.5:
resolution: {integrity: sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==}
engines: {node: '>=10'}
dependencies:
escape-string-regexp: 2.0.0
dev: true
- /stream-combiner/0.0.4:
+ /stream-combiner@0.0.4:
resolution: {integrity: sha512-rT00SPnTVyRsaSz5zgSPma/aHSOic5U1prhYdRy5HS2kTZviFpmDgzilbtsJsxiroqACmayynDN/9VzIbX5DOw==}
dependencies:
duplexer: 0.1.2
dev: false
- /string-length/4.0.2:
+ /string-length@4.0.2:
resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==}
engines: {node: '>=10'}
dependencies:
@@ -2346,7 +2356,7 @@ packages:
strip-ansi: 6.0.1
dev: true
- /string-width/4.2.3:
+ /string-width@4.2.3:
resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
engines: {node: '>=8'}
dependencies:
@@ -2355,50 +2365,50 @@ packages:
strip-ansi: 6.0.1
dev: true
- /strip-ansi/6.0.1:
+ /strip-ansi@6.0.1:
resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
engines: {node: '>=8'}
dependencies:
ansi-regex: 5.0.1
dev: true
- /strip-bom/4.0.0:
+ /strip-bom@4.0.0:
resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==}
engines: {node: '>=8'}
dev: true
- /strip-final-newline/2.0.0:
+ /strip-final-newline@2.0.0:
resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==}
engines: {node: '>=6'}
dev: true
- /strip-json-comments/3.1.1:
+ /strip-json-comments@3.1.1:
resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
engines: {node: '>=8'}
dev: true
- /supports-color/5.5.0:
+ /supports-color@5.5.0:
resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==}
engines: {node: '>=4'}
dependencies:
has-flag: 3.0.0
dev: true
- /supports-color/7.2.0:
+ /supports-color@7.2.0:
resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
engines: {node: '>=8'}
dependencies:
has-flag: 4.0.0
dev: true
- /supports-color/8.1.1:
+ /supports-color@8.1.1:
resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==}
engines: {node: '>=10'}
dependencies:
has-flag: 4.0.0
dev: true
- /supports-hyperlinks/2.3.0:
+ /supports-hyperlinks@2.3.0:
resolution: {integrity: sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==}
engines: {node: '>=8'}
dependencies:
@@ -2406,12 +2416,12 @@ packages:
supports-color: 7.2.0
dev: true
- /supports-preserve-symlinks-flag/1.0.0:
+ /supports-preserve-symlinks-flag@1.0.0:
resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
engines: {node: '>= 0.4'}
dev: true
- /terminal-link/2.1.1:
+ /terminal-link@2.1.1:
resolution: {integrity: sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==}
engines: {node: '>=8'}
dependencies:
@@ -2419,7 +2429,7 @@ packages:
supports-hyperlinks: 2.3.0
dev: true
- /test-exclude/6.0.0:
+ /test-exclude@6.0.0:
resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==}
engines: {node: '>=8'}
dependencies:
@@ -2428,26 +2438,26 @@ packages:
minimatch: 3.1.2
dev: true
- /through/2.3.8:
+ /through@2.3.8:
resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==}
dev: false
- /tmpl/1.0.5:
+ /tmpl@1.0.5:
resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==}
dev: true
- /to-fast-properties/2.0.0:
+ /to-fast-properties@2.0.0:
resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==}
engines: {node: '>=4'}
dev: true
- /to-regex-range/5.0.1:
+ /to-regex-range@5.0.1:
resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
engines: {node: '>=8.0'}
dependencies:
is-number: 7.0.0
- /ts-jest/29.0.3_2gcdg7c5hzdfd67o3khlosdlhu:
+ /ts-jest@29.0.3(@babel/core@7.19.3)(jest@29.1.2)(typescript@5.2.2):
resolution: {integrity: sha512-Ibygvmuyq1qp/z3yTh9QTwVVAbFdDy/+4BtIQR2sp6baF2SJU/8CKK/hhnGIDY2L90Az2jIqTwZPnN2p+BweiQ==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
hasBin: true
@@ -2468,19 +2478,20 @@ packages:
esbuild:
optional: true
dependencies:
+ '@babel/core': 7.19.3
bs-logger: 0.2.6
fast-json-stable-stringify: 2.1.0
- jest: 29.1.2_texb6yekbdrurkf2spvwkwkdam
+ jest: 29.1.2(@types/node@18.8.2)(ts-node@10.9.1)
jest-util: 29.1.2
json5: 2.2.1
lodash.memoize: 4.1.2
make-error: 1.3.6
semver: 7.3.8
- typescript: 4.8.4
+ typescript: 5.2.2
yargs-parser: 21.1.1
dev: true
- /ts-node/10.9.1_p2zphemn5bk5inasc666rmprwi:
+ /ts-node@10.9.1(@types/node@18.8.2)(typescript@5.2.2):
resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==}
hasBin: true
peerDependencies:
@@ -2506,36 +2517,36 @@ packages:
create-require: 1.1.1
diff: 4.0.2
make-error: 1.3.6
- typescript: 4.8.4
+ typescript: 5.2.2
v8-compile-cache-lib: 3.0.1
yn: 3.1.1
- /tunnel/0.0.6:
+ /tunnel@0.0.6:
resolution: {integrity: sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==}
engines: {node: '>=0.6.11 <=0.7.0 || >=0.7.3'}
dev: false
- /type-detect/4.0.8:
+ /type-detect@4.0.8:
resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==}
engines: {node: '>=4'}
dev: true
- /type-fest/0.21.3:
+ /type-fest@0.21.3:
resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==}
engines: {node: '>=10'}
dev: true
- /typescript/4.8.4:
- resolution: {integrity: sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==}
- engines: {node: '>=4.2.0'}
+ /typescript@5.2.2:
+ resolution: {integrity: sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==}
+ engines: {node: '>=14.17'}
hasBin: true
- /universalify/2.0.0:
+ /universalify@2.0.0:
resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==}
engines: {node: '>= 10.0.0'}
dev: false
- /update-browserslist-db/1.0.10_browserslist@4.21.4:
+ /update-browserslist-db@1.0.10(browserslist@4.21.4):
resolution: {integrity: sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==}
hasBin: true
peerDependencies:
@@ -2546,15 +2557,15 @@ packages:
picocolors: 1.0.0
dev: true
- /uuid/8.3.2:
+ /uuid@8.3.2:
resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==}
hasBin: true
dev: false
- /v8-compile-cache-lib/3.0.1:
+ /v8-compile-cache-lib@3.0.1:
resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==}
- /v8-to-istanbul/9.0.1:
+ /v8-to-istanbul@9.0.1:
resolution: {integrity: sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w==}
engines: {node: '>=10.12.0'}
dependencies:
@@ -2563,25 +2574,25 @@ packages:
convert-source-map: 1.8.0
dev: true
- /walker/1.0.8:
+ /walker@1.0.8:
resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==}
dependencies:
makeerror: 1.0.12
dev: true
- /web-streams-polyfill/3.2.1:
+ /web-streams-polyfill@3.2.1:
resolution: {integrity: sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==}
engines: {node: '>= 8'}
dev: false
- /which/2.0.2:
+ /which@2.0.2:
resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
engines: {node: '>= 8'}
hasBin: true
dependencies:
isexe: 2.0.0
- /wrap-ansi/7.0.0:
+ /wrap-ansi@7.0.0:
resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
engines: {node: '>=10'}
dependencies:
@@ -2590,11 +2601,11 @@ packages:
strip-ansi: 6.0.1
dev: true
- /wrappy/1.0.2:
+ /wrappy@1.0.2:
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
dev: true
- /write-file-atomic/4.0.2:
+ /write-file-atomic@4.0.2:
resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==}
engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0}
dependencies:
@@ -2602,26 +2613,26 @@ packages:
signal-exit: 3.0.7
dev: true
- /y18n/5.0.8:
+ /y18n@5.0.8:
resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
engines: {node: '>=10'}
dev: true
- /yallist/4.0.0:
+ /yallist@4.0.0:
resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==}
dev: true
- /yaml/2.1.2:
+ /yaml@2.1.2:
resolution: {integrity: sha512-VSdf2/K3FqAetooKQv45Hcu6sA00aDgWZeGcG6V9IYJnVLTnb6988Tie79K5nx2vK7cEpf+yW8Oy+7iPAbdiHA==}
engines: {node: '>= 14'}
dev: false
- /yargs-parser/21.1.1:
+ /yargs-parser@21.1.1:
resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==}
engines: {node: '>=12'}
dev: true
- /yargs/17.6.0:
+ /yargs@17.6.0:
resolution: {integrity: sha512-8H/wTDqlSwoSnScvV2N/JHfLWOKuh5MVla9hqLjK3nsfyy6Y4kDSYSvkU5YCUEPOSnRXfIyx3Sq+B/IWudTo4g==}
engines: {node: '>=12'}
dependencies:
@@ -2634,16 +2645,16 @@ packages:
yargs-parser: 21.1.1
dev: true
- /yn/3.1.1:
+ /yn@3.1.1:
resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==}
engines: {node: '>=6'}
- /yocto-queue/0.1.0:
+ /yocto-queue@0.1.0:
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
engines: {node: '>=10'}
dev: true
- /zx/7.0.8:
+ /zx@7.0.8:
resolution: {integrity: sha512-sNjfDHzskqrSkWNj0TVhaowVK5AbpvuyuO1RBU4+LrFcgYI5u9CtyWWgUBRtRZl3bgGEF31zByszoBmwS47d1w==}
engines: {node: '>= 16.0.0'}
hasBin: true
diff --git a/.github/actions/split-tests/src/handlers/golang.mts b/.github/actions/split-tests/src/handlers/golang.mts
deleted file mode 100644
index c017d56db6b..00000000000
--- a/.github/actions/split-tests/src/handlers/golang.mts
+++ /dev/null
@@ -1,51 +0,0 @@
-import { execSync } from "child_process";
-import {
- GolangConfig,
- GoSplits,
- GoPackageData,
- TestsBySplit,
-} from "../types.mjs";
-import { simpleSplit } from "../splitter.mjs";
-
-export interface GetGoPackagesReturn {
- packages: string[];
- testsBySplit: TestsBySplit;
- splits: GoSplits;
- serializedSplits: string
-}
-
-export function getPackageList(
- config: GolangConfig,
-): GetGoPackagesReturn {
- const { numOfSplits } = config;
- const rawPackages = execSync(
- "go list -json ./... | jq -s '[.[] | {ImportPath, TestGoFiles, XTestGoFiles}]'",
- { encoding: "utf8" }
- );
- const packages: GoPackageData[] = JSON.parse(rawPackages.trimEnd());
- const filteredData = packages.filter(
- (item) => (item.TestGoFiles && item.TestGoFiles.length > 0) || (item.XTestGoFiles && item.XTestGoFiles.length > 0)
- );
- const packagePaths = filteredData.map((item) => item.ImportPath);
- return handleSplit(packagePaths, numOfSplits);
-}
-
-function handleSplit(
- packages: string[],
- numOfSplits: number
-): GetGoPackagesReturn {
- console.log(`${packages.length} packages to split...`);
- const packagesBySplit = simpleSplit(packages, [], numOfSplits);
- const splits: GoSplits = packagesBySplit.map((pkgs, i) => ({
- idx: `${i + 1}`,
- id: `${i + 1}/${numOfSplits}`,
- pkgs: pkgs.join(" "),
- }));
- const o: GetGoPackagesReturn = {
- packages,
- testsBySplit: packagesBySplit,
- splits,
- serializedSplits: JSON.stringify(splits),
- };
- return o;
-}
diff --git a/.github/actions/split-tests/src/index.mts b/.github/actions/split-tests/src/index.mts
index 5befde03dc6..43f9eb13161 100644
--- a/.github/actions/split-tests/src/index.mts
+++ b/.github/actions/split-tests/src/index.mts
@@ -1,24 +1,16 @@
-import {$, cd, glob, fs} from "zx";
+import { $, cd, glob, fs } from "zx";
import path from "node:path";
-import {summary, setOutput} from "@actions/core";
-import {
- GolangConfig,
- SolidityConfig,
- GoSplits,
- Tests,
- SoliditySplit,
- TestsBySplit,
-} from "./types.mjs";
-import {sieveSlowTests} from "./sieve.mjs";
-import {simpleSplit} from "./splitter.mjs";
-import { getPackageList, GetGoPackagesReturn } from "../src/handlers/golang.mjs";
+import { setOutput } from "@actions/core";
+import { SolidityConfig, SoliditySplit } from "./types.mjs";
+import { sieveSlowTests } from "./sieve.mjs";
+import { simpleSplit } from "./splitter.mjs";
/**
* Get a JSON formatted config file
*
* @param path The path to the config relative to the git root
*/
-function getConfigFrom(path?: string): GolangConfig | SolidityConfig {
+function getConfigFrom(path?: string): SolidityConfig {
if (!path) {
throw Error("No config path given, specify a path via $CONFIG");
}
@@ -37,9 +29,7 @@ async function main() {
await runAtGitRoot();
const configPath = process.env.CONFIG;
const config = getConfigFrom(configPath);
- if (config.type === "golang") {
- await handleGolang(config);
- } else if (config.type === "solidity") {
+ if (config.type === "solidity") {
await handleSolidity(config);
} else {
throw Error(`Invalid config given`);
@@ -47,23 +37,17 @@ async function main() {
}
main();
-async function handleGolang(config: GolangConfig) {
- const p: GetGoPackagesReturn = getPackageList(config)
- setOutput("splits", p.serializedSplits);
- createSummary(p.packages, p.testsBySplit, p.splits);
-}
-
async function handleSolidity(config: SolidityConfig) {
- const {basePath, splits: configBySplit} = config;
+ const { basePath, splits: configBySplit } = config;
const splits = await Promise.all(
configBySplit.map(
- async ({dir, numOfSplits, slowTests: slowTestMatchers}) => {
+ async ({ dir, numOfSplits, slowTests: slowTestMatchers }) => {
const globPath = path.join(basePath, dir, "/**/*.test.ts");
const rawTests = await glob(globPath);
const pathMappedTests = rawTests.map((r) =>
r.replace("contracts/", "")
);
- const {filteredTests, slowTests} = sieveSlowTests(
+ const { filteredTests, slowTests } = sieveSlowTests(
pathMappedTests,
slowTestMatchers
);
@@ -84,53 +68,6 @@ async function handleSolidity(config: SolidityConfig) {
setOutput("splits", serializedSplits);
}
-function createSummary(
- packages: Tests,
- packagesBySplit: TestsBySplit,
- splits: GoSplits
-) {
- if (!process.env.CI) {
- return;
- }
- const numberOfPackages = packages.length;
- const numberOfSplits = packagesBySplit.length;
- const postProcessedNumberOfPackages = packagesBySplit.flat().length;
-
- summary
- .addHeading("Spliting Summary")
- .addHeading(
- `Number of packages from "go list ./...": ${numberOfPackages}`,
- 3
- )
- .addHeading(
- `Number of packages placed into splits: ${postProcessedNumberOfPackages}`,
- 3
- )
- .addHeading(`Number of splits created: ${numberOfSplits}`, 3)
- .addBreak()
- .addTable([
- [
- {data: "Split Number", header: true},
- {data: "Packages Tested", header: true},
- ],
- ...splits.map((p) => {
- const mappedPackages = p.pkgs
- .split(" ")
- .map(
- (packageName) =>
- ` ${packageName.replace(
- "github.com/smartcontractkit/",
- ""
- )} `
- )
- .join("\n");
-
- return [p.id, mappedPackages];
- }),
- ])
- .write();
-}
-
async function runAtGitRoot() {
const gitRoot = await $`git rev-parse --show-toplevel`;
cd(gitRoot.stdout.trimEnd());
diff --git a/.github/actions/split-tests/src/types.mts b/.github/actions/split-tests/src/types.mts
index 1b978ef2e94..3eae2f0eb96 100644
--- a/.github/actions/split-tests/src/types.mts
+++ b/.github/actions/split-tests/src/types.mts
@@ -22,13 +22,6 @@ export interface Split {
id: string;
}
-export interface GoSplit extends Split {
- /**
- * A space delimited list of packages to run within this split
- */
- pkgs: string;
-}
-
export interface SoliditySplit extends Split {
/**
* A string that contains a whitespace delimited list of tests to run
@@ -47,19 +40,6 @@ export interface SoliditySplit extends Split {
coverageTests: string;
}
-export type GoSplits = GoSplit[];
-
-/**
- * Configuration file for golang tests
- */
-export interface GolangConfig {
- type: "golang";
- /**
- * The number of splits to run tests across
- */
- numOfSplits: number;
-}
-
/**
* Configuration file for solidity tests
*/
@@ -93,20 +73,3 @@ export interface SolidityConfig {
slowTests?: string[];
}[];
}
-
-export interface GoPackageData {
- /**
- * The package path
- */
- ImportPath: string;
- /**
- * The list of go files asociated with the package
- */
- TestGoFiles: string[] | undefined;
- /**
- * The list of go files not associated with a specific package
- * Things like integration tests
- */
- XTestGoFiles: string[] | undefined;
- // there are many other variables in the data but they are not needed yet
-}
diff --git a/.github/scripts/bash/.shellspec b/.github/scripts/bash/.shellspec
deleted file mode 100644
index d567ecf976a..00000000000
--- a/.github/scripts/bash/.shellspec
+++ /dev/null
@@ -1,12 +0,0 @@
---require spec_helper
-
-## Default kcov (coverage) options
-# --kcov-options "--include-path=. --path-strip-level=1"
-# --kcov-options "--include-pattern=.sh"
-# --kcov-options "--exclude-pattern=/.shellspec,/spec/,/coverage/,/report/"
-
-## Example: Include script "myprog" with no extension
-# --kcov-options "--include-pattern=.sh,myprog"
-
-## Example: Only specified files/directories
-# --kcov-options "--include-pattern=myprog,/lib/"
diff --git a/.github/scripts/bash/README.md b/.github/scripts/bash/README.md
deleted file mode 100644
index ed23cd863b7..00000000000
--- a/.github/scripts/bash/README.md
+++ /dev/null
@@ -1,10 +0,0 @@
-# bash scripts
-
-These are bash helper scripts for the CI/CD pipelines.
-
-## Testing
-
-For each bash script, create a corresponding *_spec.sh file in the `./spec/` directory.
-
-1. [Install ShellSpec](https://github.com/shellspec/shellspec#installation) using ASDF (see the .tool-versions file at the root of repo for version).
-2. From this directory run `shellspec`
\ No newline at end of file
diff --git a/.github/scripts/bash/ontriggerlint.sh b/.github/scripts/bash/ontriggerlint.sh
deleted file mode 100755
index a38a5e2a203..00000000000
--- a/.github/scripts/bash/ontriggerlint.sh
+++ /dev/null
@@ -1,41 +0,0 @@
-#!/usr/bin/env bash
-set -euo pipefail
-
-##
-# Execute tests via: ./ontriggerlint_test.sh
-#
-# For the GitHub contexts that should be passed in as args, see:
-# https://docs.github.com/en/actions/learn-github-actions/contexts
-#
-# Trigger golangci-lint job steps when event is one of:
-# 1. on a schedule (GITHUB_EVENT_NAME)
-# 2. on PR's where the target branch (GITHUB_BASE_REF) is not prefixed with 'release/*'
-# and where the relevant source code (SRC_CHANGED) has changed
-# 3. on pushes to these branches (GITHUB_REF): staging, trying, rollup and where the
-# relevant source code (SRC_CHANGED) has changed
-#
-# env vars:
-# GITHUB_EVENT_NAME GitHub's event name, ex: schedule|pull_request|push (GitHub context: github.event_name)
-# GITHUB_BASE_REF GitHub's base ref - target branch of pull request (GitHub context: github.base_ref)
-# GITHUB_REF GitHub's ref - branch or tag that triggered run (GitHub context: github.ref)
-# SRC_CHANGED Specific source paths that we want to trigger on were modified. One of: true|false
-##
-
-if [[ -z "${GITHUB_REF:-}" ]]; then GITHUB_REF=""; fi
-
-# Strip out /refs/heads/ from GITHUB_REF leaving just the abbreviated name
-ABBREV_GITHUB_REF="${GITHUB_REF#refs\/heads\/}"
-
-ON_TRIGGER=false
-if [[ "${GITHUB_EVENT_NAME:-}" = "schedule" ]]; then
- # Trigger on scheduled runs
- ON_TRIGGER=true
-elif [[ "${SRC_CHANGED:-}" = "true" && "${GITHUB_EVENT_NAME:-}" = "pull_request" && "${GITHUB_BASE_REF:-}" != release/* ]]; then
- # Trigger if it's from a pull request targetting any branch EXCEPT the release branch
- ON_TRIGGER=true
-elif [[ "${SRC_CHANGED:-}" = "true" && "${GITHUB_EVENT_NAME:-}" = "push" && "${ABBREV_GITHUB_REF}" =~ ^(staging|trying|rollup)$ ]]; then
- # Trigger if it's a push to specific branches
- ON_TRIGGER=true
-fi
-
-echo "on_trigger=${ON_TRIGGER}"
diff --git a/.github/scripts/bash/spec/ontriggerlint_spec.sh b/.github/scripts/bash/spec/ontriggerlint_spec.sh
deleted file mode 100644
index 212de847cac..00000000000
--- a/.github/scripts/bash/spec/ontriggerlint_spec.sh
+++ /dev/null
@@ -1,106 +0,0 @@
-# shellcheck shell=sh
-
-Describe 'Scheduled'
- It 'Trigger on schedule when source changed'
- export SRC_CHANGED=true
- export GITHUB_EVENT_NAME=schedule
- When run ./ontriggerlint.sh
- The status should eq 0
- The stdout should equal 'on_trigger=true'
- End
-
- It 'Trigger on schedule when source unchanged'
- export SRC_CHANGED=false
- export GITHUB_EVENT_NAME=schedule
- When run ./ontriggerlint.sh
- The status should eq 0
- The stdout should equal 'on_trigger=true'
- End
-End
-
-
-Describe 'Pull Request'
- It 'Trigger on pull_request for non release branches when source changed'
- export SRC_CHANGED=true
- export GITHUB_EVENT_NAME=pull_request
- export GITHUB_BASE_REF=develop
- When run ./ontriggerlint.sh
- The status should eq 0
- The stdout should equal 'on_trigger=true'
- End
-
- It 'No trigger on pull_request for non release branches when source unchanged'
- export SRC_CHANGED=false
- export GITHUB_EVENT_NAME=pull_request
- export GITHUB_BASE_REF=develop
- When run ./ontriggerlint.sh
- The status should eq 0
- The stdout should equal 'on_trigger=false'
- End
-
- It 'No trigger on pull_request for release branches when source changed'
- export SRC_CHANGED=true
- export GITHUB_EVENT_NAME=pull_request
- export GITHUB_BASE_REF=release/1.2.3
- When run ./ontriggerlint.sh
- The status should eq 0
- The stdout should equal 'on_trigger=false'
- End
-End
-
-Describe 'Push'
- It 'Trigger on push to the staging branch when source changed'
- export SRC_CHANGED=true
- export GITHUB_EVENT_NAME=push
- export GITHUB_REF=staging
- When run ./ontriggerlint.sh
- The status should eq 0
- The stdout should equal 'on_trigger=true'
- End
-
- It 'No trigger on push to the staging branch when source unchanged'
- export SRC_CHANGED=false
- export GITHUB_EVENT_NAME=push
- export GITHUB_REF=staging
- When run ./ontriggerlint.sh
- The status should eq 0
- The stdout should equal 'on_trigger=false'
- End
-
- It 'Trigger on push to the trying branch when source changed'
- export SRC_CHANGED=true
- export GITHUB_EVENT_NAME=push
- export GITHUB_REF=trying
- When run ./ontriggerlint.sh
- The status should eq 0
- The stdout should equal 'on_trigger=true'
- End
-
- It 'Trigger on push to the rollup branch when source changed'
- export SRC_CHANGED=true
- export GITHUB_EVENT_NAME=push
- export GITHUB_REF=rollup
- When run ./ontriggerlint.sh
- The status should eq 0
- The stdout should equal 'on_trigger=true'
- End
-
- It 'No trigger on push to the develop branch when source changed'
- export SRC_CHANGED=true
- export GITHUB_EVENT_NAME=push
- export GITHUB_REF=develop
- When run ./ontriggerlint.sh
- The status should eq 0
- The stdout should equal 'on_trigger=false'
- End
-End
-
-Describe 'Misc'
- It 'No trigger on invalid event name when source changed'
- export SRC_CHANGED=true
- export GITHUB_EVENT_NAME=invalid_event_name
- When run ./ontriggerlint.sh
- The status should eq 0
- The stdout should equal 'on_trigger=false'
- End
-End
diff --git a/.github/scripts/bash/spec/spec_helper.sh b/.github/scripts/bash/spec/spec_helper.sh
deleted file mode 100644
index 93f19083cd2..00000000000
--- a/.github/scripts/bash/spec/spec_helper.sh
+++ /dev/null
@@ -1,24 +0,0 @@
-# shellcheck shell=sh
-
-# Defining variables and functions here will affect all specfiles.
-# Change shell options inside a function may cause different behavior,
-# so it is better to set them here.
-# set -eu
-
-# This callback function will be invoked only once before loading specfiles.
-spec_helper_precheck() {
- # Available functions: info, warn, error, abort, setenv, unsetenv
- # Available variables: VERSION, SHELL_TYPE, SHELL_VERSION
- : minimum_version "0.28.1"
-}
-
-# This callback function will be invoked after a specfile has been loaded.
-spec_helper_loaded() {
- :
-}
-
-# This callback function will be invoked after core modules has been loaded.
-spec_helper_configure() {
- # Available functions: import, before_each, after_each, before_all, after_all
- : import 'support/custom_matcher'
-}
diff --git a/.github/workflows/automation-benchmark-tests.yml b/.github/workflows/automation-benchmark-tests.yml
index 38c75ccbcef..3eb44ea9c65 100644
--- a/.github/workflows/automation-benchmark-tests.yml
+++ b/.github/workflows/automation-benchmark-tests.yml
@@ -97,7 +97,7 @@ jobs:
done
done <<< "$EVM_HTTP_URLS"
- name: Checkout the repo
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
+ uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
with:
ref: ${{ env.REF_NAME }}
- name: Build Test Image
@@ -107,7 +107,7 @@ jobs:
QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }}
QA_AWS_ACCOUNT_NUMBER: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}
- name: Run Tests
- uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@00c6214deb10a3f374c6d3430c32c5202015d463 # v2.2.12
+ uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@eccde1970eca69f079d3efb3409938a72ade8497 # v2.2.13
env:
DETACH_RUNNER: true
TEST_SUITE: benchmark
diff --git a/.github/workflows/automation-ondemand-tests.yml b/.github/workflows/automation-ondemand-tests.yml
index ed60a4d4e55..438264e222d 100644
--- a/.github/workflows/automation-ondemand-tests.yml
+++ b/.github/workflows/automation-ondemand-tests.yml
@@ -43,13 +43,13 @@ jobs:
this-job-name: Build Chainlink Image ${{ matrix.image.name }}
continue-on-error: true
- name: Checkout the repo
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
+ uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
with:
ref: ${{ github.head_ref || github.ref_name }}
- name: Check if image exists
if: inputs.chainlinkImage == ''
id: check-image
- uses: smartcontractkit/chainlink-github-actions/docker/image-exists@00c6214deb10a3f374c6d3430c32c5202015d463 # v2.2.12
+ uses: smartcontractkit/chainlink-github-actions/docker/image-exists@eccde1970eca69f079d3efb3409938a72ade8497 # v2.2.13
with:
repository: chainlink
tag: ${{ github.sha }}${{ matrix.image.tag-suffix }}
@@ -57,7 +57,7 @@ jobs:
AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }}
- name: Build Image
if: steps.check-image.outputs.exists == 'false' && inputs.chainlinkImage == ''
- uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/build-image@00c6214deb10a3f374c6d3430c32c5202015d463 # v2.2.12
+ uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/build-image@eccde1970eca69f079d3efb3409938a72ade8497 # v2.2.13
with:
cl_repo: smartcontractkit/chainlink
cl_ref: ${{ github.sha }}
@@ -88,7 +88,7 @@ jobs:
this-job-name: Build Test Image
continue-on-error: true
- name: Checkout the repo
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
+ uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
with:
ref: ${{ github.head_ref || github.ref_name }}
- name: Build Test Image
@@ -139,7 +139,7 @@ jobs:
name: Automation On Demand ${{ matrix.tests.name }} Test
steps:
- name: Checkout the repo
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
+ uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
with:
ref: ${{ github.head_ref || github.ref_name }}
- name: Determine build to use
@@ -160,7 +160,7 @@ jobs:
echo "version=develop" >>$GITHUB_OUTPUT
fi
- name: Run Tests
- uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@00c6214deb10a3f374c6d3430c32c5202015d463 # v2.2.12
+ uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@eccde1970eca69f079d3efb3409938a72ade8497 # v2.2.13
env:
PYROSCOPE_SERVER: ${{ matrix.tests.pyroscope_env == '' && '' || !startsWith(github.ref, 'refs/tags/') && '' || secrets.QA_PYROSCOPE_INSTANCE }} # Avoid sending blank envs https://github.com/orgs/community/discussions/25725
PYROSCOPE_ENVIRONMENT: ${{ matrix.tests.pyroscope_env }}
diff --git a/.github/workflows/bash-cicd-scripts.yml b/.github/workflows/bash-cicd-scripts.yml
deleted file mode 100644
index 73095ceee6b..00000000000
--- a/.github/workflows/bash-cicd-scripts.yml
+++ /dev/null
@@ -1,61 +0,0 @@
-name: Bash CICD Scripts
-
-on:
- pull_request:
-
-jobs:
- changes:
- name: detect changes
- runs-on: ubuntu-latest
- outputs:
- bash-cicd-scripts-src: ${{ steps.bash-cicd-scripts.outputs.src }}
- steps:
- - name: Checkout the repo
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
- - uses: dorny/paths-filter@4512585405083f25c027a35db413c2b3b9006d50 # v2.11.1
- id: bash-cicd-scripts
- with:
- filters: |
- src:
- - '.github/scripts/bash/**'
- - '.github/workflows/bash-cicd-scripts.yml'
- shellcheck:
- name: ShellCheck Lint
- runs-on: ubuntu-latest
- needs: [changes]
- steps:
- - name: Checkout the repo
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
- - name: Run ShellCheck
- if: needs.changes.outputs.bash-cicd-scripts-src == 'true'
- uses: ludeeus/action-shellcheck@00cae500b08a931fb5698e11e79bfbd38e612a38 # v2.0.0
- with:
- scandir: './.github/scripts/bash'
- shellspec:
- name: ShellSpec Tests
- runs-on: ubuntu-latest
- needs: [changes]
- defaults:
- run:
- shell: bash
- steps:
- - name: Checkout the repo
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
- - name: Install shellspec
- if: needs.changes.outputs.bash-cicd-scripts-src == 'true'
- env:
- VERSION: 0.28.1
- VERSION_SHA256SUM: 350d3de04ba61505c54eda31a3c2ee912700f1758b1a80a284bc08fd8b6c5992
- GZ_TAR_FILE: shellspec-dist.tar.gz
- run: |
- curl -sSfL "https://github.com/shellspec/shellspec/releases/download/${VERSION}/shellspec-dist.tar.gz" \
- --output "${GZ_TAR_FILE}"
- echo "Checking sha256sum of ShellSpec released archive."
- echo "${VERSION_SHA256SUM} ${GZ_TAR_FILE}" | sha256sum --check
- tar -xzf "${GZ_TAR_FILE}" -C "${HOME}/.local"
- ln -s "${HOME}/.local/shellspec/shellspec" /usr/local/bin/shellspec
- shellspec --version
- - name: Run shellspec tests
- if: needs.changes.outputs.bash-cicd-scripts-src == 'true'
- working-directory: ./.github/scripts/bash
- run: shellspec
diff --git a/.github/workflows/build-publish-develop.yml b/.github/workflows/build-publish-develop.yml
index 67bf3e1f78e..4384956da3c 100644
--- a/.github/workflows/build-publish-develop.yml
+++ b/.github/workflows/build-publish-develop.yml
@@ -1,9 +1,16 @@
-name: 'Push develop to private ECR'
+name: "Push develop to private ECR"
on:
push:
branches:
- develop
+ workflow_dispatch:
+ inputs:
+ git_ref:
+ description: "Git ref (commit SHA, branch name, tag name, etc.) to checkout"
+ required: true
+env:
+ GIT_REF: ${{ github.event.inputs.git_ref || github.ref }}
jobs:
push-chainlink-develop:
@@ -24,8 +31,9 @@ jobs:
name: push-chainlink-develop ${{ matrix.image.name }}
steps:
- name: Checkout repository
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
-
+ uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
+ with:
+ ref: ${{ env.GIT_REF }}
- name: Build, sign and publish chainlink image
uses: ./.github/actions/build-sign-publish-chainlink
with:
diff --git a/.github/workflows/build-publish.yml b/.github/workflows/build-publish.yml
index b1efc9fa9a8..e0d8a77b570 100644
--- a/.github/workflows/build-publish.yml
+++ b/.github/workflows/build-publish.yml
@@ -15,7 +15,7 @@ jobs:
runs-on: ubuntu-20.04
steps:
- name: Checkout repository
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
+ uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
- name: Check for VERSION file bump on tags
if: ${{ startsWith(github.ref, 'refs/tags/v') }}
uses: ./.github/actions/version-file-bump
@@ -32,7 +32,7 @@ jobs:
contents: read
steps:
- name: Checkout repository
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
+ uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
- name: Build, sign and publish chainlink image
uses: ./.github/actions/build-sign-publish-chainlink
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index d18946b76e6..42efe1dadab 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -12,7 +12,7 @@ jobs:
runs-on: ubuntu-20.04
steps:
- name: Checkout repository
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
+ uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
- name: Build chainlink image
uses: ./.github/actions/build-sign-publish-chainlink
diff --git a/.github/workflows/ci-core.yml b/.github/workflows/ci-core.yml
index 4ef0fb68688..245b282f2da 100644
--- a/.github/workflows/ci-core.yml
+++ b/.github/workflows/ci-core.yml
@@ -10,82 +10,35 @@ on:
branches:
- master
- develop
- - 'release/*'
- - staging
- - trying
- - rollup
+ - "release/*"
merge_group:
pull_request:
schedule:
- cron: "0 0 * * *"
jobs:
- golangci-changes:
- name: detect changes for lint
- runs-on: ubuntu-latest
- outputs:
- src: ${{ steps.golangci-changes.outputs.src }}
- steps:
- - name: Checkout the repo
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
- - uses: dorny/paths-filter@4512585405083f25c027a35db413c2b3b9006d50 # v2.11.1
- id: golangci-changes
- with:
- filters: |
- src:
- - '**/*.go'
- - '**/go.mod'
- - '**/go.sum'
- - '.golangci.yml'
- - '.github/workflows/ci-core.yml'
- init:
- name: initialize
- runs-on: ubuntu-latest
- needs: [golangci-changes]
- defaults:
- run:
- shell: bash
- outputs:
- # Determine if `on` event should trigger linting to run
- on_trigger_lint: ${{ steps.golangci-lint.outputs.on_trigger }}
- steps:
- - name: Checkout the repo
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
- - name: Check if event should trigger lint
- id: golangci-lint
- env:
- GITHUB_EVENT_NAME: ${{ github.event_name }}
- GITHUB_BASE_REF: ${{ github.base_ref }}
- GITHUB_REF: ${{ github.ref }}
- SRC_CHANGED: ${{ needs.golangci-changes.outputs.src }}
- run: ./.github/scripts/bash/ontriggerlint.sh | tee -a $GITHUB_OUTPUT
-
golangci:
+ if: ${{ github.event_name == 'pull_request' || github.event_name == 'schedule' }}
name: lint
- runs-on: ubuntu-latest
- needs: [init]
+ runs-on: ubuntu20.04-8cores-32GB
steps:
- - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
- with:
- fetch-depth: 0
- - uses: actions/setup-go@v4
- if: needs.init.outputs.on_trigger_lint == 'true'
- with:
- go-version-file: 'go.mod'
- # If cache is set to true (default), the "prepare environment" will
- # silently fail with these errors:
- # Error: /usr/bin/tar: <...>: Cannot open: File exists
- cache: false
+ - uses: actions/checkout@v4
+ - name: Setup Go
+ uses: ./.github/actions/setup-go
+ - name: Touching core/web/assets/index.html
+ run: mkdir -p core/web/assets && touch core/web/assets/index.html
+ - name: Build binary
+ run: go build ./...
- name: golangci-lint
- if: needs.init.outputs.on_trigger_lint == 'true'
uses: golangci/golangci-lint-action@3a919529898de77ec3da873e3063ca4b10e7f5cc # v3.7.0
with:
- version: v1.53.3
- only-new-issues: ${{ github.event.schedule == '' }} # show only new issues, unless it's a scheduled run
- args: --out-format checkstyle:golangci-lint-report.xml
- - name: Print lint report artifact
- if: always()
- run: test -f golangci-lint-report.xml && cat golangci-lint-report.xml || true
+ version: v1.54.2
+ # We already cache these directories in setup-go
+ skip-pkg-cache: true
+ skip-build-cache: true
+ # only-new-issues is only applicable to PRs, otherwise it is always set to false
+ only-new-issues: true
+ args: --out-format colored-line-number,checkstyle:golangci-lint-report.xml
- name: Store lint report artifact
if: always()
uses: actions/upload-artifact@3cea5372237819ed00197afe530f5a7ea3e805c8 # v3.1.0
@@ -94,7 +47,6 @@ jobs:
path: golangci-lint-report.xml
- name: Collect Metrics
if: always()
- id: collect-gha-metrics
uses: smartcontractkit/push-gha-metrics-action@d2c2b7bdc9012651230b2608a1bcb0c48538b6ec
with:
basic-auth: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }}
@@ -102,49 +54,18 @@ jobs:
this-job-name: lint
continue-on-error: true
- split-packages:
- name: Split Go Tests
- runs-on: ubuntu-latest
- outputs:
- splits: ${{ steps.split.outputs.splits }}
- steps:
- - name: Checkout the repo
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
- - name: Setup Go
- uses: ./.github/actions/setup-go
- with:
- only-modules: "true"
- - name: Touching core/web/assets/index.html
- run: mkdir -p core/web/assets && touch core/web/assets/index.html
- - name: Generate splits
- id: split
- uses: ./.github/actions/split-tests
- with:
- config: ./ci.json
- - 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: Split Go Tests
- continue-on-error: true
-
core:
- needs: [split-packages]
strategy:
fail-fast: false
matrix:
cmd: ["go_core_tests", "go_core_race_tests"]
- split: ${{ fromJson(needs.split-packages.outputs.splits) }}
- name: Core Tests (${{ matrix.cmd }}) ${{ matrix.split.id }}
- runs-on: ubuntu-latest
+ name: Core Tests (${{ matrix.cmd }})
+ runs-on: ubuntu20.04-64cores-256GB
env:
CL_DATABASE_URL: postgresql://postgres:postgres@localhost:5432/chainlink_test?sslmode=disable
steps:
- name: Checkout the repo
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
+ uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
- name: Setup node
uses: actions/setup-node@v3
- name: Setup NodeJS
@@ -177,10 +98,10 @@ jobs:
env:
OUTPUT_FILE: ./output.txt
USE_TEE: false
- run: ./tools/bin/${{ matrix.cmd }} "${{ matrix.split.pkgs }}"
+ run: ./tools/bin/${{ matrix.cmd }} ./...
- name: Print Filtered Test Results
if: failure()
- uses: smartcontractkit/chainlink-github-actions/go/go-test-results-parsing@00c6214deb10a3f374c6d3430c32c5202015d463 # v2.2.12
+ uses: smartcontractkit/chainlink-github-actions/go/go-test-results-parsing@eccde1970eca69f079d3efb3409938a72ade8497 # v2.2.13
with:
results-file: ./output.txt
output-file: ./output-short.txt
@@ -188,7 +109,7 @@ jobs:
if: always()
uses: actions/upload-artifact@3cea5372237819ed00197afe530f5a7ea3e805c8 # v3.1.0
with:
- name: ${{ matrix.cmd }}_${{ matrix.split.idx }}_logs
+ name: ${{ matrix.cmd }}_logs
path: |
./output.txt
./output-short.txt
@@ -198,41 +119,14 @@ jobs:
if: always()
run: docker compose logs postgres
working-directory: ./.github/actions/setup-postgres
- - 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: Core Tests (${{ matrix.cmd }}) ${{ matrix.split.id }}
- test-results-file: '{"testType":"go","filePath":"./output.txt"}'
- continue-on-error: true
-
- # Satisfy required check for core tests
- # while still allowing for adjustable splitting
- core-complete:
- needs: [core]
- name: Core Tests (${{ matrix.cmd }})
- runs-on: ubuntu-latest
- if: always()
- strategy:
- fail-fast: false
- matrix:
- cmd: ["go_core_tests", "go_core_race_tests"]
- steps:
- - run: echo "${{ matrix.cmd }} have finished"
- - name: Check test results
- if: needs.core.result != 'success'
- run: exit 1
- name: Notify Slack
if: ${{ failure() && matrix.cmd == 'go_core_race_tests' && github.event.schedule != '' }}
uses: slackapi/slack-github-action@e28cf165c92ffef168d23c5c9000cffc8a25e117 # v1.24.0
env:
SLACK_BOT_TOKEN: ${{ secrets.QA_SLACK_API_KEY }}
with:
- channel-id: '#topic-data-races'
- slack-message: "Race tests failed: ${{ job.html_url }}\n${{ github.event.pull_request.html_url || github.event.head_commit.url }}"
+ channel-id: "#topic-data-races"
+ slack-message: "Race tests failed: ${{ job.html_url }}\n${{ format('https://github.com/smartcontractkit/chainlink/actions/runs/{0}', github.run_id) }}"
- name: Collect Metrics
if: always()
id: collect-gha-metrics
@@ -241,6 +135,7 @@ jobs:
basic-auth: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }}
hostname: ${{ secrets.GRAFANA_CLOUD_HOST }}
this-job-name: Core Tests (${{ matrix.cmd }})
+ test-results-file: '{"testType":"go","filePath":"./output.txt"}'
continue-on-error: true
detect-flakey-tests:
@@ -252,7 +147,7 @@ jobs:
CL_DATABASE_URL: postgresql://postgres:postgres@localhost:5432/chainlink_test?sslmode=disable
steps:
- name: Checkout the repo
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
+ uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
- name: Setup node
uses: actions/setup-node@v3
- name: Setup NodeJS
@@ -289,7 +184,7 @@ jobs:
-gh_sha=$GITHUB_SHA \
-gh_event_path=$GITHUB_EVENT_PATH \
-command=./tools/bin/go_core_tests \
- `ls -R ./artifacts/go_core_tests*/output-short.txt`
+ `ls -R ./artifacts/go_core_tests*/output.txt`
- name: Store logs artifacts
if: always()
uses: actions/upload-artifact@3cea5372237819ed00197afe530f5a7ea3e805c8 # v3.1.0
@@ -305,7 +200,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout the repo
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
+ uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
with:
fetch-depth: 0 # fetches all history for all tags and branches to provide more metadata for sonar reports
- name: Download all workflow run artifacts
@@ -314,10 +209,10 @@ 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@4b0bfc149f5e285930eeb5e917327e66660c6e92 # v2.0.0
+ uses: sonarsource/sonarqube-scan-action@69c1a75940dec6249b86dace6b630d3a2ae9d2a7 # v2.0.1
with:
args: >
-Dsonar.go.tests.reportPaths=${{ steps.sonarqube_report_paths.outputs.sonarqube_tests_report_paths }}
@@ -338,12 +233,18 @@ jobs:
clean:
name: Clean Go Tidy & Generate
+ if: ${{ !contains(join(github.event.pull_request.labels.*.name, ' '), 'skip-smoke-tests') }}
runs-on: ubuntu-latest
defaults:
run:
shell: bash
steps:
- - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
+ - name: Check for Skip Tests Label
+ if: contains(join(github.event.pull_request.labels.*.name, ' '), 'skip-smoke-tests')
+ run: |
+ echo "## \`skip-smoke-tests\` label is active, skipping E2E smoke tests" >>$GITHUB_STEP_SUMMARY
+ exit 0
+ - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
with:
fetch-depth: 0
- name: Setup Go
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
index 37eaa557927..58b38015a63 100644
--- a/.github/workflows/codeql-analysis.yml
+++ b/.github/workflows/codeql-analysis.yml
@@ -4,9 +4,6 @@ on:
push:
branches:
- develop
- - staging
- - trying
- - rollup
pull_request:
# The branches below must be a subset of the branches above
branches: [develop]
@@ -25,7 +22,7 @@ jobs:
steps:
- name: Checkout repository
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
+ uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
- name: Set up Go
if: ${{ matrix.language == 'go' }}
diff --git a/.github/workflows/delete-deployments.yml b/.github/workflows/delete-deployments.yml
new file mode 100644
index 00000000000..83a4ba8dfce
--- /dev/null
+++ b/.github/workflows/delete-deployments.yml
@@ -0,0 +1,32 @@
+name: Cleanup integration deployments
+on:
+ workflow_dispatch:
+ schedule:
+ # every 10 mins
+ - cron: "*/10 * * * *"
+
+jobs:
+ cleanup:
+ name: Clean up integration environment deployments
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout repo
+ uses: actions/checkout@v4
+
+ - name: Clean up integration environment
+ uses: ./.github/actions/delete-deployments
+ with:
+ environment: integration
+ # Delete 300 deployments at a time
+ num-of-pages: 3
+ # We start with page 2 because usually the first 200 deployments are still active, so we cannot delete them
+ starting-page: 2
+
+ - name: Collect Metrics
+ id: collect-gha-metrics
+ uses: smartcontractkit/push-gha-metrics-action@d2c2b7bdc9012651230b2608a1bcb0c48538b6ec
+ with:
+ basic-auth: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }}
+ hostname: ${{ secrets.GRAFANA_CLOUD_HOST }}
+ this-job-name: Clean up integration environment deployments
+ continue-on-error: true
diff --git a/.github/workflows/dependency-check.yml b/.github/workflows/dependency-check.yml
index e4cb1081429..4bcab9091dd 100644
--- a/.github/workflows/dependency-check.yml
+++ b/.github/workflows/dependency-check.yml
@@ -11,7 +11,7 @@ jobs:
changes: ${{ steps.changes.outputs.src }}
steps:
- name: Checkout the repo
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
+ uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
- uses: dorny/paths-filter@4512585405083f25c027a35db413c2b3b9006d50 # v2.11.1
id: changes
with:
@@ -25,7 +25,7 @@ jobs:
needs: [changes]
steps:
- name: Check out code
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
+ uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
- name: Set up Go
if: needs.changes.outputs.src == 'true'
diff --git a/.github/workflows/generic-test-runner.yml b/.github/workflows/generic-test-runner.yml
deleted file mode 100644
index 727b091ac41..00000000000
--- a/.github/workflows/generic-test-runner.yml
+++ /dev/null
@@ -1,141 +0,0 @@
-name: Generic Test Runner
-on:
- workflow_dispatch:
- inputs:
- network:
- description: 'Network to run tests against'
- required: true
- default: 'SIMULATED'
- wsURL:
- description: 'Chain WS URL (Skip with SIMULATED)'
- required: false
- httpURL:
- description: 'Chain HTTP URL (Skip with SIMULATED)'
- required: false
- fundingKey:
- description: 'Private key to fund test (Skip with SIMULATED)'
- required: false
- directory:
- description: 'Directory to run tests from'
- required: true
- default: 'smoke'
- test:
- description: 'Test to run'
- required: true
- default: 'OCRBasic'
- testInputs:
- description: 'Custom test inputs'
- required: false
- default: ''
-env:
- ENV_JOB_IMAGE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink-tests:${{ github.sha }}
- CHAINLINK_IMAGE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink
-
-jobs:
- build-chainlink:
- environment: integration
- permissions:
- id-token: write
- contents: read
- strategy:
- matrix:
- image:
- - name: ""
- dockerfile: core/chainlink.Dockerfile
- tag-suffix: ""
- - name: (plugins)
- dockerfile: plugins/chainlink.Dockerfile
- tag-suffix: -plugins
- name: Build Chainlink Image ${{ matrix.image.name }}
- runs-on: ubuntu20.04-16cores-64GB
- steps:
- - name: Checkout the repo
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
- - name: Check if image exists
- id: check-image
- uses: smartcontractkit/chainlink-github-actions/docker/image-exists@00c6214deb10a3f374c6d3430c32c5202015d463 # v2.2.12
- with:
- repository: chainlink
- tag: ${{ github.sha }}${{ matrix.image.tag-suffix }}
- AWS_REGION: ${{ secrets.QA_AWS_REGION }}
- AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }}
- - name: Build Image
- if: steps.check-image.outputs.exists == 'false'
- uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/build-image@00c6214deb10a3f374c6d3430c32c5202015d463 # v2.2.12
- with:
- cl_repo: smartcontractkit/chainlink
- cl_ref: ${{ github.sha }}
- cl_dockerfile: ${{ matrix.image.dockerfile }}
- push_tag: ${{ env.CHAINLINK_IMAGE }}:${{ github.sha }}${{ matrix.image.tag-suffix }}
- QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }}
- QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }}
- - name: Print Chainlink Image Built
- run: |
- echo "### chainlink node image tag used for this test run :link:" >>$GITHUB_STEP_SUMMARY
- echo "\`${GITHUB_SHA}\`" >>$GITHUB_STEP_SUMMARY
-
- build-test-image:
- environment: integration
- permissions:
- id-token: write
- contents: read
- name: Build Test Image
- runs-on: ubuntu20.04-16cores-64GB
- env:
- TEST_SUITE: ${{ github.event.inputs.directory }}
- steps:
- - name: Checkout the repo
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
- - name: Build Test Image
- uses: ./.github/actions/build-test-image
- with:
- QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }}
- QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }}
- QA_AWS_ACCOUNT_NUMBER: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}
-
- test:
- runs-on: ubuntu-latest
- needs: [build-chainlink, build-test-image]
- name: Run Test
- environment: integration
- permissions:
- id-token: write
- contents: read
- env:
- CHAINLINK_ENV_USER: ${{ github.actor }}
- CHAINLINK_COMMIT_SHA: ${{ github.sha }}
- TEST_SUITE: ${{ github.event.inputs.directory }}
- SELECTED_NETWORKS: ${{ github.event.inputs.network }}
- TEST_LOG_LEVEL: debug
- steps:
- - name: Mask Inputs
- run: |
- EVM_URLS=$(jq -r '.inputs.wsURL' $GITHUB_EVENT_PATH)
- EVM_HTTP_URLS=$(jq -r '.inputs.httpURL' $GITHUB_EVENT_PATH)
- EVM_KEYS=$(jq -r '.inputs.fundingKey' $GITHUB_EVENT_PATH)
-
- echo ::add-mask::$EVM_URLS
- echo ::add-mask::$EVM_HTTP_URLS
- echo ::add-mask::$EVM_KEYS
-
- echo EVM_URLS=$EVM_URLS >> $GITHUB_ENV
- echo EVM_HTTP_URLS=$EVM_HTTP_URLS >> $GITHUB_ENV
- echo EVM_KEYS=$EVM_KEYS >> $GITHUB_ENV
- - name: Debug Input
- run: echo ${{ github.event.inputs.testInputs }}
- - name: Checkout the repo
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
- - name: Run Tests
- uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@00c6214deb10a3f374c6d3430c32c5202015d463 # v2.2.12
- with:
- test_command_to_run: make test_need_operator_assets && cd ./integration-tests && go test -timeout 1h -count=1 ./${{ github.event.inputs.directory }} -run ${{ github.event.inputs.test }} -v -args ${{ github.event.inputs.test-inputs }}
- test_download_vendor_packages_command: cd ./integration-tests && go mod download
- cl_repo: ${{ env.CHAINLINK_IMAGE }}
- cl_image_tag: ${{ github.sha }}
- artifacts_location: ./integration-tests/smoke/logs
- publish_check_name: Generic Test Run
- token: ${{ secrets.GITHUB_TOKEN }}
- go_mod_path: ./integration-tests/go.mod
- QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }}
- QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }}
- QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }}
diff --git a/.github/workflows/goreleaser-build-publish-develop.yml b/.github/workflows/goreleaser-build-publish-develop.yml
index 56fcff14f94..3a3236cc978 100644
--- a/.github/workflows/goreleaser-build-publish-develop.yml
+++ b/.github/workflows/goreleaser-build-publish-develop.yml
@@ -18,7 +18,7 @@ jobs:
contents: read
steps:
- name: Checkout repository
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
+ uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
- name: Configure aws credentials
uses: aws-actions/configure-aws-credentials@5fd3084fc36e372ff1fff382a39b10d03659f355 # v2.2.0
with:
@@ -55,7 +55,7 @@ jobs:
contents: read
steps:
- name: Checkout repository
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
+ uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
- name: Configure aws credentials
uses: aws-actions/configure-aws-credentials@5fd3084fc36e372ff1fff382a39b10d03659f355 # v2.2.0
with:
diff --git a/.github/workflows/helm-publish.yml b/.github/workflows/helm-publish.yml
new file mode 100644
index 00000000000..8a14ff1a7e6
--- /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-chaos-tests.yml b/.github/workflows/integration-chaos-tests.yml
index 0191c3f4615..8e1bfdd06c4 100644
--- a/.github/workflows/integration-chaos-tests.yml
+++ b/.github/workflows/integration-chaos-tests.yml
@@ -27,10 +27,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout the repo
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
+ uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
- name: Check if image exists
id: check-image
- uses: smartcontractkit/chainlink-github-actions/docker/image-exists@00c6214deb10a3f374c6d3430c32c5202015d463 # v2.2.12
+ uses: smartcontractkit/chainlink-github-actions/docker/image-exists@eccde1970eca69f079d3efb3409938a72ade8497 # v2.2.13
with:
repository: chainlink
tag: ${{ github.sha }}
@@ -38,7 +38,7 @@ jobs:
AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }}
- name: Build Image
if: steps.check-image.outputs.exists == 'false'
- uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/build-image@00c6214deb10a3f374c6d3430c32c5202015d463 # v2.2.12
+ uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/build-image@eccde1970eca69f079d3efb3409938a72ade8497 # v2.2.13
with:
cl_repo: smartcontractkit/chainlink
cl_ref: ${{ github.sha }}
@@ -69,7 +69,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout the repo
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
+ uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
- name: Build Test Image
uses: ./.github/actions/build-test-image
with:
@@ -107,9 +107,9 @@ jobs:
test-results-file: '{"testType":"go","filePath":"/tmp/gotest.log"}'
continue-on-error: true
- name: Checkout the repo
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
+ uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
- name: Run Tests
- uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@00c6214deb10a3f374c6d3430c32c5202015d463 # v2.2.12
+ uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@eccde1970eca69f079d3efb3409938a72ade8497 # v2.2.13
with:
test_command_to_run: make test_need_operator_assets && cd integration-tests && go test -timeout 1h -count=1 -json -test.parallel 11 ./chaos 2>&1 | tee /tmp/gotest.log | gotestfmt
test_download_vendor_packages_command: cd ./integration-tests && go mod download
diff --git a/.github/workflows/integration-staging-tests.yml b/.github/workflows/integration-staging-tests.yml
new file mode 100644
index 00000000000..a6fda178d50
--- /dev/null
+++ b/.github/workflows/integration-staging-tests.yml
@@ -0,0 +1,63 @@
+name: E2E Functions staging tests
+
+on:
+# TODO: enable when env will be stable
+# schedule:
+# - cron: "0 0 * * *"
+ workflow_dispatch:
+ inputs:
+ network:
+ description: Blockchain network (testnet)
+ type: choice
+ default: "MUMBAI"
+ options:
+ - "MUMBAI"
+ test_type:
+ description: Test type
+ type: choice
+ default: "mumbai_functions_soak_test_real"
+ options:
+ - "mumbai_functions_soak_test_http"
+ - "mumbai_functions_stress_test_http"
+ - "mumbai_functions_soak_test_only_secrets"
+ - "mumbai_functions_stress_test_only_secrets"
+ - "mumbai_functions_soak_test_real"
+ - "mumbai_functions_stress_test_real"
+# TODO: disabled, need GATI access
+# - "gateway_secrets_set_soak_test"
+# - "gateway_secrets_list_soak_test"
+
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}
+ cancel-in-progress: true
+
+jobs:
+ e2e-soak-test:
+ environment: sdlc
+ runs-on: ubuntu20.04-8cores-32GB
+ permissions:
+ contents: read
+ id-token: write
+ env:
+ LOKI_URL: ${{ secrets.LOKI_URL }}
+ LOKI_TOKEN: ${{ secrets.LOKI_TOKEN }}
+
+ SELECTED_NETWORKS: ${{ inputs.network }}
+ SELECTED_TEST: ${{ inputs.test_type }}
+ MUMBAI_URLS: ${{ secrets.FUNCTIONS_STAGING_MUMBAI_URLS }}
+ MUMBAI_KEYS: ${{ secrets.FUNCTIONS_STAGING_MUMBAI_KEYS }}
+
+ WASP_LOG_LEVEL: info
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v3
+ with:
+ fetch-depth: 0
+ - name: Run E2E soak tests
+ run: |
+ cd integration-tests/load/functions
+ if [[ $SELECTED_TEST == mumbai_functions* ]]; then
+ go test -v -timeout 6h -run TestFunctionsLoad/$SELECTED_TEST
+ elif [[ $SELECTED_TEST == gateway* ]]; then
+ go test -v -timeout 6h -run TestGatewayLoad/$SELECTED_TEST
+ fi
\ No newline at end of file
diff --git a/.github/workflows/integration-tests-publish.yml b/.github/workflows/integration-tests-publish.yml
index 9581a2af510..d0ce62a71bb 100644
--- a/.github/workflows/integration-tests-publish.yml
+++ b/.github/workflows/integration-tests-publish.yml
@@ -27,7 +27,7 @@ jobs:
this-job-name: Publish Integration Test Image
continue-on-error: true
- name: Checkout the repo
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
+ uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Build Image
diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml
index a47530e4d04..fd61f9b3384 100644
--- a/.github/workflows/integration-tests.yml
+++ b/.github/workflows/integration-tests.yml
@@ -3,8 +3,8 @@ on:
merge_group:
pull_request:
schedule:
- # - cron: "0 0 * * *"
- - cron: "0 * * * *" # every hour while we debug for flakes
+ - cron: "0 0 * * *"
+ # - cron: "0 * * * *" # DEBUG: Run every hour to nail down flakes
push:
tags:
- "*"
@@ -30,7 +30,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout the repo
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
+ uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
- uses: dorny/paths-filter@4512585405083f25c027a35db413c2b3b9006d50 # v2.11.1
id: changes
with:
@@ -41,6 +41,7 @@ jobs:
- '**/*go.mod'
- '.github/workflows/integration-tests.yml'
- '**/*Dockerfile'
+ - 'core/**/config/**/*.toml'
- name: Collect Metrics
if: always()
id: collect-gha-metrics
@@ -81,13 +82,13 @@ jobs:
this-job-name: Build Chainlink Image ${{ matrix.image.name }}
continue-on-error: true
- name: Checkout the repo
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
+ uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
with:
ref: ${{ github.event.pull_request.head.sha || github.event.merge_group.head_sha }}
- name: Check if image exists
if: needs.changes.outputs.src == 'true'
id: check-image
- uses: smartcontractkit/chainlink-github-actions/docker/image-exists@00c6214deb10a3f374c6d3430c32c5202015d463 # v2.2.12
+ uses: smartcontractkit/chainlink-github-actions/docker/image-exists@eccde1970eca69f079d3efb3409938a72ade8497 # v2.2.13
with:
repository: chainlink
tag: ${{ github.sha }}${{ matrix.image.tag-suffix }}
@@ -95,7 +96,7 @@ jobs:
AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }}
- name: Build Image
if: steps.check-image.outputs.exists == 'false' && needs.changes.outputs.src == 'true'
- uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/build-image@00c6214deb10a3f374c6d3430c32c5202015d463 # v2.2.12
+ uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/build-image@eccde1970eca69f079d3efb3409938a72ade8497 # v2.2.13
with:
cl_repo: smartcontractkit/chainlink
cl_ref: ${{ github.sha }}
@@ -106,10 +107,11 @@ jobs:
- name: Print Chainlink Image Built
if: needs.changes.outputs.src == 'true'
run: |
- echo "### chainlink node image tag used for this test run :link:" >>$GITHUB_STEP_SUMMARY
+ echo "### Chainlink node image tag used for this test run :link:" >>$GITHUB_STEP_SUMMARY
echo "\`${GITHUB_SHA}\`" >>$GITHUB_STEP_SUMMARY
build-test-image:
+ if: startsWith(github.ref, 'refs/tags/') || github.event_name == 'schedule' || (github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')) || contains(join(github.event.pull_request.labels.*.name, ' '), 'build-test-image')
environment: integration
permissions:
id-token: write
@@ -128,7 +130,7 @@ jobs:
this-job-name: Build Test Image
continue-on-error: true
- name: Checkout the repo
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
+ uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
with:
ref: ${{ github.event.pull_request.head.sha || github.event.merge_group.head_sha }}
- name: Build Test Image
@@ -139,14 +141,43 @@ jobs:
QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }}
QA_AWS_ACCOUNT_NUMBER: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}
- eth-smoke-tests-matrix:
+ compare-tests:
+ needs: [changes]
+ runs-on: ubuntu-latest
+ name: Compare/Build Automation Test List
+ outputs:
+ matrix: ${{ env.MATRIX_JSON }}
+ steps:
+ - name: Check for Skip Tests Label
+ if: contains(join(github.event.pull_request.labels.*.name, ' '), 'skip-smoke-tests')
+ run: |
+ echo "## \`skip-smoke-tests\` label is active, skipping E2E smoke tests" >>$GITHUB_STEP_SUMMARY
+ exit 0
+ - name: Checkout the repo
+ uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
+ - name: Compare Test Lists
+ run: |
+ cd ./integration-tests
+ ./scripts/compareTestList.sh ./smoke/automation_test.go
+ ./scripts/compareTestList.sh ./smoke/keeper_test.go
+ - name: Build Test Matrix Lists
+ id: build-test-matrix-list
+ run: |
+ cd ./integration-tests
+ MATRIX_JSON_AUTOMATION=$(./scripts/buildTestMatrixList.sh ./smoke/automation_test.go automation ubuntu20.04-8cores-32GB 1)
+ MATRIX_JSON_KEEPER=$(./scripts/buildTestMatrixList.sh ./smoke/keeper_test.go keeper ubuntu20.04-8cores-32GB 1)
+ COMBINED_ARRAY=$(jq -c -n "$MATRIX_JSON_AUTOMATION + $MATRIX_JSON_KEEPER")
+ echo "MATRIX_JSON=${COMBINED_ARRAY}" >> $GITHUB_ENV
+
+ eth-smoke-tests-matrix-automation:
+ if: ${{ !contains(join(github.event.pull_request.labels.*.name, ' '), 'skip-smoke-tests') }}
environment: integration
permissions:
checks: write
pull-requests: write
id-token: write
contents: read
- needs: [build-chainlink, changes, build-test-image]
+ needs: [build-chainlink, changes, compare-tests]
env:
SELECTED_NETWORKS: SIMULATED,SIMULATED_1,SIMULATED_2
CHAINLINK_COMMIT_SHA: ${{ github.sha }}
@@ -155,69 +186,46 @@ jobs:
strategy:
fail-fast: false
matrix:
- product:
- - name: automation
- nodes: 11
- os: ubuntu-latest
- pyroscope_env: ci-smoke-automation-evm-simulated
- # temporarily disabled
- # - name: ocr2vrf
- # nodes: 2
- # os: ubuntu-latest
- # pyroscope_env: ci-smoke-ocr2vrf-evm-simulated
+ product: ${{fromJson(needs.compare-tests.outputs.matrix)}}
runs-on: ${{ matrix.product.os }}
name: ETH Smoke Tests ${{ matrix.product.name }}
steps:
- name: Checkout the repo
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
+ uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
with:
ref: ${{ github.event.pull_request.head.sha || github.event.merge_group.head_sha }}
+ - name: Build Go Test Command
+ id: build-go-test-command
+ run: |
+ # if the matrix.product.run is set, use it for a different command
+ if [ "${{ matrix.product.run }}" != "" ]; then
+ echo "run_command=${{ matrix.product.run }} ./smoke/${{ matrix.product.file }}_test.go" >> "$GITHUB_OUTPUT"
+ else
+ echo "run_command=./smoke/${{ matrix.product.name }}_test.go" >> "$GITHUB_OUTPUT"
+ fi
## Run this step when changes that require tests to be run are made
- name: Run Tests
if: needs.changes.outputs.src == 'true'
- uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@00c6214deb10a3f374c6d3430c32c5202015d463 # v2.2.12
+ uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@eccde1970eca69f079d3efb3409938a72ade8497 # v2.2.13
env:
- TESTCONTAINERS_RYUK_DISABLED: true
PYROSCOPE_SERVER: ${{ matrix.product.pyroscope_env == '' && '' || !startsWith(github.ref, 'refs/tags/') && '' || secrets.QA_PYROSCOPE_INSTANCE }} # Avoid sending blank envs https://github.com/orgs/community/discussions/25725
PYROSCOPE_ENVIRONMENT: ${{ matrix.product.pyroscope_env }}
PYROSCOPE_KEY: ${{ secrets.QA_PYROSCOPE_KEY }}
with:
- test_command_to_run: make test_need_operator_assets && cd ./integration-tests && go test -timeout 30m -count=1 -json -test.parallel=${{ matrix.product.nodes }} ./smoke/${{ matrix.product.name }}_test.go 2>&1 | tee /tmp/gotest.log | gotestfmt
+ test_command_to_run: make test_need_operator_assets && cd ./integration-tests && go test -timeout 30m -count=1 -json -test.parallel=${{ matrix.product.nodes }} ${{ steps.build-go-test-command.outputs.run_command }} 2>&1 | tee /tmp/gotest.log | gotestfmt
test_download_vendor_packages_command: cd ./integration-tests && go mod download
cl_repo: ${{ env.CHAINLINK_IMAGE }}
cl_image_tag: ${{ github.sha }}
aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}
- artifacts_location: ./integration-tests/smoke/logs
- publish_check_name: EVM Smoke Test Results ${{ matrix.product.name }}
+ artifacts_location: ./integration-tests/smoke/logs/
+ publish_check_name: ${{ matrix.product.name }}
token: ${{ secrets.GITHUB_TOKEN }}
go_mod_path: ./integration-tests/go.mod
cache_key_id: core-e2e-${{ env.MOD_CACHE_VERSION }}
- cache_restore_only: 'true'
- QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }}
- QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }}
- QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }}
-
- ## Run this step when changes that do not need the test to run are made
- - name: Run Setup
- if: needs.changes.outputs.src == 'false'
- uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/setup-run-tests-environment@00c6214deb10a3f374c6d3430c32c5202015d463 # v2.2.12
- with:
- test_download_vendor_packages_command: cd ./integration-tests && go mod download
- go_mod_path: ./integration-tests/go.mod
- cache_key_id: core-e2e-${{ env.MOD_CACHE_VERSION }}
- cache_restore_only: 'true'
+ cache_restore_only: "true"
QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }}
QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }}
QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }}
-
- - name: Upload test log
- uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
- if: failure()
- with:
- name: test-log-${{ matrix.product.name }}
- path: /tmp/gotest.log
- retention-days: 7
- continue-on-error: true
- name: Collect Metrics
if: always()
id: collect-gha-metrics
@@ -229,7 +237,8 @@ jobs:
test-results-file: '{"testType":"go","filePath":"/tmp/gotest.log"}'
continue-on-error: true
- eth-smoke-tests-matrix-docker:
+ eth-smoke-tests-matrix:
+ if: ${{ !contains(join(github.event.pull_request.labels.*.name, ' '), 'skip-smoke-tests') }}
environment: integration
permissions:
checks: write
@@ -274,6 +283,10 @@ jobs:
nodes: 1
os: ubuntu20.04-8cores-32GB
pyroscope_env: ci-smoke-vrf2-evm-simulated
+ - name: vrfv2plus
+ nodes: 1
+ os: ubuntu-latest
+ pyroscope_env: ci-smoke-vrf2plus-evm-simulated
- name: forwarder_ocr
nodes: 1
os: ubuntu20.04-8cores-32GB
@@ -282,103 +295,11 @@ jobs:
nodes: 1
os: ubuntu20.04-8cores-32GB
pyroscope_env: ci-smoke-forwarder-ocr-evm-simulated
-
- # Keeper tests split out to use minimal environments
- - name: keeper-1
- nodes: 1
- os: ubuntu20.04-8cores-32GB
- pyroscope_env: ci-smoke-keeper-evm-simulated
- file: keeper
- run: -run ^TestKeeperBasicSmoke$
- - name: keeper-2
- nodes: 1
- os: ubuntu20.04-8cores-32GB
- pyroscope_env: ci-smoke-keeper-evm-simulated
- file: keeper
- run: -run ^TestKeeperBlockCountPerTurn/registry_1_1$
- - name: keeper-3
- nodes: 1
- os: ubuntu20.04-8cores-32GB
- pyroscope_env: ci-smoke-keeper-evm-simulated
- file: keeper
- run: -run ^TestKeeperBlockCountPerTurn/registry_1_2$
- - name: keeper-4
- nodes: 1
- os: ubuntu20.04-8cores-32GB
- pyroscope_env: ci-smoke-keeper-evm-simulated
- file: keeper
- run: -run ^TestKeeperBlockCountPerTurn/registry_1_3$
- - name: keeper-5
- nodes: 1
- os: ubuntu20.04-8cores-32GB
- pyroscope_env: ci-smoke-keeper-evm-simulated
- file: keeper
- run: -run ^TestKeeperSimulation$
- - name: keeper-6
- nodes: 1
- os: ubuntu20.04-8cores-32GB
- pyroscope_env: ci-smoke-keeper-evm-simulated
- file: keeper
- run: -run ^TestKeeperCheckPerformGasLimit/registry_1_2$
- - name: keeper-7
- nodes: 1
- os: ubuntu20.04-8cores-32GB
- pyroscope_env: ci-smoke-keeper-evm-simulated
- file: keeper
- run: -run ^TestKeeperCheckPerformGasLimit/registry_1_3$
- - name: keeper-8
- nodes: 1
- os: ubuntu20.04-8cores-32GB
- pyroscope_env: ci-smoke-keeper-evm-simulated
- file: keeper
- run: -run ^TestKeeperRegisterUpkeep$
- - name: keeper-9
- nodes: 1
- os: ubuntu20.04-8cores-32GB
- pyroscope_env: ci-smoke-keeper-evm-simulated
- file: keeper
- run: -run ^TestKeeperAddFunds$
- - name: keeper-10
- nodes: 1
- os: ubuntu20.04-8cores-32GB
- pyroscope_env: ci-smoke-keeper-evm-simulated
- file: keeper
- run: -run ^TestKeeperRemove$
- - name: keeper-11
- nodes: 1
- os: ubuntu20.04-8cores-32GB
- pyroscope_env: ci-smoke-keeper-evm-simulated
- file: keeper
- run: -run ^TestKeeperPauseRegistry$
- - name: keeper-12
- nodes: 1
- os: ubuntu20.04-8cores-32GB
- pyroscope_env: ci-smoke-keeper-evm-simulated
- file: keeper
- run: -run ^TestKeeperMigrateRegistry$
- - name: keeper-13
- nodes: 1
- os: ubuntu20.04-8cores-32GB
- pyroscope_env: ci-smoke-keeper-evm-simulated
- file: keeper
- run: -run ^TestKeeperNodeDown/registry_1_1$
- - name: keeper-14
- nodes: 1
- os: ubuntu20.04-8cores-32GB
- pyroscope_env: ci-smoke-keeper-evm-simulated
- file: keeper
- run: -run ^TestKeeperNodeDown/registry_1_2$
- - name: keeper-15
- nodes: 1
- os: ubuntu20.04-8cores-32GB
- pyroscope_env: ci-smoke-keeper-evm-simulated
- file: keeper
- run: -run ^TestKeeperNodeDown/registry_1_3$
runs-on: ${{ matrix.product.os }}
name: ETH Smoke Tests ${{ matrix.product.name }}
steps:
- name: Checkout the repo
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
+ uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
with:
ref: ${{ github.event.pull_request.head.sha || github.event.merge_group.head_sha }}
- name: Build Go Test Command
@@ -393,7 +314,7 @@ jobs:
## Run this step when changes that require tests to be run are made
- name: Run Tests
if: needs.changes.outputs.src == 'true'
- uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@00c6214deb10a3f374c6d3430c32c5202015d463 # v2.2.12
+ uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@eccde1970eca69f079d3efb3409938a72ade8497 # v2.2.13
env:
PYROSCOPE_SERVER: ${{ matrix.product.pyroscope_env == '' && '' || !startsWith(github.ref, 'refs/tags/') && '' || secrets.QA_PYROSCOPE_INSTANCE }} # Avoid sending blank envs https://github.com/orgs/community/discussions/25725
PYROSCOPE_ENVIRONMENT: ${{ matrix.product.pyroscope_env }}
@@ -404,36 +325,29 @@ jobs:
cl_repo: ${{ env.CHAINLINK_IMAGE }}
cl_image_tag: ${{ github.sha }}
aws_registries: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}
- artifacts_location: ./integration-tests/smoke/logs
- publish_check_name: EVM Smoke Test Results ${{ matrix.product.name }}
+ artifacts_name: ${{ matrix.product.name }}-test-logs
+ artifacts_location: ./integration-tests/smoke/logs/
+ publish_check_name: ${{ matrix.product.name }}
token: ${{ secrets.GITHUB_TOKEN }}
go_mod_path: ./integration-tests/go.mod
cache_key_id: core-e2e-${{ env.MOD_CACHE_VERSION }}
- cache_restore_only: 'true'
+ cache_restore_only: "true"
QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }}
QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }}
QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }}
## Run this step when changes that do not need the test to run are made
- name: Run Setup
if: needs.changes.outputs.src == 'false'
- uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/setup-run-tests-environment@00c6214deb10a3f374c6d3430c32c5202015d463 # v2.2.12
+ uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/setup-run-tests-environment@eccde1970eca69f079d3efb3409938a72ade8497 # v2.2.13
with:
test_download_vendor_packages_command: cd ./integration-tests && go mod download
go_mod_path: ./integration-tests/go.mod
cache_key_id: core-e2e-${{ env.MOD_CACHE_VERSION }}
- cache_restore_only: 'true'
+ cache_restore_only: "true"
QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }}
QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }}
QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }}
- - name: Upload test log
- uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
- if: failure()
- with:
- name: test-log-${{ matrix.product.name }}
- path: /tmp/gotest.log
- retention-days: 7
- continue-on-error: true
- name: Collect Metrics
if: always()
id: collect-gha-metrics
@@ -450,10 +364,10 @@ jobs:
if: always()
runs-on: ubuntu-latest
name: ETH Smoke Tests
- needs: [eth-smoke-tests-matrix,eth-smoke-tests-matrix-docker]
+ needs: [eth-smoke-tests-matrix, eth-smoke-tests-matrix-automation]
steps:
- name: Check smoke test matrix status
- if: needs.eth-smoke-tests-matrix.result != 'success' || needs.eth-smoke-tests-matrix-docker.result != 'success'
+ if: needs.eth-smoke-tests-matrix.result != 'success' || needs.eth-smoke-tests-matrix-automation.result != 'success'
run: exit 1
- name: Collect Metrics
if: always()
@@ -464,7 +378,34 @@ jobs:
hostname: ${{ secrets.GRAFANA_CLOUD_HOST }}
this-job-name: ETH Smoke Tests
continue-on-error: true
-
+
+ cleanup:
+ name: Clean up integration environment deployments
+ if: always()
+ needs: [eth-smoke-tests]
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout repo
+ if: ${{ github.event_name == 'pull_request' }}
+ uses: actions/checkout@v4
+
+ - name: 🧼 Clean up Environment
+ if: ${{ github.event_name == 'pull_request' }}
+ uses: ./.github/actions/delete-deployments
+ with:
+ environment: integration
+ ref: ${{ github.head_ref }} # See https://github.com/github/docs/issues/15319#issuecomment-1476705663
+
+ - name: Collect Metrics
+ if: ${{ github.event_name == 'pull_request' }}
+ 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: Clean up integration environment deployments
+ continue-on-error: true
+
# Run the setup if the matrix finishes but this time save the cache if we have a cache hit miss
# this will also only run if both of the matrix jobs pass
eth-smoke-go-mod-cache:
@@ -472,13 +413,14 @@ jobs:
needs: [eth-smoke-tests]
runs-on: ubuntu20.04-16cores-64GB
name: ETH Smoke Tests Go Mod Cache
+ continue-on-error: true
steps:
- name: Checkout the repo
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
+ uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
with:
ref: ${{ github.event.pull_request.head.sha || github.event.merge_group.head_sha }}
- name: Run Setup
- uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/setup-go@00c6214deb10a3f374c6d3430c32c5202015d463 # v2.2.12
+ uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/setup-go@eccde1970eca69f079d3efb3409938a72ade8497 # v2.2.13
with:
test_download_vendor_packages_command: |
cd ./integration-tests
@@ -487,7 +429,7 @@ jobs:
go test -run=NonExistentTest ./smoke/... || echo "ignore expected test failure"
go_mod_path: ./integration-tests/go.mod
cache_key_id: core-e2e-${{ env.MOD_CACHE_VERSION }}
- cache_restore_only: 'false'
+ cache_restore_only: "false"
### Migration tests
node-migration-tests:
@@ -513,7 +455,7 @@ jobs:
TEST_SUITE: migration
steps:
- name: Checkout the repo
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
+ uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
with:
ref: ${{ github.event.pull_request.head.sha || github.event.merge_group.head_sha }}
- name: Get Latest Version
@@ -526,7 +468,7 @@ jobs:
run: |
echo "Running migration tests from version '${{ steps.get_latest_version.outputs.latest_version }}' to: '${{ github.sha }}'"
- name: Run Migration Tests
- uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@00c6214deb10a3f374c6d3430c32c5202015d463 # v2.2.12
+ uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@eccde1970eca69f079d3efb3409938a72ade8497 # v2.2.13
with:
test_command_to_run: make test_need_operator_assets && cd ./integration-tests && go test -timeout 30m -count=1 -json ./migration 2>&1 | tee /tmp/gotest.log | gotestfmt
test_download_vendor_packages_command: cd ./integration-tests && go mod download
@@ -537,7 +479,7 @@ jobs:
token: ${{ secrets.GITHUB_TOKEN }}
go_mod_path: ./integration-tests/go.mod
cache_key_id: core-e2e-${{ env.MOD_CACHE_VERSION }}
- cache_restore_only: 'true'
+ cache_restore_only: "true"
QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }}
QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }}
QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }}
@@ -569,7 +511,7 @@ jobs:
sha: ${{ steps.getsha.outputs.sha }}
steps:
- name: Checkout the repo
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
+ uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
with:
ref: ${{ github.event.pull_request.head.sha || github.event.merge_group.head_sha }}
- name: Get the sha from go mod
@@ -580,7 +522,7 @@ jobs:
echo "short sha is: ${short_sha}"
echo "short_sha=${short_sha}" >> "$GITHUB_OUTPUT"
- name: Checkout solana
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
+ uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
with:
repository: smartcontractkit/chainlink-solana
ref: develop
@@ -603,7 +545,7 @@ jobs:
projectserum_version: ${{ steps.psversion.outputs.projectserum_version }}
steps:
- name: Checkout the solana repo
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
+ uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
with:
repository: smartcontractkit/chainlink-solana
ref: ${{ needs.get_solana_sha.outputs.sha }}
@@ -626,7 +568,7 @@ jobs:
steps:
- name: Check if image exists
id: check-image
- uses: smartcontractkit/chainlink-github-actions/docker/image-exists@00c6214deb10a3f374c6d3430c32c5202015d463 # v2.2.12
+ uses: smartcontractkit/chainlink-github-actions/docker/image-exists@eccde1970eca69f079d3efb3409938a72ade8497 # v2.2.13
with:
repository: chainlink-solana-tests
tag: ${{ needs.get_solana_sha.outputs.sha }}
@@ -665,7 +607,7 @@ jobs:
this-job-name: Solana Build Artifacts
continue-on-error: true
- name: Checkout the solana repo
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
+ uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
with:
repository: smartcontractkit/chainlink-solana
ref: ${{ needs.get_solana_sha.outputs.sha }}
@@ -695,7 +637,7 @@ jobs:
CONTRACT_ARTIFACTS_PATH: contracts/target/deploy
steps:
- name: Collect Metrics
- if: needs.changes.outputs.src == 'true'
+ if: needs.changes.outputs.src == 'true' && needs.solana-test-image-exists.outputs.exists == 'false'
id: collect-gha-metrics
uses: smartcontractkit/push-gha-metrics-action@d2c2b7bdc9012651230b2608a1bcb0c48538b6ec
with:
@@ -704,7 +646,8 @@ jobs:
this-job-name: Solana Build Test Image
continue-on-error: true
- name: Checkout the repo
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
+ if: needs.changes.outputs.src == 'true' && needs.solana-test-image-exists.outputs.exists == 'false'
+ uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
with:
repository: smartcontractkit/chainlink-solana
ref: 23816fcf7d380a30c87b6d87e4fb0ca94419b259 # swtich back to this after the next solana release${{ needs.get_solana_sha.outputs.sha }}
@@ -717,8 +660,11 @@ jobs:
QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }}
QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }}
QA_AWS_ACCOUNT_NUMBER: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}
+ - 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:
+ if: ${{ !contains(join(github.event.pull_request.labels.*.name, ' '), 'skip-smoke-tests') }}
environment: integration
permissions:
checks: write
@@ -759,13 +705,13 @@ jobs:
test-results-file: '{"testType":"go","filePath":"/tmp/gotest.log"}'
continue-on-error: true
- name: Checkout the repo
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
+ uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
with:
repository: smartcontractkit/chainlink-solana
ref: ${{ needs.get_solana_sha.outputs.sha }}
- name: Run Tests
if: needs.changes.outputs.src == 'true'
- uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@00c6214deb10a3f374c6d3430c32c5202015d463 # v2.2.12
+ uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@eccde1970eca69f079d3efb3409938a72ade8497 # v2.2.13
with:
test_command_to_run: export ENV_JOB_IMAGE=${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink-solana-tests:${{ needs.get_solana_sha.outputs.sha }} && make test_smoke
cl_repo: ${{ env.CHAINLINK_IMAGE }}
@@ -798,20 +744,19 @@ jobs:
pull-requests: write
id-token: write
contents: read
- needs: [build-chainlink, build-test-image]
+ needs: [build-chainlink]
env:
SELECTED_NETWORKS: ${{ matrix.testnet }}
CHAINLINK_COMMIT_SHA: ${{ github.sha }}
CHAINLINK_ENV_USER: ${{ github.actor }}
TEST_LOG_LEVEL: debug
EVM_KEYS: ${{ secrets.QA_EVM_KEYS }}
- TEST_EVM_KEYS: ${{ secrets.QA_EVM_KEYS }}
- TEST_OPTIMISM_GOERLI_URLS: ${{ secrets.QA_OPTIMISM_GOERLI_URLS }}
- TEST_OPTIMISM_GOERLI_HTTP_URLS: ${{ secrets.QA_OPTIMISM_GOERLI_HTTP_URLS }}
+ OPTIMISM_GOERLI_URLS: ${{ secrets.QA_OPTIMISM_GOERLI_URLS }}
+ OPTIMISM_GOERLI_HTTP_URLS: ${{ secrets.QA_OPTIMISM_GOERLI_HTTP_URLS }}
- TEST_ARBITRUM_GOERLI_URLS: ${{ secrets.QA_ARBITRUM_GOERLI_URLS }}
- TEST_ARBITRUM_GOERLI_HTTP_URLS: ${{ secrets.QA_ARBITRUM_GOERLI_HTTP_URLS }}
+ ARBITRUM_GOERLI_URLS: ${{ secrets.QA_ARBITRUM_GOERLI_URLS }}
+ ARBITRUM_GOERLI_HTTP_URLS: ${{ secrets.QA_ARBITRUM_GOERLI_HTTP_URLS }}
strategy:
fail-fast: false
matrix:
@@ -823,12 +768,12 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout the repo
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
+ uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
with:
ref: ${{ github.event.pull_request.head.sha || github.event.merge_group.head_sha }}
## Only run OCR smoke test for now
- name: Run Tests
- uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@00c6214deb10a3f374c6d3430c32c5202015d463 # v2.2.12
+ uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@eccde1970eca69f079d3efb3409938a72ade8497 # v2.2.13
env:
PYROSCOPE_SERVER: ${{ secrets.QA_PYROSCOPE_INSTANCE }}
PYROSCOPE_ENVIRONMENT: ci-smoke-ocr-evm-${{ matrix.testnet }} # TODO: Only for OCR for now
@@ -844,7 +789,7 @@ jobs:
token: ${{ secrets.GITHUB_TOKEN }}
go_mod_path: ./integration-tests/go.mod
cache_key_id: core-e2e-${{ env.MOD_CACHE_VERSION }}
- cache_restore_only: 'true'
+ cache_restore_only: "true"
QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }}
QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }}
QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }}
@@ -862,7 +807,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/')) }} ## Only run live tests on new tags and nightly
+ 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 }}
@@ -914,6 +859,7 @@ jobs:
testnet-smoke-tests-results:
name: Post Live Testnet Smoke Test Results
+ if: ${{ always() && needs.testnet-smoke-tests-matrix.result != 'skipped' && needs.testnet-smoke-tests-matrix.result != 'cancelled' }}
environment: integration
permissions:
checks: write
@@ -982,4 +928,4 @@ jobs:
env:
SLACK_BOT_TOKEN: ${{ secrets.QA_SLACK_API_KEY }}
- ### End Live Testnet Section
\ No newline at end of file
+ ### End Live Testnet Section
diff --git a/.github/workflows/lint-gh-workflows.yml b/.github/workflows/lint-gh-workflows.yml
index 95c80f3d5da..66c69420606 100644
--- a/.github/workflows/lint-gh-workflows.yml
+++ b/.github/workflows/lint-gh-workflows.yml
@@ -7,9 +7,9 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Check out Code
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
+ uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
- name: Run actionlint
- uses: reviewdog/action-actionlint@7485c2136bd093d2317a854c72910eebaee35238 # v1.37.1
+ uses: reviewdog/action-actionlint@17ea0452ae2cd009a22ca629732a9ce7f49a55e6 # v1.39.0
- name: Collect Metrics
if: always()
id: collect-gha-metrics
diff --git a/.github/workflows/on-demand-ocr-soak-test.yml b/.github/workflows/on-demand-ocr-soak-test.yml
index 284464a4d09..08e37d9c8eb 100644
--- a/.github/workflows/on-demand-ocr-soak-test.yml
+++ b/.github/workflows/on-demand-ocr-soak-test.yml
@@ -104,7 +104,7 @@ jobs:
echo EVM_KEYS=$EVM_KEYS >> $GITHUB_ENV
echo SLACK_USER=$SLACK_USER >> $GITHUB_ENV
- name: Checkout the repo
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
+ uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
with:
ref: ${{ env.REF_NAME }}
- name: Setup Push Tag
@@ -121,7 +121,7 @@ jobs:
QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }}
QA_AWS_ACCOUNT_NUMBER: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}
- name: Run Tests
- uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@00c6214deb10a3f374c6d3430c32c5202015d463 # v2.2.12
+ uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@eccde1970eca69f079d3efb3409938a72ade8497 # v2.2.13
env:
DETACH_RUNNER: true
TEST_SUITE: soak
diff --git a/.github/workflows/operator-ui.yml b/.github/workflows/operator-ui-cd.yml
similarity index 55%
rename from .github/workflows/operator-ui.yml
rename to .github/workflows/operator-ui-cd.yml
index 8aac69c04dd..488e93778e6 100644
--- a/.github/workflows/operator-ui.yml
+++ b/.github/workflows/operator-ui-cd.yml
@@ -1,4 +1,4 @@
-name: Operator UI
+name: Operator UI CD
on:
push:
@@ -6,15 +6,17 @@ on:
- develop
workflow_dispatch:
schedule:
- - cron: '0 */1 * * *' # Run every hour
+ - cron: "0 */1 * * *" # Run every hour
jobs:
update-version:
+ permissions:
+ id-token: write
name: Update Version
runs-on: ubuntu-latest
steps:
- name: Checkout the repo
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
+ uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
- name: Update version
id: update
@@ -22,10 +24,25 @@ jobs:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: ./operator_ui/check.sh
+ - name: Assume role capable of dispatching action
+ uses: aws-actions/configure-aws-credentials@5fd3084fc36e372ff1fff382a39b10d03659f355 # v2.2.0
+ with:
+ role-to-assume: ${{ secrets.AWS_OIDC_CHAINLINK_CI_AUTO_PR_TOKEN_ISSUER_ROLE_ARN }}
+ role-duration-seconds: ${{ secrets.aws-role-duration-seconds }}
+ role-session-name: operator-ui-cd.update-version
+ aws-region: ${{ secrets.AWS_REGION }}
+
+ - name: Get Github Token
+ id: get-gh-token
+ uses: smartcontractkit/chainlink-github-actions/github-app-token-issuer@chore/update-github-app-token-issuer
+ with:
+ url: ${{ secrets.AWS_INFRA_RELENG_TOKEN_ISSUER_LAMBDA_URL }}
+
- name: Open PR
uses: peter-evans/create-pull-request@38e0b6e68b4c852a5500a94740f0e535e0d7ba54 # v4.2.4
with:
title: Update Operator UI from ${{ steps.update.outputs.current_tag }} to ${{ steps.update.outputs.latest_tag }}
+ token: ${{ steps.get-gh-token.outputs.access-token }}
branch: chore/update-operator-ui
commit-message: Update Operator UI from ${{ steps.update.outputs.current_tag }} to ${{ steps.update.outputs.latest_tag }}
body: ${{ steps.update.outputs.body }}
diff --git a/.github/workflows/operator-ui-ci.yml b/.github/workflows/operator-ui-ci.yml
new file mode 100644
index 00000000000..8ced3b222cf
--- /dev/null
+++ b/.github/workflows/operator-ui-ci.yml
@@ -0,0 +1,45 @@
+name: Operator UI CI
+on:
+ pull_request:
+
+jobs:
+ check-gql:
+ permissions:
+ id-token: write
+ contents: read
+ # To allow writing comments to the current PR
+ pull-requests: write
+
+ name: Breaking Changes GQL Check
+ runs-on: ubuntu-latest
+ steps:
+ - name: Collect Metrics
+ id: collect-gha-metrics
+ uses: smartcontractkit/push-gha-metrics-action@v1
+ with:
+ basic-auth: ${{ secrets.GRAFANA_CLOUD_BASIC_AUTH }}
+ hostname: ${{ secrets.GRAFANA_CLOUD_HOST }}
+ this-job-name: Breaking Changes GQL Check
+ continue-on-error: true
+
+ - name: Assume role capable of dispatching action
+ uses: aws-actions/configure-aws-credentials@5fd3084fc36e372ff1fff382a39b10d03659f355 # v2.2.0
+ with:
+ role-to-assume: ${{ secrets.AWS_OIDC_CHAINLINK_CI_OPERATOR_UI_ACCESS_TOKEN_ISSUER_ROLE_ARN }}
+ role-duration-seconds: 3600
+ role-session-name: operator-ui-ci.check-gql
+ aws-region: ${{ secrets.AWS_REGION }}
+
+ - name: Get Github Token
+ id: get-gh-token
+ uses: smartcontractkit/chainlink-github-actions/github-app-token-issuer@main
+ with:
+ url: ${{ secrets.AWS_INFRA_RELENG_TOKEN_ISSUER_LAMBDA_URL }}
+
+ - uses: convictional/trigger-workflow-and-wait@f69fa9eedd3c62a599220f4d5745230e237904be #v1.6.5
+ with:
+ owner: smartcontractkit
+ repo: operator-ui
+ github_token: ${{ steps.get-gh-token.outputs.access-token }}
+ workflow_file_name: chainlink-ci.yml
+ client_payload: '{"ref": "${{ github.event.pull_request.head.sha }}"}'
diff --git a/.github/workflows/performance-tests.yml b/.github/workflows/performance-tests.yml
index 3c104892407..3297fa1d4bf 100644
--- a/.github/workflows/performance-tests.yml
+++ b/.github/workflows/performance-tests.yml
@@ -18,7 +18,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout the repo
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
+ uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@5fd3084fc36e372ff1fff382a39b10d03659f355 # v2.2.0
with:
@@ -55,9 +55,9 @@ jobs:
needs: build-chainlink
steps:
- name: Checkout the repo
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
+ uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
- name: Run Tests
- uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@00c6214deb10a3f374c6d3430c32c5202015d463 # v2.2.12
+ uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@eccde1970eca69f079d3efb3409938a72ade8497 # v2.2.13
with:
test_command_to_run: cd integration-tests && go test -timeout 1h -count=1 -json -test.parallel 10 ./performance 2>&1 | tee /tmp/gotest.log | gotestfmt
test_download_vendor_packages_command: make gomod
diff --git a/.github/workflows/solidity-foundry.yml b/.github/workflows/solidity-foundry.yml
index 5c114c6e0ad..8f0181640ea 100644
--- a/.github/workflows/solidity-foundry.yml
+++ b/.github/workflows/solidity-foundry.yml
@@ -12,7 +12,7 @@ jobs:
changes: ${{ steps.changes.outputs.src }}
steps:
- name: Checkout the repo
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
+ uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
- uses: dorny/paths-filter@4512585405083f25c027a35db413c2b3b9006d50 # v2.11.1
id: changes
with:
@@ -21,13 +21,17 @@ jobs:
filters: |
src:
- 'contracts/src/v0.8/**/*'
+ - 'contracts/test/v0.8/foundry/**/*'
- '.github/workflows/solidity-foundry.yml'
- 'contracts/foundry.toml'
+ - 'contracts/gas-snapshots/*.gas-snapshot'
+ - '.gitmodules'
+ - 'contracts/foundry-lib'
tests:
strategy:
matrix:
- product: [ vrf, automation, llo-feeds, functions, automation-dev, shared ]
+ product: [vrf, automation, llo-feeds, functions, shared]
needs: [changes]
if: needs.changes.outputs.changes == 'true'
name: Tests
@@ -36,7 +40,7 @@ jobs:
steps:
- name: Checkout the repo
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
+ uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
with:
submodules: recursive
@@ -49,7 +53,8 @@ jobs:
- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1
with:
- version: nightly
+ # Has to match the `make foundry` version.
+ version: nightly-ca67d15f4abd46394b324c50e21e66f306a1162d
- name: Run Forge build
run: |
@@ -69,8 +74,9 @@ jobs:
FOUNDRY_PROFILE: ${{ matrix.product }}
- name: Run Forge snapshot
+ if: ${{ !contains(fromJson('["vrf"]'), matrix.product) && !contains(fromJson('["automation"]'), matrix.product) }}
run: |
- forge snapshot --check gas-snapshots/${{ matrix.product }}.gas-snapshot
+ forge snapshot --nmt "testFuzz_\w{1,}?" --check gas-snapshots/${{ matrix.product }}.gas-snapshot
id: snapshot
working-directory: contracts
env:
diff --git a/.github/workflows/solidity-hardhat.yml b/.github/workflows/solidity-hardhat.yml
index 1c630b48bb8..ac8240aa4e2 100644
--- a/.github/workflows/solidity-hardhat.yml
+++ b/.github/workflows/solidity-hardhat.yml
@@ -19,7 +19,7 @@ jobs:
changes: ${{ steps.changes.outputs.src }}
steps:
- name: Checkout the repo
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
+ uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
- uses: dorny/paths-filter@4512585405083f25c027a35db413c2b3b9006d50 # v2.11.1
id: changes
with:
@@ -39,7 +39,7 @@ jobs:
splits: ${{ steps.split.outputs.splits }}
steps:
- name: Checkout the repo
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
+ uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
- name: Generate splits
id: split
uses: ./.github/actions/split-tests
@@ -65,7 +65,7 @@ jobs:
runs-on: ubuntu20.04-4cores-16GB
steps:
- name: Checkout the repo
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
+ uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
- name: Setup NodeJS
uses: ./.github/actions/setup-nodejs
- name: Setup Hardhat
@@ -103,7 +103,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout the repo
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
+ uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
- name: Setup NodeJS
uses: ./.github/actions/setup-nodejs
- name: Make coverage directory
@@ -130,7 +130,7 @@ jobs:
runs-on: ubuntu20.04-4cores-16GB
steps:
- name: Checkout the repo
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
+ uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
- name: Setup NodeJS
uses: ./.github/actions/setup-nodejs
- name: Setup Hardhat
diff --git a/.github/workflows/solidity.yml b/.github/workflows/solidity.yml
index b024782ed42..0e7ff30545d 100644
--- a/.github/workflows/solidity.yml
+++ b/.github/workflows/solidity.yml
@@ -16,7 +16,7 @@ jobs:
changes: ${{ steps.changes.outputs.src }}
steps:
- name: Checkout the repo
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
+ uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
- uses: dorny/paths-filter@4512585405083f25c027a35db413c2b3b9006d50 # v2.11.1
id: changes
with:
@@ -32,7 +32,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout the repo
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
+ uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
- name: Setup NodeJS
uses: ./.github/actions/setup-nodejs
- name: Run Prepublish test
@@ -54,9 +54,9 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout the repo
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
+ uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
- name: Checkout diff-so-fancy
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
+ uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
with:
repository: so-fancy/diff-so-fancy
ref: a673cb4d2707f64d92b86498a2f5f71c8e2643d5 # v1.4.3
@@ -101,7 +101,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout the repo
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
+ uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
- name: Setup NodeJS
uses: ./.github/actions/setup-nodejs
- name: Run pnpm lint
@@ -120,17 +120,19 @@ jobs:
run:
working-directory: contracts
needs: [changes]
- if: needs.changes.outputs.changes == 'true'
name: Prettier Formatting
runs-on: ubuntu-latest
steps:
- name: Checkout the repo
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
+ 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/.github/workflows/sync-develop-from-smartcontractkit-chainlink.yml b/.github/workflows/sync-develop-from-smartcontractkit-chainlink.yml
index 314095a5012..49864f1cebe 100644
--- a/.github/workflows/sync-develop-from-smartcontractkit-chainlink.yml
+++ b/.github/workflows/sync-develop-from-smartcontractkit-chainlink.yml
@@ -10,7 +10,7 @@ jobs:
name: Sync
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
+ - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
with:
ref: develop
if: env.GITHUB_REPOSITORY != 'smartcontractkit/chainlink'
diff --git a/.tool-versions b/.tool-versions
index c7deac35bf5..9b2fa11518a 100644
--- a/.tool-versions
+++ b/.tool-versions
@@ -1,8 +1,7 @@
-golang 1.20.4
+golang 1.21.1
mockery 2.28.1
nodejs 16.16.0
postgres 13.3
helm 3.10.3
zig 0.10.1
-golangci-lint 1.53.3
-shellspec 0.28.1
+golangci-lint 1.54.2
diff --git a/GNUmakefile b/GNUmakefile
index 6ee81eb5036..71279f43651 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -146,7 +146,7 @@ config-docs: ## Generate core node configuration documentation
.PHONY: golangci-lint
golangci-lint: ## Run golangci-lint for all issues.
[ -d "./golangci-lint" ] || mkdir ./golangci-lint && \
- docker run --rm -v $(shell pwd):/app -w /app golangci/golangci-lint:v1.53.2 golangci-lint run --max-issues-per-linter 0 --max-same-issues 0 > ./golangci-lint/$(shell date --iso=seconds).txt
+ docker run --rm -v $(shell pwd):/app -w /app golangci/golangci-lint:v1.54.2 golangci-lint run --max-issues-per-linter 0 --max-same-issues 0 > ./golangci-lint/$(shell date +%Y-%m-%d_%H:%M:%S).txt
GORELEASER_CONFIG ?= .goreleaser.yaml
diff --git a/README.md b/README.md
index 4de44bf802a..f8dd24ffcc2 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`
@@ -297,12 +297,8 @@ For more tips on how to build and test Chainlink, see our [development tips page
### Contributing
-Chainlink's source code is [licensed under the MIT License](./LICENSE), and contributions are welcome.
+Contributions are welcome to Chainlink's source code.
Please check out our [contributing guidelines](./docs/CONTRIBUTING.md) for more details.
Thank you!
-
-## License
-
-[MIT](https://choosealicense.com/licenses/mit/)
diff --git a/VERSION b/VERSION
index 437459cd94c..e70b4523ae7 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2.5.0
+2.6.0
diff --git a/charts/chainlink-cluster/Chart.yaml b/charts/chainlink-cluster/Chart.yaml
index 6b64d718717..bfea29c82ec 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 179e51f2fa8..f7d4c45fa5f 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 63b6f112fec..54b5f9f01e9 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 3ab1edac602..16665916f59 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 72c20892109..11fb0cbee22 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 998687790ba..96f9582435f 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 41b24a770f5..5d9025b41c5 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 cd1bf8503eb..006515f0a33 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/ci.json b/ci.json
deleted file mode 100644
index eb913f56fc1..00000000000
--- a/ci.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "type": "golang",
- "numOfSplits": 8
-}
diff --git a/common/txmgr/confirmer.go b/common/txmgr/confirmer.go
index 07ed2d29f02..dbd67693aa3 100644
--- a/common/txmgr/confirmer.go
+++ b/common/txmgr/confirmer.go
@@ -517,7 +517,7 @@ func (ec *Confirmer[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) bat
}
}
- lggr := ec.lggr.Named("batchFetchReceipts").With("blockNum", blockNum)
+ lggr := ec.lggr.Named("BatchFetchReceipts").With("blockNum", blockNum)
txReceipts, txErrs, err := ec.client.BatchGetReceipts(ctx, attempts)
if err != nil {
diff --git a/common/txmgr/reaper.go b/common/txmgr/reaper.go
index 1070674ecf0..5394266de42 100644
--- a/common/txmgr/reaper.go
+++ b/common/txmgr/reaper.go
@@ -31,7 +31,7 @@ func NewReaper[CHAIN_ID types.ID](lggr logger.Logger, store txmgrtypes.TxHistory
config,
txConfig,
chainID,
- lggr.Named("txm_reaper"),
+ lggr.Named("Reaper"),
atomic.Int64{},
make(chan struct{}, 1),
make(chan struct{}),
@@ -43,13 +43,13 @@ func NewReaper[CHAIN_ID types.ID](lggr logger.Logger, store txmgrtypes.TxHistory
// Start the reaper. Should only be called once.
func (r *Reaper[CHAIN_ID]) Start() {
- r.log.Debugf("TxmReaper: started with age threshold %v and interval %v", r.txConfig.ReaperThreshold(), r.txConfig.ReaperInterval())
+ r.log.Debugf("started with age threshold %v and interval %v", r.txConfig.ReaperThreshold(), r.txConfig.ReaperInterval())
go r.runLoop()
}
// Stop the reaper. Should only be called once.
func (r *Reaper[CHAIN_ID]) Stop() {
- r.log.Debug("TxmReaper: stopping")
+ r.log.Debug("stopping")
close(r.chStop)
<-r.chDone
}
@@ -79,7 +79,7 @@ func (r *Reaper[CHAIN_ID]) work() {
}
err := r.ReapTxes(latestBlockNum)
if err != nil {
- r.log.Error("TxmReaper: unable to reap old txes: ", err)
+ r.log.Error("unable to reap old txes: ", err)
}
}
@@ -99,20 +99,20 @@ func (r *Reaper[CHAIN_ID]) SetLatestBlockNum(latestBlockNum int64) {
func (r *Reaper[CHAIN_ID]) ReapTxes(headNum int64) error {
threshold := r.txConfig.ReaperThreshold()
if threshold == 0 {
- r.log.Debug("TxmReaper: Transactions.ReaperThreshold set to 0; skipping ReapTxes")
+ r.log.Debug("Transactions.ReaperThreshold set to 0; skipping ReapTxes")
return nil
}
minBlockNumberToKeep := headNum - int64(r.config.FinalityDepth())
mark := time.Now()
timeThreshold := mark.Add(-threshold)
- r.log.Debugw(fmt.Sprintf("TxmReaper: reaping old txes created before %s", timeThreshold.Format(time.RFC3339)), "ageThreshold", threshold, "timeThreshold", timeThreshold, "minBlockNumberToKeep", minBlockNumberToKeep)
+ r.log.Debugw(fmt.Sprintf("reaping old txes created before %s", timeThreshold.Format(time.RFC3339)), "ageThreshold", threshold, "timeThreshold", timeThreshold, "minBlockNumberToKeep", minBlockNumberToKeep)
if err := r.store.ReapTxHistory(minBlockNumberToKeep, timeThreshold, r.chainID); err != nil {
return err
}
- r.log.Debugf("TxmReaper: ReapTxes completed in %v", time.Since(mark))
+ r.log.Debugf("ReapTxes completed in %v", time.Since(mark))
return nil
}
diff --git a/common/txmgr/txmgr.go b/common/txmgr/txmgr.go
index 422e1a364b5..0bcf3e482ee 100644
--- a/common/txmgr/txmgr.go
+++ b/common/txmgr/txmgr.go
@@ -2,6 +2,7 @@ package txmgr
import (
"context"
+ "database/sql"
"fmt"
"math/big"
"sync"
@@ -435,6 +436,20 @@ func (b *Txm[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) Trigger(ad
// CreateTransaction inserts a new transaction
func (b *Txm[CHAIN_ID, HEAD, ADDR, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) CreateTransaction(txRequest txmgrtypes.TxRequest[ADDR, TX_HASH], qs ...pg.QOpt) (tx txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], err error) {
+ // Check for existing Tx with IdempotencyKey. If found, return the Tx and do nothing
+ // Skipping CreateTransaction to avoid double send
+ if txRequest.IdempotencyKey != nil {
+ var existingTx *txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]
+ existingTx, err = b.txStore.FindTxWithIdempotencyKey(*txRequest.IdempotencyKey, b.chainID)
+ if err != nil && !errors.Is(err, sql.ErrNoRows) {
+ return tx, errors.Wrap(err, "Failed to search for transaction with IdempotencyKey")
+ }
+ if existingTx != nil {
+ b.logger.Infow("Found a Tx with IdempotencyKey. Returning existing Tx without creating a new one.", "IdempotencyKey", *txRequest.IdempotencyKey)
+ return *existingTx, nil
+ }
+ }
+
if err = b.checkEnabled(txRequest.FromAddress); err != nil {
return tx, err
}
diff --git a/common/txmgr/types/mocks/tx_store.go b/common/txmgr/types/mocks/tx_store.go
index 055d7852bfd..9c812788bf6 100644
--- a/common/txmgr/types/mocks/tx_store.go
+++ b/common/txmgr/types/mocks/tx_store.go
@@ -322,6 +322,32 @@ func (_m *TxStore[ADDR, CHAIN_ID, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) FindTxAttem
return r0, r1
}
+// FindTxWithIdempotencyKey provides a mock function with given fields: idempotencyKey, chainID
+func (_m *TxStore[ADDR, CHAIN_ID, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) FindTxWithIdempotencyKey(idempotencyKey string, chainID CHAIN_ID) (*txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], error) {
+ ret := _m.Called(idempotencyKey, chainID)
+
+ var r0 *txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]
+ var r1 error
+ if rf, ok := ret.Get(0).(func(string, CHAIN_ID) (*txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], error)); ok {
+ return rf(idempotencyKey, chainID)
+ }
+ if rf, ok := ret.Get(0).(func(string, CHAIN_ID) *txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE]); ok {
+ r0 = rf(idempotencyKey, chainID)
+ } else {
+ if ret.Get(0) != nil {
+ r0 = ret.Get(0).(*txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE])
+ }
+ }
+
+ if rf, ok := ret.Get(1).(func(string, CHAIN_ID) error); ok {
+ r1 = rf(idempotencyKey, chainID)
+ } else {
+ r1 = ret.Error(1)
+ }
+
+ return r0, r1
+}
+
// FindTxWithSequence provides a mock function with given fields: fromAddress, seq
func (_m *TxStore[ADDR, CHAIN_ID, TX_HASH, BLOCK_HASH, R, SEQ, FEE]) FindTxWithSequence(fromAddress ADDR, seq SEQ) (*txmgrtypes.Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], error) {
ret := _m.Called(fromAddress, seq)
diff --git a/common/txmgr/types/tx.go b/common/txmgr/types/tx.go
index a28c72fd363..a0faa81c3aa 100644
--- a/common/txmgr/types/tx.go
+++ b/common/txmgr/types/tx.go
@@ -66,6 +66,14 @@ func (s TxAttemptState) String() (str string) {
}
type TxRequest[ADDR types.Hashable, TX_HASH types.Hashable] struct {
+ // IdempotencyKey is a globally unique ID set by the caller, to prevent accidental creation of duplicated Txs during retries or crash recovery.
+ // If this field is set, the TXM will first search existing Txs with this field.
+ // If found, it will return the existing Tx, without creating a new one. TXM will not validate or ensure that existing Tx is same as the incoming TxRequest.
+ // If not found, TXM will create a new Tx.
+ // If IdempotencyKey is set to null, TXM will always create a new Tx.
+ // Since IdempotencyKey has to be globally unique, consider prepending the service or component's name it is being used by
+ // Such as {service}-{ID}. E.g vrf-12345
+ IdempotencyKey *string
FromAddress ADDR
ToAddress ADDR
EncodedPayload []byte
@@ -178,6 +186,7 @@ type Tx[
FEE feetypes.Fee,
] struct {
ID int64
+ IdempotencyKey *string
Sequence *SEQ
FromAddress ADDR
ToAddress ADDR
diff --git a/common/txmgr/types/tx_store.go b/common/txmgr/types/tx_store.go
index 41a989fc769..8c56b8a6ed6 100644
--- a/common/txmgr/types/tx_store.go
+++ b/common/txmgr/types/tx_store.go
@@ -64,6 +64,9 @@ type TransactionStore[
FindTxAttemptsConfirmedMissingReceipt(chainID CHAIN_ID) (attempts []TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], err error)
FindTxAttemptsRequiringReceiptFetch(chainID CHAIN_ID) (attempts []TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], err error)
FindTxAttemptsRequiringResend(olderThan time.Time, maxInFlightTransactions uint32, chainID CHAIN_ID, address ADDR) (attempts []TxAttempt[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], err error)
+ // Search for Tx using the idempotencyKey and chainID
+ FindTxWithIdempotencyKey(idempotencyKey string, chainID CHAIN_ID) (tx *Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], err error)
+ // Search for Tx using the fromAddress and sequence
FindTxWithSequence(fromAddress ADDR, seq SEQ) (etx *Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], err error)
FindNextUnstartedTransactionFromAddress(etx *Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], fromAddress ADDR, chainID CHAIN_ID, qopts ...pg.QOpt) error
FindTransactionsConfirmedInBlockRange(highBlockNumber, lowBlockNumber int64, chainID CHAIN_ID) (etxs []*Tx[CHAIN_ID, ADDR, TX_HASH, BLOCK_HASH, SEQ, FEE], err error)
diff --git a/contracts/CHANGELOG.md b/contracts/CHANGELOG.md
index d842a90663f..e3ea1a31a9c 100644
--- a/contracts/CHANGELOG.md
+++ b/contracts/CHANGELOG.md
@@ -2,6 +2,10 @@
## Unreleased
+...
+
+## 0.7.1 - 2023-09-20
+
### Changed
- Add Chainlink Functions v1.0.0 (#9365)
diff --git a/contracts/GNUmakefile b/contracts/GNUmakefile
index ea70ae43f93..328c921545c 100644
--- a/contracts/GNUmakefile
+++ b/contracts/GNUmakefile
@@ -1,7 +1,6 @@
# ALL_FOUNDRY_PRODUCTS contains a list of all products that have a foundry
-# profile defined. Adding a product to this list will make it available for
-# snapshotting.
-ALL_FOUNDRY_PRODUCTS = vrf automation llo-feeds functions automation-dev shared
+# profile defined and use the Foundry snapshots.
+ALL_FOUNDRY_PRODUCTS = llo-feeds functions shared
# To make a snapshot for a specific product, either set the `FOUNDRY_PROFILE` env var
# or call the target with `FOUNDRY_PROFILE=product`
@@ -13,9 +12,11 @@ ALL_FOUNDRY_PRODUCTS = vrf automation llo-feeds functions automation-dev shared
# make snapshot
# make call example
# make FOUNDRY_PROFILE=llo-feeds snapshot
+# note make snapshot skips fuzz tests named according to best practices, although forge uses
+# a static fuzz seed by default, flaky gas results per platform are still observed.
.PHONY: snapshot
snapshot: ## Make a snapshot for a specific product.
- export FOUNDRY_PROFILE=$(FOUNDRY_PROFILE) && forge snapshot --snap gas-snapshots/$(FOUNDRY_PROFILE).gas-snapshot
+ export FOUNDRY_PROFILE=$(FOUNDRY_PROFILE) && forge snapshot --nmt "testFuzz_\w{1,}?" --snap gas-snapshots/$(FOUNDRY_PROFILE).gas-snapshot
.PHONY: snapshot-all
snapshot-all: ## Make a snapshot for all products.
@@ -31,6 +32,18 @@ pnpmdep: ## Install solidity contract dependencies through pnpm
abigen: ## Build & install abigen.
../tools/bin/build_abigen
+.PHONY: mockery
+mockery: $(mockery) ## Install mockery.
+ go install github.com/vektra/mockery/v2@v2.28.1
+
+.PHONY: foundry
+foundry: ## Install foundry.
+ foundryup --version nightly-ca67d15f4abd46394b324c50e21e66f306a1162d
+
+.PHONY: foundry-refresh
+foundry-refresh: foundry
+ git submodule deinit -f .
+ git submodule update --init --recursive
# To generate gethwrappers for a specific product, either set the `FOUNDRY_PROFILE`
# env var or call the target with `FOUNDRY_PROFILE=product`
@@ -43,7 +56,7 @@ abigen: ## Build & install abigen.
# make call example
# make FOUNDRY_PROFILE=llo-feeds wrappers
.PHONY: wrappers
-wrappers: pnpmdep abigen ## Recompiles solidity contracts and their go wrappers.
+wrappers: pnpmdep mockery abigen ## Recompiles solidity contracts and their go wrappers.
./scripts/native_solc_compile_all_$(FOUNDRY_PROFILE)
go generate ../core/gethwrappers/$(FOUNDRY_PROFILE)
@@ -51,7 +64,7 @@ wrappers: pnpmdep abigen ## Recompiles solidity contracts and their go wrappers.
# assumption that native_solc_compile_all contains sub-calls to each product, and
# go_generate does the same.
.PHONY: wrappers-all
-wrappers-all: pnpmdep abigen ## Recompiles solidity contracts and their go wrappers.
+wrappers-all: pnpmdep mockery abigen ## Recompiles solidity contracts and their go wrappers.
# go_generate contains a call to compile all contracts before generating wrappers
go generate ../core/gethwrappers/go_generate.go
diff --git a/contracts/foundry-lib/forge-std b/contracts/foundry-lib/forge-std
index f4264050aca..1d9650e9512 160000
--- a/contracts/foundry-lib/forge-std
+++ b/contracts/foundry-lib/forge-std
@@ -1 +1 @@
-Subproject commit f4264050aca5a2eedf243f9bd54b544c5a373bd2
+Subproject commit 1d9650e951204a0ddce9ff89c32f1997984cef4d
diff --git a/contracts/foundry.toml b/contracts/foundry.toml
index c1da24ad814..d1bec52c391 100644
--- a/contracts/foundry.toml
+++ b/contracts/foundry.toml
@@ -20,6 +20,7 @@ block_number = 12345
solc_version = '0.8.19'
src = 'src/v0.8/functions'
test = 'src/v0.8/functions/tests'
+gas_price = 3000000000
[profile.vrf]
optimizer_runs = 1000
@@ -31,25 +32,20 @@ solc_version = '0.8.6'
optimizer_runs = 10000
src = 'src/v0.8/automation'
test = 'src/v0.8/automation/test'
-solc_version = '0.8.6'
-
-[profile.automation-dev]
-optimizer_runs = 10000
-src = 'src/v0.8/dev/automation'
-test = 'src/v0.8/dev/automation/test'
[profile.llo-feeds]
optimizer_runs = 1000000
src = 'src/v0.8/llo-feeds'
test = 'src/v0.8/llo-feeds/test'
solc_version = '0.8.16'
+# We cannot turn on deny_warnings = true as that will
+# hide any CI failure
[profile.shared]
optimizer_runs = 1000000
src = 'src/v0.8/shared'
test = 'src/v0.8/shared/test'
solc_version = '0.8.19'
-deny_warnings = true
# See more config options https://github.com/foundry-rs/foundry/tree/master/config
diff --git a/contracts/gas-snapshots/automation-dev.gas-snapshot b/contracts/gas-snapshots/automation-dev.gas-snapshot
deleted file mode 100644
index 1a939d69e19..00000000000
--- a/contracts/gas-snapshots/automation-dev.gas-snapshot
+++ /dev/null
@@ -1,5 +0,0 @@
-AutomationForwarder_forward:testBasicSuccess() (gas: 87630)
-AutomationForwarder_forward:testNotAuthorizedReverts() (gas: 21681)
-AutomationForwarder_forward:testWrongFunctionSelectorSuccess() (gas: 17958)
-AutomationForwarder_updateRegistry:testBasicSuccess() (gas: 14577)
-AutomationForwarder_updateRegistry:testNotFromRegistryNotAuthorizedReverts() (gas: 13893)
\ No newline at end of file
diff --git a/contracts/gas-snapshots/automation.gas-snapshot b/contracts/gas-snapshots/automation.gas-snapshot
index 934aebf982d..620e0b22559 100644
--- a/contracts/gas-snapshots/automation.gas-snapshot
+++ b/contracts/gas-snapshots/automation.gas-snapshot
@@ -1,8 +1,13 @@
+AutomationForwarder_forward:testBasicSuccess() (gas: 87630)
+AutomationForwarder_forward:testNotAuthorizedReverts() (gas: 24560)
+AutomationForwarder_forward:testWrongFunctionSelectorSuccess() (gas: 17958)
+AutomationForwarder_updateRegistry:testBasicSuccess() (gas: 14577)
+AutomationForwarder_updateRegistry:testNotFromRegistryNotAuthorizedReverts() (gas: 17665)
HeartbeatRequester_getAggregatorRequestHeartbeat:testBasicSuccess() (gas: 75412)
HeartbeatRequester_getAggregatorRequestHeartbeat:testHeartbeatNotPermittedReverts() (gas: 21730)
-HeartbeatRequester_permitHeartbeat:testBasicDeployerSuccess() (gas: 48280)
-HeartbeatRequester_permitHeartbeat:testBasicSuccess() (gas: 45856)
-HeartbeatRequester_permitHeartbeat:testOnlyCallableByOwnerReverts() (gas: 13796)
+HeartbeatRequester_permitHeartbeat:testBasicDeployerSuccess() (gas: 48229)
+HeartbeatRequester_permitHeartbeat:testBasicSuccess() (gas: 45844)
+HeartbeatRequester_permitHeartbeat:testOnlyCallableByOwnerReverts() (gas: 17584)
HeartbeatRequester_removeHeartbeat:testBasicSuccess() (gas: 30192)
-HeartbeatRequester_removeHeartbeat:testOnlyCallableByOwnerReverts() (gas: 11629)
+HeartbeatRequester_removeHeartbeat:testOnlyCallableByOwnerReverts() (gas: 15417)
HeartbeatRequester_removeHeartbeat:testRemoveNoPermitsSuccess() (gas: 15660)
\ No newline at end of file
diff --git a/contracts/gas-snapshots/functions.gas-snapshot b/contracts/gas-snapshots/functions.gas-snapshot
index b0a733f39c8..0664a2eb997 100644
--- a/contracts/gas-snapshots/functions.gas-snapshot
+++ b/contracts/gas-snapshots/functions.gas-snapshot
@@ -1,17 +1,176 @@
-FunctionsOracle_sendRequest:testEmptyRequestDataReverts() (gas: 13430)
+FunctionsBilling_EstimateCost:test_EstimateCost_RevertsIfGasPriceAboveCeiling() (gas: 32391)
+FunctionsBilling_EstimateCost:test_EstimateCost_Success() (gas: 53002)
+FunctionsBilling_OracleWithdrawAll:test_OracleWithdrawAll_RevertIfNotOwner() (gas: 13274)
+FunctionsBilling_OracleWithdrawAll:test_OracleWithdrawAll_SuccessPaysTransmittersWithBalance() (gas: 146635)
+FunctionsOracle_sendRequest:testEmptyRequestDataReverts() (gas: 13452)
FunctionsOracle_setDONPublicKey:testEmptyPublicKeyReverts() (gas: 10974)
FunctionsOracle_setDONPublicKey:testOnlyOwnerReverts() (gas: 11255)
FunctionsOracle_setDONPublicKey:testSetDONPublicKeySuccess() (gas: 126453)
-FunctionsOracle_setDONPublicKey:testSetDONPublicKey_gas() (gas: 97558)
+FunctionsOracle_setDONPublicKey:testSetDONPublicKey_gas() (gas: 97580)
FunctionsOracle_setRegistry:testEmptyPublicKeyReverts() (gas: 10635)
FunctionsOracle_setRegistry:testOnlyOwnerReverts() (gas: 10927)
FunctionsOracle_setRegistry:testSetRegistrySuccess() (gas: 35791)
FunctionsOracle_setRegistry:testSetRegistry_gas() (gas: 31987)
FunctionsOracle_typeAndVersion:testTypeAndVersionSuccess() (gas: 6905)
-FunctionsRouter_Pause:test_Pause_RevertIfNotOwner() (gas: 13293)
-FunctionsRouter_Pause:test_Pause_Success() (gas: 20205)
-FunctionsRouter_Unpause:test_Unpause_RevertIfNotOwner() (gas: 13338)
-FunctionsRouter_Unpause:test_Unpause_Success() (gas: 77279)
-FunctionsSubscriptions_createSubscription:test_CreateSubscription_RevertIfNotAllowedSender() (gas: 26347)
-FunctionsSubscriptions_createSubscription:test_CreateSubscription_RevertIfPaused() (gas: 15699)
-FunctionsSubscriptions_createSubscription:test_CreateSubscription_Success() (gas: 152436)
+FunctionsRouter_Constructor:test_Constructor_Success() (gas: 12073)
+FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedCostExceedsCommitment() (gas: 172948)
+FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedInsufficientGas() (gas: 163234)
+FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedInvalidCommitment() (gas: 38092)
+FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedInvalidRequestId() (gas: 35224)
+FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedSubscriptionBalanceInvariant() (gas: 181443)
+FunctionsRouter_Fulfill:test_Fulfill_RevertIfNotCommittedCoordinator() (gas: 28063)
+FunctionsRouter_Fulfill:test_Fulfill_RevertIfPaused() (gas: 156949)
+FunctionsRouter_Fulfill:test_Fulfill_SuccessClientNoLongerExists() (gas: 297578)
+FunctionsRouter_Fulfill:test_Fulfill_SuccessFulfilled() (gas: 311147)
+FunctionsRouter_Fulfill:test_Fulfill_SuccessUserCallbackReverts() (gas: 2076842)
+FunctionsRouter_Fulfill:test_Fulfill_SuccessUserCallbackRunsOutOfGas() (gas: 515646)
+FunctionsRouter_GetAdminFee:test_GetAdminFee_Success() (gas: 18005)
+FunctionsRouter_GetAllowListId:test_GetAllowListId_Success() (gas: 12926)
+FunctionsRouter_GetConfig:test_GetConfig_Success() (gas: 37136)
+FunctionsRouter_GetContractById:test_GetContractById_RevertIfRouteDoesNotExist() (gas: 13871)
+FunctionsRouter_GetContractById:test_GetContractById_SuccessIfRouteExists() (gas: 17395)
+FunctionsRouter_GetProposedContractById:test_GetProposedContractById_RevertIfRouteDoesNotExist() (gas: 16382)
+FunctionsRouter_GetProposedContractById:test_GetProposedContractById_SuccessIfRouteExists() (gas: 23934)
+FunctionsRouter_GetProposedContractSet:test_GetProposedContractSet_Success() (gas: 25958)
+FunctionsRouter_IsValidCallbackGasLimit:test_IsValidCallbackGasLimit_RevertGasLimitTooBig() (gas: 28034)
+FunctionsRouter_IsValidCallbackGasLimit:test_IsValidCallbackGasLimit_RevertInvalidConfig() (gas: 41004)
+FunctionsRouter_IsValidCallbackGasLimit:test_IsValidCallbackGasLimit_Success() (gas: 24551)
+FunctionsRouter_Pause:test_Pause_RevertIfNotOwner() (gas: 13315)
+FunctionsRouter_Pause:test_Pause_Success() (gas: 20298)
+FunctionsRouter_ProposeContractsUpdate:test_ProposeContractsUpdate_RevertIfEmptyAddress() (gas: 14768)
+FunctionsRouter_ProposeContractsUpdate:test_ProposeContractsUpdate_RevertIfExceedsMaxProposal() (gas: 21670)
+FunctionsRouter_ProposeContractsUpdate:test_ProposeContractsUpdate_RevertIfLengthMismatch() (gas: 14647)
+FunctionsRouter_ProposeContractsUpdate:test_ProposeContractsUpdate_RevertIfNotNewContract() (gas: 19025)
+FunctionsRouter_ProposeContractsUpdate:test_ProposeContractsUpdate_RevertIfNotOwner() (gas: 23369)
+FunctionsRouter_ProposeContractsUpdate:test_ProposeContractsUpdate_Success() (gas: 118456)
+FunctionsRouter_SendRequest:test_SendRequest_RevertIfConsumerNotAllowed() (gas: 59304)
+FunctionsRouter_SendRequest:test_SendRequest_RevertIfDuplicateRequestId() (gas: 192134)
+FunctionsRouter_SendRequest:test_SendRequest_RevertIfEmptyData() (gas: 29405)
+FunctionsRouter_SendRequest:test_SendRequest_RevertIfIncorrectDonId() (gas: 57926)
+FunctionsRouter_SendRequest:test_SendRequest_RevertIfInsufficientSubscriptionBalance() (gas: 185987)
+FunctionsRouter_SendRequest:test_SendRequest_RevertIfInvalidCallbackGasLimit() (gas: 50902)
+FunctionsRouter_SendRequest:test_SendRequest_RevertIfInvalidDonId() (gas: 25061)
+FunctionsRouter_SendRequest:test_SendRequest_RevertIfNoSubscription() (gas: 29111)
+FunctionsRouter_SendRequest:test_SendRequest_RevertIfPaused() (gas: 34247)
+FunctionsRouter_SendRequest:test_SendRequest_Success() (gas: 197669)
+FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfConsumerNotAllowed() (gas: 65800)
+FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfEmptyData() (gas: 35991)
+FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfIncorrectDonId() (gas: 29897)
+FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfInvalidCallbackGasLimit() (gas: 57488)
+FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfInvalidDonId() (gas: 27482)
+FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfNoSubscription() (gas: 35696)
+FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfPaused() (gas: 40766)
+FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_Success() (gas: 204227)
+FunctionsRouter_SendRequestToProposed:test_SendRequest_RevertIfInsufficientSubscriptionBalance() (gas: 192506)
+FunctionsRouter_SetAllowListId:test_SetAllowListId_Success() (gas: 30687)
+FunctionsRouter_SetAllowListId:test_UpdateConfig_RevertIfNotOwner() (gas: 13380)
+FunctionsRouter_Unpause:test_Unpause_RevertIfNotOwner() (gas: 13337)
+FunctionsRouter_Unpause:test_Unpause_Success() (gas: 77421)
+FunctionsRouter_UpdateConfig:test_UpdateConfig_RevertIfNotOwner() (gas: 24437)
+FunctionsRouter_UpdateConfig:test_UpdateConfig_Success() (gas: 60653)
+FunctionsRouter_UpdateContracts:test_UpdateContracts_RevertIfNotOwner() (gas: 13293)
+FunctionsRouter_UpdateContracts:test_UpdateContracts_Success() (gas: 38716)
+FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_RevertIfNotAllowedSender() (gas: 60324)
+FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_RevertIfPaused() (gas: 60962)
+FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_RevertIfSenderBecomesBlocked() (gas: 94675)
+FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_RevertIfSenderIsNotNewOwner() (gas: 62691)
+FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_Success() (gas: 59679)
+FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfMaximumConsumers() (gas: 137833)
+FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfMaximumConsumersAfterConfigUpdate() (gas: 164777)
+FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfNoSubscription() (gas: 12926)
+FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfNotAllowedSender() (gas: 57789)
+FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfNotSubscriptionOwner() (gas: 87142)
+FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfPaused() (gas: 18051)
+FunctionsSubscriptions_AddConsumer:test_AddConsumer_Success() (gas: 95481)
+FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfNoSubscription() (gas: 15085)
+FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfNotAllowedSender() (gas: 57929)
+FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfNotSubscriptionOwner() (gas: 89316)
+FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfPaused() (gas: 20191)
+FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfPendingRequests() (gas: 193277)
+FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_SuccessForfeitAllBalanceAsDeposit() (gas: 113352)
+FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_SuccessForfeitSomeBalanceAsDeposit() (gas: 124604)
+FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_SuccessRecieveDeposit() (gas: 310123)
+FunctionsSubscriptions_Constructor:test_Constructor_Success() (gas: 7654)
+FunctionsSubscriptions_CreateSubscriptionWithConsumer:test_CreateSubscriptionWithConsumer_RevertIfNotAllowedSender() (gas: 28637)
+FunctionsSubscriptions_CreateSubscriptionWithConsumer:test_CreateSubscriptionWithConsumer_RevertIfPaused() (gas: 17948)
+FunctionsSubscriptions_CreateSubscriptionWithConsumer:test_CreateSubscriptionWithConsumer_Success() (gas: 371980)
+FunctionsSubscriptions_GetConsumer:test_GetConsumer_Success() (gas: 16225)
+FunctionsSubscriptions_GetFlags:test_GetFlags_Success() (gas: 40858)
+FunctionsSubscriptions_GetSubscription:test_GetSubscription_Success() (gas: 30959)
+FunctionsSubscriptions_GetSubscriptionCount:test_GetSubscriptionCount_Success() (gas: 12967)
+FunctionsSubscriptions_GetSubscriptionsInRange:test_GetSubscriptionsInRange_RevertIfEndIsAfterLastSubscription() (gas: 14949)
+FunctionsSubscriptions_GetSubscriptionsInRange:test_GetSubscriptionsInRange_RevertIfStartIsAfterEnd() (gas: 11863)
+FunctionsSubscriptions_GetSubscriptionsInRange:test_GetSubscriptionsInRange_Success() (gas: 59568)
+FunctionsSubscriptions_GetTotalBalance:test_GetTotalBalance_Success() (gas: 15032)
+FunctionsSubscriptions_OnTokenTransfer:test_OnTokenTransfer_RevertIfCallerIsNoCalldata() (gas: 27594)
+FunctionsSubscriptions_OnTokenTransfer:test_OnTokenTransfer_RevertIfCallerIsNoSubscription() (gas: 30071)
+FunctionsSubscriptions_OnTokenTransfer:test_OnTokenTransfer_RevertIfCallerIsNotLink() (gas: 13402)
+FunctionsSubscriptions_OnTokenTransfer:test_OnTokenTransfer_RevertIfPaused() (gas: 35000)
+FunctionsSubscriptions_OnTokenTransfer:test_OnTokenTransfer_Success() (gas: 56279)
+FunctionsSubscriptions_OracleWithdraw:test_OracleWithdraw_RevertIfAmountMoreThanBalance() (gas: 20745)
+FunctionsSubscriptions_OracleWithdraw:test_OracleWithdraw_RevertIfBalanceInvariant() (gas: 189)
+FunctionsSubscriptions_OracleWithdraw:test_OracleWithdraw_RevertIfNoAmount() (gas: 15638)
+FunctionsSubscriptions_OracleWithdraw:test_OracleWithdraw_RevertIfPaused() (gas: 20833)
+FunctionsSubscriptions_OracleWithdraw:test_OracleWithdraw_SuccessPaysRecipient() (gas: 59732)
+FunctionsSubscriptions_OracleWithdraw:test_OracleWithdraw_SuccessSetsBalanceToZero() (gas: 57701)
+FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_RevertIfNoSubscription() (gas: 12818)
+FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_RevertIfNotOwner() (gas: 15549)
+FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_Success() (gas: 54867)
+FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_SuccessDeletesSubscription() (gas: 48362)
+FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_SuccessSubOwnerRefunded() (gas: 50896)
+FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_SuccessWhenRequestInFlight() (gas: 163911)
+FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_RevertIfAmountMoreThanBalance() (gas: 17924)
+FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_RevertIfBalanceInvariant() (gas: 165)
+FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_RevertIfNotOwner() (gas: 15555)
+FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_SuccessIfNoAmount() (gas: 37396)
+FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_SuccessPaysRecipient() (gas: 54435)
+FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_SuccessSetsBalanceToZero() (gas: 37790)
+FunctionsSubscriptions_PendingRequestExists:test_PendingRequestExists_SuccessFalseIfNoPendingRequests() (gas: 15025)
+FunctionsSubscriptions_PendingRequestExists:test_PendingRequestExists_SuccessTrueIfPendingRequests() (gas: 175411)
+FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfEmptyNewOwner() (gas: 27610)
+FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfInvalidNewOwner() (gas: 57707)
+FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfNoSubscription() (gas: 15000)
+FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfNotAllowedSender() (gas: 75130)
+FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfNotSubscriptionOwner() (gas: 17959)
+FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfPaused() (gas: 20104)
+FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_Success() (gas: 68216)
+FunctionsSubscriptions_RecoverFunds:test_OwnerCancelSubscription_RevertIfNotOwner() (gas: 15532)
+FunctionsSubscriptions_RecoverFunds:test_RecoverFunds_Success() (gas: 41093)
+FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfInvalidConsumer() (gas: 30238)
+FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfNoSubscription() (gas: 14997)
+FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfNotAllowedSender() (gas: 57778)
+FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfNotSubscriptionOwner() (gas: 87186)
+FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfPaused() (gas: 18004)
+FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfPendingRequests() (gas: 190709)
+FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_Success() (gas: 41979)
+FunctionsSubscriptions_SetFlags:test_SetFlags_RevertIfNoSubscription() (gas: 12847)
+FunctionsSubscriptions_SetFlags:test_SetFlags_RevertIfNotOwner() (gas: 15640)
+FunctionsSubscriptions_SetFlags:test_SetFlags_Success() (gas: 35549)
+FunctionsSubscriptions_TimeoutRequests:test_TimeoutRequests_RevertIfPaused() (gas: 25910)
+FunctionsSubscriptions_TimeoutRequests:test_TimeoutRequests_RevertIfTimeoutNotExceeded() (gas: 25239)
+FunctionsSubscriptions_TimeoutRequests:test_TimeoutRequests_RevertInvalidRequest() (gas: 28220)
+FunctionsSubscriptions_TimeoutRequests:test_TimeoutRequests_Success() (gas: 57730)
+FunctionsSubscriptions_createSubscription:test_CreateSubscription_RevertIfNotAllowedSender() (gas: 26368)
+FunctionsSubscriptions_createSubscription:test_CreateSubscription_RevertIfPaused() (gas: 15714)
+FunctionsSubscriptions_createSubscription:test_CreateSubscription_Success() (gas: 152510)
+FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfAcceptorIsNotSender() (gas: 25837)
+FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfBlockedSender() (gas: 44348)
+FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfInvalidSigner() (gas: 23597)
+FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfRecipientContractIsNotSender() (gas: 1458254)
+FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfRecipientIsNotSender() (gas: 26003)
+FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_SuccessIfAcceptingForContract() (gas: 1538373)
+FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_SuccessIfAcceptingForSelf() (gas: 94684)
+FunctionsTermsOfServiceAllowList_BlockSender:test_BlockSender_RevertIfNotOwner() (gas: 15469)
+FunctionsTermsOfServiceAllowList_BlockSender:test_BlockSender_Success() (gas: 50421)
+FunctionsTermsOfServiceAllowList_Constructor:test_Constructor_Success() (gas: 12187)
+FunctionsTermsOfServiceAllowList_GetAllAllowedSenders:test_GetAllAllowedSenders_Success() (gas: 19243)
+FunctionsTermsOfServiceAllowList_GetConfig:test_GetConfig_Success() (gas: 15773)
+FunctionsTermsOfServiceAllowList_GetMessage:test_GetMessage_Success() (gas: 11583)
+FunctionsTermsOfServiceAllowList_HasAccess:test_HasAccess_FalseWhenEnabled() (gas: 15925)
+FunctionsTermsOfServiceAllowList_HasAccess:test_HasAccess_TrueWhenDisabled() (gas: 23430)
+FunctionsTermsOfServiceAllowList_IsBlockedSender:test_IsBlockedSender_SuccessFalse() (gas: 15354)
+FunctionsTermsOfServiceAllowList_IsBlockedSender:test_IsBlockedSender_SuccessTrue() (gas: 41957)
+FunctionsTermsOfServiceAllowList_UnblockSender:test_UnblockSender_RevertIfNotOwner() (gas: 13525)
+FunctionsTermsOfServiceAllowList_UnblockSender:test_UnblockSender_Success() (gas: 95184)
+FunctionsTermsOfServiceAllowList_UpdateConfig:test_UpdateConfig_RevertIfNotOwner() (gas: 13727)
+FunctionsTermsOfServiceAllowList_UpdateConfig:test_UpdateConfig_Success() (gas: 22073)
\ No newline at end of file
diff --git a/contracts/gas-snapshots/llo-feeds.gas-snapshot b/contracts/gas-snapshots/llo-feeds.gas-snapshot
index c5d28f2e6eb..74b9a9f9258 100644
--- a/contracts/gas-snapshots/llo-feeds.gas-snapshot
+++ b/contracts/gas-snapshots/llo-feeds.gas-snapshot
@@ -1,227 +1,252 @@
-FeeManagerProcessFeeTest:test_DiscountIsAppliedForNative() (gas: 47380)
-FeeManagerProcessFeeTest:test_V1PayloadVerifies() (gas: 17377)
-FeeManagerProcessFeeTest:test_V2PayloadVerifies() (gas: 105616)
-FeeManagerProcessFeeTest:test_V2PayloadWithoutQuoteFails() (gas: 19971)
-FeeManagerProcessFeeTest:test_V2PayloadWithoutZeroFee() (gas: 63248)
-FeeManagerProcessFeeTest:test_WithdrawERC20() (gas: 63905)
-FeeManagerProcessFeeTest:test_WithdrawNonAdminAddr() (gas: 48635)
-FeeManagerProcessFeeTest:test_WithdrawUnwrappedNative() (gas: 20266)
-FeeManagerProcessFeeTest:test_baseFeeIsAppliedForLink() (gas: 14770)
-FeeManagerProcessFeeTest:test_baseFeeIsAppliedForNative() (gas: 17266)
-FeeManagerProcessFeeTest:test_correctDiscountIsAppliedWhenBothTokensAreDiscounted() (gas: 83368)
-FeeManagerProcessFeeTest:test_discountAIsNotAppliedWhenSetForOtherUsers() (gas: 51028)
-FeeManagerProcessFeeTest:test_discountFeeRoundsDownWhenUneven() (gas: 47526)
-FeeManagerProcessFeeTest:test_discountIsAppliedForLink() (gas: 44813)
-FeeManagerProcessFeeTest:test_discountIsAppliedWith100PercentSurcharge() (gas: 70986)
-FeeManagerProcessFeeTest:test_discountIsNoLongerAppliedAfterRemoving() (gas: 40625)
-FeeManagerProcessFeeTest:test_discountIsNotAppliedForInvalidTokenAddress() (gas: 12439)
-FeeManagerProcessFeeTest:test_discountIsNotAppliedToOtherFeeds() (gas: 49052)
-FeeManagerProcessFeeTest:test_emptyQuoteRevertsWithError() (gas: 12305)
-FeeManagerProcessFeeTest:test_eventIsEmittedAfterSurchargeIsSet() (gas: 36250)
-FeeManagerProcessFeeTest:test_eventIsEmittedUponWithdraw() (gas: 60995)
-FeeManagerProcessFeeTest:test_feeIsUpdatedAfterDiscountIsRemoved() (gas: 43112)
-FeeManagerProcessFeeTest:test_feeIsUpdatedAfterNewDiscountIsApplied() (gas: 59576)
-FeeManagerProcessFeeTest:test_feeIsUpdatedAfterNewSurchargeIsApplied() (gas: 55837)
-FeeManagerProcessFeeTest:test_feeIsZeroWith100PercentDiscount() (gas: 47236)
-FeeManagerProcessFeeTest:test_getBaseRewardWithLinkQuote() (gas: 14790)
-FeeManagerProcessFeeTest:test_getLinkFeeIsRoundedUp() (gas: 45004)
-FeeManagerProcessFeeTest:test_getLinkRewardIsRoundedDown() (gas: 44928)
-FeeManagerProcessFeeTest:test_getLinkRewardWithNativeQuoteAndSurchargeWithLinkDiscount() (gas: 74660)
-FeeManagerProcessFeeTest:test_getRewardWithLinkDiscount() (gas: 44856)
-FeeManagerProcessFeeTest:test_getRewardWithLinkQuoteAndLinkDiscount() (gas: 44836)
-FeeManagerProcessFeeTest:test_getRewardWithNativeQuote() (gas: 17266)
-FeeManagerProcessFeeTest:test_getRewardWithNativeQuoteAndSurcharge() (gas: 45334)
-FeeManagerProcessFeeTest:test_linkAvailableForPaymentReturnsLinkBalance() (gas: 47449)
-FeeManagerProcessFeeTest:test_nativeSurcharge0Percent() (gas: 25401)
-FeeManagerProcessFeeTest:test_nativeSurcharge100Percent() (gas: 45370)
-FeeManagerProcessFeeTest:test_nativeSurchargeCannotExceed100Percent() (gas: 12085)
-FeeManagerProcessFeeTest:test_nativeSurchargeEventIsEmittedOnUpdate() (gas: 36252)
-FeeManagerProcessFeeTest:test_noFeeIsAppliedWhenReportHasZeroFee() (gas: 46898)
-FeeManagerProcessFeeTest:test_noFeeIsAppliedWhenReportHasZeroFeeAndDiscountAndSurchargeIsSet() (gas: 70466)
-FeeManagerProcessFeeTest:test_nonAdminProxyUserCannotProcessFee() (gas: 19083)
-FeeManagerProcessFeeTest:test_nonAdminUserCanNotSetDiscount() (gas: 14729)
-FeeManagerProcessFeeTest:test_payLinkDeficit() (gas: 176744)
-FeeManagerProcessFeeTest:test_payLinkDeficitOnlyCallableByAdmin() (gas: 12412)
-FeeManagerProcessFeeTest:test_payLinkDeficitPaysAllFeesProcessed() (gas: 193372)
-FeeManagerProcessFeeTest:test_payLinkDeficitTwice() (gas: 179113)
-FeeManagerProcessFeeTest:test_processFeeAsProxy() (gas: 105905)
-FeeManagerProcessFeeTest:test_processFeeDefaultReportsStillVerifiesWithEmptyQuote() (gas: 18191)
-FeeManagerProcessFeeTest:test_processFeeEmitsEventIfNotEnoughLink() (gas: 144715)
-FeeManagerProcessFeeTest:test_processFeeIfSubscriberIsSelf() (gas: 19196)
-FeeManagerProcessFeeTest:test_processFeeNative() (gas: 156773)
-FeeManagerProcessFeeTest:test_processFeeUsesCorrectDigest() (gas: 106864)
-FeeManagerProcessFeeTest:test_processFeeWithDefaultReportPayloadAndQuoteStillVerifies() (gas: 20530)
-FeeManagerProcessFeeTest:test_processFeeWithInvalidReportVersionFailsToDecode() (gas: 22030)
-FeeManagerProcessFeeTest:test_processFeeWithUnwrappedNative() (gas: 160148)
-FeeManagerProcessFeeTest:test_processFeeWithUnwrappedNativeLinkAddress() (gas: 68000)
-FeeManagerProcessFeeTest:test_processFeeWithUnwrappedNativeShortFunds() (gas: 72531)
-FeeManagerProcessFeeTest:test_processFeeWithUnwrappedNativeWithExcessiveFee() (gas: 167132)
-FeeManagerProcessFeeTest:test_processFeeWithWithCorruptQuotePayload() (gas: 19808)
-FeeManagerProcessFeeTest:test_processFeeWithWithEmptyQuotePayload() (gas: 20285)
-FeeManagerProcessFeeTest:test_processFeeWithWithZeroQuotePayload() (gas: 21225)
-FeeManagerProcessFeeTest:test_reportWithNoExpiryOrFeeReturnsZero() (gas: 10966)
-FeeManagerProcessFeeTest:test_setDiscountOver100Percent() (gas: 14453)
-FeeManagerProcessFeeTest:test_subscriberDiscountEventIsEmittedOnUpdate() (gas: 41096)
-FeeManagerProcessFeeTest:test_surchargeFeeRoundsUpWhenUneven() (gas: 45663)
-FeeManagerProcessFeeTest:test_surchargeIsApplied() (gas: 45631)
-FeeManagerProcessFeeTest:test_surchargeIsAppliedForNativeFeeWithDiscount() (gas: 71344)
-FeeManagerProcessFeeTest:test_surchargeIsNoLongerAppliedAfterRemoving() (gas: 40305)
-FeeManagerProcessFeeTest:test_surchargeIsNotAppliedForLinkFee() (gas: 44851)
-FeeManagerProcessFeeTest:test_surchargeIsNotAppliedWith100PercentDiscount() (gas: 70842)
-FeeManagerProcessFeeTest:test_testRevertIfReportHasExpired() (gas: 15287)
-RewardManagerClaimTest:test_claimAllRecipients() (gas: 261746)
-RewardManagerClaimTest:test_claimMultipleRecipients() (gas: 145152)
-RewardManagerClaimTest:test_claimRewardsWithDuplicatPoolIdsDoesNotPayoutTwice() (gas: 311112)
-RewardManagerClaimTest:test_claimSingleRecipient() (gas: 83152)
-RewardManagerClaimTest:test_claimUnevenAmountRoundsDown() (gas: 296514)
-RewardManagerClaimTest:test_claimUnregisteredPoolId() (gas: 33836)
-RewardManagerClaimTest:test_claimUnregisteredRecipient() (gas: 35153)
-RewardManagerClaimTest:test_eventIsEmittedUponClaim() (gas: 80827)
-RewardManagerClaimTest:test_eventIsNotEmittedUponUnsuccessfulClaim() (gas: 24119)
-RewardManagerClaimTest:test_recipientsClaimMultipleDeposits() (gas: 354497)
-RewardManagerClaimTest:test_singleRecipientClaimMultipleDeposits() (gas: 125594)
-RewardManagerNoRecipientSet:test_claimAllRecipientsAfterRecipientsSet() (gas: 460065)
-RewardManagerPayRecipientsTest:test_addFundsToPoolAsNonOwnerOrFeeManager() (gas: 12746)
-RewardManagerPayRecipientsTest:test_addFundsToPoolAsOwner() (gas: 49476)
-RewardManagerPayRecipientsTest:test_payAllRecipients() (gas: 243950)
-RewardManagerPayRecipientsTest:test_payAllRecipientsFromNonAdminUser() (gas: 15490)
-RewardManagerPayRecipientsTest:test_payAllRecipientsFromRecipientInPool() (gas: 244240)
-RewardManagerPayRecipientsTest:test_payAllRecipientsWithAdditionalInvalidRecipient() (gas: 255332)
-RewardManagerPayRecipientsTest:test_payAllRecipientsWithAdditionalUnregisteredRecipient() (gas: 258494)
-RewardManagerPayRecipientsTest:test_payRecipientWithInvalidPool() (gas: 28014)
-RewardManagerPayRecipientsTest:test_payRecipientsEmptyRecipientList() (gas: 19996)
-RewardManagerPayRecipientsTest:test_payRecipientsWithInvalidPoolId() (gas: 43841)
-RewardManagerPayRecipientsTest:test_paySingleRecipient() (gas: 79278)
-RewardManagerPayRecipientsTest:test_paySubsetOfRecipientsInPool() (gas: 192105)
-RewardManagerRecipientClaimDifferentWeightsTest:test_allRecipientsClaimingReceiveExpectedAmount() (gas: 264807)
-RewardManagerRecipientClaimMultiplePoolsTest:test_claimAllRecipientsMultiplePools() (gas: 484691)
-RewardManagerRecipientClaimMultiplePoolsTest:test_claimAllRecipientsSinglePool() (gas: 267815)
-RewardManagerRecipientClaimMultiplePoolsTest:test_claimEmptyPoolWhenSecondPoolContainsFunds() (gas: 274756)
-RewardManagerRecipientClaimMultiplePoolsTest:test_claimMultipleRecipientsMultiplePools() (gas: 247842)
-RewardManagerRecipientClaimMultiplePoolsTest:test_claimMultipleRecipientsSinglePool() (gas: 145214)
-RewardManagerRecipientClaimMultiplePoolsTest:test_claimSingleRecipientMultiplePools() (gas: 124215)
-RewardManagerRecipientClaimMultiplePoolsTest:test_claimSingleUniqueRecipient() (gas: 97656)
-RewardManagerRecipientClaimMultiplePoolsTest:test_claimUnevenAmountRoundsDown() (gas: 542551)
-RewardManagerRecipientClaimMultiplePoolsTest:test_claimUnregisteredRecipient() (gas: 55393)
-RewardManagerRecipientClaimMultiplePoolsTest:test_getRewardsAvailableToRecipientInBothPools() (gas: 24031)
-RewardManagerRecipientClaimMultiplePoolsTest:test_getRewardsAvailableToRecipientInNoPools() (gas: 18192)
-RewardManagerRecipientClaimMultiplePoolsTest:test_getRewardsAvailableToRecipientInSinglePool() (gas: 21793)
-RewardManagerRecipientClaimMultiplePoolsTest:test_recipientsClaimMultipleDeposits() (gas: 358947)
-RewardManagerRecipientClaimMultiplePoolsTest:test_singleRecipientClaimMultipleDeposits() (gas: 125610)
-RewardManagerRecipientClaimUnevenWeightTest:test_allRecipientsClaimingReceiveExpectedAmount() (gas: 187397)
-RewardManagerRecipientClaimUnevenWeightTest:test_allRecipientsClaimingReceiveExpectedAmountWithSmallDeposit() (gas: 207289)
-RewardManagerSetRecipientsTest:test_eventIsEmittedUponSetRecipients() (gas: 185494)
-RewardManagerSetRecipientsTest:test_setRecipientContainsDuplicateRecipients() (gas: 117290)
-RewardManagerSetRecipientsTest:test_setRewardRecipientFromManagerAddress() (gas: 185271)
-RewardManagerSetRecipientsTest:test_setRewardRecipientFromNonOwnerOrFeeManagerAddress() (gas: 16348)
-RewardManagerSetRecipientsTest:test_setRewardRecipientTwice() (gas: 184667)
-RewardManagerSetRecipientsTest:test_setRewardRecipientWeights() (gas: 174935)
-RewardManagerSetRecipientsTest:test_setRewardRecipientWithZeroAddress() (gas: 84821)
-RewardManagerSetRecipientsTest:test_setRewardRecipientWithZeroWeight() (gas: 177469)
-RewardManagerSetRecipientsTest:test_setRewardRecipients() (gas: 179469)
-RewardManagerSetRecipientsTest:test_setRewardRecipientsIsEmpty() (gas: 82005)
-RewardManagerSetRecipientsTest:test_setSingleRewardRecipient() (gas: 105112)
-RewardManagerSetupTest:test_eventEmittedUponFeeManagerUpdate() (gas: 16365)
-RewardManagerSetupTest:test_eventEmittedUponFeePaid() (gas: 251334)
-RewardManagerSetupTest:test_rejectsZeroLinkAddressOnConstruction() (gas: 59237)
-RewardManagerSetupTest:test_setFeeManagerZeroAddress() (gas: 12015)
-RewardManagerUpdateRewardRecipientsMultiplePoolsTest:test_updatePrimaryRecipientWeights() (gas: 351585)
-RewardManagerUpdateRewardRecipientsTest:test_eventIsEmittedUponUpdateRecipients() (gas: 271069)
-RewardManagerUpdateRewardRecipientsTest:test_onlyAdminCanUpdateRecipients() (gas: 14622)
-RewardManagerUpdateRewardRecipientsTest:test_partialUpdateRecipientWeights() (gas: 202980)
-RewardManagerUpdateRewardRecipientsTest:test_updateAllRecipientsWithSameAddressAndWeight() (gas: 265007)
-RewardManagerUpdateRewardRecipientsTest:test_updatePartialRecipientsToSubset() (gas: 239393)
-RewardManagerUpdateRewardRecipientsTest:test_updatePartialRecipientsWithExcessiveWeight() (gas: 252954)
-RewardManagerUpdateRewardRecipientsTest:test_updatePartialRecipientsWithSameAddressAndWeight() (gas: 143091)
-RewardManagerUpdateRewardRecipientsTest:test_updatePartialRecipientsWithUnderWeightSet() (gas: 253019)
-RewardManagerUpdateRewardRecipientsTest:test_updateRecipientWeights() (gas: 347067)
-RewardManagerUpdateRewardRecipientsTest:test_updateRecipientWithNewZeroAddress() (gas: 251680)
-RewardManagerUpdateRewardRecipientsTest:test_updateRecipientsContainsDuplicateRecipients() (gas: 278976)
-RewardManagerUpdateRewardRecipientsTest:test_updateRecipientsToDifferentLargerSet() (gas: 254184)
-RewardManagerUpdateRewardRecipientsTest:test_updateRecipientsToDifferentPartialSet() (gas: 252404)
-RewardManagerUpdateRewardRecipientsTest:test_updateRecipientsToDifferentSet() (gas: 253625)
-RewardManagerUpdateRewardRecipientsTest:test_updateRecipientsToDifferentSetWithInvalidWeights() (gas: 252514)
-RewardManagerUpdateRewardRecipientsTest:test_updateRecipientsUpdateAndRemoveExistingForLargerSet() (gas: 245636)
-RewardManagerUpdateRewardRecipientsTest:test_updateRecipientsUpdateAndRemoveExistingForSmallerSet() (gas: 243962)
-VerificationdeactivateConfigWhenThereAreMultipleDigestsTest:test_correctlyRemovesAMiddleDigest() (gas: 24221)
-VerificationdeactivateConfigWhenThereAreMultipleDigestsTest:test_correctlyRemovesTheFirstDigest() (gas: 24188)
-VerificationdeactivateConfigWhenThereAreMultipleDigestsTest:test_correctlyUnsetsDigestsInSequence() (gas: 44250)
-VerificationdeactivateConfigWhenThereAreMultipleDigestsTest:test_revertsIfCalledByNonOwner() (gas: 11300)
-VerificationdeactivateConfigWhenThereAreMultipleDigestsTest:test_revertsIfRemovingAnEmptyDigest() (gas: 10929)
-VerificationdeactivateConfigWhenThereAreMultipleDigestsTest:test_revertsIfRemovingAnNonExistentDigest() (gas: 13403)
-VerifierActivateConfigTest:test_revertsIfDigestIsEmpty() (gas: 10939)
-VerifierActivateConfigTest:test_revertsIfDigestNotSet() (gas: 13371)
-VerifierActivateConfigTest:test_revertsIfNotOwner() (gas: 13410)
-VerifierActivateConfigWithDeactivatedConfigTest:test_allowsVerification() (gas: 93459)
+FeeManagerProcessFeeTest:test_DiscountIsAppliedForNative() (gas: 52282)
+FeeManagerProcessFeeTest:test_DiscountIsReturnedForNative() (gas: 52235)
+FeeManagerProcessFeeTest:test_DiscountIsReturnedForNativeWithSurcharge() (gas: 78440)
+FeeManagerProcessFeeTest:test_V1PayloadVerifies() (gas: 26980)
+FeeManagerProcessFeeTest:test_V1PayloadVerifiesAndReturnsChange() (gas: 57895)
+FeeManagerProcessFeeTest:test_V2PayloadVerifies() (gas: 116092)
+FeeManagerProcessFeeTest:test_V2PayloadWithoutQuoteFails() (gas: 27395)
+FeeManagerProcessFeeTest:test_V2PayloadWithoutZeroFee() (gas: 70368)
+FeeManagerProcessFeeTest:test_WithdrawERC20() (gas: 71617)
+FeeManagerProcessFeeTest:test_WithdrawNonAdminAddr() (gas: 56261)
+FeeManagerProcessFeeTest:test_WithdrawUnwrappedNative() (gas: 25322)
+FeeManagerProcessFeeTest:test_baseFeeIsAppliedForLink() (gas: 14345)
+FeeManagerProcessFeeTest:test_baseFeeIsAppliedForNative() (gas: 17279)
+FeeManagerProcessFeeTest:test_correctDiscountIsAppliedWhenBothTokensAreDiscounted() (gas: 90285)
+FeeManagerProcessFeeTest:test_discountAIsNotAppliedWhenSetForOtherUsers() (gas: 56171)
+FeeManagerProcessFeeTest:test_discountFeeRoundsDownWhenUneven() (gas: 52482)
+FeeManagerProcessFeeTest:test_discountIsAppliedForLink() (gas: 49277)
+FeeManagerProcessFeeTest:test_discountIsAppliedWith100PercentSurcharge() (gas: 78530)
+FeeManagerProcessFeeTest:test_discountIsNoLongerAppliedAfterRemoving() (gas: 45936)
+FeeManagerProcessFeeTest:test_discountIsNotAppliedForInvalidTokenAddress() (gas: 17546)
+FeeManagerProcessFeeTest:test_discountIsNotAppliedToOtherFeeds() (gas: 54241)
+FeeManagerProcessFeeTest:test_discountIsReturnedForLink() (gas: 49252)
+FeeManagerProcessFeeTest:test_emptyQuoteRevertsWithError() (gas: 11286)
+FeeManagerProcessFeeTest:test_eventIsEmittedAfterSurchargeIsSet() (gas: 41348)
+FeeManagerProcessFeeTest:test_eventIsEmittedIfNotEnoughLink() (gas: 172711)
+FeeManagerProcessFeeTest:test_eventIsEmittedUponWithdraw() (gas: 68984)
+FeeManagerProcessFeeTest:test_feeIsUpdatedAfterDiscountIsRemoved() (gas: 49176)
+FeeManagerProcessFeeTest:test_feeIsUpdatedAfterNewDiscountIsApplied() (gas: 66973)
+FeeManagerProcessFeeTest:test_feeIsUpdatedAfterNewSurchargeIsApplied() (gas: 63650)
+FeeManagerProcessFeeTest:test_feeIsZeroWith100PercentDiscount() (gas: 51682)
+FeeManagerProcessFeeTest:test_getBaseRewardWithLinkQuote() (gas: 14362)
+FeeManagerProcessFeeTest:test_getLinkFeeIsRoundedUp() (gas: 49468)
+FeeManagerProcessFeeTest:test_getLinkRewardIsSameAsFee() (gas: 54932)
+FeeManagerProcessFeeTest:test_getLinkRewardWithNativeQuoteAndSurchargeWithLinkDiscount() (gas: 82394)
+FeeManagerProcessFeeTest:test_getRewardWithLinkDiscount() (gas: 49295)
+FeeManagerProcessFeeTest:test_getRewardWithLinkQuoteAndLinkDiscount() (gas: 49298)
+FeeManagerProcessFeeTest:test_getRewardWithNativeQuote() (gas: 17299)
+FeeManagerProcessFeeTest:test_getRewardWithNativeQuoteAndSurcharge() (gas: 50481)
+FeeManagerProcessFeeTest:test_linkAvailableForPaymentReturnsLinkBalance() (gas: 52419)
+FeeManagerProcessFeeTest:test_nativeSurcharge0Percent() (gas: 30491)
+FeeManagerProcessFeeTest:test_nativeSurcharge100Percent() (gas: 50504)
+FeeManagerProcessFeeTest:test_nativeSurchargeCannotExceed100Percent() (gas: 17167)
+FeeManagerProcessFeeTest:test_nativeSurchargeEventIsEmittedOnUpdate() (gas: 41394)
+FeeManagerProcessFeeTest:test_noFeeIsAppliedWhenReportHasZeroFee() (gas: 51505)
+FeeManagerProcessFeeTest:test_noFeeIsAppliedWhenReportHasZeroFeeAndDiscountAndSurchargeIsSet() (gas: 77733)
+FeeManagerProcessFeeTest:test_nonAdminProxyUserCannotProcessFee() (gas: 21881)
+FeeManagerProcessFeeTest:test_nonAdminUserCanNotSetDiscount() (gas: 19835)
+FeeManagerProcessFeeTest:test_payLinkDeficit() (gas: 193856)
+FeeManagerProcessFeeTest:test_payLinkDeficitOnlyCallableByAdmin() (gas: 17405)
+FeeManagerProcessFeeTest:test_payLinkDeficitPaysAllFeesProcessed() (gas: 213891)
+FeeManagerProcessFeeTest:test_payLinkDeficitTwice() (gas: 198224)
+FeeManagerProcessFeeTest:test_processFeeAsProxy() (gas: 116430)
+FeeManagerProcessFeeTest:test_processFeeDefaultReportsStillVerifiesWithEmptyQuote() (gas: 27468)
+FeeManagerProcessFeeTest:test_processFeeEmitsEventIfNotEnoughLink() (gas: 161837)
+FeeManagerProcessFeeTest:test_processFeeIfSubscriberIsSelf() (gas: 27822)
+FeeManagerProcessFeeTest:test_processFeeNative() (gas: 172458)
+FeeManagerProcessFeeTest:test_processFeeUsesCorrectDigest() (gas: 117390)
+FeeManagerProcessFeeTest:test_processFeeWithDefaultReportPayloadAndQuoteStillVerifies() (gas: 29542)
+FeeManagerProcessFeeTest:test_processFeeWithDiscountEmitsEvent() (gas: 241269)
+FeeManagerProcessFeeTest:test_processFeeWithInvalidReportVersionFailsToDecode() (gas: 28517)
+FeeManagerProcessFeeTest:test_processFeeWithNoDiscountDoesNotEmitEvent() (gas: 166400)
+FeeManagerProcessFeeTest:test_processFeeWithUnwrappedNative() (gas: 179992)
+FeeManagerProcessFeeTest:test_processFeeWithUnwrappedNativeLinkAddress() (gas: 131459)
+FeeManagerProcessFeeTest:test_processFeeWithUnwrappedNativeLinkAddressExcessiveFee() (gas: 155388)
+FeeManagerProcessFeeTest:test_processFeeWithUnwrappedNativeShortFunds() (gas: 92624)
+FeeManagerProcessFeeTest:test_processFeeWithUnwrappedNativeWithExcessiveFee() (gas: 186953)
+FeeManagerProcessFeeTest:test_processFeeWithWithCorruptQuotePayload() (gas: 70679)
+FeeManagerProcessFeeTest:test_processFeeWithWithEmptyQuotePayload() (gas: 27733)
+FeeManagerProcessFeeTest:test_processFeeWithWithZeroQuotePayload() (gas: 27783)
+FeeManagerProcessFeeTest:test_processFeeWithZeroLinkNonZeroNativeWithLinkQuote() (gas: 32971)
+FeeManagerProcessFeeTest:test_processFeeWithZeroLinkNonZeroNativeWithNativeQuote() (gas: 152357)
+FeeManagerProcessFeeTest:test_processFeeWithZeroNativeNonZeroLinkReturnsChange() (gas: 53468)
+FeeManagerProcessFeeTest:test_processFeeWithZeroNativeNonZeroLinkWithLinkQuote() (gas: 116341)
+FeeManagerProcessFeeTest:test_processFeeWithZeroNativeNonZeroLinkWithNativeQuote() (gas: 35738)
+FeeManagerProcessFeeTest:test_processMultipleLinkReports() (gas: 221457)
+FeeManagerProcessFeeTest:test_processMultipleUnwrappedNativeReports() (gas: 255272)
+FeeManagerProcessFeeTest:test_processMultipleV1Reports() (gas: 74135)
+FeeManagerProcessFeeTest:test_processMultipleWrappedNativeReports() (gas: 238399)
+FeeManagerProcessFeeTest:test_processV1V2V3Reports() (gas: 206219)
+FeeManagerProcessFeeTest:test_processV1V2V3ReportsWithUnwrapped() (gas: 247873)
+FeeManagerProcessFeeTest:test_reportWithNoExpiryOrFeeReturnsZero() (gas: 10770)
+FeeManagerProcessFeeTest:test_setDiscountOver100Percent() (gas: 19548)
+FeeManagerProcessFeeTest:test_subscriberDiscountEventIsEmittedOnUpdate() (gas: 46259)
+FeeManagerProcessFeeTest:test_surchargeFeeRoundsUpWhenUneven() (gas: 50856)
+FeeManagerProcessFeeTest:test_surchargeIsApplied() (gas: 50737)
+FeeManagerProcessFeeTest:test_surchargeIsAppliedForNativeFeeWithDiscount() (gas: 78892)
+FeeManagerProcessFeeTest:test_surchargeIsNoLongerAppliedAfterRemoving() (gas: 46503)
+FeeManagerProcessFeeTest:test_surchargeIsNotAppliedForLinkFee() (gas: 49585)
+FeeManagerProcessFeeTest:test_surchargeIsNotAppliedWith100PercentDiscount() (gas: 77890)
+FeeManagerProcessFeeTest:test_testRevertIfReportHasExpired() (gas: 14042)
+RewardManagerClaimTest:test_claimAllRecipients() (gas: 275763)
+RewardManagerClaimTest:test_claimMultipleRecipients() (gas: 153306)
+RewardManagerClaimTest:test_claimRewardsWithDuplicatePoolIdsDoesNotPayoutTwice() (gas: 328345)
+RewardManagerClaimTest:test_claimSingleRecipient() (gas: 88340)
+RewardManagerClaimTest:test_claimUnevenAmountRoundsDown() (gas: 313549)
+RewardManagerClaimTest:test_claimUnregisteredPoolId() (gas: 34461)
+RewardManagerClaimTest:test_claimUnregisteredRecipient() (gas: 40491)
+RewardManagerClaimTest:test_eventIsEmittedUponClaim() (gas: 86069)
+RewardManagerClaimTest:test_eventIsNotEmittedUponUnsuccessfulClaim() (gas: 24700)
+RewardManagerClaimTest:test_recipientsClaimMultipleDeposits() (gas: 383214)
+RewardManagerClaimTest:test_singleRecipientClaimMultipleDeposits() (gas: 136289)
+RewardManagerNoRecipientSet:test_claimAllRecipientsAfterRecipientsSet() (gas: 489377)
+RewardManagerPayRecipientsTest:test_addFundsToPoolAsNonOwnerOrFeeManager() (gas: 11428)
+RewardManagerPayRecipientsTest:test_addFundsToPoolAsOwner() (gas: 53876)
+RewardManagerPayRecipientsTest:test_payAllRecipients() (gas: 249472)
+RewardManagerPayRecipientsTest:test_payAllRecipientsFromNonAdminUser() (gas: 20475)
+RewardManagerPayRecipientsTest:test_payAllRecipientsFromRecipientInPool() (gas: 249718)
+RewardManagerPayRecipientsTest:test_payAllRecipientsWithAdditionalInvalidRecipient() (gas: 260922)
+RewardManagerPayRecipientsTest:test_payAllRecipientsWithAdditionalUnregisteredRecipient() (gas: 264058)
+RewardManagerPayRecipientsTest:test_payRecipientWithInvalidPool() (gas: 28549)
+RewardManagerPayRecipientsTest:test_payRecipientsEmptyRecipientList() (gas: 24970)
+RewardManagerPayRecipientsTest:test_payRecipientsWithInvalidPoolId() (gas: 31055)
+RewardManagerPayRecipientsTest:test_paySingleRecipient() (gas: 84354)
+RewardManagerPayRecipientsTest:test_paySubsetOfRecipientsInPool() (gas: 197449)
+RewardManagerRecipientClaimDifferentWeightsTest:test_allRecipientsClaimingReceiveExpectedAmount() (gas: 279714)
+RewardManagerRecipientClaimMultiplePoolsTest:test_claimAllRecipientsMultiplePools() (gas: 509889)
+RewardManagerRecipientClaimMultiplePoolsTest:test_claimAllRecipientsSinglePool() (gas: 281811)
+RewardManagerRecipientClaimMultiplePoolsTest:test_claimEmptyPoolWhenSecondPoolContainsFunds() (gas: 291640)
+RewardManagerRecipientClaimMultiplePoolsTest:test_claimMultipleRecipientsMultiplePools() (gas: 261589)
+RewardManagerRecipientClaimMultiplePoolsTest:test_claimMultipleRecipientsSinglePool() (gas: 153434)
+RewardManagerRecipientClaimMultiplePoolsTest:test_claimSingleRecipientMultiplePools() (gas: 131911)
+RewardManagerRecipientClaimMultiplePoolsTest:test_claimSingleUniqueRecipient() (gas: 105312)
+RewardManagerRecipientClaimMultiplePoolsTest:test_claimUnevenAmountRoundsDown() (gas: 576289)
+RewardManagerRecipientClaimMultiplePoolsTest:test_claimUnregisteredRecipient() (gas: 63555)
+RewardManagerRecipientClaimMultiplePoolsTest:test_getAvailableRewardsCursorAndTotalPoolsEqual() (gas: 10202)
+RewardManagerRecipientClaimMultiplePoolsTest:test_getAvailableRewardsCursorCannotBeGreaterThanTotalPools() (gas: 11107)
+RewardManagerRecipientClaimMultiplePoolsTest:test_getAvailableRewardsCursorSingleResult() (gas: 19606)
+RewardManagerRecipientClaimMultiplePoolsTest:test_getRewardsAvailableToRecipientInBothPools() (gas: 29052)
+RewardManagerRecipientClaimMultiplePoolsTest:test_getRewardsAvailableToRecipientInBothPoolsWhereAlreadyClaimed() (gas: 147218)
+RewardManagerRecipientClaimMultiplePoolsTest:test_getRewardsAvailableToRecipientInNoPools() (gas: 18532)
+RewardManagerRecipientClaimMultiplePoolsTest:test_getRewardsAvailableToRecipientInSinglePool() (gas: 24569)
+RewardManagerRecipientClaimMultiplePoolsTest:test_recipientsClaimMultipleDeposits() (gas: 387664)
+RewardManagerRecipientClaimMultiplePoolsTest:test_singleRecipientClaimMultipleDeposits() (gas: 136328)
+RewardManagerRecipientClaimUnevenWeightTest:test_allRecipientsClaimingReceiveExpectedAmount() (gas: 198450)
+RewardManagerRecipientClaimUnevenWeightTest:test_allRecipientsClaimingReceiveExpectedAmountWithSmallDeposit() (gas: 218320)
+RewardManagerSetRecipientsTest:test_eventIsEmittedUponSetRecipients() (gas: 191729)
+RewardManagerSetRecipientsTest:test_setRecipientContainsDuplicateRecipients() (gas: 126058)
+RewardManagerSetRecipientsTest:test_setRewardRecipientFromManagerAddress() (gas: 193880)
+RewardManagerSetRecipientsTest:test_setRewardRecipientFromNonOwnerOrFeeManagerAddress() (gas: 21452)
+RewardManagerSetRecipientsTest:test_setRewardRecipientTwice() (gas: 193324)
+RewardManagerSetRecipientsTest:test_setRewardRecipientWeights() (gas: 180630)
+RewardManagerSetRecipientsTest:test_setRewardRecipientWithZeroAddress() (gas: 90224)
+RewardManagerSetRecipientsTest:test_setRewardRecipients() (gas: 185567)
+RewardManagerSetRecipientsTest:test_setRewardRecipientsIsEmpty() (gas: 87113)
+RewardManagerSetRecipientsTest:test_setSingleRewardRecipient() (gas: 110414)
+RewardManagerSetupTest:test_eventEmittedUponFeeManagerUpdate() (gas: 21388)
+RewardManagerSetupTest:test_eventEmittedUponFeePaid() (gas: 259121)
+RewardManagerSetupTest:test_rejectsZeroLinkAddressOnConstruction() (gas: 59411)
+RewardManagerSetupTest:test_setFeeManagerZeroAddress() (gas: 17038)
+RewardManagerUpdateRewardRecipientsMultiplePoolsTest:test_updatePrimaryRecipientWeights() (gas: 373535)
+RewardManagerUpdateRewardRecipientsTest:test_eventIsEmittedUponUpdateRecipients() (gas: 279096)
+RewardManagerUpdateRewardRecipientsTest:test_onlyAdminCanUpdateRecipients() (gas: 19704)
+RewardManagerUpdateRewardRecipientsTest:test_partialUpdateRecipientWeights() (gas: 218880)
+RewardManagerUpdateRewardRecipientsTest:test_updateAllRecipientsWithSameAddressAndWeight() (gas: 272941)
+RewardManagerUpdateRewardRecipientsTest:test_updatePartialRecipientsWithExcessiveWeight() (gas: 259196)
+RewardManagerUpdateRewardRecipientsTest:test_updatePartialRecipientsWithSameAddressAndWeight() (gas: 148912)
+RewardManagerUpdateRewardRecipientsTest:test_updatePartialRecipientsWithUnderWeightSet() (gas: 259270)
+RewardManagerUpdateRewardRecipientsTest:test_updateRecipientWeights() (gas: 368972)
+RewardManagerUpdateRewardRecipientsTest:test_updateRecipientWithNewZeroAddress() (gas: 270802)
+RewardManagerUpdateRewardRecipientsTest:test_updateRecipientsContainsDuplicateRecipients() (gas: 288572)
+VerificationdeactivateConfigWhenThereAreMultipleDigestsTest:test_correctlyRemovesAMiddleDigest() (gas: 24177)
+VerificationdeactivateConfigWhenThereAreMultipleDigestsTest:test_correctlyRemovesTheFirstDigest() (gas: 24144)
+VerificationdeactivateConfigWhenThereAreMultipleDigestsTest:test_correctlyUnsetsDigestsInSequence() (gas: 44109)
+VerificationdeactivateConfigWhenThereAreMultipleDigestsTest:test_revertsIfCalledByNonOwner() (gas: 15016)
+VerificationdeactivateConfigWhenThereAreMultipleDigestsTest:test_revertsIfRemovingAnEmptyDigest() (gas: 10907)
+VerificationdeactivateConfigWhenThereAreMultipleDigestsTest:test_revertsIfRemovingAnNonExistentDigest() (gas: 13381)
+VerifierActivateConfigTest:test_revertsIfDigestIsEmpty() (gas: 10984)
+VerifierActivateConfigTest:test_revertsIfDigestNotSet() (gas: 13394)
+VerifierActivateConfigTest:test_revertsIfNotOwner() (gas: 17171)
+VerifierActivateConfigWithDeactivatedConfigTest:test_allowsVerification() (gas: 97164)
VerifierActivateFeedTest:test_revertsIfNoFeedExistsActivate() (gas: 13179)
-VerifierActivateFeedTest:test_revertsIfNoFeedExistsDeactivate() (gas: 13179)
-VerifierActivateFeedTest:test_revertsIfNotOwnerActivateFeed() (gas: 13360)
-VerifierActivateFeedTest:test_revertsIfNotOwnerDeactivateFeed() (gas: 13437)
-VerifierConstructorTest:test_revertsIfInitializedWithEmptyVerifierProxy() (gas: 59939)
-VerifierConstructorTest:test_setsTheCorrectProperties() (gas: 1785046)
-VerifierDeactivateFeedWithVerifyTest:test_currentReportAllowsVerification() (gas: 188309)
-VerifierDeactivateFeedWithVerifyTest:test_currentReportFailsVerification() (gas: 109640)
-VerifierDeactivateFeedWithVerifyTest:test_previousReportAllowsVerification() (gas: 95886)
-VerifierDeactivateFeedWithVerifyTest:test_previousReportFailsVerification() (gas: 66198)
-VerifierProxyAccessControlledVerificationTest:test_proxiesToTheVerifierIfHasAccess() (gas: 203049)
-VerifierProxyAccessControlledVerificationTest:test_revertsIfNoAccess() (gas: 105809)
-VerifierProxyConstructorTest:test_correctlySetsTheCorrectAccessControllerInterface() (gas: 1073832)
-VerifierProxyConstructorTest:test_correctlySetsTheOwner() (gas: 1053935)
-VerifierProxyConstructorTest:test_correctlySetsVersion() (gas: 6939)
-VerifierProxyInitializeVerifierTest:test_revertsIfDigestAlreadySet() (gas: 50301)
-VerifierProxyInitializeVerifierTest:test_revertsIfNotCorrectVerifier() (gas: 13573)
-VerifierProxyInitializeVerifierTest:test_revertsIfNotOwner() (gas: 13375)
-VerifierProxyInitializeVerifierTest:test_revertsIfVerifierAlreadyInitialized() (gas: 41915)
-VerifierProxyInitializeVerifierTest:test_revertsIfZeroAddress() (gas: 10904)
-VerifierProxyInitializeVerifierTest:test_setFeeManagerZeroAddress() (gas: 10913)
-VerifierProxyInitializeVerifierTest:test_updatesVerifierIfVerifier() (gas: 49628)
-VerifierProxySetAccessControllerTest:test_emitsTheCorrectEvent() (gas: 35384)
-VerifierProxySetAccessControllerTest:test_revertsIfCalledByNonOwner() (gas: 11367)
-VerifierProxySetAccessControllerTest:test_successfullySetsNewAccessController() (gas: 32075)
-VerifierProxySetAccessControllerTest:test_successfullySetsNewAccessControllerIsEmpty() (gas: 12174)
-VerifierProxyUnsetVerifierTest:test_revertsIfDigestDoesNotExist() (gas: 13174)
-VerifierProxyUnsetVerifierTest:test_revertsIfNotAdmin() (gas: 11249)
-VerifierProxyUnsetVerifierWithPreviouslySetVerifierTest:test_correctlyUnsetsVerifier() (gas: 12719)
+VerifierActivateFeedTest:test_revertsIfNoFeedExistsDeactivate() (gas: 13157)
+VerifierActivateFeedTest:test_revertsIfNotOwnerActivateFeed() (gas: 17098)
+VerifierActivateFeedTest:test_revertsIfNotOwnerDeactivateFeed() (gas: 17153)
+VerifierBulkVerifyBillingReport:test_verifyMultiVersions() (gas: 475575)
+VerifierBulkVerifyBillingReport:test_verifyMultiVersionsReturnsVerifiedReports() (gas: 681851)
+VerifierBulkVerifyBillingReport:test_verifyWithBulkLink() (gas: 556847)
+VerifierBulkVerifyBillingReport:test_verifyWithBulkNative() (gas: 560426)
+VerifierBulkVerifyBillingReport:test_verifyWithBulkNativeUnwrapped() (gas: 567917)
+VerifierBulkVerifyBillingReport:test_verifyWithBulkNativeUnwrappedReturnsChange() (gas: 574921)
+VerifierConstructorTest:test_revertsIfInitializedWithEmptyVerifierProxy() (gas: 59967)
+VerifierConstructorTest:test_setsTheCorrectProperties() (gas: 1815769)
+VerifierDeactivateFeedWithVerifyTest:test_currentReportAllowsVerification() (gas: 192062)
+VerifierDeactivateFeedWithVerifyTest:test_currentReportFailsVerification() (gas: 111727)
+VerifierDeactivateFeedWithVerifyTest:test_previousReportAllowsVerification() (gas: 99613)
+VerifierDeactivateFeedWithVerifyTest:test_previousReportFailsVerification() (gas: 68305)
+VerifierProxyAccessControlledVerificationTest:test_proxiesToTheVerifierIfHasAccess() (gas: 205796)
+VerifierProxyAccessControlledVerificationTest:test_revertsIfNoAccess() (gas: 110688)
+VerifierProxyConstructorTest:test_correctlySetsTheCorrectAccessControllerInterface() (gas: 1482522)
+VerifierProxyConstructorTest:test_correctlySetsTheOwner() (gas: 1462646)
+VerifierProxyConstructorTest:test_correctlySetsVersion() (gas: 6873)
+VerifierProxyInitializeVerifierTest:test_revertsIfDigestAlreadySet() (gas: 54108)
+VerifierProxyInitializeVerifierTest:test_revertsIfNotCorrectVerifier() (gas: 13595)
+VerifierProxyInitializeVerifierTest:test_revertsIfNotOwner() (gas: 17157)
+VerifierProxyInitializeVerifierTest:test_revertsIfVerifierAlreadyInitialized() (gas: 42025)
+VerifierProxyInitializeVerifierTest:test_revertsIfZeroAddress() (gas: 10948)
+VerifierProxyInitializeVerifierTest:test_setFeeManagerWhichDoesntHonourIERC165Interface() (gas: 13815)
+VerifierProxyInitializeVerifierTest:test_setFeeManagerWhichDoesntHonourInterface() (gas: 16301)
+VerifierProxyInitializeVerifierTest:test_setFeeManagerZeroAddress() (gas: 10947)
+VerifierProxyInitializeVerifierTest:test_updatesVerifierIfVerifier() (gas: 53406)
+VerifierProxySetAccessControllerTest:test_emitsTheCorrectEvent() (gas: 35340)
+VerifierProxySetAccessControllerTest:test_revertsIfCalledByNonOwner() (gas: 15061)
+VerifierProxySetAccessControllerTest:test_successfullySetsNewAccessController() (gas: 32032)
+VerifierProxySetAccessControllerTest:test_successfullySetsNewAccessControllerIsEmpty() (gas: 12131)
+VerifierProxyUnsetVerifierTest:test_revertsIfDigestDoesNotExist() (gas: 13141)
+VerifierProxyUnsetVerifierTest:test_revertsIfNotAdmin() (gas: 14965)
+VerifierProxyUnsetVerifierWithPreviouslySetVerifierTest:test_correctlyUnsetsVerifier() (gas: 12720)
VerifierProxyUnsetVerifierWithPreviouslySetVerifierTest:test_emitsAnEventAfterUnsettingVerifier() (gas: 17965)
-VerifierProxyVerifyTest:test_proxiesToTheCorrectVerifier() (gas: 200395)
-VerifierProxyVerifyTest:test_revertsIfNoVerifierConfigured() (gas: 108443)
-VerifierSetConfigFromSourceMultipleDigestsTest:test_correctlySetsConfigWhenDigestsAreRemoved() (gas: 538606)
-VerifierSetConfigFromSourceMultipleDigestsTest:test_correctlyUpdatesDigestsOnMultipleVerifiersInTheProxy() (gas: 964141)
-VerifierSetConfigFromSourceMultipleDigestsTest:test_correctlyUpdatesTheDigestInTheProxy() (gas: 520142)
-VerifierSetConfigFromSourceTest:test_revertsIfCalledByNonOwner() (gas: 179332)
-VerifierSetConfigTest:test_correctlyUpdatesTheConfig() (gas: 1057626)
-VerifierSetConfigTest:test_revertsIfCalledByNonOwner() (gas: 179223)
-VerifierSetConfigTest:test_revertsIfDuplicateSigners() (gas: 251573)
-VerifierSetConfigTest:test_revertsIfFaultToleranceIsZero() (gas: 176522)
-VerifierSetConfigTest:test_revertsIfNotEnoughSigners() (gas: 15814)
-VerifierSetConfigTest:test_revertsIfSetWithTooManySigners() (gas: 22170)
-VerifierSetConfigTest:test_revertsIfSignerContainsZeroAddress() (gas: 228003)
-VerifierSetConfigWhenThereAreMultipleDigestsTest:test_correctlySetsConfigWhenDigestsAreRemoved() (gas: 538415)
-VerifierSetConfigWhenThereAreMultipleDigestsTest:test_correctlyUpdatesDigestsOnMultipleVerifiersInTheProxy() (gas: 963754)
-VerifierSetConfigWhenThereAreMultipleDigestsTest:test_correctlyUpdatesTheDigestInTheProxy() (gas: 519945)
+VerifierProxyVerifyTest:test_proxiesToTheCorrectVerifier() (gas: 201609)
+VerifierProxyVerifyTest:test_revertsIfNoVerifierConfigured() (gas: 115615)
+VerifierSetConfigFromSourceMultipleDigestsTest:test_correctlySetsConfigWhenDigestsAreRemoved() (gas: 538896)
+VerifierSetConfigFromSourceMultipleDigestsTest:test_correctlyUpdatesDigestsOnMultipleVerifiersInTheProxy() (gas: 964726)
+VerifierSetConfigFromSourceMultipleDigestsTest:test_correctlyUpdatesTheDigestInTheProxy() (gas: 520480)
+VerifierSetConfigFromSourceTest:test_revertsIfCalledByNonOwner() (gas: 183215)
+VerifierSetConfigTest:test_correctlyUpdatesTheConfig() (gas: 1057923)
+VerifierSetConfigTest:test_revertsIfCalledByNonOwner() (gas: 182984)
+VerifierSetConfigTest:test_revertsIfDuplicateSigners() (gas: 251559)
+VerifierSetConfigTest:test_revertsIfFaultToleranceIsZero() (gas: 176543)
+VerifierSetConfigTest:test_revertsIfNotEnoughSigners() (gas: 15835)
+VerifierSetConfigTest:test_revertsIfSetWithTooManySigners() (gas: 22213)
+VerifierSetConfigTest:test_revertsIfSignerContainsZeroAddress() (gas: 228032)
+VerifierSetConfigWhenThereAreMultipleDigestsTest:test_correctlySetsConfigWhenDigestsAreRemoved() (gas: 538645)
+VerifierSetConfigWhenThereAreMultipleDigestsTest:test_correctlyUpdatesDigestsOnMultipleVerifiersInTheProxy() (gas: 964215)
+VerifierSetConfigWhenThereAreMultipleDigestsTest:test_correctlyUpdatesTheDigestInTheProxy() (gas: 520220)
VerifierSupportsInterfaceTest:test_falseIfIsNotCorrectInterface() (gas: 5590)
-VerifierSupportsInterfaceTest:test_trueIfIsCorrectInterface() (gas: 5611)
-VerifierTestBillingReport:test_verifyWithLink() (gas: 274848)
-VerifierTestBillingReport:test_verifyWithNative() (gas: 275476)
-VerifierTestBillingReport:test_verifyWithNativeUnwrapped() (gas: 285450)
-VerifierTestBillingReport:test_verifyWithNativeUnwrappedReturnsChange() (gas: 292517)
-VerifierVerifyMultipleConfigDigestTest:test_canVerifyNewerReportsWithNewerConfigs() (gas: 127500)
-VerifierVerifyMultipleConfigDigestTest:test_canVerifyOlderReportsWithOlderConfigs() (gas: 183379)
-VerifierVerifyMultipleConfigDigestTest:test_revertsIfAReportIsVerifiedWithAnExistingButIncorrectDigest() (gas: 84470)
-VerifierVerifyMultipleConfigDigestTest:test_revertsIfVerifyingWithAnUnsetDigest() (gas: 124347)
-VerifierVerifySingleConfigDigestTest:test_emitsAnEventIfReportVerified() (gas: 183237)
-VerifierVerifySingleConfigDigestTest:test_returnsThePriceAndBlockNumIfReportVerified() (gas: 183406)
-VerifierVerifySingleConfigDigestTest:test_revertsIfConfigDigestNotSet() (gas: 112459)
-VerifierVerifySingleConfigDigestTest:test_revertsIfDuplicateSignersHaveSigned() (gas: 178601)
-VerifierVerifySingleConfigDigestTest:test_revertsIfMismatchedSignatureLength() (gas: 49278)
-VerifierVerifySingleConfigDigestTest:test_revertsIfReportHasUnconfiguredFeedID() (gas: 100262)
-VerifierVerifySingleConfigDigestTest:test_revertsIfVerifiedByNonProxy() (gas: 101024)
-VerifierVerifySingleConfigDigestTest:test_revertsIfVerifiedWithIncorrectAddresses() (gas: 180352)
-VerifierVerifySingleConfigDigestTest:test_revertsIfWrongNumberOfSigners() (gas: 106317)
-VerifierVerifySingleConfigDigestTest:test_setsTheCorrectEpoch() (gas: 190539)
-Verifier_accessControlledVerify:testVerifyWithAccessControl_gas() (gas: 207063)
-Verifier_setConfig:testSetConfigSuccess_gas() (gas: 922408)
-Verifier_verify:testVerifyProxySuccess_gas() (gas: 197508)
-Verifier_verify:testVerifySuccess_gas() (gas: 182991)
-Verifier_verifyWithFee:testVerifyProxyWithLinkFeeSuccess_gas() (gas: 246271)
-Verifier_verifyWithFee:testVerifyProxyWithNativeFeeSuccess_gas() (gas: 263976)
\ No newline at end of file
+VerifierSupportsInterfaceTest:test_trueIfIsCorrectInterface() (gas: 5633)
+VerifierTestBillingReport:test_verifyWithLink() (gas: 274946)
+VerifierTestBillingReport:test_verifyWithNative() (gas: 315644)
+VerifierTestBillingReport:test_verifyWithNativeUnwrapped() (gas: 317892)
+VerifierTestBillingReport:test_verifyWithNativeUnwrappedReturnsChange() (gas: 324958)
+VerifierVerifyMultipleConfigDigestTest:test_canVerifyNewerReportsWithNewerConfigs() (gas: 131228)
+VerifierVerifyMultipleConfigDigestTest:test_canVerifyOlderReportsWithOlderConfigs() (gas: 187132)
+VerifierVerifyMultipleConfigDigestTest:test_revertsIfAReportIsVerifiedWithAnExistingButIncorrectDigest() (gas: 86566)
+VerifierVerifyMultipleConfigDigestTest:test_revertsIfVerifyingWithAnUnsetDigest() (gas: 126411)
+VerifierVerifySingleConfigDigestTest:test_emitsAnEventIfReportVerified() (gas: 186945)
+VerifierVerifySingleConfigDigestTest:test_returnsThePriceAndBlockNumIfReportVerified() (gas: 187114)
+VerifierVerifySingleConfigDigestTest:test_revertsIfConfigDigestNotSet() (gas: 114479)
+VerifierVerifySingleConfigDigestTest:test_revertsIfDuplicateSignersHaveSigned() (gas: 180665)
+VerifierVerifySingleConfigDigestTest:test_revertsIfMismatchedSignatureLength() (gas: 51479)
+VerifierVerifySingleConfigDigestTest:test_revertsIfReportHasUnconfiguredFeedID() (gas: 102318)
+VerifierVerifySingleConfigDigestTest:test_revertsIfVerifiedByNonProxy() (gas: 99348)
+VerifierVerifySingleConfigDigestTest:test_revertsIfVerifiedWithIncorrectAddresses() (gas: 182416)
+VerifierVerifySingleConfigDigestTest:test_revertsIfWrongNumberOfSigners() (gas: 108382)
+VerifierVerifySingleConfigDigestTest:test_setsTheCorrectEpoch() (gas: 194270)
+Verifier_accessControlledVerify:testVerifyWithAccessControl_gas() (gas: 212066)
+Verifier_bulkVerifyWithFee:testBulkVerifyProxyWithLinkFeeSuccess_gas() (gas: 519368)
+Verifier_bulkVerifyWithFee:testBulkVerifyProxyWithNativeFeeSuccess_gas() (gas: 542767)
+Verifier_setConfig:testSetConfigSuccess_gas() (gas: 922682)
+Verifier_verify:testVerifyProxySuccess_gas() (gas: 198731)
+Verifier_verify:testVerifySuccess_gas() (gas: 186725)
+Verifier_verifyWithFee:testVerifyProxyWithLinkFeeSuccess_gas() (gas: 238886)
+Verifier_verifyWithFee:testVerifyProxyWithNativeFeeSuccess_gas() (gas: 257382)
\ No newline at end of file
diff --git a/contracts/gas-snapshots/shared.gas-snapshot b/contracts/gas-snapshots/shared.gas-snapshot
index cb2e8defe4a..cf003c5a26d 100644
--- a/contracts/gas-snapshots/shared.gas-snapshot
+++ b/contracts/gas-snapshots/shared.gas-snapshot
@@ -1,32 +1,32 @@
-BurnMintERC677_approve:testApproveSuccess() (gas: 52254)
-BurnMintERC677_approve:testInvalidAddressReverts() (gas: 10641)
-BurnMintERC677_burn:testBasicBurnSuccess() (gas: 164344)
-BurnMintERC677_burn:testBurnFromZeroAddressReverts() (gas: 43462)
-BurnMintERC677_burn:testExceedsBalanceReverts() (gas: 18035)
+BurnMintERC677_approve:testApproveSuccess() (gas: 55248)
+BurnMintERC677_approve:testInvalidAddressReverts() (gas: 10663)
+BurnMintERC677_burn:testBasicBurnSuccess() (gas: 164342)
+BurnMintERC677_burn:testBurnFromZeroAddressReverts() (gas: 47201)
+BurnMintERC677_burn:testExceedsBalanceReverts() (gas: 21841)
BurnMintERC677_burn:testSenderNotBurnerReverts() (gas: 13359)
-BurnMintERC677_burnFrom:testBurnFromSuccess() (gas: 54662)
-BurnMintERC677_burnFrom:testExceedsBalanceReverts() (gas: 32873)
-BurnMintERC677_burnFrom:testInsufficientAllowanceReverts() (gas: 18107)
+BurnMintERC677_burnFrom:testBurnFromSuccess() (gas: 57658)
+BurnMintERC677_burnFrom:testExceedsBalanceReverts() (gas: 35864)
+BurnMintERC677_burnFrom:testInsufficientAllowanceReverts() (gas: 21849)
BurnMintERC677_burnFrom:testSenderNotBurnerReverts() (gas: 13359)
-BurnMintERC677_burnFromAlias:testBurnFromSuccess() (gas: 54688)
-BurnMintERC677_burnFromAlias:testExceedsBalanceReverts() (gas: 32889)
-BurnMintERC677_burnFromAlias:testInsufficientAllowanceReverts() (gas: 18127)
+BurnMintERC677_burnFromAlias:testBurnFromSuccess() (gas: 57684)
+BurnMintERC677_burnFromAlias:testExceedsBalanceReverts() (gas: 35880)
+BurnMintERC677_burnFromAlias:testInsufficientAllowanceReverts() (gas: 21869)
BurnMintERC677_burnFromAlias:testSenderNotBurnerReverts() (gas: 13379)
BurnMintERC677_constructor:testConstructorSuccess() (gas: 1669109)
-BurnMintERC677_decreaseApproval:testDecreaseApprovalSuccess() (gas: 28520)
-BurnMintERC677_grantMintAndBurnRoles:testGrantMintAndBurnRolesSuccess() (gas: 120049)
-BurnMintERC677_grantRole:testGrantBurnAccessSuccess() (gas: 52707)
+BurnMintERC677_decreaseApproval:testDecreaseApprovalSuccess() (gas: 28537)
+BurnMintERC677_grantMintAndBurnRoles:testGrantMintAndBurnRolesSuccess() (gas: 120071)
+BurnMintERC677_grantRole:testGrantBurnAccessSuccess() (gas: 52724)
BurnMintERC677_grantRole:testGrantManySuccess() (gas: 935521)
-BurnMintERC677_grantRole:testGrantMintAccessSuccess() (gas: 93588)
+BurnMintERC677_grantRole:testGrantMintAccessSuccess() (gas: 93605)
BurnMintERC677_increaseApproval:testIncreaseApprovalSuccess() (gas: 40911)
BurnMintERC677_mint:testBasicMintSuccess() (gas: 149365)
-BurnMintERC677_mint:testMaxSupplyExceededReverts() (gas: 46627)
+BurnMintERC677_mint:testMaxSupplyExceededReverts() (gas: 50385)
BurnMintERC677_mint:testSenderNotMinterReverts() (gas: 11195)
BurnMintERC677_supportsInterface:testConstructorSuccess() (gas: 8685)
-BurnMintERC677_transfer:testInvalidAddressReverts() (gas: 10617)
+BurnMintERC677_transfer:testInvalidAddressReverts() (gas: 10639)
BurnMintERC677_transfer:testTransferSuccess() (gas: 39462)
OpStackBurnMintERC677_constructor:testConstructorSuccess() (gas: 1739317)
-OpStackBurnMintERC677_interfaceCompatibility:testBurnCompatibility() (gas: 259440)
-OpStackBurnMintERC677_interfaceCompatibility:testMintCompatibility() (gas: 137935)
+OpStackBurnMintERC677_interfaceCompatibility:testBurnCompatibility() (gas: 263373)
+OpStackBurnMintERC677_interfaceCompatibility:testMintCompatibility() (gas: 137957)
OpStackBurnMintERC677_interfaceCompatibility:testStaticFunctionsCompatibility() (gas: 10622)
OpStackBurnMintERC677_supportsInterface:testConstructorSuccess() (gas: 8961)
\ No newline at end of file
diff --git a/contracts/gas-snapshots/vrf.gas-snapshot b/contracts/gas-snapshots/vrf.gas-snapshot
deleted file mode 100644
index 637a0edf963..00000000000
--- a/contracts/gas-snapshots/vrf.gas-snapshot
+++ /dev/null
@@ -1,15 +0,0 @@
-TrustedBlockhashStoreTest:testGenericBHSFunctions() (gas: 53507)
-TrustedBlockhashStoreTest:testTrustedBHSFunctions() (gas: 49536)
-VRFCoordinatorV2Plus_Migration:testDeregister() (gas: 99368)
-VRFCoordinatorV2Plus_Migration:testMigrateRevertsWhenInvalidCaller() (gas: 27234)
-VRFCoordinatorV2Plus_Migration:testMigrateRevertsWhenInvalidCoordinator() (gas: 17734)
-VRFCoordinatorV2Plus_Migration:testMigrateRevertsWhenPendingFulfillment() (gas: 237536)
-VRFCoordinatorV2Plus_Migration:testMigration() (gas: 468424)
-VRFV2Plus:testCreateSubscription() (gas: 181121)
-VRFV2Plus:testGetActiveSubscriptionIds() (gas: 3465607)
-VRFV2Plus:testRegisterProvingKey() (gas: 101019)
-VRFV2Plus:testRequestAndFulfillRandomWordsLINK() (gas: 755125)
-VRFV2Plus:testRequestAndFulfillRandomWordsNative() (gas: 705549)
-VRFV2Plus:testSetConfig() (gas: 73057)
-VRFV2PlusWrapperTest:testRequestAndFulfillRandomWordsLINKWrapper() (gas: 390063)
-VRFV2PlusWrapperTest:testRequestAndFulfillRandomWordsNativeWrapper() (gas: 290612)
\ No newline at end of file
diff --git a/contracts/hardhat.config.ts b/contracts/hardhat.config.ts
index d52174f2f55..521345ffc9e 100644
--- a/contracts/hardhat.config.ts
+++ b/contracts/hardhat.config.ts
@@ -54,6 +54,7 @@ let config = {
allowUnlimitedContractSize: Boolean(
process.env.ALLOW_UNLIMITED_CONTRACT_SIZE,
),
+ hardfork: 'merge',
},
},
solidity: {
diff --git a/contracts/package.json b/contracts/package.json
index 5f7a8c3d325..750eaca181a 100644
--- a/contracts/package.json
+++ b/contracts/package.json
@@ -1,6 +1,6 @@
{
"name": "@chainlink/contracts",
- "version": "0.6.1",
+ "version": "0.7.1",
"description": "Chainlink smart contracts",
"author": "Chainlink devs",
"license": "MIT",
@@ -17,7 +17,7 @@
"coverage": "hardhat coverage",
"prepublishOnly": "pnpm compile && ./scripts/prepublish_generate_abi_folder",
"publish-beta": "pnpm publish --tag beta",
- "publish-prod": "npm dist-tag add @chainlink/contracts@0.6.1 latest"
+ "publish-prod": "npm dist-tag add @chainlink/contracts@0.7.1 latest"
},
"files": [
"src/",
@@ -32,13 +32,13 @@
},
"devDependencies": {
"@ethereum-waffle/mock-contract": "^3.3.0",
- "@ethersproject/abi": "~5.6.0",
- "@ethersproject/bignumber": "~5.6.0",
- "@ethersproject/contracts": "~5.6.0",
- "@ethersproject/providers": "~5.6.1",
- "@ethersproject/random": "~5.6.0",
+ "@ethersproject/abi": "~5.7.0",
+ "@ethersproject/bignumber": "~5.7.0",
+ "@ethersproject/contracts": "~5.7.0",
+ "@ethersproject/providers": "~5.7.2",
+ "@ethersproject/random": "~5.7.0",
"@nomicfoundation/hardhat-network-helpers": "^1.0.8",
- "@nomiclabs/hardhat-ethers": "^2.0.2",
+ "@nomiclabs/hardhat-ethers": "^2.2.3",
"@nomiclabs/hardhat-etherscan": "^3.1.0",
"@nomiclabs/hardhat-waffle": "^2.0.1",
"@openzeppelin/hardhat-upgrades": "1.22.1",
@@ -46,39 +46,39 @@
"@typechain/ethers-v5": "^7.0.1",
"@typechain/hardhat": "^3.0.0",
"@types/cbor": "5.0.1",
- "@types/chai": "^4.2.18",
- "@types/debug": "^4.1.7",
+ "@types/chai": "^4.3.6",
+ "@types/debug": "^4.1.8",
"@types/deep-equal-in-any-order": "^1.0.1",
- "@types/mocha": "^8.2.2",
- "@types/node": "^15.12.2",
- "@typescript-eslint/eslint-plugin": "^5.59.5",
- "@typescript-eslint/parser": "^5.59.5",
+ "@types/mocha": "^10.0.1",
+ "@types/node": "^16.18.52",
+ "@typescript-eslint/eslint-plugin": "^6.7.0",
+ "@typescript-eslint/parser": "^6.7.0",
"abi-to-sol": "^0.6.6",
- "chai": "^4.3.4",
- "debug": "^4.3.2",
- "eslint": "^8.40.0",
- "eslint-config-prettier": "^8.8.0",
+ "chai": "^4.3.8",
+ "debug": "^4.3.4",
+ "eslint": "^8.49.0",
+ "eslint-config-prettier": "^9.0.0",
"deep-equal-in-any-order": "^2.0.6",
- "eslint-plugin-prettier": "^4.2.1",
+ "eslint-plugin-prettier": "^5.0.0",
"ethereum-waffle": "^3.3.0",
"ethers": "~5.6.0",
- "hardhat": "~2.12.7",
+ "hardhat": "~2.17.3",
"hardhat-abi-exporter": "^2.2.1",
"hardhat-contract-sizer": "^2.5.1",
"hardhat-gas-reporter": "^1.0.9",
"hardhat-ignore-warnings": "^0.2.6",
"istanbul": "^0.4.5",
"moment": "^2.29.4",
- "prettier": "^2.8.8",
+ "prettier": "^3.0.3",
"prettier-plugin-solidity": "1.1.3",
- "rlp": "^2.0.0",
- "solhint": "^3.4.1",
+ "rlp": "^2.2.7",
+ "solhint": "^3.6.2",
"solhint-plugin-prettier": "^0.0.5",
"solidity-coverage": "^0.8.4",
- "ts-node": "^10.0.0",
- "tslib": "^2.4.0",
- "typechain": "^8.0.0",
- "typescript": "^4.3.2"
+ "ts-node": "^10.9.1",
+ "tslib": "^2.6.2",
+ "typechain": "^8.2.0",
+ "typescript": "^5.2.2"
},
"dependencies": {
"@eth-optimism/contracts": "^0.5.21",
diff --git a/contracts/pnpm-lock.yaml b/contracts/pnpm-lock.yaml
index da673532152..b7179be4c60 100644
--- a/contracts/pnpm-lock.yaml
+++ b/contracts/pnpm-lock.yaml
@@ -26,107 +26,107 @@ devDependencies:
specifier: ^3.3.0
version: 3.4.4
'@ethersproject/abi':
- specifier: ~5.6.0
- version: 5.6.1
+ specifier: ~5.7.0
+ version: 5.7.0
'@ethersproject/bignumber':
- specifier: ~5.6.0
- version: 5.6.1
+ specifier: ~5.7.0
+ version: 5.7.0
'@ethersproject/contracts':
- specifier: ~5.6.0
- version: 5.6.1
+ specifier: ~5.7.0
+ version: 5.7.0
'@ethersproject/providers':
- specifier: ~5.6.1
- version: 5.6.1
+ specifier: ~5.7.2
+ version: 5.7.2
'@ethersproject/random':
- specifier: ~5.6.0
- version: 5.6.1
+ specifier: ~5.7.0
+ version: 5.7.0
'@nomicfoundation/hardhat-network-helpers':
specifier: ^1.0.8
- version: 1.0.8(hardhat@2.12.7)
+ version: 1.0.8(hardhat@2.17.3)
'@nomiclabs/hardhat-ethers':
- specifier: ^2.0.2
- version: 2.0.2(ethers@5.6.1)(hardhat@2.12.7)
+ specifier: ^2.2.3
+ version: 2.2.3(ethers@5.6.1)(hardhat@2.17.3)
'@nomiclabs/hardhat-etherscan':
specifier: ^3.1.0
- version: 3.1.0(hardhat@2.12.7)
+ version: 3.1.0(hardhat@2.17.3)
'@nomiclabs/hardhat-waffle':
specifier: ^2.0.1
- version: 2.0.1(@nomiclabs/hardhat-ethers@2.0.2)(ethereum-waffle@3.3.0)(ethers@5.6.1)(hardhat@2.12.7)
+ version: 2.0.1(@nomiclabs/hardhat-ethers@2.2.3)(ethereum-waffle@3.3.0)(ethers@5.6.1)(hardhat@2.17.3)
'@openzeppelin/hardhat-upgrades':
specifier: 1.22.1
- version: 1.22.1(@nomiclabs/hardhat-ethers@2.0.2)(@nomiclabs/hardhat-etherscan@3.1.0)(ethers@5.6.1)(hardhat@2.12.7)
+ version: 1.22.1(@nomiclabs/hardhat-ethers@2.2.3)(@nomiclabs/hardhat-etherscan@3.1.0)(ethers@5.6.1)(hardhat@2.17.3)
'@openzeppelin/test-helpers':
specifier: ^0.5.11
version: 0.5.11(bn.js@4.12.0)
'@typechain/ethers-v5':
specifier: ^7.0.1
- version: 7.2.0(@ethersproject/abi@5.6.1)(@ethersproject/bytes@5.7.0)(@ethersproject/providers@5.6.1)(ethers@5.6.1)(typechain@8.2.0)(typescript@4.9.5)
+ version: 7.2.0(@ethersproject/abi@5.7.0)(@ethersproject/bytes@5.7.0)(@ethersproject/providers@5.7.2)(ethers@5.6.1)(typechain@8.2.0)(typescript@5.2.2)
'@typechain/hardhat':
specifier: ^3.0.0
- version: 3.1.0(hardhat@2.12.7)(lodash@4.17.21)(typechain@8.2.0)
+ version: 3.1.0(hardhat@2.17.3)(lodash@4.17.21)(typechain@8.2.0)
'@types/cbor':
specifier: 5.0.1
version: 5.0.1
'@types/chai':
- specifier: ^4.2.18
- version: 4.3.3
+ specifier: ^4.3.6
+ version: 4.3.6
'@types/debug':
- specifier: ^4.1.7
- version: 4.1.7
+ specifier: ^4.1.8
+ version: 4.1.8
'@types/deep-equal-in-any-order':
specifier: ^1.0.1
version: 1.0.1
'@types/mocha':
- specifier: ^8.2.2
- version: 8.2.2
+ specifier: ^10.0.1
+ version: 10.0.1
'@types/node':
- specifier: ^15.12.2
- version: 15.14.9
+ specifier: ^16.18.52
+ version: 16.18.52
'@typescript-eslint/eslint-plugin':
- specifier: ^5.59.5
- version: 5.59.8(@typescript-eslint/parser@5.59.8)(eslint@8.42.0)(typescript@4.9.5)
+ specifier: ^6.7.0
+ version: 6.7.0(@typescript-eslint/parser@6.7.0)(eslint@8.49.0)(typescript@5.2.2)
'@typescript-eslint/parser':
- specifier: ^5.59.5
- version: 5.59.8(eslint@8.42.0)(typescript@4.9.5)
+ specifier: ^6.7.0
+ version: 6.7.0(eslint@8.49.0)(typescript@5.2.2)
abi-to-sol:
specifier: ^0.6.6
version: 0.6.6
chai:
- specifier: ^4.3.4
- version: 4.3.6
+ specifier: ^4.3.8
+ version: 4.3.8
debug:
- specifier: ^4.3.2
+ specifier: ^4.3.4
version: 4.3.4(supports-color@8.1.1)
deep-equal-in-any-order:
specifier: ^2.0.6
version: 2.0.6
eslint:
- specifier: ^8.40.0
- version: 8.42.0
+ specifier: ^8.49.0
+ version: 8.49.0
eslint-config-prettier:
- specifier: ^8.8.0
- version: 8.8.0(eslint@8.42.0)
+ specifier: ^9.0.0
+ version: 9.0.0(eslint@8.49.0)
eslint-plugin-prettier:
- specifier: ^4.2.1
- version: 4.2.1(eslint-config-prettier@8.8.0)(eslint@8.42.0)(prettier@2.8.8)
+ specifier: ^5.0.0
+ version: 5.0.0(eslint-config-prettier@9.0.0)(eslint@8.49.0)(prettier@3.0.3)
ethereum-waffle:
specifier: ^3.3.0
- version: 3.3.0(typescript@4.9.5)
+ version: 3.3.0(typescript@5.2.2)
ethers:
specifier: ~5.6.0
version: 5.6.1
hardhat:
- specifier: ~2.12.7
- version: 2.12.7(ts-node@10.0.0)(typescript@4.9.5)
+ specifier: ~2.17.3
+ version: 2.17.3(ts-node@10.9.1)(typescript@5.2.2)
hardhat-abi-exporter:
specifier: ^2.2.1
- version: 2.2.1(hardhat@2.12.7)
+ version: 2.2.1(hardhat@2.17.3)
hardhat-contract-sizer:
specifier: ^2.5.1
- version: 2.5.1(hardhat@2.12.7)
+ version: 2.5.1(hardhat@2.17.3)
hardhat-gas-reporter:
specifier: ^1.0.9
- version: 1.0.9(hardhat@2.12.7)
+ version: 1.0.9(hardhat@2.17.3)
hardhat-ignore-warnings:
specifier: ^0.2.6
version: 0.2.9
@@ -137,38 +137,43 @@ devDependencies:
specifier: ^2.29.4
version: 2.29.4
prettier:
- specifier: ^2.8.8
- version: 2.8.8
+ specifier: ^3.0.3
+ version: 3.0.3
prettier-plugin-solidity:
specifier: 1.1.3
- version: 1.1.3(prettier@2.8.8)
+ version: 1.1.3(prettier@3.0.3)
rlp:
- specifier: ^2.0.0
+ specifier: ^2.2.7
version: 2.2.7
solhint:
- specifier: ^3.4.1
- version: 3.4.1
+ specifier: ^3.6.2
+ version: 3.6.2
solhint-plugin-prettier:
specifier: ^0.0.5
- version: 0.0.5(prettier-plugin-solidity@1.1.3)(prettier@2.8.8)
+ version: 0.0.5(prettier-plugin-solidity@1.1.3)(prettier@3.0.3)
solidity-coverage:
specifier: ^0.8.4
- version: 0.8.4(hardhat@2.12.7)
+ version: 0.8.4(hardhat@2.17.3)
ts-node:
- specifier: ^10.0.0
- version: 10.0.0(@types/node@15.14.9)(typescript@4.9.5)
+ specifier: ^10.9.1
+ version: 10.9.1(@types/node@16.18.52)(typescript@5.2.2)
tslib:
- specifier: ^2.4.0
- version: 2.4.0
+ specifier: ^2.6.2
+ version: 2.6.2
typechain:
- specifier: ^8.0.0
- version: 8.2.0(typescript@4.9.5)
+ specifier: ^8.2.0
+ version: 8.2.0(typescript@5.2.2)
typescript:
- specifier: ^4.3.2
- version: 4.9.5
+ specifier: ^5.2.2
+ version: 5.2.2
packages:
+ /@aashutoshrathi/word-wrap@1.2.6:
+ resolution: {integrity: sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==}
+ engines: {node: '>=0.10.0'}
+ dev: true
+
/@babel/code-frame@7.18.6:
resolution: {integrity: sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==}
engines: {node: '>=6.9.0'}
@@ -197,6 +202,37 @@ packages:
regenerator-runtime: 0.13.9
dev: true
+ /@chainsafe/as-sha256@0.3.1:
+ resolution: {integrity: sha512-hldFFYuf49ed7DAakWVXSJODuq3pzJEguD8tQ7h+sGkM18vja+OFoJI9krnGmgzyuZC2ETX0NOIcCTy31v2Mtg==}
+ dev: true
+
+ /@chainsafe/persistent-merkle-tree@0.4.2:
+ resolution: {integrity: sha512-lLO3ihKPngXLTus/L7WHKaw9PnNJWizlOF1H9NNzHP6Xvh82vzg9F2bzkXhYIFshMZ2gTCEz8tq6STe7r5NDfQ==}
+ dependencies:
+ '@chainsafe/as-sha256': 0.3.1
+ dev: true
+
+ /@chainsafe/persistent-merkle-tree@0.5.0:
+ resolution: {integrity: sha512-l0V1b5clxA3iwQLXP40zYjyZYospQLZXzBVIhhr9kDg/1qHZfzzHw0jj4VPBijfYCArZDlPkRi1wZaV2POKeuw==}
+ dependencies:
+ '@chainsafe/as-sha256': 0.3.1
+ dev: true
+
+ /@chainsafe/ssz@0.10.2:
+ resolution: {integrity: sha512-/NL3Lh8K+0q7A3LsiFq09YXS9fPE+ead2rr7vM2QK8PLzrNsw3uqrif9bpRX5UxgeRjM+vYi+boCM3+GM4ovXg==}
+ dependencies:
+ '@chainsafe/as-sha256': 0.3.1
+ '@chainsafe/persistent-merkle-tree': 0.5.0
+ dev: true
+
+ /@chainsafe/ssz@0.9.4:
+ resolution: {integrity: sha512-77Qtg2N1ayqs4Bg/wvnWfg5Bta7iy7IRh8XqXh7oNMeP2HBbBwx8m6yTpA8p0EHItWPEBkgZd5S5/LSlp3GXuQ==}
+ dependencies:
+ '@chainsafe/as-sha256': 0.3.1
+ '@chainsafe/persistent-merkle-tree': 0.4.2
+ case: 1.6.3
+ dev: true
+
/@colors/colors@1.5.0:
resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==}
engines: {node: '>=0.1.90'}
@@ -204,6 +240,13 @@ packages:
dev: true
optional: true
+ /@cspotcode/source-map-support@0.8.1:
+ resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==}
+ engines: {node: '>=12'}
+ dependencies:
+ '@jridgewell/trace-mapping': 0.3.9
+ dev: true
+
/@ensdomains/address-encoder@0.1.9:
resolution: {integrity: sha512-E2d2gP4uxJQnDu2Kfg1tHNspefzbLT8Tyjrm5sEuim32UkU2sm5xL4VXtgc2X33fmPEw9+jUMpGs4veMbf+PYg==}
dependencies:
@@ -248,28 +291,28 @@ packages:
deprecated: Please use @ensdomains/ens-contracts
dev: true
- /@eslint-community/eslint-utils@4.4.0(eslint@8.42.0):
+ /@eslint-community/eslint-utils@4.4.0(eslint@8.49.0):
resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies:
eslint: ^6.0.0 || ^7.0.0 || >=8.0.0
dependencies:
- eslint: 8.42.0
- eslint-visitor-keys: 3.4.1
+ eslint: 8.49.0
+ eslint-visitor-keys: 3.4.3
dev: true
- /@eslint-community/regexpp@4.5.1:
- resolution: {integrity: sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ==}
+ /@eslint-community/regexpp@4.8.0:
+ resolution: {integrity: sha512-JylOEEzDiOryeUnFbQz+oViCXS0KsvR1mvHkoMiu5+UiBvy+RYX7tzlIIIEstF/gVa2tj9AQXk3dgnxv6KxhFg==}
engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0}
dev: true
- /@eslint/eslintrc@2.0.3:
- resolution: {integrity: sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ==}
+ /@eslint/eslintrc@2.1.2:
+ resolution: {integrity: sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
dependencies:
ajv: 6.12.6
debug: 4.3.4(supports-color@8.1.1)
- espree: 9.5.2
+ espree: 9.6.1
globals: 13.20.0
ignore: 5.2.4
import-fresh: 3.3.0
@@ -280,8 +323,8 @@ packages:
- supports-color
dev: true
- /@eslint/js@8.42.0:
- resolution: {integrity: sha512-6SWlXpWU5AvId8Ac7zjzmIOqMOba/JWY8XZ4A7q7Gn1Vlfg/SFFIlrtHXt9nPn4op9ZPAkl91Jao+QQv3r/ukw==}
+ /@eslint/js@8.49.0:
+ resolution: {integrity: sha512-1S8uAY/MTJqVx0SC4epBq+N2yhuwtNwLbJYNZyhL2pO1ZVKn5HFXav5T41Ryzy9K9V7ZId2JB2oy/W4aCd9/2w==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
dev: true
@@ -312,12 +355,12 @@ packages:
'@ethersproject/hash': 5.7.0
'@ethersproject/keccak256': 5.7.0
'@ethersproject/properties': 5.7.0
- '@ethersproject/providers': 5.7.1
+ '@ethersproject/providers': 5.7.2
'@ethersproject/rlp': 5.7.0
'@ethersproject/transactions': 5.7.0
'@ethersproject/web': 5.7.1
bufio: 1.0.7
- chai: 4.3.6
+ chai: 4.3.8
transitivePeerDependencies:
- bufferutil
- utf-8-validate
@@ -336,7 +379,7 @@ packages:
- utf-8-validate
dev: true
- /@ethereum-waffle/compiler@3.4.4(typescript@4.9.5):
+ /@ethereum-waffle/compiler@3.4.4(typescript@5.2.2):
resolution: {integrity: sha512-RUK3axJ8IkD5xpWjWoJgyHclOeEzDLQFga6gKpeGxiS/zBu+HB0W2FvsrrLalTFIaPw/CGYACRBSIxqiCqwqTQ==}
engines: {node: '>=10.0'}
dependencies:
@@ -350,7 +393,7 @@ packages:
node-fetch: 2.6.7
solc: 0.6.12
ts-generator: 0.1.1
- typechain: 3.0.0(typescript@4.9.5)
+ typechain: 3.0.0(typescript@5.2.2)
transitivePeerDependencies:
- bufferutil
- encoding
@@ -375,7 +418,7 @@ packages:
resolution: {integrity: sha512-Mp0iB2YNWYGUV+VMl5tjPsaXKbKo8MDH9wSJ702l9EBjdxFf/vBvnMBAC1Fub1lLtmD0JHtp1pq+mWzg/xlLnA==}
engines: {node: '>=10.0'}
dependencies:
- '@ethersproject/abi': 5.6.1
+ '@ethersproject/abi': 5.7.0
ethers: 5.6.1
transitivePeerDependencies:
- bufferutil
@@ -432,20 +475,7 @@ packages:
resolution: {integrity: sha512-AhVByTwdXCc2YQ20v300w6KVHle9g2OFc28ZAFCPnJyEpkv1xKXjZcSTgWOlv1i+0dqlgF8RCF2Rn2KC1t+1Vg==}
dependencies:
'@ethersproject/address': 5.7.0
- '@ethersproject/bignumber': 5.6.1
- '@ethersproject/bytes': 5.7.0
- '@ethersproject/constants': 5.7.0
- '@ethersproject/hash': 5.7.0
- '@ethersproject/keccak256': 5.7.0
- '@ethersproject/logger': 5.0.6
- '@ethersproject/properties': 5.7.0
- '@ethersproject/strings': 5.7.0
-
- /@ethersproject/abi@5.6.1:
- resolution: {integrity: sha512-0cqssYh6FXjlwKWBmLm3+zH2BNARoS5u/hxbz+LpQmcDB3w0W553h2btWui1/uZp2GBM/SI3KniTuMcYyHpA5w==}
- dependencies:
- '@ethersproject/address': 5.7.0
- '@ethersproject/bignumber': 5.6.1
+ '@ethersproject/bignumber': 5.7.0
'@ethersproject/bytes': 5.7.0
'@ethersproject/constants': 5.7.0
'@ethersproject/hash': 5.7.0
@@ -453,7 +483,6 @@ packages:
'@ethersproject/logger': 5.0.6
'@ethersproject/properties': 5.7.0
'@ethersproject/strings': 5.7.0
- dev: true
/@ethersproject/abi@5.7.0:
resolution: {integrity: sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA==}
@@ -471,7 +500,7 @@ packages:
/@ethersproject/abstract-provider@5.6.0:
resolution: {integrity: sha512-oPMFlKLN+g+y7a79cLK3WiLcjWFnZQtXWgnLAbHZcN3s7L4v90UHpTOrLk+m3yr0gt+/h9STTM6zrr7PM8uoRw==}
dependencies:
- '@ethersproject/bignumber': 5.6.1
+ '@ethersproject/bignumber': 5.7.0
'@ethersproject/bytes': 5.7.0
'@ethersproject/logger': 5.0.6
'@ethersproject/networks': 5.7.1
@@ -494,7 +523,7 @@ packages:
resolution: {integrity: sha512-WOqnG0NJKtI8n0wWZPReHtaLkDByPL67tn4nBaDAhmVq8sjHTPbCdz4DRhVu/cfTOvfy9w3iq5QZ7BX7zw56BQ==}
dependencies:
'@ethersproject/abstract-provider': 5.7.0
- '@ethersproject/bignumber': 5.6.1
+ '@ethersproject/bignumber': 5.7.0
'@ethersproject/bytes': 5.7.0
'@ethersproject/logger': 5.0.6
'@ethersproject/properties': 5.7.0
@@ -511,7 +540,7 @@ packages:
/@ethersproject/address@5.6.0:
resolution: {integrity: sha512-6nvhYXjbXsHPS+30sHZ+U4VMagFC/9zAk6Gd/h3S21YW4+yfb0WfRtaAIZ4kfM4rrVwqiy284LP0GtL5HXGLxQ==}
dependencies:
- '@ethersproject/bignumber': 5.6.1
+ '@ethersproject/bignumber': 5.7.0
'@ethersproject/bytes': 5.7.0
'@ethersproject/keccak256': 5.7.0
'@ethersproject/logger': 5.0.6
@@ -555,13 +584,6 @@ packages:
'@ethersproject/logger': 5.0.6
bn.js: 4.12.0
- /@ethersproject/bignumber@5.6.1:
- resolution: {integrity: sha512-UtMeZ3GaUuF9sx2u9nPZiPP3ULcAFmXyvynR7oHl/tPrM+vldZh7ocMsoa1PqKYGnQnqUZJoqxZnGN6J0qdipA==}
- dependencies:
- '@ethersproject/bytes': 5.7.0
- '@ethersproject/logger': 5.0.6
- bn.js: 4.12.0
-
/@ethersproject/bignumber@5.7.0:
resolution: {integrity: sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw==}
dependencies:
@@ -582,7 +604,7 @@ packages:
/@ethersproject/constants@5.6.0:
resolution: {integrity: sha512-SrdaJx2bK0WQl23nSpV/b1aq293Lh0sUaZT/yYKPDKn4tlAbkH96SPJwIhwSwTsoQQZxuh1jnqsKwyymoiBdWA==}
dependencies:
- '@ethersproject/bignumber': 5.6.1
+ '@ethersproject/bignumber': 5.7.0
/@ethersproject/constants@5.7.0:
resolution: {integrity: sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA==}
@@ -596,27 +618,12 @@ packages:
'@ethersproject/abstract-provider': 5.7.0
'@ethersproject/abstract-signer': 5.7.0
'@ethersproject/address': 5.7.0
- '@ethersproject/bignumber': 5.6.1
- '@ethersproject/bytes': 5.7.0
- '@ethersproject/constants': 5.7.0
- '@ethersproject/logger': 5.0.6
- '@ethersproject/properties': 5.7.0
- '@ethersproject/transactions': 5.7.0
-
- /@ethersproject/contracts@5.6.1:
- resolution: {integrity: sha512-0fpBBDoPqJMsutE6sNjg6pvCJaIcl7tliMQTMRcoUWDACfjO68CpKOJBlsEhEhmzdnu/41KbrfAeg+sB3y35MQ==}
- dependencies:
- '@ethersproject/abi': 5.6.1
- '@ethersproject/abstract-provider': 5.7.0
- '@ethersproject/abstract-signer': 5.7.0
- '@ethersproject/address': 5.7.0
- '@ethersproject/bignumber': 5.6.1
+ '@ethersproject/bignumber': 5.7.0
'@ethersproject/bytes': 5.7.0
'@ethersproject/constants': 5.7.0
'@ethersproject/logger': 5.0.6
'@ethersproject/properties': 5.7.0
'@ethersproject/transactions': 5.7.0
- dev: true
/@ethersproject/contracts@5.7.0:
resolution: {integrity: sha512-5GJbzEU3X+d33CdfPhcyS+z8MzsTrBGk/sc+G+59+tPa9yFkl6HQ9D6L0QMgNTA9q8dT0XKxxkyp883XsQvbbg==}
@@ -631,14 +638,13 @@ packages:
'@ethersproject/logger': 5.0.6
'@ethersproject/properties': 5.7.0
'@ethersproject/transactions': 5.7.0
- dev: false
/@ethersproject/hash@5.6.0:
resolution: {integrity: sha512-fFd+k9gtczqlr0/BruWLAu7UAOas1uRRJvOR84uDf4lNZ+bTkGl366qvniUZHKtlqxBRU65MkOobkmvmpHU+jA==}
dependencies:
'@ethersproject/abstract-signer': 5.7.0
'@ethersproject/address': 5.7.0
- '@ethersproject/bignumber': 5.6.1
+ '@ethersproject/bignumber': 5.7.0
'@ethersproject/bytes': 5.7.0
'@ethersproject/keccak256': 5.7.0
'@ethersproject/logger': 5.0.6
@@ -701,7 +707,7 @@ packages:
'@ethersproject/logger': 5.0.6
'@ethersproject/pbkdf2': 5.7.0
'@ethersproject/properties': 5.7.0
- '@ethersproject/random': 5.6.1
+ '@ethersproject/random': 5.7.0
'@ethersproject/strings': 5.7.0
'@ethersproject/transactions': 5.7.0
aes-js: 3.0.0
@@ -778,14 +784,14 @@ packages:
'@ethersproject/abstract-signer': 5.7.0
'@ethersproject/address': 5.7.0
'@ethersproject/basex': 5.7.0
- '@ethersproject/bignumber': 5.6.1
+ '@ethersproject/bignumber': 5.7.0
'@ethersproject/bytes': 5.7.0
'@ethersproject/constants': 5.7.0
'@ethersproject/hash': 5.7.0
'@ethersproject/logger': 5.0.6
'@ethersproject/networks': 5.7.1
'@ethersproject/properties': 5.7.0
- '@ethersproject/random': 5.6.1
+ '@ethersproject/random': 5.7.0
'@ethersproject/rlp': 5.7.0
'@ethersproject/sha2': 5.7.0
'@ethersproject/strings': 5.7.0
@@ -797,8 +803,8 @@ packages:
- bufferutil
- utf-8-validate
- /@ethersproject/providers@5.7.1:
- resolution: {integrity: sha512-vZveG/DLyo+wk4Ga1yx6jSEHrLPgmTt+dFv0dv8URpVCRf0jVhalps1jq/emN/oXnMRsC7cQgAF32DcXLL7BPQ==}
+ /@ethersproject/providers@5.7.2:
+ resolution: {integrity: sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg==}
dependencies:
'@ethersproject/abstract-provider': 5.7.0
'@ethersproject/abstract-signer': 5.7.0
@@ -823,7 +829,6 @@ packages:
transitivePeerDependencies:
- bufferutil
- utf-8-validate
- dev: false
/@ethersproject/random@5.6.0:
resolution: {integrity: sha512-si0PLcLjq+NG/XHSZz90asNf+YfKEqJGVdxoEkSukzbnBgC8rydbgbUgBbBGLeHN4kAJwUFEKsu3sCXT93YMsw==}
@@ -831,12 +836,6 @@ packages:
'@ethersproject/bytes': 5.7.0
'@ethersproject/logger': 5.0.6
- /@ethersproject/random@5.6.1:
- resolution: {integrity: sha512-/wtPNHwbmng+5yi3fkipA8YBT59DdkGRoC2vWk09Dci/q5DlgnMkhIycjHlavrvrjJBkFjO/ueLyT+aUDfc4lA==}
- dependencies:
- '@ethersproject/bytes': 5.7.0
- '@ethersproject/logger': 5.0.6
-
/@ethersproject/random@5.7.0:
resolution: {integrity: sha512-19WjScqRA8IIeWclFme75VMXSBvi4e6InrUNuaR4s5pTF2qNhcGdCUwdxUVGtDDqC00sDLCO93jPQoDUH4HVmQ==}
dependencies:
@@ -899,6 +898,17 @@ packages:
'@ethersproject/sha2': 5.7.0
'@ethersproject/strings': 5.7.0
+ /@ethersproject/solidity@5.7.0:
+ resolution: {integrity: sha512-HmabMd2Dt/raavyaGukF4XxizWKhKQ24DoLtdNbBmNKUOPqwjsKQSdV9GQtj9CBEea9DlzETlVER1gYeXXBGaA==}
+ dependencies:
+ '@ethersproject/bignumber': 5.7.0
+ '@ethersproject/bytes': 5.7.0
+ '@ethersproject/keccak256': 5.7.0
+ '@ethersproject/logger': 5.0.6
+ '@ethersproject/sha2': 5.7.0
+ '@ethersproject/strings': 5.7.0
+ dev: true
+
/@ethersproject/strings@5.6.0:
resolution: {integrity: sha512-uv10vTtLTZqrJuqBZR862ZQjTIa724wGPWQqZrofaPI/kUsf53TBG0I0D+hQ1qyNtllbNzaW+PDPHHUI6/65Mg==}
dependencies:
@@ -946,6 +956,14 @@ packages:
'@ethersproject/constants': 5.7.0
'@ethersproject/logger': 5.0.6
+ /@ethersproject/units@5.7.0:
+ resolution: {integrity: sha512-pD3xLMy3SJu9kG5xDGI7+xhTEmGXlEqXU4OfNapmfnxLVY4EMSSRp7j1k7eezutBPH7RBN/7QPnwR7hzNlEFeg==}
+ dependencies:
+ '@ethersproject/bignumber': 5.7.0
+ '@ethersproject/constants': 5.7.0
+ '@ethersproject/logger': 5.0.6
+ dev: true
+
/@ethersproject/wallet@5.6.0:
resolution: {integrity: sha512-qMlSdOSTyp0MBeE+r7SUhr1jjDlC1zAXB8VD84hCnpijPQiSNbxr6GdiLXxpUs8UKzkDiNYYC5DRI3MZr+n+tg==}
dependencies:
@@ -960,11 +978,31 @@ packages:
'@ethersproject/keccak256': 5.7.0
'@ethersproject/logger': 5.0.6
'@ethersproject/properties': 5.7.0
- '@ethersproject/random': 5.6.1
+ '@ethersproject/random': 5.7.0
'@ethersproject/signing-key': 5.7.0
'@ethersproject/transactions': 5.7.0
'@ethersproject/wordlists': 5.7.0
+ /@ethersproject/wallet@5.7.0:
+ resolution: {integrity: sha512-MhmXlJXEJFBFVKrDLB4ZdDzxcBxQ3rLyCkhNqVu3CDYvR97E+8r01UgrI+TI99Le+aYm/in/0vp86guJuM7FCA==}
+ dependencies:
+ '@ethersproject/abstract-provider': 5.7.0
+ '@ethersproject/abstract-signer': 5.7.0
+ '@ethersproject/address': 5.7.0
+ '@ethersproject/bignumber': 5.7.0
+ '@ethersproject/bytes': 5.7.0
+ '@ethersproject/hash': 5.7.0
+ '@ethersproject/hdnode': 5.7.0
+ '@ethersproject/json-wallets': 5.7.0
+ '@ethersproject/keccak256': 5.7.0
+ '@ethersproject/logger': 5.0.6
+ '@ethersproject/properties': 5.7.0
+ '@ethersproject/random': 5.7.0
+ '@ethersproject/signing-key': 5.7.0
+ '@ethersproject/transactions': 5.7.0
+ '@ethersproject/wordlists': 5.7.0
+ dev: true
+
/@ethersproject/web@5.6.0:
resolution: {integrity: sha512-G/XHj0hV1FxI2teHRfCGvfBUHFmU+YOSbCxlAMqJklxSa7QMiHFQfAxvwY2PFqgvdkxEKwRNr/eCjfAPEm2Ctg==}
dependencies:
@@ -1001,8 +1039,8 @@ packages:
'@ethersproject/properties': 5.7.0
'@ethersproject/strings': 5.7.0
- /@humanwhocodes/config-array@0.11.10:
- resolution: {integrity: sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==}
+ /@humanwhocodes/config-array@0.11.11:
+ resolution: {integrity: sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA==}
engines: {node: '>=10.10.0'}
dependencies:
'@humanwhocodes/object-schema': 1.2.1
@@ -1021,6 +1059,22 @@ packages:
resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==}
dev: true
+ /@jridgewell/resolve-uri@3.1.1:
+ resolution: {integrity: sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==}
+ engines: {node: '>=6.0.0'}
+ dev: true
+
+ /@jridgewell/sourcemap-codec@1.4.15:
+ resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==}
+ dev: true
+
+ /@jridgewell/trace-mapping@0.3.9:
+ resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==}
+ dependencies:
+ '@jridgewell/resolve-uri': 3.1.1
+ '@jridgewell/sourcemap-codec': 1.4.15
+ dev: true
+
/@metamask/eth-sig-util@4.0.1:
resolution: {integrity: sha512-tghyZKLHZjcdlDqCA3gNZmLeR0XvOE9U1qoQO9ohyAZT6Pya+H9vkBPcsyXytmYLNgVoin7CKCmweo/R43V+tQ==}
engines: {node: '>=12.0.0'}
@@ -1061,28 +1115,33 @@ packages:
fastq: 1.6.0
dev: true
- /@nomicfoundation/ethereumjs-block@4.0.0:
- resolution: {integrity: sha512-bk8uP8VuexLgyIZAHExH1QEovqx0Lzhc9Ntm63nCRKLHXIZkobaFaeCVwTESV7YkPKUk7NiK11s8ryed4CS9yA==}
+ /@nomicfoundation/ethereumjs-block@5.0.2:
+ resolution: {integrity: sha512-hSe6CuHI4SsSiWWjHDIzWhSiAVpzMUcDRpWYzN0T9l8/Rz7xNn3elwVOJ/tAyS0LqL6vitUD78Uk7lQDXZun7Q==}
engines: {node: '>=14'}
dependencies:
- '@nomicfoundation/ethereumjs-common': 3.0.0
- '@nomicfoundation/ethereumjs-rlp': 4.0.0
- '@nomicfoundation/ethereumjs-trie': 5.0.0
- '@nomicfoundation/ethereumjs-tx': 4.0.0
- '@nomicfoundation/ethereumjs-util': 8.0.0
+ '@nomicfoundation/ethereumjs-common': 4.0.2
+ '@nomicfoundation/ethereumjs-rlp': 5.0.2
+ '@nomicfoundation/ethereumjs-trie': 6.0.2
+ '@nomicfoundation/ethereumjs-tx': 5.0.2
+ '@nomicfoundation/ethereumjs-util': 9.0.2
ethereum-cryptography: 0.1.3
+ ethers: 5.7.2
+ transitivePeerDependencies:
+ - bufferutil
+ - utf-8-validate
dev: true
- /@nomicfoundation/ethereumjs-blockchain@6.0.0:
- resolution: {integrity: sha512-pLFEoea6MWd81QQYSReLlLfH7N9v7lH66JC/NMPN848ySPPQA5renWnE7wPByfQFzNrPBuDDRFFULMDmj1C0xw==}
+ /@nomicfoundation/ethereumjs-blockchain@7.0.2:
+ resolution: {integrity: sha512-8UUsSXJs+MFfIIAKdh3cG16iNmWzWC/91P40sazNvrqhhdR/RtGDlFk2iFTGbBAZPs2+klZVzhRX8m2wvuvz3w==}
engines: {node: '>=14'}
dependencies:
- '@nomicfoundation/ethereumjs-block': 4.0.0
- '@nomicfoundation/ethereumjs-common': 3.0.0
- '@nomicfoundation/ethereumjs-ethash': 2.0.0
- '@nomicfoundation/ethereumjs-rlp': 4.0.0
- '@nomicfoundation/ethereumjs-trie': 5.0.0
- '@nomicfoundation/ethereumjs-util': 8.0.0
+ '@nomicfoundation/ethereumjs-block': 5.0.2
+ '@nomicfoundation/ethereumjs-common': 4.0.2
+ '@nomicfoundation/ethereumjs-ethash': 3.0.2
+ '@nomicfoundation/ethereumjs-rlp': 5.0.2
+ '@nomicfoundation/ethereumjs-trie': 6.0.2
+ '@nomicfoundation/ethereumjs-tx': 5.0.2
+ '@nomicfoundation/ethereumjs-util': 9.0.2
abstract-level: 1.0.3
debug: 4.3.4(supports-color@8.1.1)
ethereum-cryptography: 0.1.3
@@ -1090,123 +1149,137 @@ packages:
lru-cache: 5.1.1
memory-level: 1.0.0
transitivePeerDependencies:
+ - bufferutil
- supports-color
+ - utf-8-validate
dev: true
- /@nomicfoundation/ethereumjs-common@3.0.0:
- resolution: {integrity: sha512-WS7qSshQfxoZOpHG/XqlHEGRG1zmyjYrvmATvc4c62+gZXgre1ymYP8ZNgx/3FyZY0TWe9OjFlKOfLqmgOeYwA==}
+ /@nomicfoundation/ethereumjs-common@4.0.2:
+ resolution: {integrity: sha512-I2WGP3HMGsOoycSdOTSqIaES0ughQTueOsddJ36aYVpI3SN8YSusgRFLwzDJwRFVIYDKx/iJz0sQ5kBHVgdDwg==}
dependencies:
- '@nomicfoundation/ethereumjs-util': 8.0.0
+ '@nomicfoundation/ethereumjs-util': 9.0.2
crc-32: 1.2.2
dev: true
- /@nomicfoundation/ethereumjs-ethash@2.0.0:
- resolution: {integrity: sha512-WpDvnRncfDUuXdsAXlI4lXbqUDOA+adYRQaEezIkxqDkc+LDyYDbd/xairmY98GnQzo1zIqsIL6GB5MoMSJDew==}
+ /@nomicfoundation/ethereumjs-ethash@3.0.2:
+ resolution: {integrity: sha512-8PfoOQCcIcO9Pylq0Buijuq/O73tmMVURK0OqdjhwqcGHYC2PwhbajDh7GZ55ekB0Px197ajK3PQhpKoiI/UPg==}
engines: {node: '>=14'}
dependencies:
- '@nomicfoundation/ethereumjs-block': 4.0.0
- '@nomicfoundation/ethereumjs-rlp': 4.0.0
- '@nomicfoundation/ethereumjs-util': 8.0.0
+ '@nomicfoundation/ethereumjs-block': 5.0.2
+ '@nomicfoundation/ethereumjs-rlp': 5.0.2
+ '@nomicfoundation/ethereumjs-util': 9.0.2
abstract-level: 1.0.3
bigint-crypto-utils: 3.1.8
ethereum-cryptography: 0.1.3
+ transitivePeerDependencies:
+ - bufferutil
+ - utf-8-validate
dev: true
- /@nomicfoundation/ethereumjs-evm@1.0.0:
- resolution: {integrity: sha512-hVS6qRo3V1PLKCO210UfcEQHvlG7GqR8iFzp0yyjTg2TmJQizcChKgWo8KFsdMw6AyoLgLhHGHw4HdlP8a4i+Q==}
+ /@nomicfoundation/ethereumjs-evm@2.0.2:
+ resolution: {integrity: sha512-rBLcUaUfANJxyOx9HIdMX6uXGin6lANCulIm/pjMgRqfiCRMZie3WKYxTSd8ZE/d+qT+zTedBF4+VHTdTSePmQ==}
engines: {node: '>=14'}
dependencies:
- '@nomicfoundation/ethereumjs-common': 3.0.0
- '@nomicfoundation/ethereumjs-util': 8.0.0
- '@types/async-eventemitter': 0.2.1
- async-eventemitter: 0.2.4
+ '@ethersproject/providers': 5.7.2
+ '@nomicfoundation/ethereumjs-common': 4.0.2
+ '@nomicfoundation/ethereumjs-tx': 5.0.2
+ '@nomicfoundation/ethereumjs-util': 9.0.2
debug: 4.3.4(supports-color@8.1.1)
ethereum-cryptography: 0.1.3
mcl-wasm: 0.7.9
rustbn.js: 0.2.0
transitivePeerDependencies:
+ - bufferutil
- supports-color
+ - utf-8-validate
dev: true
- /@nomicfoundation/ethereumjs-rlp@4.0.0:
- resolution: {integrity: sha512-GaSOGk5QbUk4eBP5qFbpXoZoZUj/NrW7MRa0tKY4Ew4c2HAS0GXArEMAamtFrkazp0BO4K5p2ZCG3b2FmbShmw==}
+ /@nomicfoundation/ethereumjs-rlp@5.0.2:
+ resolution: {integrity: sha512-QwmemBc+MMsHJ1P1QvPl8R8p2aPvvVcKBbvHnQOKBpBztEo0omN0eaob6FeZS/e3y9NSe+mfu3nNFBHszqkjTA==}
engines: {node: '>=14'}
hasBin: true
dev: true
- /@nomicfoundation/ethereumjs-statemanager@1.0.0:
- resolution: {integrity: sha512-jCtqFjcd2QejtuAMjQzbil/4NHf5aAWxUc+CvS0JclQpl+7M0bxMofR2AJdtz+P3u0ke2euhYREDiE7iSO31vQ==}
+ /@nomicfoundation/ethereumjs-statemanager@2.0.2:
+ resolution: {integrity: sha512-dlKy5dIXLuDubx8Z74sipciZnJTRSV/uHG48RSijhgm1V7eXYFC567xgKtsKiVZB1ViTP9iFL4B6Je0xD6X2OA==}
dependencies:
- '@nomicfoundation/ethereumjs-common': 3.0.0
- '@nomicfoundation/ethereumjs-rlp': 4.0.0
- '@nomicfoundation/ethereumjs-trie': 5.0.0
- '@nomicfoundation/ethereumjs-util': 8.0.0
+ '@nomicfoundation/ethereumjs-common': 4.0.2
+ '@nomicfoundation/ethereumjs-rlp': 5.0.2
debug: 4.3.4(supports-color@8.1.1)
ethereum-cryptography: 0.1.3
- functional-red-black-tree: 1.0.1
+ ethers: 5.7.2
+ js-sdsl: 4.4.2
transitivePeerDependencies:
+ - bufferutil
- supports-color
+ - utf-8-validate
dev: true
- /@nomicfoundation/ethereumjs-trie@5.0.0:
- resolution: {integrity: sha512-LIj5XdE+s+t6WSuq/ttegJzZ1vliwg6wlb+Y9f4RlBpuK35B9K02bO7xU+E6Rgg9RGptkWd6TVLdedTI4eNc2A==}
+ /@nomicfoundation/ethereumjs-trie@6.0.2:
+ resolution: {integrity: sha512-yw8vg9hBeLYk4YNg5MrSJ5H55TLOv2FSWUTROtDtTMMmDGROsAu+0tBjiNGTnKRi400M6cEzoFfa89Fc5k8NTQ==}
engines: {node: '>=14'}
dependencies:
- '@nomicfoundation/ethereumjs-rlp': 4.0.0
- '@nomicfoundation/ethereumjs-util': 8.0.0
+ '@nomicfoundation/ethereumjs-rlp': 5.0.2
+ '@nomicfoundation/ethereumjs-util': 9.0.2
+ '@types/readable-stream': 2.3.15
ethereum-cryptography: 0.1.3
readable-stream: 3.6.0
dev: true
- /@nomicfoundation/ethereumjs-tx@4.0.0:
- resolution: {integrity: sha512-Gg3Lir2lNUck43Kp/3x6TfBNwcWC9Z1wYue9Nz3v4xjdcv6oDW9QSMJxqsKw9QEGoBBZ+gqwpW7+F05/rs/g1w==}
+ /@nomicfoundation/ethereumjs-tx@5.0.2:
+ resolution: {integrity: sha512-T+l4/MmTp7VhJeNloMkM+lPU3YMUaXdcXgTGCf8+ZFvV9NYZTRLFekRwlG6/JMmVfIfbrW+dRRJ9A6H5Q/Z64g==}
engines: {node: '>=14'}
dependencies:
- '@nomicfoundation/ethereumjs-common': 3.0.0
- '@nomicfoundation/ethereumjs-rlp': 4.0.0
- '@nomicfoundation/ethereumjs-util': 8.0.0
+ '@chainsafe/ssz': 0.9.4
+ '@ethersproject/providers': 5.7.2
+ '@nomicfoundation/ethereumjs-common': 4.0.2
+ '@nomicfoundation/ethereumjs-rlp': 5.0.2
+ '@nomicfoundation/ethereumjs-util': 9.0.2
ethereum-cryptography: 0.1.3
+ transitivePeerDependencies:
+ - bufferutil
+ - utf-8-validate
dev: true
- /@nomicfoundation/ethereumjs-util@8.0.0:
- resolution: {integrity: sha512-2emi0NJ/HmTG+CGY58fa+DQuAoroFeSH9gKu9O6JnwTtlzJtgfTixuoOqLEgyyzZVvwfIpRueuePb8TonL1y+A==}
+ /@nomicfoundation/ethereumjs-util@9.0.2:
+ resolution: {integrity: sha512-4Wu9D3LykbSBWZo8nJCnzVIYGvGCuyiYLIJa9XXNVt1q1jUzHdB+sJvx95VGCpPkCT+IbLecW6yfzy3E1bQrwQ==}
engines: {node: '>=14'}
dependencies:
- '@nomicfoundation/ethereumjs-rlp': 4.0.0
+ '@chainsafe/ssz': 0.10.2
+ '@nomicfoundation/ethereumjs-rlp': 5.0.2
ethereum-cryptography: 0.1.3
dev: true
- /@nomicfoundation/ethereumjs-vm@6.0.0:
- resolution: {integrity: sha512-JMPxvPQ3fzD063Sg3Tp+UdwUkVxMoo1uML6KSzFhMH3hoQi/LMuXBoEHAoW83/vyNS9BxEe6jm6LmT5xdeEJ6w==}
+ /@nomicfoundation/ethereumjs-vm@7.0.2:
+ resolution: {integrity: sha512-Bj3KZT64j54Tcwr7Qm/0jkeZXJMfdcAtRBedou+Hx0dPOSIgqaIr0vvLwP65TpHbak2DmAq+KJbW2KNtIoFwvA==}
engines: {node: '>=14'}
dependencies:
- '@nomicfoundation/ethereumjs-block': 4.0.0
- '@nomicfoundation/ethereumjs-blockchain': 6.0.0
- '@nomicfoundation/ethereumjs-common': 3.0.0
- '@nomicfoundation/ethereumjs-evm': 1.0.0
- '@nomicfoundation/ethereumjs-rlp': 4.0.0
- '@nomicfoundation/ethereumjs-statemanager': 1.0.0
- '@nomicfoundation/ethereumjs-trie': 5.0.0
- '@nomicfoundation/ethereumjs-tx': 4.0.0
- '@nomicfoundation/ethereumjs-util': 8.0.0
- '@types/async-eventemitter': 0.2.1
- async-eventemitter: 0.2.4
+ '@nomicfoundation/ethereumjs-block': 5.0.2
+ '@nomicfoundation/ethereumjs-blockchain': 7.0.2
+ '@nomicfoundation/ethereumjs-common': 4.0.2
+ '@nomicfoundation/ethereumjs-evm': 2.0.2
+ '@nomicfoundation/ethereumjs-rlp': 5.0.2
+ '@nomicfoundation/ethereumjs-statemanager': 2.0.2
+ '@nomicfoundation/ethereumjs-trie': 6.0.2
+ '@nomicfoundation/ethereumjs-tx': 5.0.2
+ '@nomicfoundation/ethereumjs-util': 9.0.2
debug: 4.3.4(supports-color@8.1.1)
ethereum-cryptography: 0.1.3
- functional-red-black-tree: 1.0.1
mcl-wasm: 0.7.9
rustbn.js: 0.2.0
transitivePeerDependencies:
+ - bufferutil
- supports-color
+ - utf-8-validate
dev: true
- /@nomicfoundation/hardhat-network-helpers@1.0.8(hardhat@2.12.7):
+ /@nomicfoundation/hardhat-network-helpers@1.0.8(hardhat@2.17.3):
resolution: {integrity: sha512-MNqQbzUJZnCMIYvlniC3U+kcavz/PhhQSsY90tbEtUyMj/IQqsLwIRZa4ctjABh3Bz0KCh9OXUZ7Yk/d9hr45Q==}
peerDependencies:
hardhat: ^2.9.5
dependencies:
ethereumjs-util: 7.1.5
- hardhat: 2.12.7(ts-node@10.0.0)(typescript@4.9.5)
+ hardhat: 2.17.3(ts-node@10.9.1)(typescript@5.2.2)
dev: true
/@nomicfoundation/solidity-analyzer-darwin-arm64@0.1.0:
@@ -1315,28 +1388,28 @@ packages:
'@nomicfoundation/solidity-analyzer-win32-x64-msvc': 0.1.0
dev: true
- /@nomiclabs/hardhat-ethers@2.0.2(ethers@5.6.1)(hardhat@2.12.7):
- resolution: {integrity: sha512-6quxWe8wwS4X5v3Au8q1jOvXYEPkS1Fh+cME5u6AwNdnI4uERvPlVjlgRWzpnb+Rrt1l/cEqiNRH9GlsBMSDQg==}
+ /@nomiclabs/hardhat-ethers@2.2.3(ethers@5.6.1)(hardhat@2.17.3):
+ resolution: {integrity: sha512-YhzPdzb612X591FOe68q+qXVXGG2ANZRvDo0RRUtimev85rCrAlv/TLMEZw5c+kq9AbzocLTVX/h2jVIFPL9Xg==}
peerDependencies:
ethers: ^5.0.0
hardhat: ^2.0.0
dependencies:
ethers: 5.6.1
- hardhat: 2.12.7(ts-node@10.0.0)(typescript@4.9.5)
+ hardhat: 2.17.3(ts-node@10.9.1)(typescript@5.2.2)
dev: true
- /@nomiclabs/hardhat-etherscan@3.1.0(hardhat@2.12.7):
+ /@nomiclabs/hardhat-etherscan@3.1.0(hardhat@2.17.3):
resolution: {integrity: sha512-JroYgfN1AlYFkQTQ3nRwFi4o8NtZF7K/qFR2dxDUgHbCtIagkUseca9L4E/D2ScUm4XT40+8PbCdqZi+XmHyQA==}
peerDependencies:
hardhat: ^2.0.4
dependencies:
- '@ethersproject/abi': 5.6.1
+ '@ethersproject/abi': 5.7.0
'@ethersproject/address': 5.7.0
cbor: 5.2.0
chalk: 2.4.2
debug: 4.3.4(supports-color@8.1.1)
fs-extra: 7.0.1
- hardhat: 2.12.7(ts-node@10.0.0)(typescript@4.9.5)
+ hardhat: 2.17.3(ts-node@10.9.1)(typescript@5.2.2)
lodash: 4.17.21
semver: 6.3.0
table: 6.8.0
@@ -1345,7 +1418,7 @@ packages:
- supports-color
dev: true
- /@nomiclabs/hardhat-waffle@2.0.1(@nomiclabs/hardhat-ethers@2.0.2)(ethereum-waffle@3.3.0)(ethers@5.6.1)(hardhat@2.12.7):
+ /@nomiclabs/hardhat-waffle@2.0.1(@nomiclabs/hardhat-ethers@2.2.3)(ethereum-waffle@3.3.0)(ethers@5.6.1)(hardhat@2.17.3):
resolution: {integrity: sha512-2YR2V5zTiztSH9n8BYWgtv3Q+EL0N5Ltm1PAr5z20uAY4SkkfylJ98CIqt18XFvxTD5x4K2wKBzddjV9ViDAZQ==}
peerDependencies:
'@nomiclabs/hardhat-ethers': ^2.0.0
@@ -1353,12 +1426,12 @@ packages:
ethers: ^5.0.0
hardhat: ^2.0.0
dependencies:
- '@nomiclabs/hardhat-ethers': 2.0.2(ethers@5.6.1)(hardhat@2.12.7)
+ '@nomiclabs/hardhat-ethers': 2.2.3(ethers@5.6.1)(hardhat@2.17.3)
'@types/sinon-chai': 3.2.8
'@types/web3': 1.0.19
- ethereum-waffle: 3.3.0(typescript@4.9.5)
+ ethereum-waffle: 3.3.0(typescript@5.2.2)
ethers: 5.6.1
- hardhat: 2.12.7(ts-node@10.0.0)(typescript@4.9.5)
+ hardhat: 2.17.3(ts-node@10.9.1)(typescript@5.2.2)
dev: true
/@openzeppelin/contract-loader@0.6.3:
@@ -1380,7 +1453,7 @@ packages:
resolution: {integrity: sha512-tDBopO1c98Yk7Cv/PZlHqrvtVjlgK5R4J6jxLwoO7qxK4xqOiZG+zSkIvGFpPZ0ikc3QOED3plgdqjgNTnBc7g==}
dev: false
- /@openzeppelin/hardhat-upgrades@1.22.1(@nomiclabs/hardhat-ethers@2.0.2)(@nomiclabs/hardhat-etherscan@3.1.0)(ethers@5.6.1)(hardhat@2.12.7):
+ /@openzeppelin/hardhat-upgrades@1.22.1(@nomiclabs/hardhat-ethers@2.2.3)(@nomiclabs/hardhat-etherscan@3.1.0)(ethers@5.6.1)(hardhat@2.17.3):
resolution: {integrity: sha512-MdoitCTLl4zwMU8MeE/bCj+7JMWBEvd38XqJkw36PkJrXlbv6FedDVCPoumMAhpmtymm0nTwTYYklYG+L6WiiQ==}
hasBin: true
peerDependencies:
@@ -1393,13 +1466,13 @@ packages:
'@nomiclabs/harhdat-etherscan':
optional: true
dependencies:
- '@nomiclabs/hardhat-ethers': 2.0.2(ethers@5.6.1)(hardhat@2.12.7)
- '@nomiclabs/hardhat-etherscan': 3.1.0(hardhat@2.12.7)
+ '@nomiclabs/hardhat-ethers': 2.2.3(ethers@5.6.1)(hardhat@2.17.3)
+ '@nomiclabs/hardhat-etherscan': 3.1.0(hardhat@2.17.3)
'@openzeppelin/upgrades-core': 1.22.0
chalk: 4.1.2
debug: 4.3.4(supports-color@8.1.1)
ethers: 5.6.1
- hardhat: 2.12.7(ts-node@10.0.0)(typescript@4.9.5)
+ hardhat: 2.17.3(ts-node@10.9.1)(typescript@5.2.2)
proper-lockfile: 4.1.2
transitivePeerDependencies:
- supports-color
@@ -1411,8 +1484,8 @@ packages:
'@openzeppelin/contract-loader': 0.6.3
'@truffle/contract': 4.6.2
ansi-colors: 3.2.4
- chai: 4.3.6
- chai-bn: 0.2.2(bn.js@4.12.0)(chai@4.3.6)
+ chai: 4.3.8
+ chai-bn: 0.2.2(bn.js@4.12.0)(chai@4.3.8)
ethjs-abi: 0.2.1
lodash.flatten: 4.4.0
semver: 5.7.1
@@ -1440,6 +1513,18 @@ packages:
- supports-color
dev: true
+ /@pkgr/utils@2.4.2:
+ resolution: {integrity: sha512-POgTXhjrTfbTV63DiFXav4lBHiICLKKwDeaKn9Nphwj7WH6m0hMMCaJkMyRWjgtPFyRKRVoMXXjczsTQRDEhYw==}
+ engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0}
+ dependencies:
+ cross-spawn: 7.0.3
+ fast-glob: 3.3.1
+ is-glob: 4.0.3
+ open: 9.1.0
+ picocolors: 1.0.0
+ tslib: 2.6.2
+ dev: true
+
/@resolver-engine/core@0.3.3:
resolution: {integrity: sha512-eB8nEbKDJJBi5p5SrvrvILn4a0h42bKtbCTri3ZxCGt6UvoQyp7HnGOfki944bUjBSHKK3RvgfViHn+kqdXtnQ==}
dependencies:
@@ -1741,10 +1826,10 @@ packages:
typechain: ^3.0.0
dependencies:
ethers: 5.6.1
- typechain: 3.0.0(typescript@4.9.5)
+ typechain: 3.0.0(typescript@5.2.2)
dev: true
- /@typechain/ethers-v5@7.2.0(@ethersproject/abi@5.6.1)(@ethersproject/bytes@5.7.0)(@ethersproject/providers@5.6.1)(ethers@5.6.1)(typechain@8.2.0)(typescript@4.9.5):
+ /@typechain/ethers-v5@7.2.0(@ethersproject/abi@5.7.0)(@ethersproject/bytes@5.7.0)(@ethersproject/providers@5.7.2)(ethers@5.6.1)(typechain@8.2.0)(typescript@5.2.2):
resolution: {integrity: sha512-jfcmlTvaaJjng63QsT49MT6R1HFhtO/TBMWbyzPFSzMmVIqb2tL6prnKBs4ZJrSvmgIXWy+ttSjpaxCTq8D/Tw==}
peerDependencies:
'@ethersproject/abi': ^5.0.0
@@ -1754,17 +1839,17 @@ packages:
typechain: ^5.0.0
typescript: '>=4.0.0'
dependencies:
- '@ethersproject/abi': 5.6.1
+ '@ethersproject/abi': 5.7.0
'@ethersproject/bytes': 5.7.0
- '@ethersproject/providers': 5.6.1
+ '@ethersproject/providers': 5.7.2
ethers: 5.6.1
lodash: 4.17.21
- ts-essentials: 7.0.3(typescript@4.9.5)
- typechain: 8.2.0(typescript@4.9.5)
- typescript: 4.9.5
+ ts-essentials: 7.0.3(typescript@5.2.2)
+ typechain: 8.2.0(typescript@5.2.2)
+ typescript: 5.2.2
dev: true
- /@typechain/hardhat@3.1.0(hardhat@2.12.7)(lodash@4.17.21)(typechain@8.2.0):
+ /@typechain/hardhat@3.1.0(hardhat@2.17.3)(lodash@4.17.21)(typechain@8.2.0):
resolution: {integrity: sha512-C6Be6l+vTpao19PvMH2CB/lhL1TRLkhdPkvQCF/zqkY1e+0iqY2Bb9Jd3PTt6I8QvMm89ZDerrCJC9927ZHmlg==}
peerDependencies:
hardhat: ^2.0.10
@@ -1772,25 +1857,21 @@ packages:
typechain: ^6.0.0
dependencies:
fs-extra: 9.1.0
- hardhat: 2.12.7(ts-node@10.0.0)(typescript@4.9.5)
+ hardhat: 2.17.3(ts-node@10.9.1)(typescript@5.2.2)
lodash: 4.17.21
- typechain: 8.2.0(typescript@4.9.5)
- dev: true
-
- /@types/async-eventemitter@0.2.1:
- resolution: {integrity: sha512-M2P4Ng26QbAeITiH7w1d7OxtldgfAe0wobpyJzVK/XOb0cUGKU2R4pfAhqcJBXAe2ife5ZOhSv4wk7p+ffURtg==}
+ typechain: 8.2.0(typescript@5.2.2)
dev: true
/@types/bn.js@4.11.6:
resolution: {integrity: sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==}
dependencies:
- '@types/node': 15.14.9
+ '@types/node': 16.18.52
dev: true
/@types/bn.js@5.1.1:
resolution: {integrity: sha512-qNrYbZqMx0uJAfKnKclPh+dTwK33KfLHYqtyODwd5HnXOjnkhc4qgn3BrK6RWyGZm5+sIFE7Q7Vz6QQtJB7w7g==}
dependencies:
- '@types/node': 15.14.9
+ '@types/node': 16.18.52
dev: true
/@types/cacheable-request@6.0.2:
@@ -1798,28 +1879,28 @@ packages:
dependencies:
'@types/http-cache-semantics': 4.0.1
'@types/keyv': 3.1.4
- '@types/node': 15.14.9
+ '@types/node': 16.18.52
'@types/responselike': 1.0.0
dev: true
/@types/cbor@5.0.1:
resolution: {integrity: sha512-zVqJy2KzusZPLOgyGJDnOIbu3DxIGGqxYbEwtEEe4Z+la8jwIhOyb+GMrlHafs5tvKruwf8f8qOYP6zTvse/pw==}
dependencies:
- '@types/node': 15.14.9
+ '@types/node': 16.18.52
dev: true
- /@types/chai@4.3.3:
- resolution: {integrity: sha512-hC7OMnszpxhZPduX+m+nrx+uFoLkWOMiR4oa/AZF3MuSETYTZmFfJAHqZEM8MVlvfG7BEUcgvtwoCTxBp6hm3g==}
+ /@types/chai@4.3.6:
+ resolution: {integrity: sha512-VOVRLM1mBxIRxydiViqPcKn6MIxZytrbMpd6RJLIWKxUNr3zux8no0Oc7kJx0WAPIitgZ0gkrDS+btlqQpubpw==}
dev: true
/@types/concat-stream@1.6.1:
resolution: {integrity: sha512-eHE4cQPoj6ngxBZMvVf6Hw7Mh4jMW4U9lpGmS5GBPB9RYxlFg+CHaVN7ErNY4W9XfLIEn20b4VDYaIrbq0q4uA==}
dependencies:
- '@types/node': 15.14.9
+ '@types/node': 16.18.52
dev: true
- /@types/debug@4.1.7:
- resolution: {integrity: sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg==}
+ /@types/debug@4.1.8:
+ resolution: {integrity: sha512-/vPO1EPOs306Cvhwv7KfVfYvOJqA/S/AXjaHQiJboCZzcNDb+TIJFN9/2C9DZ//ijSKWioNyUxD792QmDJ+HKQ==}
dependencies:
'@types/ms': 0.7.31
dev: true
@@ -1835,7 +1916,7 @@ packages:
/@types/form-data@0.0.33:
resolution: {integrity: sha512-8BSvG1kGm83cyJITQMZSulnl6QV8jqAGreJsc5tPu1Jq0vTSOiY/k24Wx82JRpWwZSqrala6sd5rWi6aNXvqcw==}
dependencies:
- '@types/node': 15.14.9
+ '@types/node': 16.18.52
dev: true
/@types/glob@7.1.1:
@@ -1843,21 +1924,21 @@ packages:
dependencies:
'@types/events': 3.0.0
'@types/minimatch': 3.0.3
- '@types/node': 15.14.9
+ '@types/node': 16.18.52
dev: true
/@types/http-cache-semantics@4.0.1:
resolution: {integrity: sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==}
dev: true
- /@types/json-schema@7.0.11:
- resolution: {integrity: sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==}
+ /@types/json-schema@7.0.12:
+ resolution: {integrity: sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==}
dev: true
/@types/keyv@3.1.4:
resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==}
dependencies:
- '@types/node': 15.14.9
+ '@types/node': 16.18.52
dev: true
/@types/lru-cache@5.1.1:
@@ -1871,11 +1952,11 @@ packages:
/@types/mkdirp@0.5.2:
resolution: {integrity: sha512-U5icWpv7YnZYGsN4/cmh3WD2onMY0aJIiTE6+51TwJCttdHvtCYmkBNOobHlXwrJRL0nkH9jH4kD+1FAdMN4Tg==}
dependencies:
- '@types/node': 15.14.9
+ '@types/node': 16.18.52
dev: true
- /@types/mocha@8.2.2:
- resolution: {integrity: sha512-Lwh0lzzqT5Pqh6z61P3c3P5nm6fzQK/MMHl9UKeneAeInVflBSz1O2EkX6gM6xfJd7FBXBY5purtLx7fUiZ7Hw==}
+ /@types/mocha@10.0.1:
+ resolution: {integrity: sha512-/fvYntiO1GeICvqbQ3doGDIP97vWmvFt83GKguJ6prmQM2iXZfFcq6YE8KteFyRtX2/h5Hf91BYvPodJKFYv5Q==}
dev: true
/@types/ms@0.7.31:
@@ -1885,7 +1966,7 @@ packages:
/@types/node-fetch@2.6.2:
resolution: {integrity: sha512-DHqhlq5jeESLy19TYhLakJ07kNumXWjcDdxXsLUMJZ6ue8VZJj4kLPQVE/2mdHh3xZziNF1xppu5lwmS53HR+A==}
dependencies:
- '@types/node': 15.14.9
+ '@types/node': 16.18.52
form-data: 3.0.1
dev: true
@@ -1897,8 +1978,8 @@ packages:
resolution: {integrity: sha512-7xHmXm/QJ7cbK2laF+YYD7gb5MggHIIQwqyjin3bpEGiSuvScMQ5JZZXPvRipi1MwckTQbJZROMns/JxdnIL1Q==}
dev: true
- /@types/node@15.14.9:
- resolution: {integrity: sha512-qjd88DrCxupx/kJD5yQgZdcYKZKSIGBVDIBE1/LTGcNm3d2Np/jxojkdePDdfnBHJc5W7vSMpbJ1aB7p/Py69A==}
+ /@types/node@16.18.52:
+ resolution: {integrity: sha512-sm2aph6cRSsTMFYFgI+RpPLunXO9ClJkpizUVdT7KmGeyfQ14xnjTMT/f3MHcfKqevXqGT6BgVFzW8wcEoDUtA==}
dev: true
/@types/node@8.10.66:
@@ -1908,7 +1989,7 @@ packages:
/@types/pbkdf2@3.1.0:
resolution: {integrity: sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==}
dependencies:
- '@types/node': 15.14.9
+ '@types/node': 16.18.52
dev: true
/@types/prettier@2.7.1:
@@ -1919,22 +2000,29 @@ packages:
resolution: {integrity: sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==}
dev: true
+ /@types/readable-stream@2.3.15:
+ resolution: {integrity: sha512-oM5JSKQCcICF1wvGgmecmHldZ48OZamtMxcGGVICOJA8o8cahXC1zEVAif8iwoc5j8etxFaRFnf095+CDsuoFQ==}
+ dependencies:
+ '@types/node': 16.18.52
+ safe-buffer: 5.1.2
+ dev: true
+
/@types/resolve@0.0.8:
resolution: {integrity: sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ==}
dependencies:
- '@types/node': 15.14.9
+ '@types/node': 16.18.52
dev: true
/@types/responselike@1.0.0:
resolution: {integrity: sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==}
dependencies:
- '@types/node': 15.14.9
+ '@types/node': 16.18.52
dev: true
/@types/secp256k1@4.0.3:
resolution: {integrity: sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w==}
dependencies:
- '@types/node': 15.14.9
+ '@types/node': 16.18.52
dev: true
/@types/semver@7.5.0:
@@ -1944,7 +2032,7 @@ packages:
/@types/sinon-chai@3.2.8:
resolution: {integrity: sha512-d4ImIQbT/rKMG8+AXpmcan5T2/PNeSjrYhvkwet6z0p8kzYtfgA32xzOBlbU0yqJfq+/0Ml805iFoODO0LP5/g==}
dependencies:
- '@types/chai': 4.3.3
+ '@types/chai': 4.3.6
'@types/sinon': 10.0.13
dev: true
@@ -1969,134 +2057,135 @@ packages:
'@types/underscore': 1.11.4
dev: true
- /@typescript-eslint/eslint-plugin@5.59.8(@typescript-eslint/parser@5.59.8)(eslint@8.42.0)(typescript@4.9.5):
- resolution: {integrity: sha512-JDMOmhXteJ4WVKOiHXGCoB96ADWg9q7efPWHRViT/f09bA8XOMLAVHHju3l0MkZnG1izaWXYmgvQcUjTRcpShQ==}
- engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ /@typescript-eslint/eslint-plugin@6.7.0(@typescript-eslint/parser@6.7.0)(eslint@8.49.0)(typescript@5.2.2):
+ resolution: {integrity: sha512-gUqtknHm0TDs1LhY12K2NA3Rmlmp88jK9Tx8vGZMfHeNMLE3GH2e9TRub+y+SOjuYgtOmok+wt1AyDPZqxbNag==}
+ engines: {node: ^16.0.0 || >=18.0.0}
peerDependencies:
- '@typescript-eslint/parser': ^5.0.0
- eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
+ '@typescript-eslint/parser': ^6.0.0 || ^6.0.0-alpha
+ eslint: ^7.0.0 || ^8.0.0
typescript: '*'
peerDependenciesMeta:
typescript:
optional: true
dependencies:
- '@eslint-community/regexpp': 4.5.1
- '@typescript-eslint/parser': 5.59.8(eslint@8.42.0)(typescript@4.9.5)
- '@typescript-eslint/scope-manager': 5.59.8
- '@typescript-eslint/type-utils': 5.59.8(eslint@8.42.0)(typescript@4.9.5)
- '@typescript-eslint/utils': 5.59.8(eslint@8.42.0)(typescript@4.9.5)
+ '@eslint-community/regexpp': 4.8.0
+ '@typescript-eslint/parser': 6.7.0(eslint@8.49.0)(typescript@5.2.2)
+ '@typescript-eslint/scope-manager': 6.7.0
+ '@typescript-eslint/type-utils': 6.7.0(eslint@8.49.0)(typescript@5.2.2)
+ '@typescript-eslint/utils': 6.7.0(eslint@8.49.0)(typescript@5.2.2)
+ '@typescript-eslint/visitor-keys': 6.7.0
debug: 4.3.4(supports-color@8.1.1)
- eslint: 8.42.0
- grapheme-splitter: 1.0.4
+ eslint: 8.49.0
+ graphemer: 1.4.0
ignore: 5.2.4
- natural-compare-lite: 1.4.0
- semver: 7.5.0
- tsutils: 3.21.0(typescript@4.9.5)
- typescript: 4.9.5
+ natural-compare: 1.4.0
+ semver: 7.5.4
+ ts-api-utils: 1.0.3(typescript@5.2.2)
+ typescript: 5.2.2
transitivePeerDependencies:
- supports-color
dev: true
- /@typescript-eslint/parser@5.59.8(eslint@8.42.0)(typescript@4.9.5):
- resolution: {integrity: sha512-AnR19RjJcpjoeGojmwZtCwBX/RidqDZtzcbG3xHrmz0aHHoOcbWnpDllenRDmDvsV0RQ6+tbb09/kyc+UT9Orw==}
- engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ /@typescript-eslint/parser@6.7.0(eslint@8.49.0)(typescript@5.2.2):
+ resolution: {integrity: sha512-jZKYwqNpNm5kzPVP5z1JXAuxjtl2uG+5NpaMocFPTNC2EdYIgbXIPImObOkhbONxtFTTdoZstLZefbaK+wXZng==}
+ engines: {node: ^16.0.0 || >=18.0.0}
peerDependencies:
- eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
+ eslint: ^7.0.0 || ^8.0.0
typescript: '*'
peerDependenciesMeta:
typescript:
optional: true
dependencies:
- '@typescript-eslint/scope-manager': 5.59.8
- '@typescript-eslint/types': 5.59.8
- '@typescript-eslint/typescript-estree': 5.59.8(typescript@4.9.5)
+ '@typescript-eslint/scope-manager': 6.7.0
+ '@typescript-eslint/types': 6.7.0
+ '@typescript-eslint/typescript-estree': 6.7.0(typescript@5.2.2)
+ '@typescript-eslint/visitor-keys': 6.7.0
debug: 4.3.4(supports-color@8.1.1)
- eslint: 8.42.0
- typescript: 4.9.5
+ eslint: 8.49.0
+ typescript: 5.2.2
transitivePeerDependencies:
- supports-color
dev: true
- /@typescript-eslint/scope-manager@5.59.8:
- resolution: {integrity: sha512-/w08ndCYI8gxGf+9zKf1vtx/16y8MHrZs5/tnjHhMLNSixuNcJavSX4wAiPf4aS5x41Es9YPCn44MIe4cxIlig==}
- engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ /@typescript-eslint/scope-manager@6.7.0:
+ resolution: {integrity: sha512-lAT1Uau20lQyjoLUQ5FUMSX/dS07qux9rYd5FGzKz/Kf8W8ccuvMyldb8hadHdK/qOI7aikvQWqulnEq2nCEYA==}
+ engines: {node: ^16.0.0 || >=18.0.0}
dependencies:
- '@typescript-eslint/types': 5.59.8
- '@typescript-eslint/visitor-keys': 5.59.8
+ '@typescript-eslint/types': 6.7.0
+ '@typescript-eslint/visitor-keys': 6.7.0
dev: true
- /@typescript-eslint/type-utils@5.59.8(eslint@8.42.0)(typescript@4.9.5):
- resolution: {integrity: sha512-+5M518uEIHFBy3FnyqZUF3BMP+AXnYn4oyH8RF012+e7/msMY98FhGL5SrN29NQ9xDgvqCgYnsOiKp1VjZ/fpA==}
- engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ /@typescript-eslint/type-utils@6.7.0(eslint@8.49.0)(typescript@5.2.2):
+ resolution: {integrity: sha512-f/QabJgDAlpSz3qduCyQT0Fw7hHpmhOzY/Rv6zO3yO+HVIdPfIWhrQoAyG+uZVtWAIS85zAyzgAFfyEr+MgBpg==}
+ engines: {node: ^16.0.0 || >=18.0.0}
peerDependencies:
- eslint: '*'
+ eslint: ^7.0.0 || ^8.0.0
typescript: '*'
peerDependenciesMeta:
typescript:
optional: true
dependencies:
- '@typescript-eslint/typescript-estree': 5.59.8(typescript@4.9.5)
- '@typescript-eslint/utils': 5.59.8(eslint@8.42.0)(typescript@4.9.5)
+ '@typescript-eslint/typescript-estree': 6.7.0(typescript@5.2.2)
+ '@typescript-eslint/utils': 6.7.0(eslint@8.49.0)(typescript@5.2.2)
debug: 4.3.4(supports-color@8.1.1)
- eslint: 8.42.0
- tsutils: 3.21.0(typescript@4.9.5)
- typescript: 4.9.5
+ eslint: 8.49.0
+ ts-api-utils: 1.0.3(typescript@5.2.2)
+ typescript: 5.2.2
transitivePeerDependencies:
- supports-color
dev: true
- /@typescript-eslint/types@5.59.8:
- resolution: {integrity: sha512-+uWuOhBTj/L6awoWIg0BlWy0u9TyFpCHrAuQ5bNfxDaZ1Ppb3mx6tUigc74LHcbHpOHuOTOJrBoAnhdHdaea1w==}
- engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ /@typescript-eslint/types@6.7.0:
+ resolution: {integrity: sha512-ihPfvOp7pOcN/ysoj0RpBPOx3HQTJTrIN8UZK+WFd3/iDeFHHqeyYxa4hQk4rMhsz9H9mXpR61IzwlBVGXtl9Q==}
+ engines: {node: ^16.0.0 || >=18.0.0}
dev: true
- /@typescript-eslint/typescript-estree@5.59.8(typescript@4.9.5):
- resolution: {integrity: sha512-Jy/lPSDJGNow14vYu6IrW790p7HIf/SOV1Bb6lZ7NUkLc2iB2Z9elESmsaUtLw8kVqogSbtLH9tut5GCX1RLDg==}
- engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ /@typescript-eslint/typescript-estree@6.7.0(typescript@5.2.2):
+ resolution: {integrity: sha512-dPvkXj3n6e9yd/0LfojNU8VMUGHWiLuBZvbM6V6QYD+2qxqInE7J+J/ieY2iGwR9ivf/R/haWGkIj04WVUeiSQ==}
+ engines: {node: ^16.0.0 || >=18.0.0}
peerDependencies:
typescript: '*'
peerDependenciesMeta:
typescript:
optional: true
dependencies:
- '@typescript-eslint/types': 5.59.8
- '@typescript-eslint/visitor-keys': 5.59.8
+ '@typescript-eslint/types': 6.7.0
+ '@typescript-eslint/visitor-keys': 6.7.0
debug: 4.3.4(supports-color@8.1.1)
globby: 11.1.0
is-glob: 4.0.3
- semver: 7.5.0
- tsutils: 3.21.0(typescript@4.9.5)
- typescript: 4.9.5
+ semver: 7.5.4
+ ts-api-utils: 1.0.3(typescript@5.2.2)
+ typescript: 5.2.2
transitivePeerDependencies:
- supports-color
dev: true
- /@typescript-eslint/utils@5.59.8(eslint@8.42.0)(typescript@4.9.5):
- resolution: {integrity: sha512-Tr65630KysnNn9f9G7ROF3w1b5/7f6QVCJ+WK9nhIocWmx9F+TmCAcglF26Vm7z8KCTwoKcNEBZrhlklla3CKg==}
- engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ /@typescript-eslint/utils@6.7.0(eslint@8.49.0)(typescript@5.2.2):
+ resolution: {integrity: sha512-MfCq3cM0vh2slSikQYqK2Gq52gvOhe57vD2RM3V4gQRZYX4rDPnKLu5p6cm89+LJiGlwEXU8hkYxhqqEC/V3qA==}
+ engines: {node: ^16.0.0 || >=18.0.0}
peerDependencies:
- eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
+ eslint: ^7.0.0 || ^8.0.0
dependencies:
- '@eslint-community/eslint-utils': 4.4.0(eslint@8.42.0)
- '@types/json-schema': 7.0.11
+ '@eslint-community/eslint-utils': 4.4.0(eslint@8.49.0)
+ '@types/json-schema': 7.0.12
'@types/semver': 7.5.0
- '@typescript-eslint/scope-manager': 5.59.8
- '@typescript-eslint/types': 5.59.8
- '@typescript-eslint/typescript-estree': 5.59.8(typescript@4.9.5)
- eslint: 8.42.0
- eslint-scope: 5.1.1
- semver: 7.5.0
+ '@typescript-eslint/scope-manager': 6.7.0
+ '@typescript-eslint/types': 6.7.0
+ '@typescript-eslint/typescript-estree': 6.7.0(typescript@5.2.2)
+ eslint: 8.49.0
+ semver: 7.5.4
transitivePeerDependencies:
- supports-color
- typescript
dev: true
- /@typescript-eslint/visitor-keys@5.59.8:
- resolution: {integrity: sha512-pJhi2ms0x0xgloT7xYabil3SGGlojNNKjK/q6dB3Ey0uJLMjK2UDGJvHieiyJVW/7C3KI+Z4Q3pEHkm4ejA+xQ==}
- engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ /@typescript-eslint/visitor-keys@6.7.0:
+ resolution: {integrity: sha512-/C1RVgKFDmGMcVGeD8HjKv2bd72oI1KxQDeY8uc66gw9R0OK0eMq48cA+jv9/2Ag6cdrsUGySm1yzYmfz0hxwQ==}
+ engines: {node: ^16.0.0 || >=18.0.0}
dependencies:
- '@typescript-eslint/types': 5.59.8
- eslint-visitor-keys: 3.4.1
+ '@typescript-eslint/types': 6.7.0
+ eslint-visitor-keys: 3.4.3
dev: true
/@yarnpkg/lockfile@1.1.0:
@@ -2129,13 +2218,6 @@ packages:
- supports-color
dev: true
- /abort-controller@3.0.0:
- resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==}
- engines: {node: '>=6.5'}
- dependencies:
- event-target-shim: 5.0.1
- dev: true
-
/abortcontroller-polyfill@1.7.3:
resolution: {integrity: sha512-zetDJxd89y3X99Kvo4qFx8GKlt6GsvN3UcRZHwU6iFA/0KiOmhkTVhe8oRoTBiTVPZu09x3vCra47+w8Yz1+2Q==}
dev: true
@@ -2187,16 +2269,21 @@ packages:
negotiator: 0.6.2
dev: true
- /acorn-jsx@5.3.2(acorn@8.8.0):
+ /acorn-jsx@5.3.2(acorn@8.10.0):
resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
peerDependencies:
acorn: ^6.0.0 || ^7.0.0 || ^8.0.0
dependencies:
- acorn: 8.8.0
+ acorn: 8.10.0
dev: true
- /acorn@8.8.0:
- resolution: {integrity: sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==}
+ /acorn-walk@8.2.0:
+ resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==}
+ engines: {node: '>=0.4.0'}
+ dev: true
+
+ /acorn@8.10.0:
+ resolution: {integrity: sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==}
engines: {node: '>=0.4.0'}
hasBin: true
dev: true
@@ -3109,6 +3196,11 @@ packages:
engines: {node: '>=0.6'}
dev: true
+ /big-integer@1.6.51:
+ resolution: {integrity: sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==}
+ engines: {node: '>=0.6'}
+ dev: true
+
/big.js@6.2.1:
resolution: {integrity: sha512-bCtHMwL9LeDIozFn+oNhhFoq+yQ3BNdnsLSASUxLciOb1vgvpHsIO1dsENiGMgbb4SkP5TrzWzRiLddn8ahVOQ==}
dev: true
@@ -3200,6 +3292,13 @@ packages:
resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==}
dev: true
+ /bplist-parser@0.2.0:
+ resolution: {integrity: sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw==}
+ engines: {node: '>= 5.10.0'}
+ dependencies:
+ big-integer: 1.6.51
+ dev: true
+
/brace-expansion@1.1.11:
resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==}
dependencies:
@@ -3375,6 +3474,13 @@ packages:
engines: {node: '>=8.0.0'}
dev: false
+ /bundle-name@3.0.0:
+ resolution: {integrity: sha512-PKA4BeSvBpQKQ8iPOGCSiell+N8P+Tf1DlwqmYhpe2gAhKPHn8EYOxVT+ShuGmhg8lN8XiSlS80yiExKXrURlw==}
+ engines: {node: '>=12'}
+ dependencies:
+ run-applescript: 5.0.0
+ dev: true
+
/busboy@1.6.0:
resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==}
engines: {node: '>=10.16.0'}
@@ -3502,6 +3608,11 @@ packages:
resolution: {integrity: sha512-t55jfSaWjCdocnFdKQoO+d2ct9C59UZg4dY3OnUlSZ447r8pUtIKdp0hpAzrGFultmTC+Us+KpKi4GZl/LXlFg==}
dev: true
+ /case@1.6.3:
+ resolution: {integrity: sha512-mzDSXIPaFwVDvZAHqZ9VlbyF4yyXRuX6IvB06WvPYkqJVO24kX1PPhv9bfpKNFZyxYFmmgo03HUiD8iklmJYRQ==}
+ engines: {node: '>= 0.8.0'}
+ dev: true
+
/caseless@0.12.0:
resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==}
dev: true
@@ -3526,23 +3637,23 @@ packages:
nofilter: 3.1.0
dev: true
- /chai-bn@0.2.2(bn.js@4.12.0)(chai@4.3.6):
+ /chai-bn@0.2.2(bn.js@4.12.0)(chai@4.3.8):
resolution: {integrity: sha512-MzjelH0p8vWn65QKmEq/DLBG1Hle4WeyqT79ANhXZhn/UxRWO0OogkAxi5oGGtfzwU9bZR8mvbvYdoqNVWQwFg==}
peerDependencies:
bn.js: ^4.11.0
chai: ^4.0.0
dependencies:
bn.js: 4.12.0
- chai: 4.3.6
+ chai: 4.3.8
dev: true
- /chai@4.3.6:
- resolution: {integrity: sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q==}
+ /chai@4.3.8:
+ resolution: {integrity: sha512-vX4YvVVtxlfSZ2VecZgFUTU5qPCYsobVI2O9FmwEXBhDigYGQA6jRXCycIs1yJnnWbZ6/+a2zNIF5DfVCcJBFQ==}
engines: {node: '>=4'}
dependencies:
assertion-error: 1.1.0
check-error: 1.0.2
- deep-eql: 3.0.1
+ deep-eql: 4.1.3
get-func-name: 2.0.0
loupe: 2.3.4
pathval: 1.1.1
@@ -3880,7 +3991,7 @@ packages:
dev: true
/concat-map@0.0.1:
- resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
+ resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=}
dev: true
/concat-stream@1.6.2:
@@ -4209,9 +4320,9 @@ packages:
mimic-response: 3.1.0
dev: true
- /deep-eql@3.0.1:
- resolution: {integrity: sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==}
- engines: {node: '>=0.12'}
+ /deep-eql@4.1.3:
+ resolution: {integrity: sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==}
+ engines: {node: '>=6'}
dependencies:
type-detect: 4.0.8
@@ -4242,6 +4353,24 @@ packages:
resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
dev: true
+ /default-browser-id@3.0.0:
+ resolution: {integrity: sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA==}
+ engines: {node: '>=12'}
+ dependencies:
+ bplist-parser: 0.2.0
+ untildify: 4.0.0
+ dev: true
+
+ /default-browser@4.0.0:
+ resolution: {integrity: sha512-wX5pXO1+BrhMkSbROFsyxUm0i/cJEScyNhA4PPxc41ICuv05ZZB/MX28s8aZx6xjmatvebIapF6hLEKEcpneUA==}
+ engines: {node: '>=14.16'}
+ dependencies:
+ bundle-name: 3.0.0
+ default-browser-id: 3.0.0
+ execa: 7.2.0
+ titleize: 3.0.0
+ dev: true
+
/defer-to-connect@1.1.1:
resolution: {integrity: sha512-J7thop4u3mRTkYRQ+Vpfwy2G5Ehoy82I14+14W4YMDLKdWloI9gSzRbV30s/NckQGVJtPkWNcW4oMAUigTdqiQ==}
requiresBuild: true
@@ -4266,6 +4395,11 @@ packages:
inherits: 2.0.4
dev: true
+ /define-lazy-prop@3.0.0:
+ resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==}
+ engines: {node: '>=12'}
+ dev: true
+
/define-properties@1.1.4:
resolution: {integrity: sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==}
engines: {node: '>= 0.4'}
@@ -4645,63 +4779,59 @@ packages:
source-map: 0.2.0
dev: true
- /eslint-config-prettier@8.8.0(eslint@8.42.0):
- resolution: {integrity: sha512-wLbQiFre3tdGgpDv67NQKnJuTlcUVYHas3k+DZCc2U2BadthoEY4B7hLPvAxaqdyOGCzuLfii2fqGph10va7oA==}
+ /eslint-config-prettier@9.0.0(eslint@8.49.0):
+ resolution: {integrity: sha512-IcJsTkJae2S35pRsRAwoCE+925rJJStOdkKnLVgtE+tEpqU0EVVM7OqrwxqgptKdX29NUwC82I5pXsGFIgSevw==}
hasBin: true
peerDependencies:
eslint: '>=7.0.0'
dependencies:
- eslint: 8.42.0
+ eslint: 8.49.0
dev: true
- /eslint-plugin-prettier@4.2.1(eslint-config-prettier@8.8.0)(eslint@8.42.0)(prettier@2.8.8):
- resolution: {integrity: sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==}
- engines: {node: '>=12.0.0'}
+ /eslint-plugin-prettier@5.0.0(eslint-config-prettier@9.0.0)(eslint@8.49.0)(prettier@3.0.3):
+ resolution: {integrity: sha512-AgaZCVuYDXHUGxj/ZGu1u8H8CYgDY3iG6w5kUFw4AzMVXzB7VvbKgYR4nATIN+OvUrghMbiDLeimVjVY5ilq3w==}
+ engines: {node: ^14.18.0 || >=16.0.0}
peerDependencies:
- eslint: '>=7.28.0'
+ '@types/eslint': '>=8.0.0'
+ eslint: '>=8.0.0'
eslint-config-prettier: '*'
- prettier: '>=2.0.0'
+ prettier: '>=3.0.0'
peerDependenciesMeta:
+ '@types/eslint':
+ optional: true
eslint-config-prettier:
optional: true
dependencies:
- eslint: 8.42.0
- eslint-config-prettier: 8.8.0(eslint@8.42.0)
- prettier: 2.8.8
+ eslint: 8.49.0
+ eslint-config-prettier: 9.0.0(eslint@8.49.0)
+ prettier: 3.0.3
prettier-linter-helpers: 1.0.0
+ synckit: 0.8.5
dev: true
- /eslint-scope@5.1.1:
- resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==}
- engines: {node: '>=8.0.0'}
- dependencies:
- esrecurse: 4.3.0
- estraverse: 4.3.0
- dev: true
-
- /eslint-scope@7.2.0:
- resolution: {integrity: sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==}
+ /eslint-scope@7.2.2:
+ resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
dependencies:
esrecurse: 4.3.0
estraverse: 5.3.0
dev: true
- /eslint-visitor-keys@3.4.1:
- resolution: {integrity: sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==}
+ /eslint-visitor-keys@3.4.3:
+ resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
dev: true
- /eslint@8.42.0:
- resolution: {integrity: sha512-ulg9Ms6E1WPf67PHaEY4/6E2tEn5/f7FXGzr3t9cBMugOmf1INYvuUwwh1aXQN4MfJ6a5K2iNwP3w4AColvI9A==}
+ /eslint@8.49.0:
+ resolution: {integrity: sha512-jw03ENfm6VJI0jA9U+8H5zfl5b+FvuU3YYvZRdZHOlU2ggJkxrlkJH4HcDrZpj6YwD8kuYqvQM8LyesoazrSOQ==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
hasBin: true
dependencies:
- '@eslint-community/eslint-utils': 4.4.0(eslint@8.42.0)
- '@eslint-community/regexpp': 4.5.1
- '@eslint/eslintrc': 2.0.3
- '@eslint/js': 8.42.0
- '@humanwhocodes/config-array': 0.11.10
+ '@eslint-community/eslint-utils': 4.4.0(eslint@8.49.0)
+ '@eslint-community/regexpp': 4.8.0
+ '@eslint/eslintrc': 2.1.2
+ '@eslint/js': 8.49.0
+ '@humanwhocodes/config-array': 0.11.11
'@humanwhocodes/module-importer': 1.0.1
'@nodelib/fs.walk': 1.2.8
ajv: 6.12.6
@@ -4710,9 +4840,9 @@ packages:
debug: 4.3.4(supports-color@8.1.1)
doctrine: 3.0.0
escape-string-regexp: 4.0.0
- eslint-scope: 7.2.0
- eslint-visitor-keys: 3.4.1
- espree: 9.5.2
+ eslint-scope: 7.2.2
+ eslint-visitor-keys: 3.4.3
+ espree: 9.6.1
esquery: 1.5.0
esutils: 2.0.3
fast-deep-equal: 3.1.3
@@ -4721,8 +4851,7 @@ packages:
glob-parent: 6.0.2
globals: 13.20.0
graphemer: 1.4.0
- ignore: 5.2.0
- import-fresh: 3.3.0
+ ignore: 5.2.4
imurmurhash: 0.1.4
is-glob: 4.0.3
is-path-inside: 3.0.3
@@ -4732,21 +4861,20 @@ packages:
lodash.merge: 4.6.2
minimatch: 3.1.2
natural-compare: 1.4.0
- optionator: 0.9.1
+ optionator: 0.9.3
strip-ansi: 6.0.1
- strip-json-comments: 3.1.1
text-table: 0.2.0
transitivePeerDependencies:
- supports-color
dev: true
- /espree@9.5.2:
- resolution: {integrity: sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw==}
+ /espree@9.6.1:
+ resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
dependencies:
- acorn: 8.8.0
- acorn-jsx: 5.3.2(acorn@8.8.0)
- eslint-visitor-keys: 3.4.1
+ acorn: 8.10.0
+ acorn-jsx: 5.3.2(acorn@8.10.0)
+ eslint-visitor-keys: 3.4.3
dev: true
/esprima@2.7.3:
@@ -4780,11 +4908,6 @@ packages:
engines: {node: '>=0.10.0'}
dev: true
- /estraverse@4.3.0:
- resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==}
- engines: {node: '>=4.0'}
- dev: true
-
/estraverse@5.3.0:
resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==}
engines: {node: '>=4.0'}
@@ -4996,13 +5119,13 @@ packages:
'@scure/bip39': 1.1.0
dev: true
- /ethereum-waffle@3.3.0(typescript@4.9.5):
+ /ethereum-waffle@3.3.0(typescript@5.2.2):
resolution: {integrity: sha512-4xm3RWAPCu5LlaVxYEg0tG3L7g5ovBw1GY/UebrzZ+OTx22vcPjI+bvelFlGBpkdnO5yOIFXjH2eK59tNAe9IA==}
engines: {node: '>=10.0'}
hasBin: true
dependencies:
'@ethereum-waffle/chai': 3.4.4
- '@ethereum-waffle/compiler': 3.4.4(typescript@4.9.5)
+ '@ethereum-waffle/compiler': 3.4.4(typescript@5.2.2)
'@ethereum-waffle/mock-contract': 3.4.4
'@ethereum-waffle/provider': 3.4.4
ethers: 5.6.1
@@ -5254,6 +5377,44 @@ packages:
- bufferutil
- utf-8-validate
+ /ethers@5.7.2:
+ resolution: {integrity: sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg==}
+ dependencies:
+ '@ethersproject/abi': 5.7.0
+ '@ethersproject/abstract-provider': 5.7.0
+ '@ethersproject/abstract-signer': 5.7.0
+ '@ethersproject/address': 5.7.0
+ '@ethersproject/base64': 5.7.0
+ '@ethersproject/basex': 5.7.0
+ '@ethersproject/bignumber': 5.7.0
+ '@ethersproject/bytes': 5.7.0
+ '@ethersproject/constants': 5.7.0
+ '@ethersproject/contracts': 5.7.0
+ '@ethersproject/hash': 5.7.0
+ '@ethersproject/hdnode': 5.7.0
+ '@ethersproject/json-wallets': 5.7.0
+ '@ethersproject/keccak256': 5.7.0
+ '@ethersproject/logger': 5.0.6
+ '@ethersproject/networks': 5.7.1
+ '@ethersproject/pbkdf2': 5.7.0
+ '@ethersproject/properties': 5.7.0
+ '@ethersproject/providers': 5.7.2
+ '@ethersproject/random': 5.7.0
+ '@ethersproject/rlp': 5.7.0
+ '@ethersproject/sha2': 5.7.0
+ '@ethersproject/signing-key': 5.7.0
+ '@ethersproject/solidity': 5.7.0
+ '@ethersproject/strings': 5.7.0
+ '@ethersproject/transactions': 5.7.0
+ '@ethersproject/units': 5.7.0
+ '@ethersproject/wallet': 5.7.0
+ '@ethersproject/web': 5.7.1
+ '@ethersproject/wordlists': 5.7.0
+ transitivePeerDependencies:
+ - bufferutil
+ - utf-8-validate
+ dev: true
+
/ethjs-abi@0.2.1:
resolution: {integrity: sha512-g2AULSDYI6nEJyJaEVEXtTimRY2aPC2fi7ddSy0W+LXvEVL8Fe1y76o43ecbgdUKwZD+xsmEgX1yJr1Ia3r1IA==}
engines: {node: '>=6.5.0', npm: '>=3'}
@@ -5279,11 +5440,6 @@ packages:
strip-hex-prefix: 1.0.0
dev: true
- /event-target-shim@5.0.1:
- resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==}
- engines: {node: '>=6'}
- dev: true
-
/eventemitter3@4.0.4:
resolution: {integrity: sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ==}
dev: true
@@ -5300,6 +5456,36 @@ packages:
safe-buffer: 5.2.1
dev: true
+ /execa@5.1.1:
+ resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==}
+ engines: {node: '>=10'}
+ dependencies:
+ cross-spawn: 7.0.3
+ get-stream: 6.0.1
+ human-signals: 2.1.0
+ is-stream: 2.0.1
+ merge-stream: 2.0.0
+ npm-run-path: 4.0.1
+ onetime: 5.1.2
+ signal-exit: 3.0.7
+ strip-final-newline: 2.0.0
+ dev: true
+
+ /execa@7.2.0:
+ resolution: {integrity: sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==}
+ engines: {node: ^14.18.0 || ^16.14.0 || >=18.0.0}
+ dependencies:
+ cross-spawn: 7.0.3
+ get-stream: 6.0.1
+ human-signals: 4.3.1
+ is-stream: 3.0.0
+ merge-stream: 2.0.0
+ npm-run-path: 5.1.0
+ onetime: 6.0.0
+ signal-exit: 3.0.7
+ strip-final-newline: 3.0.0
+ dev: true
+
/expand-brackets@2.1.4:
resolution: {integrity: sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==}
engines: {node: '>=0.10.0'}
@@ -5436,6 +5622,17 @@ packages:
micromatch: 4.0.5
dev: true
+ /fast-glob@3.3.1:
+ resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==}
+ engines: {node: '>=8.6.0'}
+ dependencies:
+ '@nodelib/fs.stat': 2.0.5
+ '@nodelib/fs.walk': 1.2.8
+ glob-parent: 5.1.2
+ merge2: 1.4.1
+ micromatch: 4.0.5
+ dev: true
+
/fast-json-stable-stringify@2.1.0:
resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==}
dev: true
@@ -6023,7 +6220,7 @@ packages:
dependencies:
array-union: 2.1.0
dir-glob: 3.0.1
- fast-glob: 3.2.12
+ fast-glob: 3.3.1
ignore: 5.2.4
merge2: 1.4.1
slash: 3.0.0
@@ -6133,33 +6330,33 @@ packages:
har-schema: 2.0.0
dev: true
- /hardhat-abi-exporter@2.2.1(hardhat@2.12.7):
+ /hardhat-abi-exporter@2.2.1(hardhat@2.17.3):
resolution: {integrity: sha512-Um7+RPvJEj+OqWjPoPKlTTkO1Akr10pqpgMk8Pw2jz2wrGv5XQBGNW5aQgGVDUosYktUIWDaEhcwwFKbFsir9A==}
engines: {node: '>=12.10.0'}
peerDependencies:
hardhat: ^2.0.0
dependencies:
- hardhat: 2.12.7(ts-node@10.0.0)(typescript@4.9.5)
+ hardhat: 2.17.3(ts-node@10.9.1)(typescript@5.2.2)
dev: true
- /hardhat-contract-sizer@2.5.1(hardhat@2.12.7):
+ /hardhat-contract-sizer@2.5.1(hardhat@2.17.3):
resolution: {integrity: sha512-28yRb73e30aBVaZOOHTlHZFIdIasA/iFunIehrUviIJTubvdQjtSiQUo2wexHFtt71mQeMPP8qjw2sdbgatDnQ==}
peerDependencies:
hardhat: ^2.0.0
dependencies:
chalk: 4.1.2
cli-table3: 0.6.3
- hardhat: 2.12.7(ts-node@10.0.0)(typescript@4.9.5)
+ hardhat: 2.17.3(ts-node@10.9.1)(typescript@5.2.2)
dev: true
- /hardhat-gas-reporter@1.0.9(hardhat@2.12.7):
+ /hardhat-gas-reporter@1.0.9(hardhat@2.17.3):
resolution: {integrity: sha512-INN26G3EW43adGKBNzYWOlI3+rlLnasXTwW79YNnUhXPDa+yHESgt639dJEs37gCjhkbNKcRRJnomXEuMFBXJg==}
peerDependencies:
hardhat: ^2.0.2
dependencies:
array-uniq: 1.0.3
eth-gas-reporter: 0.2.25
- hardhat: 2.12.7(ts-node@10.0.0)(typescript@4.9.5)
+ hardhat: 2.17.3(ts-node@10.9.1)(typescript@5.2.2)
sha1: 1.1.1
transitivePeerDependencies:
- '@codechecks/client'
@@ -6173,9 +6370,8 @@ packages:
solidity-comments: 0.0.2
dev: true
- /hardhat@2.12.7(ts-node@10.0.0)(typescript@4.9.5):
- resolution: {integrity: sha512-voWoN6zn5d8BOEaczSyK/1PyfdeOeI3SbGCFb36yCHTJUt6OIqLb+ZDX30VhA1UsYKzLqG7UnWl3fKJUuANc6A==}
- engines: {node: ^14.0.0 || ^16.0.0 || ^18.0.0}
+ /hardhat@2.17.3(ts-node@10.9.1)(typescript@5.2.2):
+ resolution: {integrity: sha512-SFZoYVXW1bWJZrIIKXOA+IgcctfuKXDwENywiYNT2dM3YQc4fXNaTbuk/vpPzHIF50upByx4zW5EqczKYQubsA==}
hasBin: true
peerDependencies:
ts-node: '*'
@@ -6188,21 +6384,20 @@ packages:
dependencies:
'@ethersproject/abi': 5.7.0
'@metamask/eth-sig-util': 4.0.1
- '@nomicfoundation/ethereumjs-block': 4.0.0
- '@nomicfoundation/ethereumjs-blockchain': 6.0.0
- '@nomicfoundation/ethereumjs-common': 3.0.0
- '@nomicfoundation/ethereumjs-evm': 1.0.0
- '@nomicfoundation/ethereumjs-rlp': 4.0.0
- '@nomicfoundation/ethereumjs-statemanager': 1.0.0
- '@nomicfoundation/ethereumjs-trie': 5.0.0
- '@nomicfoundation/ethereumjs-tx': 4.0.0
- '@nomicfoundation/ethereumjs-util': 8.0.0
- '@nomicfoundation/ethereumjs-vm': 6.0.0
+ '@nomicfoundation/ethereumjs-block': 5.0.2
+ '@nomicfoundation/ethereumjs-blockchain': 7.0.2
+ '@nomicfoundation/ethereumjs-common': 4.0.2
+ '@nomicfoundation/ethereumjs-evm': 2.0.2
+ '@nomicfoundation/ethereumjs-rlp': 5.0.2
+ '@nomicfoundation/ethereumjs-statemanager': 2.0.2
+ '@nomicfoundation/ethereumjs-trie': 6.0.2
+ '@nomicfoundation/ethereumjs-tx': 5.0.2
+ '@nomicfoundation/ethereumjs-util': 9.0.2
+ '@nomicfoundation/ethereumjs-vm': 7.0.2
'@nomicfoundation/solidity-analyzer': 0.1.0
'@sentry/node': 5.30.0
'@types/bn.js': 5.1.1
'@types/lru-cache': 5.1.1
- abort-controller: 3.0.0
adm-zip: 0.4.16
aggregate-error: 3.1.0
ansi-escapes: 4.3.2
@@ -6225,16 +6420,15 @@ packages:
mnemonist: 0.38.5
mocha: 10.2.0
p-map: 4.0.0
- qs: 6.11.0
raw-body: 2.5.1
resolve: 1.17.0
semver: 6.3.0
solc: 0.7.3(debug@4.3.4)
source-map-support: 0.5.21
stacktrace-parser: 0.1.10
- ts-node: 10.0.0(@types/node@15.14.9)(typescript@4.9.5)
+ ts-node: 10.9.1(@types/node@16.18.52)(typescript@5.2.2)
tsort: 0.0.1
- typescript: 4.9.5
+ typescript: 5.2.2
undici: 5.19.1
uuid: 8.3.2
ws: 7.5.9
@@ -6494,6 +6688,16 @@ packages:
- supports-color
dev: true
+ /human-signals@2.1.0:
+ resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==}
+ engines: {node: '>=10.17.0'}
+ dev: true
+
+ /human-signals@4.3.1:
+ resolution: {integrity: sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==}
+ engines: {node: '>=14.18.0'}
+ dev: true
+
/iconv-lite@0.4.24:
resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==}
engines: {node: '>=0.10.0'}
@@ -6519,11 +6723,6 @@ packages:
resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==}
dev: true
- /ignore@5.2.0:
- resolution: {integrity: sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==}
- engines: {node: '>= 4'}
- dev: true
-
/ignore@5.2.4:
resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==}
engines: {node: '>= 4'}
@@ -6727,6 +6926,12 @@ packages:
hasBin: true
dev: true
+ /is-docker@3.0.0:
+ resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==}
+ engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+ hasBin: true
+ dev: true
+
/is-extendable@0.1.1:
resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==}
engines: {node: '>=0.10.0'}
@@ -6792,6 +6997,14 @@ packages:
engines: {node: '>=6.5.0', npm: '>=3'}
dev: true
+ /is-inside-container@1.0.0:
+ resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==}
+ engines: {node: '>=14.16'}
+ hasBin: true
+ dependencies:
+ is-docker: 3.0.0
+ dev: true
+
/is-lower-case@1.1.3:
resolution: {integrity: sha512-+5A1e/WJpLLXZEDlgz4G//WYSHyQBD32qa4Jd3Lw06qQlv3fJHnp3YIHjTQSGzHMgzmVKz2ZP3rBxTHkPw/lxA==}
dependencies:
@@ -6872,6 +7085,16 @@ packages:
engines: {node: '>=0.10.0'}
dev: true
+ /is-stream@2.0.1:
+ resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==}
+ engines: {node: '>=8'}
+ dev: true
+
+ /is-stream@3.0.0:
+ resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==}
+ engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+ dev: true
+
/is-string@1.0.7:
resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==}
engines: {node: '>= 0.4'}
@@ -6998,6 +7221,10 @@ packages:
is-object: 1.0.1
dev: true
+ /js-sdsl@4.4.2:
+ resolution: {integrity: sha512-dwXFwByc/ajSV6m5bcKAPwe4yDDF6D614pxmIi5odytzxRlwqF6nwoiCek80Ixc7Cvma5awClxrzFtxCQvcM8w==}
+ dev: true
+
/js-sha3@0.5.5:
resolution: {integrity: sha512-yLLwn44IVeunwjpDVTDZmQeVbB0h+dZpY2eO68B/Zik8hu6dH+rKeLxwua79GGIvW6xr8NBAcrtiUbYrTjEFTA==}
dev: true
@@ -7664,6 +7891,10 @@ packages:
resolution: {integrity: sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==}
dev: true
+ /merge-stream@2.0.0:
+ resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==}
+ dev: true
+
/merge2@1.4.1:
resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
engines: {node: '>= 8'}
@@ -7754,6 +7985,16 @@ packages:
hasBin: true
dev: true
+ /mimic-fn@2.1.0:
+ resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==}
+ engines: {node: '>=6'}
+ dev: true
+
+ /mimic-fn@4.0.0:
+ resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==}
+ engines: {node: '>=12'}
+ dev: true
+
/mimic-response@1.0.1:
resolution: {integrity: sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==}
engines: {node: '>=4'}
@@ -8064,10 +8305,6 @@ packages:
resolution: {integrity: sha512-A0xLykHtARfueITVDernsAWdtIMbOJgKgcluwENp3AlsKN/PloyO10HtmoqnFAQAcxPkgZN7wdfPfEd0zNGxbg==}
dev: true
- /natural-compare-lite@1.4.0:
- resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==}
- dev: true
-
/natural-compare@1.4.0:
resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
dev: true
@@ -8191,6 +8428,20 @@ packages:
engines: {node: '>=10'}
dev: true
+ /npm-run-path@4.0.1:
+ resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==}
+ engines: {node: '>=8'}
+ dependencies:
+ path-key: 3.1.1
+ dev: true
+
+ /npm-run-path@5.1.0:
+ resolution: {integrity: sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==}
+ engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+ dependencies:
+ path-key: 4.0.0
+ dev: true
+
/nth-check@2.1.1:
resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==}
dependencies:
@@ -8324,6 +8575,20 @@ packages:
wrappy: 1.0.2
dev: true
+ /onetime@5.1.2:
+ resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==}
+ engines: {node: '>=6'}
+ dependencies:
+ mimic-fn: 2.1.0
+ dev: true
+
+ /onetime@6.0.0:
+ resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==}
+ engines: {node: '>=12'}
+ dependencies:
+ mimic-fn: 4.0.0
+ dev: true
+
/open@7.4.2:
resolution: {integrity: sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==}
engines: {node: '>=8'}
@@ -8332,6 +8597,16 @@ packages:
is-wsl: 2.2.0
dev: true
+ /open@9.1.0:
+ resolution: {integrity: sha512-OS+QTnw1/4vrf+9hh1jc1jnYjzSG4ttTBB8UxOwAnInG3Uo4ssetzC1ihqaIHjLJnA5GGlRl6QlZXOTQhRBUvg==}
+ engines: {node: '>=14.16'}
+ dependencies:
+ default-browser: 4.0.0
+ define-lazy-prop: 3.0.0
+ is-inside-container: 1.0.0
+ is-wsl: 2.2.0
+ dev: true
+
/optionator@0.8.3:
resolution: {integrity: sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==}
engines: {node: '>= 0.8.0'}
@@ -8344,16 +8619,16 @@ packages:
word-wrap: 1.2.3
dev: true
- /optionator@0.9.1:
- resolution: {integrity: sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==}
+ /optionator@0.9.3:
+ resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==}
engines: {node: '>= 0.8.0'}
dependencies:
+ '@aashutoshrathi/word-wrap': 1.2.6
deep-is: 0.1.4
fast-levenshtein: 2.0.6
levn: 0.4.1
prelude-ls: 1.2.1
type-check: 0.4.0
- word-wrap: 1.2.3
dev: true
/os-homedir@1.0.2:
@@ -8629,6 +8904,11 @@ packages:
engines: {node: '>=8'}
dev: true
+ /path-key@4.0.0:
+ resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==}
+ engines: {node: '>=12'}
+ dev: true
+
/path-parse@1.0.7:
resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
dev: true
@@ -8669,6 +8949,10 @@ packages:
resolution: {integrity: sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==}
dev: true
+ /picocolors@1.0.0:
+ resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==}
+ dev: true
+
/picomatch@2.3.1:
resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
engines: {node: '>=8.6'}
@@ -8755,6 +9039,19 @@ packages:
semver: 7.5.0
solidity-comments-extractor: 0.0.7
dev: true
+ optional: true
+
+ /prettier-plugin-solidity@1.1.3(prettier@3.0.3):
+ resolution: {integrity: sha512-fQ9yucPi2sBbA2U2Xjh6m4isUTJ7S7QLc/XDDsktqqxYfTwdYKJ0EnnywXHwCGAaYbQNK+HIYPL1OemxuMsgeg==}
+ engines: {node: '>=12'}
+ peerDependencies:
+ prettier: '>=2.3.0 || >=3.0.0-alpha.0'
+ dependencies:
+ '@solidity-parser/parser': 0.16.0
+ prettier: 3.0.3
+ semver: 7.5.0
+ solidity-comments-extractor: 0.0.7
+ dev: true
/prettier@2.8.8:
resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==}
@@ -8762,6 +9059,12 @@ packages:
hasBin: true
dev: true
+ /prettier@3.0.3:
+ resolution: {integrity: sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg==}
+ engines: {node: '>=14'}
+ hasBin: true
+ dev: true
+
/private@0.1.8:
resolution: {integrity: sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==}
engines: {node: '>= 0.6'}
@@ -9319,6 +9622,13 @@ packages:
bn.js: 5.2.1
dev: true
+ /run-applescript@5.0.0:
+ resolution: {integrity: sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg==}
+ engines: {node: '>=12'}
+ dependencies:
+ execa: 5.1.1
+ dev: true
+
/run-parallel-limit@1.1.0:
resolution: {integrity: sha512-jJA7irRNM91jaKc3Hcl1npHsFLOXOoTkPCUL1JEa1R82O2miplXXRaGdjW/KM/98YQWDhJLiSs793CnXfblJUw==}
dependencies:
@@ -9466,6 +9776,14 @@ packages:
lru-cache: 6.0.0
dev: true
+ /semver@7.5.4:
+ resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==}
+ engines: {node: '>=10'}
+ hasBin: true
+ dependencies:
+ lru-cache: 6.0.0
+ dev: true
+
/send@0.17.1:
resolution: {integrity: sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==}
engines: {node: '>= 0.8.0'}
@@ -9756,19 +10074,19 @@ packages:
- debug
dev: true
- /solhint-plugin-prettier@0.0.5(prettier-plugin-solidity@1.1.3)(prettier@2.8.8):
+ /solhint-plugin-prettier@0.0.5(prettier-plugin-solidity@1.1.3)(prettier@3.0.3):
resolution: {integrity: sha512-7jmWcnVshIrO2FFinIvDQmhQpfpS2rRRn3RejiYgnjIE68xO2bvrYvjqVNfrio4xH9ghOqn83tKuTzLjEbmGIA==}
peerDependencies:
prettier: ^1.15.0 || ^2.0.0
prettier-plugin-solidity: ^1.0.0-alpha.14
dependencies:
- prettier: 2.8.8
+ prettier: 3.0.3
prettier-linter-helpers: 1.0.0
- prettier-plugin-solidity: 1.1.3(prettier@2.8.8)
+ prettier-plugin-solidity: 1.1.3(prettier@3.0.3)
dev: true
- /solhint@3.4.1:
- resolution: {integrity: sha512-pzZn2RlZhws1XwvLPVSsxfHrwsteFf5eySOhpAytzXwKQYbTCJV6z8EevYDiSVKMpWrvbKpEtJ055CuEmzp4Xg==}
+ /solhint@3.6.2:
+ resolution: {integrity: sha512-85EeLbmkcPwD+3JR7aEMKsVC9YrRSxd4qkXuMzrlf7+z2Eqdfm1wHWq1ffTuo5aDhoZxp2I9yF3QkxZOxOL7aQ==}
hasBin: true
dependencies:
'@solidity-parser/parser': 0.16.0
@@ -9784,7 +10102,7 @@ packages:
js-yaml: 4.1.0
lodash: 4.17.21
pluralize: 8.0.0
- semver: 6.3.0
+ semver: 7.5.4
strip-ansi: 6.0.1
table: 6.8.1
text-table: 0.2.0
@@ -9906,7 +10224,7 @@ packages:
solidity-comments-win32-x64-msvc: 0.0.2
dev: true
- /solidity-coverage@0.8.4(hardhat@2.12.7):
+ /solidity-coverage@0.8.4(hardhat@2.17.3):
resolution: {integrity: sha512-xeHOfBOjdMF6hWTbt42iH4x+7j1Atmrf5OldDPMxI+i/COdExUxszOswD9qqvcBTaLGiOrrpnh9UZjSpt4rBsg==}
hasBin: true
peerDependencies:
@@ -9922,7 +10240,7 @@ packages:
ghost-testrpc: 0.0.2
global-modules: 2.0.0
globby: 10.0.2
- hardhat: 2.12.7(ts-node@10.0.0)(typescript@4.9.5)
+ hardhat: 2.17.3(ts-node@10.9.1)(typescript@5.2.2)
jsonschema: 1.4.0
lodash: 4.17.21
mocha: 7.1.2
@@ -10209,6 +10527,16 @@ packages:
is-utf8: 0.2.1
dev: true
+ /strip-final-newline@2.0.0:
+ resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==}
+ engines: {node: '>=6'}
+ dev: true
+
+ /strip-final-newline@3.0.0:
+ resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==}
+ engines: {node: '>=12'}
+ dev: true
+
/strip-hex-prefix@1.0.0:
resolution: {integrity: sha512-q8d4ue7JGEiVcypji1bALTos+0pWtyGlivAWyPuTkHzuTCJqrK9sWxYQZUq6Nq3cuyv3bm734IhHvHtGGURU6A==}
engines: {node: '>=6.5.0', npm: '>=3'}
@@ -10318,6 +10646,14 @@ packages:
get-port: 3.2.0
dev: true
+ /synckit@0.8.5:
+ resolution: {integrity: sha512-L1dapNV6vu2s/4Sputv8xGsCdAVlb5nRDMFU/E27D44l5U6cw1g0dGd45uLc+OXjNMmF4ntiMdCimzcjFKQI8Q==}
+ engines: {node: ^14.18.0 || >=16.0.0}
+ dependencies:
+ '@pkgr/utils': 2.4.2
+ tslib: 2.6.2
+ dev: true
+
/table-layout@1.0.2:
resolution: {integrity: sha512-qd/R7n5rQTRFi+Zf2sk5XVVd9UQl6ZkduPFC3S7WEGJAmetDTjY3qPN50eSKzwuzEyQKy5TN2TiZdkIjos2L6A==}
engines: {node: '>=8.0.0'}
@@ -10441,6 +10777,11 @@ packages:
upper-case: 1.1.3
dev: true
+ /titleize@3.0.0:
+ resolution: {integrity: sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ==}
+ engines: {node: '>=12'}
+ dev: true
+
/tmp@0.0.33:
resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==}
engines: {node: '>=0.6.0'}
@@ -10525,6 +10866,15 @@ packages:
engines: {node: '>=0.10.0'}
dev: true
+ /ts-api-utils@1.0.3(typescript@5.2.2):
+ resolution: {integrity: sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==}
+ engines: {node: '>=16.13.0'}
+ peerDependencies:
+ typescript: '>=4.2.0'
+ dependencies:
+ typescript: 5.2.2
+ dev: true
+
/ts-command-line-args@2.5.1:
resolution: {integrity: sha512-H69ZwTw3rFHb5WYpQya40YAX2/w7Ut75uUECbgBIsLmM+BNuYnxsltfyyLMxy6sEeKxgijLTnQtLd0nKd6+IYw==}
hasBin: true
@@ -10539,20 +10889,20 @@ packages:
resolution: {integrity: sha512-q3N1xS4vZpRouhYHDPwO0bDW3EZ6SK9CrrDHxi/D6BPReSjpVgWIOpLS2o0gSBZm+7q/wyKp6RVM1AeeW7uyfQ==}
dev: true
- /ts-essentials@6.0.7(typescript@4.9.5):
+ /ts-essentials@6.0.7(typescript@5.2.2):
resolution: {integrity: sha512-2E4HIIj4tQJlIHuATRHayv0EfMGK3ris/GRk1E3CFnsZzeNV+hUmelbaTZHLtXaZppM5oLhHRtO04gINC4Jusw==}
peerDependencies:
typescript: '>=3.7.0'
dependencies:
- typescript: 4.9.5
+ typescript: 5.2.2
dev: true
- /ts-essentials@7.0.3(typescript@4.9.5):
+ /ts-essentials@7.0.3(typescript@5.2.2):
resolution: {integrity: sha512-8+gr5+lqO3G84KdiTSMRLtuyJ+nTBVRKuCrK4lidMPdVeEp0uqC875uE5NMcaA7YYMN7XsNiFQuMvasF8HT/xQ==}
peerDependencies:
typescript: '>=3.7.0'
dependencies:
- typescript: 4.9.5
+ typescript: 5.2.2
dev: true
/ts-generator@0.1.1:
@@ -10570,13 +10920,12 @@ packages:
ts-essentials: 1.0.4
dev: true
- /ts-node@10.0.0(@types/node@15.14.9)(typescript@4.9.5):
- resolution: {integrity: sha512-ROWeOIUvfFbPZkoDis0L/55Fk+6gFQNZwwKPLinacRl6tsxstTF1DbAcLKkovwnpKMVvOMHP1TIbnwXwtLg1gg==}
- engines: {node: '>=12.0.0'}
+ /ts-node@10.9.1(@types/node@16.18.52)(typescript@5.2.2):
+ resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==}
hasBin: true
peerDependencies:
- '@swc/core': '>=1.2.45'
- '@swc/wasm': '>=1.2.45'
+ '@swc/core': '>=1.2.50'
+ '@swc/wasm': '>=1.2.50'
'@types/node': '*'
typescript: '>=2.7'
peerDependenciesMeta:
@@ -10585,17 +10934,20 @@ packages:
'@swc/wasm':
optional: true
dependencies:
+ '@cspotcode/source-map-support': 0.8.1
'@tsconfig/node10': 1.0.9
'@tsconfig/node12': 1.0.11
'@tsconfig/node14': 1.0.3
'@tsconfig/node16': 1.0.3
- '@types/node': 15.14.9
+ '@types/node': 16.18.52
+ acorn: 8.10.0
+ acorn-walk: 8.2.0
arg: 4.1.3
create-require: 1.1.1
diff: 4.0.2
make-error: 1.3.6
- source-map-support: 0.5.21
- typescript: 4.9.5
+ typescript: 5.2.2
+ v8-compile-cache-lib: 3.0.1
yn: 3.1.1
dev: true
@@ -10603,24 +10955,14 @@ packages:
resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==}
dev: true
- /tslib@2.4.0:
- resolution: {integrity: sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==}
+ /tslib@2.6.2:
+ resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==}
dev: true
/tsort@0.0.1:
resolution: {integrity: sha512-Tyrf5mxF8Ofs1tNoxA13lFeZ2Zrbd6cKbuH3V+MQ5sb6DtBj5FjrXVsRWT8YvNAQTqNoz66dz1WsbigI22aEnw==}
dev: true
- /tsutils@3.21.0(typescript@4.9.5):
- resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==}
- engines: {node: '>= 6'}
- peerDependencies:
- typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta'
- dependencies:
- tslib: 1.14.1
- typescript: 4.9.5
- dev: true
-
/tunnel-agent@0.6.0:
resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==}
dependencies:
@@ -10688,7 +11030,7 @@ packages:
resolution: {integrity: sha512-KBt58xCHry4Cejnc2ISQAF7QY+ORngsWfxezO68+12hKV6lQY8P/psIkcbjeHWn7MqcgciWJyCCevFMJdIXpow==}
dev: true
- /typechain@3.0.0(typescript@4.9.5):
+ /typechain@3.0.0(typescript@5.2.2):
resolution: {integrity: sha512-ft4KVmiN3zH4JUFu2WJBrwfHeDf772Tt2d8bssDTo/YcckKW2D+OwFrHXRC6hJvO3mHjFQTihoMV6fJOi0Hngg==}
hasBin: true
dependencies:
@@ -10697,14 +11039,14 @@ packages:
fs-extra: 7.0.1
js-sha3: 0.8.0
lodash: 4.17.21
- ts-essentials: 6.0.7(typescript@4.9.5)
+ ts-essentials: 6.0.7(typescript@5.2.2)
ts-generator: 0.1.1
transitivePeerDependencies:
- supports-color
- typescript
dev: true
- /typechain@8.2.0(typescript@4.9.5):
+ /typechain@8.2.0(typescript@5.2.2):
resolution: {integrity: sha512-tZqhqjxJ9xAS/Lh32jccTjMkpx7sTdUVVHAy5Bf0TIer5QFNYXotiX74oCvoVYjyxUKDK3MXHtMFzMyD3kE+jg==}
hasBin: true
peerDependencies:
@@ -10719,8 +11061,8 @@ packages:
mkdirp: 1.0.4
prettier: 2.8.8
ts-command-line-args: 2.5.1
- ts-essentials: 7.0.3(typescript@4.9.5)
- typescript: 4.9.5
+ ts-essentials: 7.0.3(typescript@5.2.2)
+ typescript: 5.2.2
transitivePeerDependencies:
- supports-color
dev: true
@@ -10735,9 +11077,9 @@ packages:
resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==}
dev: true
- /typescript@4.9.5:
- resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==}
- engines: {node: '>=4.2.0'}
+ /typescript@5.2.2:
+ resolution: {integrity: sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==}
+ engines: {node: '>=14.17'}
hasBin: true
dev: true
@@ -10846,6 +11188,11 @@ packages:
isobject: 3.0.1
dev: true
+ /untildify@4.0.0:
+ resolution: {integrity: sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==}
+ engines: {node: '>=8'}
+ dev: true
+
/upper-case-first@1.1.2:
resolution: {integrity: sha512-wINKYvI3Db8dtjikdAqoBbZoP6Q+PZUyfMR7pmwHzjC2quzSkUq5DmPrTtPEqHaz8AGtmsB4TqwapMTM1QAQOQ==}
dependencies:
@@ -10967,6 +11314,10 @@ packages:
hasBin: true
dev: true
+ /v8-compile-cache-lib@3.0.1:
+ resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==}
+ dev: true
+
/validate-npm-package-license@3.0.4:
resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==}
dependencies:
diff --git a/contracts/scripts/generate-automation-master-interface.ts b/contracts/scripts/generate-automation-master-interface.ts
index c480098c77f..5b71c99bc75 100644
--- a/contracts/scripts/generate-automation-master-interface.ts
+++ b/contracts/scripts/generate-automation-master-interface.ts
@@ -9,7 +9,7 @@ import { utils } from 'ethers'
import fs from 'fs'
import { exec } from 'child_process'
-const dest = 'src/v0.8/dev/automation/2_1/interfaces'
+const dest = 'src/v0.8/automation/interfaces/v2_1'
const srcDest = `${dest}/IKeeperRegistryMaster.sol`
const tmpDest = `${dest}/tmp.txt`
diff --git a/contracts/scripts/native_solc_compile_all_automation b/contracts/scripts/native_solc_compile_all_automation
index b6de82b8892..005570f4c12 100755
--- a/contracts/scripts/native_solc_compile_all_automation
+++ b/contracts/scripts/native_solc_compile_all_automation
@@ -27,17 +27,17 @@ compileContract () {
}
compileContract automation/upkeeps/CronUpkeepFactory.sol
-compileContract automation/1_2/KeeperRegistrar1_2.sol
-compileContract automation/1_2/KeeperRegistry1_2.sol
-compileContract automation/1_2/KeeperRegistryCheckUpkeepGasUsageWrapper1_2.sol
-compileContract automation/1_3/KeeperRegistry1_3.sol
-compileContract automation/1_3/KeeperRegistryLogic1_3.sol
-compileContract automation/2_0/KeeperRegistrar2_0.sol
-compileContract automation/2_0/KeeperRegistry2_0.sol
-compileContract automation/2_0/KeeperRegistryLogic2_0.sol
+compileContract automation/v1_2/KeeperRegistrar1_2.sol
+compileContract automation/v1_2/KeeperRegistry1_2.sol
+compileContract automation/v1_2/KeeperRegistryCheckUpkeepGasUsageWrapper1_2.sol
+compileContract automation/v1_3/KeeperRegistry1_3.sol
+compileContract automation/v1_3/KeeperRegistryLogic1_3.sol
+compileContract automation/v2_0/KeeperRegistrar2_0.sol
+compileContract automation/v2_0/KeeperRegistry2_0.sol
+compileContract automation/v2_0/KeeperRegistryLogic2_0.sol
compileContract automation/UpkeepTranscoder.sol
compileContract automation/mocks/MockAggregatorProxy.sol
-compileContract dev/automation/tests/LogUpkeepCounter.sol
+compileContract automation/testhelpers/LogUpkeepCounter.sol
# Keepers x VRF v2
compileContract KeepersVRFConsumer.sol
@@ -52,20 +52,20 @@ solc-select use $SOLC_VERSION
export SOLC_VERSION=$SOLC_VERSION
# v0.8.16
-compileContract dev/automation/2_1/AutomationRegistrar2_1.sol
-compileContract dev/automation/2_1/KeeperRegistry2_1.sol
-compileContract dev/automation/2_1/KeeperRegistryLogicA2_1.sol
-compileContract dev/automation/2_1/KeeperRegistryLogicB2_1.sol
-compileContract dev/automation/2_1/interfaces/IKeeperRegistryMaster.sol
-compileContract dev/automation/2_1/interfaces/ILogAutomation.sol
-compileContract dev/automation/2_1/AutomationUtils2_1.sol
-compileContract dev/automation/2_1/AutomationForwarderLogic.sol
-compileContract dev/automation/tests/LogTriggeredFeedLookup.sol
-compileContract dev/automation/tests/DummyProtocol.sol
-compileContract dev/automation/2_1/interfaces/FeedLookupCompatibleInterface.sol
+compileContract automation/v2_1/AutomationRegistrar2_1.sol
+compileContract automation/v2_1/KeeperRegistry2_1.sol
+compileContract automation/v2_1/KeeperRegistryLogicA2_1.sol
+compileContract automation/v2_1/KeeperRegistryLogicB2_1.sol
+compileContract automation/interfaces/v2_1/IKeeperRegistryMaster.sol
+compileContract automation/interfaces/ILogAutomation.sol
+compileContract automation/v2_1/AutomationUtils2_1.sol
+compileContract automation/v2_1/AutomationForwarderLogic.sol
+compileContract automation/testhelpers/LogTriggeredStreamsLookup.sol
+compileContract automation/testhelpers/DummyProtocol.sol
+compileContract automation/interfaces/StreamsLookupCompatibleInterface.sol
compileContract tests/VerifiableLoadUpkeep.sol
-compileContract tests/VerifiableLoadMercuryUpkeep.sol
+compileContract tests/VerifiableLoadStreamsLookupUpkeep.sol
compileContract tests/VerifiableLoadLogTriggerUpkeep.sol
compileContract tests/AutomationConsumerBenchmark.sol
-compileContract tests/MercuryUpkeep.sol
+compileContract tests/StreamsLookupUpkeep.sol
diff --git a/contracts/scripts/native_solc_compile_all_functions b/contracts/scripts/native_solc_compile_all_functions
index 904ad0563b3..99ded8afbb8 100755
--- a/contracts/scripts/native_solc_compile_all_functions
+++ b/contracts/scripts/native_solc_compile_all_functions
@@ -31,15 +31,15 @@ compileContract () {
# Version 0 (Testnet Beta)
##########################
-compileContract 0_0_0 dev/0_0_0/Functions.sol
-compileContract 0_0_0 dev/0_0_0/FunctionsBillingRegistry.sol
-compileContract 0_0_0 dev/0_0_0/FunctionsClient.sol
-compileContract 0_0_0 dev/0_0_0/FunctionsOracle.sol
-compileContract 0_0_0 dev/0_0_0/example/FunctionsClientExample.sol
+compileContract v0_0_0 dev/v0_0_0/Functions.sol
+compileContract v0_0_0 dev/v0_0_0/FunctionsBillingRegistry.sol
+compileContract v0_0_0 dev/v0_0_0/FunctionsClient.sol
+compileContract v0_0_0 dev/v0_0_0/FunctionsOracle.sol
+compileContract v0_0_0 dev/v0_0_0/example/FunctionsClientExample.sol
# Test helpers
-compileContract 0_0_0 tests/0_0_0/testhelpers/FunctionsBillingRegistryWithInit.sol
-compileContract 0_0_0 tests/0_0_0/testhelpers/FunctionsOracleWithInit.sol
+compileContract v0_0_0 tests/v0_0_0/testhelpers/FunctionsBillingRegistryWithInit.sol
+compileContract v0_0_0 tests/v0_0_0/testhelpers/FunctionsOracleWithInit.sol
############################
# Version 1 (Mainnet Preview)
@@ -50,11 +50,15 @@ solc-select install $SOLC_VERSION
solc-select use $SOLC_VERSION
export SOLC_VERSION=$SOLC_VERSION
-compileContract 1_0_0 dev/1_0_0/libraries/FunctionsRequest.sol
-compileContract 1_0_0 dev/1_0_0/FunctionsRouter.sol
-compileContract 1_0_0 dev/1_0_0/FunctionsCoordinator.sol
-compileContract 1_0_0 dev/1_0_0/accessControl/TermsOfServiceAllowList.sol
-compileContract 1_0_0 dev/1_0_0/example/FunctionsClientExample.sol
-## Test helpers
-compileContract 1_0_0 tests/1_0_0/testhelpers/FunctionsCoordinatorTestHelper.sol
-compileContract 1_0_0 tests/1_0_0/testhelpers/FunctionsLoadTestClient.sol
\ No newline at end of file
+compileContract v1_0_0 dev/v1_0_0/libraries/FunctionsRequest.sol
+compileContract v1_0_0 dev/v1_0_0/FunctionsRouter.sol
+compileContract v1_0_0 dev/v1_0_0/FunctionsCoordinator.sol
+compileContract v1_0_0 dev/v1_0_0/accessControl/TermsOfServiceAllowList.sol
+compileContract v1_0_0 dev/v1_0_0/example/FunctionsClientExample.sol
+
+# Test helpers
+compileContract v1_0_0 tests/v1_0_0/testhelpers/FunctionsCoordinatorTestHelper.sol
+compileContract v1_0_0 tests/v1_0_0/testhelpers/FunctionsLoadTestClient.sol
+
+# Mocks
+compileContract v1_0_0 dev/v1_0_0/mocks/FunctionsV1EventsMock.sol
diff --git a/contracts/scripts/native_solc_compile_all_llo-feeds b/contracts/scripts/native_solc_compile_all_llo-feeds
index 7c09857451c..27ef714ec1c 100755
--- a/contracts/scripts/native_solc_compile_all_llo-feeds
+++ b/contracts/scripts/native_solc_compile_all_llo-feeds
@@ -7,7 +7,7 @@ echo " │ Compiling Low Latency Oracle contracts... │"
echo " └──────────────────────────────────────────────┘"
SOLC_VERSION="0.8.16"
-OPTIMIZE_RUNS=15000
+OPTIMIZE_RUNS=1000000
SCRIPTPATH="$( cd "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )"
@@ -27,8 +27,8 @@ compileContract () {
compileContract llo-feeds/Verifier.sol
compileContract llo-feeds/VerifierProxy.sol
-compileContract llo-feeds/dev/FeeManager.sol
-compileContract llo-feeds/dev/RewardManager.sol
+compileContract llo-feeds/FeeManager.sol
+compileContract llo-feeds/RewardManager.sol
#Test | Mocks
compileContract llo-feeds/test/mocks/ErroredVerifier.sol
diff --git a/contracts/scripts/native_solc_compile_all_transmission b/contracts/scripts/native_solc_compile_all_transmission
index 6537757f429..6bd237f4a7d 100755
--- a/contracts/scripts/native_solc_compile_all_transmission
+++ b/contracts/scripts/native_solc_compile_all_transmission
@@ -25,9 +25,9 @@ compileContract () {
}
# Contracts
-compileContract dev/transmission/4337/SCA.sol
-compileContract dev/transmission/4337/Paymaster.sol
-compileContract dev/transmission/4337/SmartContractAccountFactory.sol
+compileContract dev/transmission/ERC-4337/SCA.sol
+compileContract dev/transmission/ERC-4337/Paymaster.sol
+compileContract dev/transmission/ERC-4337/SmartContractAccountFactory.sol
# Testhelpers
compileContract dev/transmission/testhelpers/SmartContractAccountHelper.sol
diff --git a/contracts/scripts/native_solc_compile_all_vrf b/contracts/scripts/native_solc_compile_all_vrf
index 8b35ac45748..0a3b1367bdf 100755
--- a/contracts/scripts/native_solc_compile_all_vrf
+++ b/contracts/scripts/native_solc_compile_all_vrf
@@ -51,11 +51,13 @@ compileContract vrf/BatchBlockhashStore.sol
compileContract vrf/BatchVRFCoordinatorV2.sol
compileContract vrf/testhelpers/VRFCoordinatorV2TestHelper.sol
compileContractAltOpts vrf/VRFCoordinatorV2.sol 10000
+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
@@ -65,9 +67,13 @@ compileContract dev/vrf/testhelpers/VRFV2PlusSingleConsumerExample.sol
compileContract dev/vrf/testhelpers/VRFV2PlusWrapperConsumerExample.sol
compileContract dev/vrf/testhelpers/VRFV2PlusRevertingExample.sol
compileContract dev/vrf/testhelpers/VRFConsumerV2PlusUpgradeableExample.sol
+compileContract dev/vrf/testhelpers/VRFV2PlusMaliciousMigrator.sol
compileContract dev/vrf/libraries/VRFV2PlusClient.sol
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 f3d3fd0aabd..324121c9fa5 100644
--- a/contracts/src/v0.8/ChainSpecificUtil.sol
+++ b/contracts/src/v0.8/ChainSpecificUtil.sol
@@ -14,10 +14,15 @@ library ChainSpecificUtil {
ArbGasInfo private constant ARBGAS = ArbGasInfo(ARBGAS_ADDR);
uint256 private constant ARB_MAINNET_CHAIN_ID = 42161;
uint256 private constant ARB_GOERLI_TESTNET_CHAIN_ID = 421613;
+ uint256 private constant ARB_SEPOLIA_TESTNET_CHAIN_ID = 421614;
function getBlockhash(uint64 blockNumber) internal view returns (bytes32) {
uint256 chainid = block.chainid;
- if (chainid == ARB_MAINNET_CHAIN_ID || chainid == ARB_GOERLI_TESTNET_CHAIN_ID) {
+ if (
+ chainid == ARB_MAINNET_CHAIN_ID ||
+ chainid == ARB_GOERLI_TESTNET_CHAIN_ID ||
+ chainid == ARB_SEPOLIA_TESTNET_CHAIN_ID
+ ) {
if ((getBlockNumber() - blockNumber) > 256 || blockNumber >= getBlockNumber()) {
return "";
}
diff --git a/contracts/src/v0.8/Flags.sol b/contracts/src/v0.8/Flags.sol
index 1aa62fc25c1..c4d1d0e61cd 100644
--- a/contracts/src/v0.8/Flags.sol
+++ b/contracts/src/v0.8/Flags.sol
@@ -1,8 +1,8 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
-import "./SimpleReadAccessController.sol";
-import "./interfaces/AccessControllerInterface.sol";
+import "./shared/access/SimpleReadAccessController.sol";
+import "./shared/interfaces/AccessControllerInterface.sol";
import "./interfaces/FlagsInterface.sol";
/**
diff --git a/contracts/src/v0.8/dev/automation/2_1/Chainable.sol b/contracts/src/v0.8/automation/Chainable.sol
similarity index 85%
rename from contracts/src/v0.8/dev/automation/2_1/Chainable.sol
rename to contracts/src/v0.8/automation/Chainable.sol
index 03112c51aa3..1b446f013a0 100644
--- a/contracts/src/v0.8/dev/automation/2_1/Chainable.sol
+++ b/contracts/src/v0.8/automation/Chainable.sol
@@ -10,20 +10,20 @@ contract Chainable {
/**
* @dev addresses of the next contract in the chain **have to be immutable/constant** or the system won't work
*/
- address private immutable i_next;
+ address private immutable FALLBACK_ADDRESS;
/**
- * @param next the address of the next contract in the chain
+ * @param fallbackAddress the address of the next contract in the chain
*/
- constructor(address next) {
- i_next = next;
+ constructor(address fallbackAddress) {
+ FALLBACK_ADDRESS = fallbackAddress;
}
/**
* @notice returns the address of the next contract in the chain
*/
function fallbackTo() external view returns (address) {
- return i_next;
+ return FALLBACK_ADDRESS;
}
/**
@@ -32,7 +32,7 @@ contract Chainable {
*/
fallback() external {
// copy to memory for assembly access
- address next = i_next;
+ address next = FALLBACK_ADDRESS;
// copied directly from OZ's Proxy contract
assembly {
// Copy msg.data. We take full control of memory in this inline assembly
diff --git a/contracts/src/v0.8/automation/dev/MercuryRegistry.sol b/contracts/src/v0.8/automation/dev/MercuryRegistry.sol
new file mode 100644
index 00000000000..e47b33fc012
--- /dev/null
+++ b/contracts/src/v0.8/automation/dev/MercuryRegistry.sol
@@ -0,0 +1,312 @@
+pragma solidity 0.8.6;
+
+import "../../shared/access/ConfirmedOwner.sol";
+import "../interfaces/AutomationCompatibleInterface.sol";
+import "../interfaces/StreamsLookupCompatibleInterface.sol";
+import "../../ChainSpecificUtil.sol";
+
+/*--------------------------------------------------------------------------------------------------------------------+
+| Mercury + Automation |
+| ________________ |
+| This implementation allows for an on-chain registry of price feed data to be maintained and updated by Automation |
+| nodes. The upkeep provides the following advantages: |
+| - Node operator savings. The single committee of automation nodes is able to update all price feed data using |
+| off-chain feed data. |
+| - Fetch batches of price data. All price feed data is held on the same contract, so a contract that needs |
+| multiple sets of feed data can fetch them while paying for only one external call. |
+| - Scalability. Feeds can be added or removed from the contract with a single contract call, and the number of |
+| feeds that the registry can store is unbounded. |
+| |
+| Key Contracts: |
+| - `MercuryRegistry.sol` - stores price feed data and implements core logic. |
+| - `MercuryRegistryBatchUpkeep.sol` - enables batching for the registry. |
+| - `MercuryRegistry.t.sol` - contains foundry tests to demonstrate various flows. |
+| |
+| NOTE: This contract uses Mercury v0.2. Automation will likely upgrade to v0.3 eventually, which may change some |
+| components such as the Report struct, verification, and the StreamsLookup revert. |
+| |
+| TODO: |
+| - Optimize gas consumption. |
+-+---------------------------------------------------------------------------------------------------------------------*/
+contract MercuryRegistry is ConfirmedOwner, AutomationCompatibleInterface, StreamsLookupCompatibleInterface {
+ error DuplicateFeed(string feedId);
+ error FeedNotActive(string feedId);
+ error StaleReport(string feedId, uint32 currentTimestamp, uint32 incomingTimestamp);
+ error InvalidFeeds();
+
+ // Feed object used for storing feed data.
+ // not included but contained in reports:
+ // - blocknumberUpperBound
+ // - upperBlockhash
+ // - blocknumberLowerBound
+ // - currentBlockTimestamp
+ struct Feed {
+ uint32 observationsTimestamp; // the timestamp of the most recent data assigned to this feed
+ int192 price; // the current price of the feed
+ int192 bid; // the current bid price of the feed
+ int192 ask; // the current ask price of the feed
+ string feedName; // the name of the feed
+ string feedId; // the id of the feed (hex encoded)
+ bool active; // true if the feed is being actively updated, otherwise false
+ int192 deviationPercentagePPM; // acceptable deviation threshold - 1.5% = 15_000, 100% = 1_000_000, etc..
+ uint32 stalenessSeconds; // acceptable staleness threshold - 60 = 1 minute, 300 = 5 minutes, etc..
+ }
+
+ // Report object obtained from off-chain Mercury server.
+ struct Report {
+ bytes32 feedId; // the feed Id of the report
+ uint32 observationsTimestamp; // the timestamp of when the data was observed
+ int192 price; // the median value of the OCR round
+ int192 bid; // the median bid of the OCR round
+ int192 ask; // the median ask if the OCR round
+ uint64 blocknumberUpperBound; // the highest block observed at the time the report was generated
+ bytes32 upperBlockhash; // the blockhash of the highest block observed
+ uint64 blocknumberLowerBound; // the lowest block observed at the time the report was generated
+ uint64 currentBlockTimestamp; // the timestamp of the highest block observed
+ }
+
+ event FeedUpdated(uint32 observationsTimestamp, int192 price, int192 bid, int192 ask, string feedId);
+
+ uint32 private constant MIN_GAS_FOR_PERFORM = 200_000;
+
+ string constant c_feedParamKey = "feedIdHex"; // for Mercury v0.2 - format by which feeds are identified
+ string constant c_timeParamKey = "blockNumber"; // for Mercury v0.2 - format by which feeds are filtered to be sufficiently recent
+ IVerifierProxy public s_verifier; // for Mercury v0.2 - verifies off-chain reports
+
+ int192 constant scale = 1_000_000; // a scalar used for measuring deviation with precision
+
+ string[] public s_feeds; // list of feed Ids
+ mapping(string => Feed) public s_feedMapping; // mapping of feed Ids to stored feed data
+
+ constructor(
+ string[] memory feedIds,
+ string[] memory feedNames,
+ int192[] memory deviationPercentagePPMs,
+ uint32[] memory stalenessSeconds,
+ address verifier
+ ) ConfirmedOwner(msg.sender) {
+ s_verifier = IVerifierProxy(verifier);
+
+ // Store desired feeds.
+ setFeeds(feedIds, feedNames, deviationPercentagePPMs, stalenessSeconds);
+ }
+
+ // Returns a user-defined batch of feed data, based on the on-chain state.
+ function getLatestFeedData(string[] memory feedIds) external view returns (Feed[] memory) {
+ Feed[] memory feeds = new Feed[](feedIds.length);
+ for (uint256 i = 0; i < feedIds.length; i++) {
+ feeds[i] = s_feedMapping[feedIds[i]];
+ }
+
+ return feeds;
+ }
+
+ // Invoke a feed lookup through the checkUpkeep function. Expected to run on a cron schedule.
+ function checkUpkeep(bytes calldata /* data */) external view override returns (bool, bytes memory) {
+ string[] memory feeds = s_feeds;
+ return revertForFeedLookup(feeds);
+ }
+
+ // Extracted from `checkUpkeep` for batching purposes.
+ function revertForFeedLookup(string[] memory feeds) public view returns (bool, bytes memory) {
+ uint256 blockNumber = ChainSpecificUtil.getBlockNumber();
+ revert StreamsLookup(c_feedParamKey, feeds, c_timeParamKey, blockNumber, "");
+ }
+
+ // Filter for feeds that have deviated sufficiently from their respective on-chain values, or where
+ // the on-chain values are sufficiently stale.
+ function checkCallback(
+ bytes[] memory values,
+ bytes memory lookupData
+ ) external view override returns (bool, bytes memory) {
+ bytes[] memory filteredValues = new bytes[](values.length);
+ uint256 count = 0;
+ for (uint256 i = 0; i < values.length; i++) {
+ Report memory report = getReport(values[i]);
+ string memory feedId = bytes32ToHexString(abi.encodePacked(report.feedId));
+ Feed memory feed = s_feedMapping[feedId];
+ if (
+ (report.observationsTimestamp - feed.observationsTimestamp > feed.stalenessSeconds) ||
+ deviationExceedsThreshold(feed.price, report.price, feed.deviationPercentagePPM)
+ ) {
+ filteredValues[count] = values[i];
+ count++;
+ }
+ }
+
+ // Adjusts the length of the filteredValues array to `count` such that it
+ // does not have extra empty slots, in case some items were filtered.
+ assembly {
+ mstore(filteredValues, count)
+ }
+
+ bytes memory performData = abi.encode(filteredValues, lookupData);
+ return (filteredValues.length > 0, performData);
+ }
+
+ // Use deviated off-chain values to update on-chain state.
+ function performUpkeep(bytes calldata performData) external override {
+ (bytes[] memory values /* bytes memory lookupData */, ) = abi.decode(performData, (bytes[], bytes));
+ for (uint256 i = 0; i < values.length; i++) {
+ // Verify and decode the Mercury report.
+ Report memory report = abi.decode(s_verifier.verify(values[i]), (Report));
+ string memory feedId = bytes32ToHexString(abi.encodePacked(report.feedId));
+
+ // Feeds that have been removed between checkUpkeep and performUpkeep should not be updated.
+ if (!s_feedMapping[feedId].active) {
+ revert FeedNotActive(feedId);
+ }
+
+ // Ensure stale reports do not cause a regression in the registry.
+ if (s_feedMapping[feedId].observationsTimestamp > report.observationsTimestamp) {
+ revert StaleReport(feedId, s_feedMapping[feedId].observationsTimestamp, report.observationsTimestamp);
+ }
+
+ // Assign new values to state.
+ s_feedMapping[feedId].bid = report.bid;
+ s_feedMapping[feedId].ask = report.ask;
+ s_feedMapping[feedId].price = report.price;
+ s_feedMapping[feedId].observationsTimestamp = report.observationsTimestamp;
+
+ // Emit log.
+ emit FeedUpdated(report.observationsTimestamp, report.price, report.bid, report.ask, feedId);
+
+ // Ensure enough gas remains for the next iteration. Otherwise, stop here.
+ if (gasleft() < MIN_GAS_FOR_PERFORM) {
+ return;
+ }
+ }
+ }
+
+ // Decodes a mercury respone into an on-chain object. Thanks @mikestone!!
+ function getReport(bytes memory signedReport) internal pure returns (Report memory) {
+ /*
+ * bytes32[3] memory reportContext,
+ * bytes memory reportData,
+ * bytes32[] memory rs,
+ * bytes32[] memory ss,
+ * bytes32 rawVs
+ **/
+ (, bytes memory reportData, , , ) = abi.decode(signedReport, (bytes32[3], bytes, bytes32[], bytes32[], bytes32));
+
+ Report memory report = abi.decode(reportData, (Report));
+ return report;
+ }
+
+ // Check if the off-chain value has deviated sufficiently from the on-chain value to justify an update.
+ // `scale` is used to ensure precision is not lost.
+ function deviationExceedsThreshold(
+ int192 onChain,
+ int192 offChain,
+ int192 deviationPercentagePPM
+ ) public pure returns (bool) {
+ // Compute absolute difference between the on-chain and off-chain values.
+ int192 scaledDifference = (onChain - offChain) * scale;
+ if (scaledDifference < 0) {
+ scaledDifference = -scaledDifference;
+ }
+
+ // Compare to the allowed deviation from the on-chain value.
+ int192 deviationMax = ((onChain * scale) * deviationPercentagePPM) / scale;
+ return scaledDifference > deviationMax;
+ }
+
+ // Helper function to reconcile a difference in formatting:
+ // - Automation passes feedId into their off-chain lookup function as a string.
+ // - Mercury stores feedId in their reports as a bytes32.
+ function bytes32ToHexString(bytes memory buffer) internal pure returns (string memory) {
+ bytes memory converted = new bytes(buffer.length * 2);
+ bytes memory _base = "0123456789abcdef";
+ for (uint256 i = 0; i < buffer.length; i++) {
+ converted[i * 2] = _base[uint8(buffer[i]) / _base.length];
+ converted[i * 2 + 1] = _base[uint8(buffer[i]) % _base.length];
+ }
+ return string(abi.encodePacked("0x", converted));
+ }
+
+ function addFeeds(
+ string[] memory feedIds,
+ string[] memory feedNames,
+ int192[] memory deviationPercentagePPMs,
+ uint32[] memory stalenessSeconds
+ ) external onlyOwner feedsAreValid(feedIds, feedNames, deviationPercentagePPMs, stalenessSeconds) {
+ for (uint256 i = 0; i < feedIds.length; i++) {
+ string memory feedId = feedIds[i];
+ if (s_feedMapping[feedId].active) {
+ revert DuplicateFeed(feedId);
+ }
+ updateFeed(feedId, feedNames[i], deviationPercentagePPMs[i], stalenessSeconds[i]);
+ s_feedMapping[feedId].active = true;
+
+ s_feeds.push(feedId);
+ }
+ }
+
+ function setFeeds(
+ string[] memory feedIds,
+ string[] memory feedNames,
+ int192[] memory deviationPercentagePPMs,
+ uint32[] memory stalenessSeconds
+ ) public onlyOwner feedsAreValid(feedIds, feedNames, deviationPercentagePPMs, stalenessSeconds) {
+ // Clear prior feeds.
+ for (uint256 i = 0; i < s_feeds.length; i++) {
+ s_feedMapping[s_feeds[i]].active = false;
+ }
+
+ // Assign new feeds.
+ for (uint256 i = 0; i < feedIds.length; i++) {
+ string memory feedId = feedIds[i];
+ if (s_feedMapping[feedId].active) {
+ revert DuplicateFeed(feedId);
+ }
+ updateFeed(feedId, feedNames[i], deviationPercentagePPMs[i], stalenessSeconds[i]);
+ s_feedMapping[feedId].active = true;
+ }
+ s_feeds = feedIds;
+ }
+
+ function updateFeed(
+ string memory feedId,
+ string memory feedName,
+ int192 deviationPercentagePPM,
+ uint32 stalnessSeconds
+ ) internal {
+ s_feedMapping[feedId].feedName = feedName;
+ s_feedMapping[feedId].deviationPercentagePPM = deviationPercentagePPM;
+ s_feedMapping[feedId].stalenessSeconds = stalnessSeconds;
+ s_feedMapping[feedId].feedId = feedId;
+ }
+
+ function setVerifier(address verifier) external onlyOwner {
+ s_verifier = IVerifierProxy(verifier);
+ }
+
+ modifier feedsAreValid(
+ string[] memory feedIds,
+ string[] memory feedNames,
+ int192[] memory deviationPercentagePPMs,
+ uint32[] memory stalenessSeconds
+ ) {
+ if (feedIds.length != feedNames.length) {
+ revert InvalidFeeds();
+ }
+ if (feedIds.length != deviationPercentagePPMs.length) {
+ revert InvalidFeeds();
+ }
+ if (feedIds.length != stalenessSeconds.length) {
+ revert InvalidFeeds();
+ }
+ _;
+ }
+}
+
+interface IVerifierProxy {
+ /**
+ * @notice Verifies that the data encoded has been signed
+ * correctly by routing to the correct verifier, and bills the user if applicable.
+ * @param payload The encoded data to be verified, including the signed
+ * report and any metadata for billing.
+ * @return verifiedReport The encoded report from the verifier.
+ */
+ function verify(bytes calldata payload) external payable returns (bytes memory verifiedReport);
+}
diff --git a/contracts/src/v0.8/automation/dev/MercuryRegistryBatchUpkeep.sol b/contracts/src/v0.8/automation/dev/MercuryRegistryBatchUpkeep.sol
new file mode 100644
index 00000000000..416b68f3a79
--- /dev/null
+++ b/contracts/src/v0.8/automation/dev/MercuryRegistryBatchUpkeep.sol
@@ -0,0 +1,80 @@
+pragma solidity 0.8.6;
+
+import "../../shared/access/ConfirmedOwner.sol";
+import "../interfaces/AutomationCompatibleInterface.sol";
+import "../interfaces/StreamsLookupCompatibleInterface.sol";
+import "./MercuryRegistry.sol";
+
+contract MercuryRegistryBatchUpkeep is ConfirmedOwner, AutomationCompatibleInterface, StreamsLookupCompatibleInterface {
+ error BatchSizeTooLarge(uint256 batchsize, uint256 maxBatchSize);
+ // Use a reasonable maximum batch size. Every Mercury report is ~750 bytes, too many reports
+ // passed into a single batch could exceed the calldata or transaction size limit for some blockchains.
+ uint256 constant MAX_BATCH_SIZE = 50;
+
+ MercuryRegistry immutable i_registry; // master registry, where feed data is stored
+
+ uint256 s_batchStart; // starting index of upkeep batch on the MercuryRegistry's s_feeds array, inclusive
+ uint256 s_batchEnd; // ending index of upkeep batch on the MercuryRegistry's s_feeds array, exclusive
+
+ constructor(address mercuryRegistry, uint256 batchStart, uint256 batchEnd) ConfirmedOwner(msg.sender) {
+ i_registry = MercuryRegistry(mercuryRegistry);
+
+ updateBatchingWindow(batchStart, batchEnd);
+ }
+
+ // Invoke a feed lookup for the feeds this upkeep is responsible for.
+ function checkUpkeep(bytes calldata /* data */) external view override returns (bool, bytes memory) {
+ uint256 start = s_batchStart;
+ uint256 end = s_batchEnd;
+ string[] memory feeds = new string[](end - start);
+ uint256 count = 0;
+ for (uint256 i = start; i < end; i++) {
+ string memory feedId;
+
+ // If the feed doesn't exist, then the batching window exceeds the underlying registry length.
+ // So, the batch will be partially empty.
+ try i_registry.s_feeds(i) returns (string memory f) {
+ feedId = f;
+ } catch (bytes memory /* data */) {
+ break;
+ }
+
+ // Assign feed.
+ feeds[i - start] = feedId;
+ count++;
+ }
+
+ // Adjusts the length of the batch to `count` such that it does not
+ // contain any empty feed Ids.
+ assembly {
+ mstore(feeds, count)
+ }
+
+ return i_registry.revertForFeedLookup(feeds);
+ }
+
+ // Use the master registry to assess deviations.
+ function checkCallback(
+ bytes[] memory values,
+ bytes memory lookupData
+ ) external view override returns (bool, bytes memory) {
+ return i_registry.checkCallback(values, lookupData);
+ }
+
+ // Use the master registry to update state.
+ function performUpkeep(bytes calldata performData) external override {
+ i_registry.performUpkeep(performData);
+ }
+
+ function updateBatchingWindow(uint256 batchStart, uint256 batchEnd) public onlyOwner {
+ // Do not allow a batched mercury registry to use an excessive batch size, as to avoid
+ // calldata size limits. If more feeds need to be updated than allowed by the batch size,
+ // deploy another `MercuryRegistryBatchUpkeep` contract and register another upkeep job.
+ if (batchEnd - batchStart > MAX_BATCH_SIZE) {
+ revert BatchSizeTooLarge(batchEnd - batchStart, MAX_BATCH_SIZE);
+ }
+
+ s_batchStart = batchStart;
+ s_batchEnd = batchEnd;
+ }
+}
diff --git a/contracts/src/v0.8/dev/automation/2_1/interfaces/IAutomationForwarder.sol b/contracts/src/v0.8/automation/interfaces/IAutomationForwarder.sol
similarity index 85%
rename from contracts/src/v0.8/dev/automation/2_1/interfaces/IAutomationForwarder.sol
rename to contracts/src/v0.8/automation/interfaces/IAutomationForwarder.sol
index fbf9743d0ca..0a53de697a1 100644
--- a/contracts/src/v0.8/dev/automation/2_1/interfaces/IAutomationForwarder.sol
+++ b/contracts/src/v0.8/automation/interfaces/IAutomationForwarder.sol
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
-import {ITypeAndVersion} from "../../../../shared/interfaces/ITypeAndVersion.sol";
+import {ITypeAndVersion} from "../../shared/interfaces/ITypeAndVersion.sol";
import {IAutomationRegistryConsumer} from "./IAutomationRegistryConsumer.sol";
interface IAutomationForwarder is ITypeAndVersion {
diff --git a/contracts/src/v0.8/dev/automation/2_1/interfaces/IAutomationRegistryConsumer.sol b/contracts/src/v0.8/automation/interfaces/IAutomationRegistryConsumer.sol
similarity index 100%
rename from contracts/src/v0.8/dev/automation/2_1/interfaces/IAutomationRegistryConsumer.sol
rename to contracts/src/v0.8/automation/interfaces/IAutomationRegistryConsumer.sol
diff --git a/contracts/src/v0.8/dev/automation/2_1/interfaces/ILogAutomation.sol b/contracts/src/v0.8/automation/interfaces/ILogAutomation.sol
similarity index 81%
rename from contracts/src/v0.8/dev/automation/2_1/interfaces/ILogAutomation.sol
rename to contracts/src/v0.8/automation/interfaces/ILogAutomation.sol
index ebb098ee31c..20a41f473be 100644
--- a/contracts/src/v0.8/dev/automation/2_1/interfaces/ILogAutomation.sol
+++ b/contracts/src/v0.8/automation/interfaces/ILogAutomation.sol
@@ -1,9 +1,19 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
+/**
+ * @member index the index of the log in the block. 0 for the first log
+ * @member timestamp the timestamp of the block containing the log
+ * @member txHash the hash of the transaction containing the log
+ * @member blockNumber the number of the block containing the log
+ * @member blockHash the hash of the block containing the log
+ * @member source the address of the contract that emitted the log
+ * @member topics the indexed topics of the log
+ * @member data the data of the log
+ */
struct Log {
uint256 index;
- uint256 txIndex;
+ uint256 timestamp;
bytes32 txHash;
uint256 blockNumber;
bytes32 blockHash;
diff --git a/contracts/src/v0.8/dev/automation/2_1/interfaces/FeedLookupCompatibleInterface.sol b/contracts/src/v0.8/automation/interfaces/StreamsLookupCompatibleInterface.sol
similarity index 60%
rename from contracts/src/v0.8/dev/automation/2_1/interfaces/FeedLookupCompatibleInterface.sol
rename to contracts/src/v0.8/automation/interfaces/StreamsLookupCompatibleInterface.sol
index 8653782f88f..cf8526a4651 100644
--- a/contracts/src/v0.8/dev/automation/2_1/interfaces/FeedLookupCompatibleInterface.sol
+++ b/contracts/src/v0.8/automation/interfaces/StreamsLookupCompatibleInterface.sol
@@ -1,14 +1,14 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
-interface FeedLookupCompatibleInterface {
- error FeedLookup(string feedParamKey, string[] feeds, string timeParamKey, uint256 time, bytes extraData);
+interface StreamsLookupCompatibleInterface {
+ error StreamsLookup(string feedParamKey, string[] feeds, string timeParamKey, uint256 time, bytes extraData);
/**
- * @notice any contract which wants to utilize FeedLookup feature needs to
+ * @notice any contract which wants to utilize StreamsLookup feature needs to
* implement this interface as well as the automation compatible interface.
- * @param values an array of bytes returned from Mercury endpoint.
- * @param extraData context data from feed lookup process.
+ * @param values an array of bytes returned from data streams endpoint.
+ * @param extraData context data from streams lookup process.
* @return upkeepNeeded boolean to indicate whether the keeper should call performUpkeep or not.
* @return performData bytes that the keeper should call performUpkeep with, if
* upkeep is needed. If you would like to encode data to decode later, try `abi.encode`.
diff --git a/contracts/src/v0.8/automation/interfaces/1_2/AutomationRegistryInterface1_2.sol b/contracts/src/v0.8/automation/interfaces/v1_2/AutomationRegistryInterface1_2.sol
similarity index 100%
rename from contracts/src/v0.8/automation/interfaces/1_2/AutomationRegistryInterface1_2.sol
rename to contracts/src/v0.8/automation/interfaces/v1_2/AutomationRegistryInterface1_2.sol
diff --git a/contracts/src/v0.8/automation/interfaces/1_2/KeeperRegistryInterface1_2.sol b/contracts/src/v0.8/automation/interfaces/v1_2/KeeperRegistryInterface1_2.sol
similarity index 100%
rename from contracts/src/v0.8/automation/interfaces/1_2/KeeperRegistryInterface1_2.sol
rename to contracts/src/v0.8/automation/interfaces/v1_2/KeeperRegistryInterface1_2.sol
diff --git a/contracts/src/v0.8/automation/interfaces/1_3/AutomationRegistryInterface1_3.sol b/contracts/src/v0.8/automation/interfaces/v1_3/AutomationRegistryInterface1_3.sol
similarity index 100%
rename from contracts/src/v0.8/automation/interfaces/1_3/AutomationRegistryInterface1_3.sol
rename to contracts/src/v0.8/automation/interfaces/v1_3/AutomationRegistryInterface1_3.sol
diff --git a/contracts/src/v0.8/automation/interfaces/2_0/AutomationRegistryInterface2_0.sol b/contracts/src/v0.8/automation/interfaces/v2_0/AutomationRegistryInterface2_0.sol
similarity index 100%
rename from contracts/src/v0.8/automation/interfaces/2_0/AutomationRegistryInterface2_0.sol
rename to contracts/src/v0.8/automation/interfaces/v2_0/AutomationRegistryInterface2_0.sol
diff --git a/contracts/src/v0.8/dev/automation/2_1/interfaces/IKeeperRegistryMaster.sol b/contracts/src/v0.8/automation/interfaces/v2_1/IKeeperRegistryMaster.sol
similarity index 100%
rename from contracts/src/v0.8/dev/automation/2_1/interfaces/IKeeperRegistryMaster.sol
rename to contracts/src/v0.8/automation/interfaces/v2_1/IKeeperRegistryMaster.sol
diff --git a/contracts/src/v0.8/dev/automation/2_1/mocks/MockKeeperRegistry2_1.sol b/contracts/src/v0.8/automation/mocks/MockKeeperRegistry2_1.sol
similarity index 100%
rename from contracts/src/v0.8/dev/automation/2_1/mocks/MockKeeperRegistry2_1.sol
rename to contracts/src/v0.8/automation/mocks/MockKeeperRegistry2_1.sol
diff --git a/contracts/src/v0.8/automation/test/MercuryRegistry.t.sol b/contracts/src/v0.8/automation/test/MercuryRegistry.t.sol
new file mode 100644
index 00000000000..4018c769f9a
--- /dev/null
+++ b/contracts/src/v0.8/automation/test/MercuryRegistry.t.sol
@@ -0,0 +1,336 @@
+pragma solidity ^0.8.0;
+
+import {Test} from "forge-std/Test.sol";
+import "../dev/MercuryRegistry.sol";
+import "../dev/MercuryRegistryBatchUpkeep.sol";
+import "../interfaces/StreamsLookupCompatibleInterface.sol";
+
+contract MercuryRegistryTest is Test {
+ address internal constant OWNER = 0x00007e64E1fB0C487F25dd6D3601ff6aF8d32e4e;
+ int192 internal constant DEVIATION_THRESHOLD = 10_000; // 1%
+ uint32 internal constant STALENESS_SECONDS = 3600; // 1 hour
+
+ address s_verifier = 0x60448B880c9f3B501af3f343DA9284148BD7D77C;
+
+ string[] feedIds;
+ string s_BTCUSDFeedId = "0x6962e629c3a0f5b7e3e9294b0c283c9b20f94f1c89c8ba8c1ee4650738f20fb2";
+ string s_ETHUSDFeedId = "0xf753e1201d54ac94dfd9334c542562ff7e42993419a661261d010af0cbfd4e34";
+ MercuryRegistry s_testRegistry;
+
+ // Feed: BTC/USD
+ // Date: Tuesday, August 22, 2023 7:29:28 PM
+ // Price: $25,857.11126720
+ bytes s_august22BTCUSDMercuryReport =
+ hex"0006a2f7f9b6c10385739c687064aa1e457812927f59446cccddf7740cc025ad00000000000000000000000000000000000000000000000000000000014cb94e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000002200000000000000000000000000000000000000000000000000000000000000280010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001206962e629c3a0f5b7e3e9294b0c283c9b20f94f1c89c8ba8c1ee4650738f20fb20000000000000000000000000000000000000000000000000000000064e50c980000000000000000000000000000000000000000000000000000025a0864a8c00000000000000000000000000000000000000000000000000000025a063481720000000000000000000000000000000000000000000000000000025a0a94d00f000000000000000000000000000000000000000000000000000000000226181f4733a6d98892d1821771c041d5d69298210fdca9d643ad74477423b6a3045647000000000000000000000000000000000000000000000000000000000226181f0000000000000000000000000000000000000000000000000000000064e50c9700000000000000000000000000000000000000000000000000000000000000027f3056b1b71dd516037afd2e636f8afb39853f5cb3ccaa4b02d6f9a2a64622534e94aa1f794f6a72478deb7e0eb2942864b7fac76d6e120bd809530b1b74a32b00000000000000000000000000000000000000000000000000000000000000027bd3b385c0812dfcad2652d225410a014a0b836cd9635a6e7fb404f65f7a912f0b193db57e5c4f38ce71f29170f7eadfa94d972338858bacd59ab224245206db";
+
+ // Feed: BTC/USD
+ // Date: Wednesday, August 23, 2023 7:55:02 PM
+ // Price: $26,720.37346975
+ bytes s_august23BTCUSDMercuryReport =
+ hex"0006a2f7f9b6c10385739c687064aa1e457812927f59446cccddf7740cc025ad000000000000000000000000000000000000000000000000000000000159a630000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000002200000000000000000000000000000000000000000000000000000000000000280000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001206962e629c3a0f5b7e3e9294b0c283c9b20f94f1c89c8ba8c1ee4650738f20fb20000000000000000000000000000000000000000000000000000000064e664160000000000000000000000000000000000000000000000000000026e21d63e9f0000000000000000000000000000000000000000000000000000026e2147576a0000000000000000000000000000000000000000000000000000026e226525d30000000000000000000000000000000000000000000000000000000002286ce7c44fa27f67f6dd0a8bb40c12f0f050231845789f022a82aa5f4b3fe5bf2068fb0000000000000000000000000000000000000000000000000000000002286ce70000000000000000000000000000000000000000000000000000000064e664150000000000000000000000000000000000000000000000000000000000000002e9c5857631172082a47a20aa2fd9f580c1c48275d030c17a2dff77da04f88708ce776ef74c04b9ef6ba87c56d8f8c57e80ddd5298b477d60dd49fb8120f1b9ce000000000000000000000000000000000000000000000000000000000000000248624e0e2341cdaf989098f8b3dee2660b792b24e5251d6e48e3abe0a879c0683163a3a199969010e15353a99926d113f6d4cbab9d82ae90a159af9f74f8c157";
+
+ // Feed: BTC/USD
+ // Date: Wednesday, August 23, 2023 8:13:28 PM
+ // Price: $26,559.67100000
+ bytes s_august23BTCUSDMercuryReport_2 =
+ hex"0006a2f7f9b6c10385739c687064aa1e457812927f59446cccddf7740cc025ad000000000000000000000000000000000000000000000000000000000159d009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000002200000000000000000000000000000000000000000000000000000000000000280010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001206962e629c3a0f5b7e3e9294b0c283c9b20f94f1c89c8ba8c1ee4650738f20fb20000000000000000000000000000000000000000000000000000000064e668690000000000000000000000000000000000000000000000000000026a63f9bc600000000000000000000000000000000000000000000000000000026a635984c00000000000000000000000000000000000000000000000000000026a67bb929d00000000000000000000000000000000000000000000000000000000022873e999d3ff9b644bba530af933dfaa6c59e31c3e232fcaa1e5f7304e2e79d939da1900000000000000000000000000000000000000000000000000000000022873e80000000000000000000000000000000000000000000000000000000064e66868000000000000000000000000000000000000000000000000000000000000000247c21657a6c2795986e95081876bf8b5f24bf72abd2dc4c601e7c96d654bcf543b5bb730e3d4736a308095e4531e7c03f581ac364f0889922ba3ae24b7cf968000000000000000000000000000000000000000000000000000000000000000020d3037d9f55256a001a2aa79ea746526c7cb36747e1deb4c804311394b4027667e5b711bcecfe60632e86cf8e83c28d1465e2d8d90bc0638dad8347f55488e8e";
+
+ // Feed: ETH/USD
+ // Date: Wednesday, August 23, 2023 7:55:01 PM
+ // Price: $1,690.76482169
+ bytes s_august23ETHUSDMercuryReport =
+ hex"0006c41ec94138ae62cce3f1a2b852e42fe70359502fa7b6bdbf81207970d88e00000000000000000000000000000000000000000000000000000000016d874d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000220000000000000000000000000000000000000000000000000000000000000028000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000120f753e1201d54ac94dfd9334c542562ff7e42993419a661261d010af0cbfd4e340000000000000000000000000000000000000000000000000000000064e66415000000000000000000000000000000000000000000000000000000275dbe6079000000000000000000000000000000000000000000000000000000275c905eba000000000000000000000000000000000000000000000000000000275e5693080000000000000000000000000000000000000000000000000000000002286ce7c44fa27f67f6dd0a8bb40c12f0f050231845789f022a82aa5f4b3fe5bf2068fb0000000000000000000000000000000000000000000000000000000002286ce70000000000000000000000000000000000000000000000000000000064e664150000000000000000000000000000000000000000000000000000000000000002a2b01f7741563cfe305efaec43e56cd85731e3a8e2396f7c625bd16adca7b39c97805b6170adc84d065f9d68c87104c3509aeefef42c0d1711e028ace633888000000000000000000000000000000000000000000000000000000000000000025d984ad476bda9547cf0f90d32732dc5a0d84b0e2fe9795149b786fb05332d4c092e278b4dddeef45c070b818c6e221db2633b573d616ef923c755a145ea099c";
+
+ // Feed: USDC/USD
+ // Date: Wednesday, August 30, 2023 5:05:01 PM
+ // Price: $1.00035464
+ bytes s_august30USDCUSDMercuryReport =
+ hex"0006970c13551e2a390246f5eccb62b9be26848e72026830f4688f49201b5a050000000000000000000000000000000000000000000000000000000001c89843000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000220000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000120a5b07943b89e2c278fc8a2754e2854316e03cb959f6d323c2d5da218fb6b0ff80000000000000000000000000000000000000000000000000000000064ef69fa0000000000000000000000000000000000000000000000000000000005f5da000000000000000000000000000000000000000000000000000000000005f5b0f80000000000000000000000000000000000000000000000000000000005f5f8b0000000000000000000000000000000000000000000000000000000000240057307d0a0421d25328cb6dcfc5d0e211ff0580baaaf104e9877fc52cf2e8ec0aa7d00000000000000000000000000000000000000000000000000000000024005730000000000000000000000000000000000000000000000000000000064ef69fa0000000000000000000000000000000000000000000000000000000000000002b9e7fb46f1e9d22a1156024dc2bbf2bc6d337e0a2d78aaa3fb6e43b880217e5897732b516e39074ef4dcda488733bfee80c0a10714b94621cd93df6842373cf5000000000000000000000000000000000000000000000000000000000000000205ca5f8da9d6ae01ec6d85c681e536043323405b3b8a15e4d2a288e02dac32f10b2294593e270a4bbf53b0c4978b725293e85e49685f1d3ce915ff670ab6612f";
+
+ function setUp() public virtual {
+ // Set owner, and fork Arbitrum Goerli Testnet (chain ID 421613).
+ // The fork is only used with the `FORK_TEST` flag enabeld, as to not disrupt CI. For CI, a mock verifier is used instead.
+ vm.startPrank(OWNER);
+ try vm.envBool("FORK_TEST") returns (bool /* fork testing enabled */) {
+ vm.selectFork(vm.createFork("https://goerli-rollup.arbitrum.io/rpc"));
+ } catch {
+ s_verifier = address(new MockVerifierProxy());
+ }
+ vm.chainId(31337); // restore chain Id
+
+ // Use a BTC feed and ETH feed.
+ feedIds = new string[](2);
+ feedIds[0] = s_BTCUSDFeedId;
+ feedIds[1] = s_ETHUSDFeedId;
+
+ // Deviation threshold and staleness are the same for all feeds.
+ int192[] memory thresholds = new int192[](1);
+ thresholds[0] = DEVIATION_THRESHOLD;
+ uint32[] memory stalenessSeconds = new uint32[](1);
+ stalenessSeconds[0] = STALENESS_SECONDS;
+
+ // Initialize with BTC feed.
+ string[] memory initialFeedIds = new string[](1);
+ initialFeedIds[0] = feedIds[0];
+ string[] memory initialFeedNames = new string[](1);
+ initialFeedNames[0] = "BTC/USD";
+ s_testRegistry = new MercuryRegistry(
+ initialFeedIds,
+ initialFeedNames,
+ thresholds,
+ stalenessSeconds,
+ address(0) // verifier unset
+ );
+ s_testRegistry.setVerifier(s_verifier); // set verifier
+
+ // Add ETH feed.
+ string[] memory addedFeedIds = new string[](1);
+ addedFeedIds[0] = feedIds[1];
+ string[] memory addedFeedNames = new string[](1);
+ addedFeedNames[0] = "ETH/USD";
+ s_testRegistry.addFeeds(addedFeedIds, addedFeedNames, thresholds, stalenessSeconds);
+ }
+
+ function testMercuryRegistry() public {
+ // Check upkeep, receive Mercury revert.
+ uint256 blockNumber = block.number;
+ vm.expectRevert(
+ abi.encodeWithSelector(
+ StreamsLookupCompatibleInterface.StreamsLookup.selector,
+ "feedIdHex", // feedParamKey
+ feedIds, // feed Ids
+ "blockNumber", // timeParamKey
+ blockNumber, // block number on which request is occuring
+ "" // extra data
+ )
+ );
+ s_testRegistry.checkUpkeep("");
+
+ // Obtain mercury report off-chain (for August 22 BTC/USD price)
+ bytes[] memory values = new bytes[](1);
+ values[0] = s_august22BTCUSDMercuryReport;
+
+ // Pass the obtained mercury report into checkCallback, to assert that an update is warranted.
+ (bool shouldPerformUpkeep, bytes memory performData) = s_testRegistry.checkCallback(values, bytes(""));
+ assertEq(shouldPerformUpkeep, true);
+
+ // Perform upkeep to update on-chain state.
+ s_testRegistry.performUpkeep(performData);
+
+ // Check state of BTC/USD feed to ensure update was propagated.
+ bytes memory oldPerformData;
+ uint32 oldObservationsTimestamp;
+ {
+ // scoped to prevent stack-too-deep error
+ (
+ uint32 observationsTimestamp,
+ int192 price,
+ int192 bid,
+ int192 ask,
+ string memory feedName,
+ string memory localFeedId,
+ bool active,
+ int192 deviationPercentagePPM,
+ uint32 stalenessSeconds
+ ) = s_testRegistry.s_feedMapping(s_BTCUSDFeedId);
+ assertEq(observationsTimestamp, 1692732568); // Tuesday, August 22, 2023 7:29:28 PM
+ assertEq(bid, 2585674416498); // $25,856.74416498
+ assertEq(price, 2585711126720); // $25,857.11126720
+ assertEq(ask, 2585747836943); // $25,857.47836943
+ assertEq(feedName, "BTC/USD");
+ assertEq(localFeedId, s_BTCUSDFeedId);
+ assertEq(active, true);
+ assertEq(deviationPercentagePPM, DEVIATION_THRESHOLD);
+ assertEq(stalenessSeconds, STALENESS_SECONDS);
+
+ // Save this for later in the test.
+ oldPerformData = performData;
+ oldObservationsTimestamp = observationsTimestamp;
+ }
+ // Obtain mercury report off-chain (for August 23 BTC/USD price & ETH/USD price)
+ values = new bytes[](2);
+ values[0] = s_august23BTCUSDMercuryReport;
+ values[1] = s_august23ETHUSDMercuryReport;
+
+ // Pass the obtained mercury report into checkCallback, to assert that an update is warranted.
+ (shouldPerformUpkeep, performData) = s_testRegistry.checkCallback(values, bytes(""));
+ assertEq(shouldPerformUpkeep, true);
+
+ // Perform upkeep to update on-chain state.
+ s_testRegistry.performUpkeep(performData);
+
+ // Make a batch request for both the BTC/USD feed data and the ETH/USD feed data.
+ MercuryRegistry.Feed[] memory feeds = s_testRegistry.getLatestFeedData(feedIds);
+
+ // Check state of BTC/USD feed to ensure update was propagated.
+ assertEq(feeds[0].observationsTimestamp, 1692820502); // Wednesday, August 23, 2023 7:55:02 PM
+ assertEq(feeds[0].bid, 2672027981674); // $26,720.27981674
+ assertEq(feeds[0].price, 2672037346975); // $26,720.37346975
+ assertEq(feeds[0].ask, 2672046712275); // $26,720.46712275
+ assertEq(feeds[0].feedName, "BTC/USD");
+ assertEq(feeds[0].feedId, s_BTCUSDFeedId);
+
+ // Check state of ETH/USD feed to ensure update was propagated.
+ assertEq(feeds[1].observationsTimestamp, 1692820501); // Wednesday, August 23, 2023 7:55:01 PM
+ assertEq(feeds[1].bid, 169056689850); // $1,690.56689850
+ assertEq(feeds[1].price, 169076482169); // $1,690.76482169
+ assertEq(feeds[1].ask, 169086456584); // $16,90.86456584
+ assertEq(feeds[1].feedName, "ETH/USD");
+ assertEq(feeds[1].feedId, s_ETHUSDFeedId);
+ assertEq(feeds[1].active, true);
+ assertEq(feeds[1].deviationPercentagePPM, DEVIATION_THRESHOLD);
+ assertEq(feeds[1].stalenessSeconds, STALENESS_SECONDS);
+
+ // Obtain mercury report off-chain for August 23 BTC/USD price (second report of the day).
+ // The price of this incoming report will not deviate enough from the on-chain value to trigger an update,
+ // nor is the on-chain data stale enough.
+ values = new bytes[](1);
+ values[0] = s_august23BTCUSDMercuryReport_2;
+
+ // Pass the obtained mercury report into checkCallback, to assert that an update is not warranted.
+ (shouldPerformUpkeep, performData) = s_testRegistry.checkCallback(values, bytes(""));
+ assertEq(shouldPerformUpkeep, false);
+
+ // Ensure stale reports cannot be included.
+ vm.expectRevert(
+ abi.encodeWithSelector(
+ MercuryRegistry.StaleReport.selector,
+ feedIds[0],
+ feeds[0].observationsTimestamp,
+ oldObservationsTimestamp
+ )
+ );
+ s_testRegistry.performUpkeep(oldPerformData);
+
+ // Ensure reports for inactive feeds cannot be included.
+ bytes[] memory inactiveFeedReports = new bytes[](1);
+ inactiveFeedReports[0] = s_august30USDCUSDMercuryReport;
+ bytes memory lookupData = "";
+ vm.expectRevert(
+ abi.encodeWithSelector(
+ MercuryRegistry.FeedNotActive.selector,
+ "0xa5b07943b89e2c278fc8a2754e2854316e03cb959f6d323c2d5da218fb6b0ff8" // USDC/USD feed id
+ )
+ );
+ s_testRegistry.performUpkeep(abi.encode(inactiveFeedReports, lookupData));
+ }
+
+ // Below are the same tests as `testMercuryRegistry`, except done via a batching Mercury registry that
+ // consumes the test registry. This is to assert that batching can be accomplished by multiple different
+ // upkeep jobs, which can populate the same
+ function testMercuryRegistryBatchUpkeep() public {
+ MercuryRegistryBatchUpkeep batchedRegistry = new MercuryRegistryBatchUpkeep(
+ address(s_testRegistry), // use the test registry as master registry
+ 0, // start batch at index 0.
+ 50 // end batch beyond length of feed Ids (take responsibility for all feeds)
+ );
+ // Check upkeep, receive Mercury revert.
+ uint256 blockNumber = block.number;
+ vm.expectRevert(
+ abi.encodeWithSelector(
+ StreamsLookupCompatibleInterface.StreamsLookup.selector,
+ "feedIdHex", // feedParamKey
+ feedIds, // feed Ids
+ "blockNumber", // timeParamKey
+ blockNumber, // block number on which request is occuring
+ "" // extra data
+ )
+ );
+ batchedRegistry.checkUpkeep("");
+
+ // Obtain mercury report off-chain (for August 22 BTC/USD price)
+ bytes[] memory values = new bytes[](1);
+ values[0] = s_august22BTCUSDMercuryReport;
+
+ // Pass the obtained mercury report into checkCallback, to assert that an update is warranted.
+ (bool shouldPerformUpkeep, bytes memory performData) = batchedRegistry.checkCallback(values, bytes(""));
+ assertEq(shouldPerformUpkeep, true);
+
+ // Perform upkeep to update on-chain state.
+ batchedRegistry.performUpkeep(performData);
+
+ // Check state of BTC/USD feed to ensure update was propagated.
+ (
+ uint32 observationsTimestamp,
+ int192 price,
+ int192 bid,
+ int192 ask,
+ string memory feedName,
+ string memory localFeedId,
+ bool active,
+ int192 deviationPercentagePPM,
+ uint32 stalenessSeconds
+ ) = s_testRegistry.s_feedMapping(s_BTCUSDFeedId);
+ assertEq(observationsTimestamp, 1692732568); // Tuesday, August 22, 2023 7:29:28 PM
+ assertEq(bid, 2585674416498); // $25,856.74416498
+ assertEq(price, 2585711126720); // $25,857.11126720
+ assertEq(ask, 2585747836943); // $25,857.47836943
+ assertEq(feedName, "BTC/USD");
+ assertEq(localFeedId, s_BTCUSDFeedId);
+ assertEq(active, true);
+ assertEq(deviationPercentagePPM, DEVIATION_THRESHOLD);
+ assertEq(stalenessSeconds, STALENESS_SECONDS);
+
+ // Obtain mercury report off-chain (for August 23 BTC/USD price & ETH/USD price)
+ values = new bytes[](2);
+ values[0] = s_august23BTCUSDMercuryReport;
+ values[1] = s_august23ETHUSDMercuryReport;
+
+ // Pass the obtained mercury report into checkCallback, to assert that an update is warranted.
+ (shouldPerformUpkeep, performData) = batchedRegistry.checkCallback(values, bytes(""));
+ assertEq(shouldPerformUpkeep, true);
+
+ // Perform upkeep to update on-chain state, but with not enough gas to update both feeds.
+ batchedRegistry.performUpkeep{gas: 250_000}(performData);
+
+ // Make a batch request for both the BTC/USD feed data and the ETH/USD feed data.
+ MercuryRegistry.Feed[] memory feeds = s_testRegistry.getLatestFeedData(feedIds);
+
+ // Check state of BTC/USD feed to ensure update was propagated.
+ assertEq(feeds[0].observationsTimestamp, 1692820502); // Wednesday, August 23, 2023 7:55:02 PM
+ assertEq(feeds[0].bid, 2672027981674); // $26,720.27981674
+ assertEq(feeds[0].price, 2672037346975); // $26,720.37346975
+ assertEq(feeds[0].ask, 2672046712275); // $26,720.46712275
+ assertEq(feeds[0].feedName, "BTC/USD");
+ assertEq(feeds[0].feedId, s_BTCUSDFeedId);
+
+ // Check state of ETH/USD feed to observe that the update was not propagated.
+ assertEq(feeds[1].observationsTimestamp, 0);
+ assertEq(feeds[1].bid, 0);
+ assertEq(feeds[1].price, 0);
+ assertEq(feeds[1].ask, 0);
+ assertEq(feeds[1].feedName, "ETH/USD");
+ assertEq(feeds[1].feedId, s_ETHUSDFeedId);
+ assertEq(feeds[1].active, true);
+ assertEq(feeds[1].deviationPercentagePPM, DEVIATION_THRESHOLD);
+ assertEq(feeds[1].stalenessSeconds, STALENESS_SECONDS);
+
+ // Try again, with sufficient gas to update both feeds.
+ batchedRegistry.performUpkeep{gas: 2_500_000}(performData);
+ feeds = s_testRegistry.getLatestFeedData(feedIds);
+
+ // Check state of ETH/USD feed to ensure update was propagated.
+ assertEq(feeds[1].observationsTimestamp, 1692820501); // Wednesday, August 23, 2023 7:55:01 PM
+ assertEq(feeds[1].bid, 169056689850); // $1,690.56689850
+ assertEq(feeds[1].price, 169076482169); // $1,690.76482169
+ assertEq(feeds[1].ask, 169086456584); // $16,90.86456584
+ assertEq(feeds[1].feedName, "ETH/USD");
+ assertEq(feeds[1].feedId, s_ETHUSDFeedId);
+
+ // Obtain mercury report off-chain for August 23 BTC/USD price (second report of the day).
+ // The price of this incoming report will not deviate enough from the on-chain value to trigger an update.
+ values = new bytes[](1);
+ values[0] = s_august23BTCUSDMercuryReport_2;
+
+ // Pass the obtained mercury report into checkCallback, to assert that an update is not warranted.
+ (shouldPerformUpkeep, performData) = batchedRegistry.checkCallback(values, bytes(""));
+ assertEq(shouldPerformUpkeep, false);
+ }
+}
+
+contract MockVerifierProxy is IVerifierProxy {
+ function verify(bytes calldata payload) external payable override returns (bytes memory) {
+ (, bytes memory reportData, , , ) = abi.decode(payload, (bytes32[3], bytes, bytes32[], bytes32[], bytes32));
+ return reportData;
+ }
+}
diff --git a/contracts/src/v0.8/dev/automation/tests/DummyProtocol.sol b/contracts/src/v0.8/automation/testhelpers/DummyProtocol.sol
similarity index 100%
rename from contracts/src/v0.8/dev/automation/tests/DummyProtocol.sol
rename to contracts/src/v0.8/automation/testhelpers/DummyProtocol.sol
diff --git a/contracts/src/v0.8/dev/automation/tests/LogTriggeredFeedLookup.sol b/contracts/src/v0.8/automation/testhelpers/LogTriggeredStreamsLookup.sol
similarity index 89%
rename from contracts/src/v0.8/dev/automation/tests/LogTriggeredFeedLookup.sol
rename to contracts/src/v0.8/automation/testhelpers/LogTriggeredStreamsLookup.sol
index f7861c34554..eb7f3c48f69 100644
--- a/contracts/src/v0.8/dev/automation/tests/LogTriggeredFeedLookup.sol
+++ b/contracts/src/v0.8/automation/testhelpers/LogTriggeredStreamsLookup.sol
@@ -1,9 +1,9 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.16;
-import {ILogAutomation, Log} from "../2_1/interfaces/ILogAutomation.sol";
-import "../2_1/interfaces/FeedLookupCompatibleInterface.sol";
-import {ArbSys} from "../../../vendor/@arbitrum/nitro-contracts/src/precompiles/ArbSys.sol";
+import {ILogAutomation, Log} from "../interfaces/ILogAutomation.sol";
+import "../interfaces/StreamsLookupCompatibleInterface.sol";
+import {ArbSys} from "../../vendor/@arbitrum/nitro-contracts/src/precompiles/ArbSys.sol";
interface IVerifierProxy {
/**
@@ -15,7 +15,7 @@ interface IVerifierProxy {
function verify(bytes memory signedReport) external returns (bytes memory verifierResponse);
}
-contract LogTriggeredFeedLookup is ILogAutomation, FeedLookupCompatibleInterface {
+contract LogTriggeredStreamsLookup is ILogAutomation, StreamsLookupCompatibleInterface {
event PerformingLogTriggerUpkeep(
address indexed from,
uint256 orderId,
@@ -74,7 +74,7 @@ contract LogTriggeredFeedLookup is ILogAutomation, FeedLookupCompatibleInterface
bytes memory t3 = abi.encodePacked(log.topics[3]);
address exchange = abi.decode(t3, (address));
- revert FeedLookup(feedParamKey, feedsHex, timeParamKey, blockNum, abi.encode(orderId, amount, exchange));
+ revert StreamsLookup(feedParamKey, feedsHex, timeParamKey, blockNum, abi.encode(orderId, amount, exchange));
}
revert("could not find matching event sig");
}
diff --git a/contracts/src/v0.8/dev/automation/tests/LogUpkeepCounter.sol b/contracts/src/v0.8/automation/testhelpers/LogUpkeepCounter.sol
similarity index 97%
rename from contracts/src/v0.8/dev/automation/tests/LogUpkeepCounter.sol
rename to contracts/src/v0.8/automation/testhelpers/LogUpkeepCounter.sol
index 84e53b65493..a51f2d2af1a 100644
--- a/contracts/src/v0.8/dev/automation/tests/LogUpkeepCounter.sol
+++ b/contracts/src/v0.8/automation/testhelpers/LogUpkeepCounter.sol
@@ -2,7 +2,7 @@
pragma solidity 0.8.6;
-import {ILogAutomation, Log} from "../2_1/interfaces/ILogAutomation.sol";
+import {ILogAutomation, Log} from "../interfaces/ILogAutomation.sol";
contract LogUpkeepCounter is ILogAutomation {
bytes32 sig1 = 0x3d53a39550e04688065827f3bb86584cb007ab9ebca7ebd528e7301c9c31eb5d;
diff --git a/contracts/src/v0.8/dev/automation/2_1/mocks/UpkeepCounter.sol b/contracts/src/v0.8/automation/testhelpers/UpkeepCounter.sol
similarity index 100%
rename from contracts/src/v0.8/dev/automation/2_1/mocks/UpkeepCounter.sol
rename to contracts/src/v0.8/automation/testhelpers/UpkeepCounter.sol
diff --git a/contracts/src/v0.8/dev/automation/upkeeps/LinkAvailableBalanceMonitor.sol b/contracts/src/v0.8/automation/upkeeps/LinkAvailableBalanceMonitor.sol
similarity index 96%
rename from contracts/src/v0.8/dev/automation/upkeeps/LinkAvailableBalanceMonitor.sol
rename to contracts/src/v0.8/automation/upkeeps/LinkAvailableBalanceMonitor.sol
index 1ed1237f615..af24d86e3c8 100644
--- a/contracts/src/v0.8/dev/automation/upkeeps/LinkAvailableBalanceMonitor.sol
+++ b/contracts/src/v0.8/automation/upkeeps/LinkAvailableBalanceMonitor.sol
@@ -2,11 +2,11 @@
pragma solidity 0.8.6;
-import "../../../shared/access/ConfirmedOwner.sol";
-import "../../../automation/interfaces/KeeperCompatibleInterface.sol";
-import "../../../vendor/openzeppelin-solidity/v4.7.0/contracts/security/Pausable.sol";
-import "../../../vendor/openzeppelin-solidity/v4.7.0/contracts/token/ERC20/IERC20.sol";
-import "../../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/structs/EnumerableMap.sol";
+import "../../shared/access/ConfirmedOwner.sol";
+import "../interfaces/KeeperCompatibleInterface.sol";
+import "../../vendor/openzeppelin-solidity/v4.7.0/contracts/security/Pausable.sol";
+import "../../vendor/openzeppelin-solidity/v4.7.0/contracts/token/ERC20/IERC20.sol";
+import "../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/structs/EnumerableMap.sol";
interface IAggregatorProxy {
function aggregator() external view returns (address);
diff --git a/contracts/src/v0.8/automation/1_2/KeeperRegistrar1_2.sol b/contracts/src/v0.8/automation/v1_2/KeeperRegistrar1_2.sol
similarity index 99%
rename from contracts/src/v0.8/automation/1_2/KeeperRegistrar1_2.sol
rename to contracts/src/v0.8/automation/v1_2/KeeperRegistrar1_2.sol
index e3e10de131d..f455d56f17a 100644
--- a/contracts/src/v0.8/automation/1_2/KeeperRegistrar1_2.sol
+++ b/contracts/src/v0.8/automation/v1_2/KeeperRegistrar1_2.sol
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.6;
-import "../interfaces/1_2/KeeperRegistryInterface1_2.sol";
+import "../interfaces/v1_2/KeeperRegistryInterface1_2.sol";
import "../../interfaces/TypeAndVersionInterface.sol";
import "../../shared/interfaces/LinkTokenInterface.sol";
import "../../shared/access/ConfirmedOwner.sol";
diff --git a/contracts/src/v0.8/automation/1_2/KeeperRegistry1_2.sol b/contracts/src/v0.8/automation/v1_2/KeeperRegistry1_2.sol
similarity index 99%
rename from contracts/src/v0.8/automation/1_2/KeeperRegistry1_2.sol
rename to contracts/src/v0.8/automation/v1_2/KeeperRegistry1_2.sol
index 70bd176f82e..262b8357f7a 100644
--- a/contracts/src/v0.8/automation/1_2/KeeperRegistry1_2.sol
+++ b/contracts/src/v0.8/automation/v1_2/KeeperRegistry1_2.sol
@@ -9,7 +9,7 @@ import "../KeeperBase.sol";
import "../../interfaces/TypeAndVersionInterface.sol";
import "../../interfaces/AggregatorV3Interface.sol";
import "../interfaces/KeeperCompatibleInterface.sol";
-import "../interfaces/1_2/KeeperRegistryInterface1_2.sol";
+import "../interfaces/v1_2/KeeperRegistryInterface1_2.sol";
import "../interfaces/MigratableKeeperRegistryInterface.sol";
import "../interfaces/UpkeepTranscoderInterface.sol";
import "../../shared/interfaces/IERC677Receiver.sol";
diff --git a/contracts/src/v0.8/automation/1_2/KeeperRegistryCheckUpkeepGasUsageWrapper1_2.sol b/contracts/src/v0.8/automation/v1_2/KeeperRegistryCheckUpkeepGasUsageWrapper1_2.sol
similarity index 97%
rename from contracts/src/v0.8/automation/1_2/KeeperRegistryCheckUpkeepGasUsageWrapper1_2.sol
rename to contracts/src/v0.8/automation/v1_2/KeeperRegistryCheckUpkeepGasUsageWrapper1_2.sol
index dd6c83565bb..253a421a5a0 100644
--- a/contracts/src/v0.8/automation/1_2/KeeperRegistryCheckUpkeepGasUsageWrapper1_2.sol
+++ b/contracts/src/v0.8/automation/v1_2/KeeperRegistryCheckUpkeepGasUsageWrapper1_2.sol
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.6;
-import {AutomationRegistryExecutableInterface} from "../interfaces/1_2/AutomationRegistryInterface1_2.sol";
+import {AutomationRegistryExecutableInterface} from "../interfaces/v1_2/AutomationRegistryInterface1_2.sol";
import {ConfirmedOwner} from "../../shared/access/ConfirmedOwner.sol";
/**
diff --git a/contracts/src/v0.8/automation/1_3/KeeperRegistry1_3.sol b/contracts/src/v0.8/automation/v1_3/KeeperRegistry1_3.sol
similarity index 99%
rename from contracts/src/v0.8/automation/1_3/KeeperRegistry1_3.sol
rename to contracts/src/v0.8/automation/v1_3/KeeperRegistry1_3.sol
index 7f75ae87af2..c40f79f85b4 100644
--- a/contracts/src/v0.8/automation/1_3/KeeperRegistry1_3.sol
+++ b/contracts/src/v0.8/automation/v1_3/KeeperRegistry1_3.sol
@@ -6,7 +6,7 @@ import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
import "@openzeppelin/contracts/utils/Address.sol";
import "./KeeperRegistryBase1_3.sol";
import "./KeeperRegistryLogic1_3.sol";
-import {AutomationRegistryExecutableInterface} from "../interfaces/1_3/AutomationRegistryInterface1_3.sol";
+import {AutomationRegistryExecutableInterface} from "../interfaces/v1_3/AutomationRegistryInterface1_3.sol";
import "../interfaces/MigratableKeeperRegistryInterface.sol";
import "../../interfaces/TypeAndVersionInterface.sol";
import "../../shared/interfaces/IERC677Receiver.sol";
diff --git a/contracts/src/v0.8/automation/1_3/KeeperRegistryBase1_3.sol b/contracts/src/v0.8/automation/v1_3/KeeperRegistryBase1_3.sol
similarity index 98%
rename from contracts/src/v0.8/automation/1_3/KeeperRegistryBase1_3.sol
rename to contracts/src/v0.8/automation/v1_3/KeeperRegistryBase1_3.sol
index 2f5156ee081..d63f6f40e88 100644
--- a/contracts/src/v0.8/automation/1_3/KeeperRegistryBase1_3.sol
+++ b/contracts/src/v0.8/automation/v1_3/KeeperRegistryBase1_3.sol
@@ -4,9 +4,9 @@ import "@openzeppelin/contracts/security/Pausable.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
import "../../vendor/@arbitrum/nitro-contracts/src/precompiles/ArbGasInfo.sol";
-import "../../vendor/@eth-optimism/contracts/0.8.6/contracts/L2/predeploys/OVM_GasPriceOracle.sol";
+import "../../vendor/@eth-optimism/contracts/v0.8.6/contracts/L2/predeploys/OVM_GasPriceOracle.sol";
import "../ExecutionPrevention.sol";
-import {Config, State, Upkeep} from "../interfaces/1_3/AutomationRegistryInterface1_3.sol";
+import {Config, State, Upkeep} from "../interfaces/v1_3/AutomationRegistryInterface1_3.sol";
import "../../shared/access/ConfirmedOwner.sol";
import "../../interfaces/AggregatorV3Interface.sol";
import "../../shared/interfaces/LinkTokenInterface.sol";
diff --git a/contracts/src/v0.8/automation/1_3/KeeperRegistryLogic1_3.sol b/contracts/src/v0.8/automation/v1_3/KeeperRegistryLogic1_3.sol
similarity index 100%
rename from contracts/src/v0.8/automation/1_3/KeeperRegistryLogic1_3.sol
rename to contracts/src/v0.8/automation/v1_3/KeeperRegistryLogic1_3.sol
diff --git a/contracts/src/v0.8/automation/2_0/KeeperRegistrar2_0.sol b/contracts/src/v0.8/automation/v2_0/KeeperRegistrar2_0.sol
similarity index 99%
rename from contracts/src/v0.8/automation/2_0/KeeperRegistrar2_0.sol
rename to contracts/src/v0.8/automation/v2_0/KeeperRegistrar2_0.sol
index 15cba57e7bb..c1b7e45b859 100644
--- a/contracts/src/v0.8/automation/2_0/KeeperRegistrar2_0.sol
+++ b/contracts/src/v0.8/automation/v2_0/KeeperRegistrar2_0.sol
@@ -2,7 +2,7 @@
pragma solidity 0.8.6;
import "../../shared/interfaces/LinkTokenInterface.sol";
-import "../interfaces/2_0/AutomationRegistryInterface2_0.sol";
+import "../interfaces/v2_0/AutomationRegistryInterface2_0.sol";
import "../../interfaces/TypeAndVersionInterface.sol";
import "../../shared/access/ConfirmedOwner.sol";
import "../../shared/interfaces/IERC677Receiver.sol";
diff --git a/contracts/src/v0.8/automation/2_0/KeeperRegistry2_0.sol b/contracts/src/v0.8/automation/v2_0/KeeperRegistry2_0.sol
similarity index 99%
rename from contracts/src/v0.8/automation/2_0/KeeperRegistry2_0.sol
rename to contracts/src/v0.8/automation/v2_0/KeeperRegistry2_0.sol
index bc928bd4292..34781f18258 100644
--- a/contracts/src/v0.8/automation/2_0/KeeperRegistry2_0.sol
+++ b/contracts/src/v0.8/automation/v2_0/KeeperRegistry2_0.sol
@@ -5,7 +5,7 @@ import "../../vendor/openzeppelin-solidity/v4.7.3/contracts/proxy/Proxy.sol";
import "../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/structs/EnumerableSet.sol";
import "../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/Address.sol";
import "./KeeperRegistryBase2_0.sol";
-import {AutomationRegistryExecutableInterface, UpkeepInfo} from "../interfaces/2_0/AutomationRegistryInterface2_0.sol";
+import {AutomationRegistryExecutableInterface, UpkeepInfo} from "../interfaces/v2_0/AutomationRegistryInterface2_0.sol";
import "../interfaces/MigratableKeeperRegistryInterface.sol";
import "../interfaces/MigratableKeeperRegistryInterfaceV2.sol";
import "../../shared/interfaces/IERC677Receiver.sol";
diff --git a/contracts/src/v0.8/automation/2_0/KeeperRegistryBase2_0.sol b/contracts/src/v0.8/automation/v2_0/KeeperRegistryBase2_0.sol
similarity index 99%
rename from contracts/src/v0.8/automation/2_0/KeeperRegistryBase2_0.sol
rename to contracts/src/v0.8/automation/v2_0/KeeperRegistryBase2_0.sol
index 74a13d71100..c1e9a279f84 100644
--- a/contracts/src/v0.8/automation/2_0/KeeperRegistryBase2_0.sol
+++ b/contracts/src/v0.8/automation/v2_0/KeeperRegistryBase2_0.sol
@@ -3,10 +3,10 @@ pragma solidity 0.8.6;
import "../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/structs/EnumerableSet.sol";
import "../../vendor/@arbitrum/nitro-contracts/src/precompiles/ArbGasInfo.sol";
-import "../../vendor/@eth-optimism/contracts/0.8.6/contracts/L2/predeploys/OVM_GasPriceOracle.sol";
+import "../../vendor/@eth-optimism/contracts/v0.8.6/contracts/L2/predeploys/OVM_GasPriceOracle.sol";
import {ArbSys} from "../../vendor/@arbitrum/nitro-contracts/src/precompiles/ArbSys.sol";
import "../ExecutionPrevention.sol";
-import {OnchainConfig, State, UpkeepFailureReason} from "../interfaces/2_0/AutomationRegistryInterface2_0.sol";
+import {OnchainConfig, State, UpkeepFailureReason} from "../interfaces/v2_0/AutomationRegistryInterface2_0.sol";
import "../../shared/access/ConfirmedOwner.sol";
import "../../interfaces/AggregatorV3Interface.sol";
import "../../shared/interfaces/LinkTokenInterface.sol";
diff --git a/contracts/src/v0.8/automation/2_0/KeeperRegistryLogic2_0.sol b/contracts/src/v0.8/automation/v2_0/KeeperRegistryLogic2_0.sol
similarity index 100%
rename from contracts/src/v0.8/automation/2_0/KeeperRegistryLogic2_0.sol
rename to contracts/src/v0.8/automation/v2_0/KeeperRegistryLogic2_0.sol
diff --git a/contracts/src/v0.8/dev/automation/UpkeepTranscoder3_0.sol b/contracts/src/v0.8/automation/v2_0/UpkeepTranscoder3_0.sol
similarity index 94%
rename from contracts/src/v0.8/dev/automation/UpkeepTranscoder3_0.sol
rename to contracts/src/v0.8/automation/v2_0/UpkeepTranscoder3_0.sol
index 618f97db8fd..0a56f209cc8 100644
--- a/contracts/src/v0.8/dev/automation/UpkeepTranscoder3_0.sol
+++ b/contracts/src/v0.8/automation/v2_0/UpkeepTranscoder3_0.sol
@@ -4,9 +4,9 @@ pragma solidity 0.8.6;
import "../../automation/interfaces/UpkeepTranscoderInterface.sol";
import "../../interfaces/TypeAndVersionInterface.sol";
-import {Upkeep as UpkeepV1} from "../../automation/1_2/KeeperRegistry1_2.sol";
-import {Upkeep as UpkeepV2} from "../../automation/1_3/KeeperRegistryBase1_3.sol";
-import {Upkeep as UpkeepV3} from "../../automation/2_0/KeeperRegistryBase2_0.sol";
+import {Upkeep as UpkeepV1} from "../../automation/v1_2/KeeperRegistry1_2.sol";
+import {Upkeep as UpkeepV2} from "../../automation/v1_3/KeeperRegistryBase1_3.sol";
+import {Upkeep as UpkeepV3} from "../../automation/v2_0/KeeperRegistryBase2_0.sol";
import "../../automation/UpkeepFormat.sol";
/**
diff --git a/contracts/src/v0.8/dev/automation/2_1/AutomationForwarder.sol b/contracts/src/v0.8/automation/v2_1/AutomationForwarder.sol
similarity index 93%
rename from contracts/src/v0.8/dev/automation/2_1/AutomationForwarder.sol
rename to contracts/src/v0.8/automation/v2_1/AutomationForwarder.sol
index 1391a2babe7..e5a80ce3252 100644
--- a/contracts/src/v0.8/dev/automation/2_1/AutomationForwarder.sol
+++ b/contracts/src/v0.8/automation/v2_1/AutomationForwarder.sol
@@ -1,8 +1,7 @@
-// SPDX-License-Identifier: MIT
+// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.16;
-import "../../../interfaces/TypeAndVersionInterface.sol";
-import {IAutomationRegistryConsumer} from "./interfaces/IAutomationRegistryConsumer.sol";
+import {IAutomationRegistryConsumer} from "../interfaces/IAutomationRegistryConsumer.sol";
uint256 constant PERFORM_GAS_CUSHION = 5_000;
@@ -13,8 +12,12 @@ uint256 constant PERFORM_GAS_CUSHION = 5_000;
* want to programatically interact with the registry (ie top up funds) can do so.
*/
contract AutomationForwarder {
+ /// @notice the user's target contract address
address private immutable i_target;
+
+ /// @notice the shared logic address
address private immutable i_logic;
+
IAutomationRegistryConsumer private s_registry;
constructor(address target, address registry, address logic) {
diff --git a/contracts/src/v0.8/dev/automation/2_1/AutomationForwarderLogic.sol b/contracts/src/v0.8/automation/v2_1/AutomationForwarderLogic.sol
similarity index 76%
rename from contracts/src/v0.8/dev/automation/2_1/AutomationForwarderLogic.sol
rename to contracts/src/v0.8/automation/v2_1/AutomationForwarderLogic.sol
index 0a5535ce061..a7903c379df 100644
--- a/contracts/src/v0.8/dev/automation/2_1/AutomationForwarderLogic.sol
+++ b/contracts/src/v0.8/automation/v2_1/AutomationForwarderLogic.sol
@@ -1,8 +1,8 @@
-// SPDX-License-Identifier: MIT
+// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.16;
-import {IAutomationRegistryConsumer} from "./interfaces/IAutomationRegistryConsumer.sol";
-import {ITypeAndVersion} from "../../../shared/interfaces/ITypeAndVersion.sol";
+import {IAutomationRegistryConsumer} from "../interfaces/IAutomationRegistryConsumer.sol";
+import {ITypeAndVersion} from "../../shared/interfaces/ITypeAndVersion.sol";
contract AutomationForwarderLogic is ITypeAndVersion {
IAutomationRegistryConsumer private s_registry;
diff --git a/contracts/src/v0.8/dev/automation/2_1/AutomationRegistrar2_1.sol b/contracts/src/v0.8/automation/v2_1/AutomationRegistrar2_1.sol
similarity index 95%
rename from contracts/src/v0.8/dev/automation/2_1/AutomationRegistrar2_1.sol
rename to contracts/src/v0.8/automation/v2_1/AutomationRegistrar2_1.sol
index 0f60426cfa2..407dda2414e 100644
--- a/contracts/src/v0.8/dev/automation/2_1/AutomationRegistrar2_1.sol
+++ b/contracts/src/v0.8/automation/v2_1/AutomationRegistrar2_1.sol
@@ -1,11 +1,11 @@
-// SPDX-License-Identifier: MIT
+// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.16;
-import "../../../shared/interfaces/LinkTokenInterface.sol";
-import "./interfaces/IKeeperRegistryMaster.sol";
-import "../../../interfaces/TypeAndVersionInterface.sol";
-import "../../../shared/access/ConfirmedOwner.sol";
-import "../../../shared/interfaces/IERC677Receiver.sol";
+import {LinkTokenInterface} from "../../shared/interfaces/LinkTokenInterface.sol";
+import {IKeeperRegistryMaster} from "../interfaces/v2_1/IKeeperRegistryMaster.sol";
+import {TypeAndVersionInterface} from "../../interfaces/TypeAndVersionInterface.sol";
+import {ConfirmedOwner} from "../../shared/access/ConfirmedOwner.sol";
+import {IERC677Receiver} from "../../shared/interfaces/IERC677Receiver.sol";
/**
* @notice Contract to accept requests for upkeep registrations
@@ -379,7 +379,9 @@ contract AutomationRegistrar2_1 is TypeAndVersionInterface, ConfirmedOwner, IERC
}
}
- //PRIVATE
+ // ================================================================
+ // | PRIVATE |
+ // ================================================================
/**
* @dev verify registration request and emit RegistrationRequested event
@@ -431,8 +433,6 @@ contract AutomationRegistrar2_1 is TypeAndVersionInterface, ConfirmedOwner, IERC
*/
function _approve(RegistrationParams memory params, bytes32 hash) private returns (uint256) {
IKeeperRegistryMaster keeperRegistry = s_config.keeperRegistry;
-
- // register upkeep
uint256 upkeepId = keeperRegistry.registerUpkeep(
params.upkeepContract,
params.gasLimit,
@@ -442,14 +442,11 @@ contract AutomationRegistrar2_1 is TypeAndVersionInterface, ConfirmedOwner, IERC
params.triggerConfig,
params.offchainConfig
);
- // fund upkeep
bool success = LINK.transferAndCall(address(keeperRegistry), params.amount, abi.encode(upkeepId));
if (!success) {
revert LinkTransferFailed(address(keeperRegistry));
}
-
emit RegistrationApproved(hash, params.name, upkeepId);
-
return upkeepId;
}
@@ -469,7 +466,9 @@ contract AutomationRegistrar2_1 is TypeAndVersionInterface, ConfirmedOwner, IERC
return false;
}
- //MODIFIERS
+ // ================================================================
+ // | MODIFIERS |
+ // ================================================================
/**
* @dev Reverts if not sent from the LINK token
diff --git a/contracts/src/v0.8/dev/automation/2_1/AutomationUtils2_1.sol b/contracts/src/v0.8/automation/v2_1/AutomationUtils2_1.sol
similarity index 87%
rename from contracts/src/v0.8/dev/automation/2_1/AutomationUtils2_1.sol
rename to contracts/src/v0.8/automation/v2_1/AutomationUtils2_1.sol
index 3de56b6a1d0..ed19b450d8b 100644
--- a/contracts/src/v0.8/dev/automation/2_1/AutomationUtils2_1.sol
+++ b/contracts/src/v0.8/automation/v2_1/AutomationUtils2_1.sol
@@ -1,8 +1,8 @@
-// SPDX-License-Identifier: MIT
+// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.16;
-import "./KeeperRegistryBase2_1.sol";
-import "./interfaces/ILogAutomation.sol";
+import {KeeperRegistryBase2_1} from "./KeeperRegistryBase2_1.sol";
+import {ILogAutomation, Log} from "../interfaces/ILogAutomation.sol";
/**
* @notice this file exposes structs that are otherwise internal to the automation registry
diff --git a/contracts/src/v0.8/dev/automation/2_1/KeeperRegistry2_1.sol b/contracts/src/v0.8/automation/v2_1/KeeperRegistry2_1.sol
similarity index 91%
rename from contracts/src/v0.8/dev/automation/2_1/KeeperRegistry2_1.sol
rename to contracts/src/v0.8/automation/v2_1/KeeperRegistry2_1.sol
index db3a9b14113..bb287c3c731 100644
--- a/contracts/src/v0.8/dev/automation/2_1/KeeperRegistry2_1.sol
+++ b/contracts/src/v0.8/automation/v2_1/KeeperRegistry2_1.sol
@@ -1,12 +1,14 @@
-// SPDX-License-Identifier: MIT
+// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.16;
-import "../../../vendor/openzeppelin-solidity/v4.7.3/contracts/proxy/Proxy.sol";
-import "./KeeperRegistryBase2_1.sol";
-import "./KeeperRegistryLogicB2_1.sol";
-import "./Chainable.sol";
-import "../../../shared/interfaces/IERC677Receiver.sol";
-import "../../../shared/ocr2/OCR2Abstract.sol";
+import {EnumerableSet} from "../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/structs/EnumerableSet.sol";
+import {Address} from "../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/Address.sol";
+import {Proxy} from "../../vendor/openzeppelin-solidity/v4.7.3/contracts/proxy/Proxy.sol";
+import {KeeperRegistryBase2_1} from "./KeeperRegistryBase2_1.sol";
+import {KeeperRegistryLogicB2_1} from "./KeeperRegistryLogicB2_1.sol";
+import {Chainable} from "../Chainable.sol";
+import {IERC677Receiver} from "../../shared/interfaces/IERC677Receiver.sol";
+import {OCR2Abstract} from "../../shared/ocr2/OCR2Abstract.sol";
/**
* @notice Registry for adding work for Chainlink Keepers to perform on client
@@ -55,9 +57,9 @@ contract KeeperRegistry2_1 is KeeperRegistryBase2_1, OCR2Abstract, Chainable, IE
Chainable(address(logicA))
{}
- ////////
- // ACTIONS
- ////////
+ // ================================================================
+ // | ACTIONS |
+ // ================================================================
/**
* @inheritdoc OCR2Abstract
@@ -215,9 +217,9 @@ contract KeeperRegistry2_1 is KeeperRegistryBase2_1, OCR2Abstract, Chainable, IE
emit FundsAdded(id, sender, uint96(amount));
}
- /////////////
- // SETTERS //
- /////////////
+ // ================================================================
+ // | SETTERS |
+ // ================================================================
/**
* @inheritdoc OCR2Abstract
@@ -365,9 +367,9 @@ contract KeeperRegistry2_1 is KeeperRegistryBase2_1, OCR2Abstract, Chainable, IE
);
}
- /////////////
- // GETTERS //
- /////////////
+ // ================================================================
+ // | GETTERS |
+ // ================================================================
/**
* @inheritdoc OCR2Abstract
diff --git a/contracts/src/v0.8/dev/automation/2_1/KeeperRegistryBase2_1.sol b/contracts/src/v0.8/automation/v2_1/KeeperRegistryBase2_1.sol
similarity index 95%
rename from contracts/src/v0.8/dev/automation/2_1/KeeperRegistryBase2_1.sol
rename to contracts/src/v0.8/automation/v2_1/KeeperRegistryBase2_1.sol
index 45501eaae95..86942f3108d 100644
--- a/contracts/src/v0.8/dev/automation/2_1/KeeperRegistryBase2_1.sol
+++ b/contracts/src/v0.8/automation/v2_1/KeeperRegistryBase2_1.sol
@@ -1,20 +1,20 @@
-// SPDX-License-Identifier: MIT
+// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.16;
-import "../../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/structs/EnumerableSet.sol";
-import "../../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/Address.sol";
-import "../../../vendor/@arbitrum/nitro-contracts/src/precompiles/ArbGasInfo.sol";
-import "../../../vendor/@eth-optimism/contracts/0.8.9/contracts/L2/predeploys/OVM_GasPriceOracle.sol";
-import "../../../automation/ExecutionPrevention.sol";
-import {ArbSys} from "../../../vendor/@arbitrum/nitro-contracts/src/precompiles/ArbSys.sol";
-import "./interfaces/FeedLookupCompatibleInterface.sol";
-import "./interfaces/ILogAutomation.sol";
-import {IAutomationForwarder} from "./interfaces/IAutomationForwarder.sol";
-import "../../../shared/access/ConfirmedOwner.sol";
-import "../../../interfaces/AggregatorV3Interface.sol";
-import "../../../shared/interfaces/LinkTokenInterface.sol";
-import "../../../automation/interfaces/KeeperCompatibleInterface.sol";
-import "../../../automation/interfaces/UpkeepTranscoderInterface.sol";
+import {EnumerableSet} from "../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/structs/EnumerableSet.sol";
+import {Address} from "../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/Address.sol";
+import {ArbGasInfo} from "../../vendor/@arbitrum/nitro-contracts/src/precompiles/ArbGasInfo.sol";
+import {OVM_GasPriceOracle} from "../../vendor/@eth-optimism/contracts/v0.8.9/contracts/L2/predeploys/OVM_GasPriceOracle.sol";
+import {ExecutionPrevention} from "../ExecutionPrevention.sol";
+import {ArbSys} from "../../vendor/@arbitrum/nitro-contracts/src/precompiles/ArbSys.sol";
+import {StreamsLookupCompatibleInterface} from "../interfaces/StreamsLookupCompatibleInterface.sol";
+import {ILogAutomation, Log} from "../interfaces/ILogAutomation.sol";
+import {IAutomationForwarder} from "../interfaces/IAutomationForwarder.sol";
+import {ConfirmedOwner} from "../../shared/access/ConfirmedOwner.sol";
+import {AggregatorV3Interface} from "../../interfaces/AggregatorV3Interface.sol";
+import {LinkTokenInterface} from "../../shared/interfaces/LinkTokenInterface.sol";
+import {KeeperCompatibleInterface} from "../interfaces/KeeperCompatibleInterface.sol";
+import {UpkeepTranscoderInterface, UpkeepFormat} from "../interfaces/UpkeepTranscoderInterface.sol";
/**
* @notice Base Keeper Registry contract, contains shared logic between
@@ -30,7 +30,7 @@ abstract contract KeeperRegistryBase2_1 is ConfirmedOwner, ExecutionPrevention {
address internal constant IGNORE_ADDRESS = 0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF;
bytes4 internal constant CHECK_SELECTOR = KeeperCompatibleInterface.checkUpkeep.selector;
bytes4 internal constant PERFORM_SELECTOR = KeeperCompatibleInterface.performUpkeep.selector;
- bytes4 internal constant CHECK_CALLBACK_SELECTOR = FeedLookupCompatibleInterface.checkCallback.selector;
+ bytes4 internal constant CHECK_CALLBACK_SELECTOR = StreamsLookupCompatibleInterface.checkCallback.selector;
bytes4 internal constant CHECK_LOG_SELECTOR = ILogAutomation.checkLog.selector;
uint256 internal constant PERFORM_GAS_MIN = 2_300;
uint256 internal constant CANCELLATION_DELAY = 50;
@@ -398,6 +398,7 @@ abstract contract KeeperRegistryBase2_1 is ConfirmedOwner, ExecutionPrevention {
* not necessarily the block number that the log was emitted in!!!!
*/
struct LogTrigger {
+ bytes32 logBlockHash;
bytes32 txHash;
uint32 logIndex;
uint32 blockNum;
@@ -461,9 +462,9 @@ abstract contract KeeperRegistryBase2_1 is ConfirmedOwner, ExecutionPrevention {
i_automationForwarderLogic = automationForwarderLogic;
}
- ///////////////////////////////////////////////////////////////////////////////////////
- /////////////////////////////// INTERNAL FUNCTIONS ONLY ///////////////////////////////
- ///////////////////////////////////////////////////////////////////////////////////////
+ // ================================================================
+ // | INTERNAL FUNCTIONS ONLY |
+ // ================================================================
/**
* @dev creates a new upkeep with the given fields
@@ -794,7 +795,7 @@ abstract contract KeeperRegistryBase2_1 is ConfirmedOwner, ExecutionPrevention {
UpkeepTransmitInfo memory transmitInfo
) internal returns (bool, bytes32) {
LogTrigger memory trigger = abi.decode(rawTrigger, (LogTrigger));
- bytes32 dedupID = keccak256(abi.encodePacked(upkeepId, trigger.txHash, trigger.logIndex));
+ bytes32 dedupID = keccak256(abi.encodePacked(upkeepId, trigger.logBlockHash, trigger.txHash, trigger.logIndex));
if (
(trigger.blockHash != bytes32("") && _blockHash(trigger.blockNum) != trigger.blockHash) ||
trigger.blockNum >= _blockNum()
diff --git a/contracts/src/v0.8/dev/automation/2_1/KeeperRegistryLogicA2_1.sol b/contracts/src/v0.8/automation/v2_1/KeeperRegistryLogicA2_1.sol
similarity index 94%
rename from contracts/src/v0.8/dev/automation/2_1/KeeperRegistryLogicA2_1.sol
rename to contracts/src/v0.8/automation/v2_1/KeeperRegistryLogicA2_1.sol
index ca3d6f7efd0..e3845ce63bd 100644
--- a/contracts/src/v0.8/dev/automation/2_1/KeeperRegistryLogicA2_1.sol
+++ b/contracts/src/v0.8/automation/v2_1/KeeperRegistryLogicA2_1.sol
@@ -1,12 +1,15 @@
-// SPDX-License-Identifier: MIT
+// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.16;
-import "./KeeperRegistryBase2_1.sol";
-import "./KeeperRegistryLogicB2_1.sol";
-import "./Chainable.sol";
+import {EnumerableSet} from "../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/structs/EnumerableSet.sol";
+import {Address} from "../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/Address.sol";
+import {KeeperRegistryBase2_1} from "./KeeperRegistryBase2_1.sol";
+import {KeeperRegistryLogicB2_1} from "./KeeperRegistryLogicB2_1.sol";
+import {Chainable} from "../Chainable.sol";
import {AutomationForwarder} from "./AutomationForwarder.sol";
-import "../../../automation/interfaces/UpkeepTranscoderInterfaceV2.sol";
-import "../../../automation/interfaces/MigratableKeeperRegistryInterfaceV2.sol";
+import {IAutomationForwarder} from "../interfaces/IAutomationForwarder.sol";
+import {UpkeepTranscoderInterfaceV2} from "../interfaces/UpkeepTranscoderInterfaceV2.sol";
+import {MigratableKeeperRegistryInterfaceV2} from "../interfaces/MigratableKeeperRegistryInterfaceV2.sol";
/**
* @notice Logic contract, works in tandem with KeeperRegistry as a proxy
@@ -158,9 +161,9 @@ contract KeeperRegistryLogicA2_1 is KeeperRegistryBase2_1, Chainable {
}
/**
- * @dev checkCallback is used specifically for automation feed lookups (see FeedLookupCompatibleInterface.sol)
+ * @dev checkCallback is used specifically for automation data streams lookups (see StreamsLookupCompatibleInterface.sol)
* @param id the upkeepID to execute a callback for
- * @param values the values returned from the feed lookup
+ * @param values the values returned from the data streams lookup
* @param extraData the user-provided extra context data
*/
function checkCallback(
diff --git a/contracts/src/v0.8/dev/automation/2_1/KeeperRegistryLogicB2_1.sol b/contracts/src/v0.8/automation/v2_1/KeeperRegistryLogicB2_1.sol
similarity index 92%
rename from contracts/src/v0.8/dev/automation/2_1/KeeperRegistryLogicB2_1.sol
rename to contracts/src/v0.8/automation/v2_1/KeeperRegistryLogicB2_1.sol
index c34d2a01aaf..b394bff4ee8 100644
--- a/contracts/src/v0.8/dev/automation/2_1/KeeperRegistryLogicB2_1.sol
+++ b/contracts/src/v0.8/automation/v2_1/KeeperRegistryLogicB2_1.sol
@@ -1,7 +1,11 @@
-// SPDX-License-Identifier: MIT
+// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.16;
-import "./KeeperRegistryBase2_1.sol";
+import {KeeperRegistryBase2_1} from "./KeeperRegistryBase2_1.sol";
+import {EnumerableSet} from "../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/structs/EnumerableSet.sol";
+import {Address} from "../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/Address.sol";
+import {UpkeepFormat} from "../interfaces/UpkeepTranscoderInterface.sol";
+import {IAutomationForwarder} from "../interfaces/IAutomationForwarder.sol";
contract KeeperRegistryLogicB2_1 is KeeperRegistryBase2_1 {
using Address for address;
@@ -19,9 +23,9 @@ contract KeeperRegistryLogicB2_1 is KeeperRegistryBase2_1 {
address automationForwarderLogic
) KeeperRegistryBase2_1(mode, link, linkNativeFeed, fastGasFeed, automationForwarderLogic) {}
- ///////////////////////
- // UPKEEP MANAGEMENT //
- ///////////////////////
+ // ================================================================
+ // | UPKEEP MANAGEMENT |
+ // ================================================================
/**
* @notice transfers the address of an admin for an upkeep
@@ -120,9 +124,9 @@ contract KeeperRegistryLogicB2_1 is KeeperRegistryBase2_1 {
emit FundsWithdrawn(id, amountToWithdraw, to);
}
- /////////////////////
- // NODE MANAGEMENT //
- /////////////////////
+ // ================================================================
+ // | NODE MANAGEMENT |
+ // ================================================================
/**
* @notice transfers the address of payee for a transmitter
@@ -162,9 +166,9 @@ contract KeeperRegistryLogicB2_1 is KeeperRegistryBase2_1 {
emit PaymentWithdrawn(from, balance, to, msg.sender);
}
- /////////////////////////////
- // OWNER / MANAGER ACTIONS //
- /////////////////////////////
+ // ================================================================
+ // | OWNER / MANAGER ACTIONS |
+ // ================================================================
/**
* @notice sets the privilege config for an upkeep
@@ -252,9 +256,9 @@ contract KeeperRegistryLogicB2_1 is KeeperRegistryBase2_1 {
emit AdminPrivilegeConfigSet(admin, newPrivilegeConfig);
}
- /////////////
- // GETTERS //
- /////////////
+ // ================================================================
+ // | GETTERS |
+ // ================================================================
function getConditionalGasOverhead() external pure returns (uint256) {
return REGISTRY_CONDITIONAL_OVERHEAD;
diff --git a/contracts/src/v0.8/automation/v2_1/LICENSE b/contracts/src/v0.8/automation/v2_1/LICENSE
new file mode 100644
index 00000000000..03ba03d7792
--- /dev/null
+++ b/contracts/src/v0.8/automation/v2_1/LICENSE
@@ -0,0 +1,55 @@
+Business Source License 1.1
+
+License text copyright (c) 2017 MariaDB Corporation Ab, All Rights Reserved.
+"Business Source License" is a trademark of MariaDB Corporation Ab.
+
+---
+
+Parameters
+
+Licensor: SmartContract Chainlink Limited SEZC
+
+Licensed Work: Automation v2.1
+The Licensed Work is (c) 2023 SmartContract Chainlink Limited SEZC
+
+Additional Use Grant: Any uses listed and defined at https://github.com/smartcontractkit/ocr2keepers/tree/main/pkg/v3/Automation_v2.1_Grants.md
+
+Change Date: September 12, 2027
+
+Change License: MIT
+
+---
+
+Terms
+
+The Licensor hereby grants you the right to copy, modify, create derivative works, redistribute, and make non-production use of the Licensed Work. The Licensor may make an Additional Use Grant, above, permitting limited production use.
+
+Effective on the Change Date, or the fourth anniversary of the first publicly available distribution of a specific version of the Licensed Work under this License, whichever comes first, the Licensor hereby grants you rights under the terms of the Change License, and the rights granted in the paragraph above terminate.
+
+If your use of the Licensed Work does not comply with the requirements currently in effect as described in this License, you must purchase a commercial license from the Licensor, its affiliated entities, or authorized resellers, or you must refrain from using the Licensed Work.
+
+All copies of the original and modified Licensed Work, and derivative works of the Licensed Work, are subject to this License. This License applies separately for each version of the Licensed Work and the Change Date may vary for each version of the Licensed Work released by Licensor.
+
+You must conspicuously display this License on each original or modified copy of the Licensed Work. If you receive the Licensed Work in original or modified form from a third party, the terms and conditions set forth in this License apply to your use of that work.
+
+Any use of the Licensed Work in violation of this License will automatically terminate your rights under this License for the current and all other versions of the Licensed Work.
+
+This License does not grant you any right in any trademark or logo of Licensor or its affiliates (provided that you may use a trademark or logo of Licensor as expressly required by this License).
+
+TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON AN "AS IS" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
+
+MariaDB hereby grants you permission to use this License’s text to license your works, and to refer to it using the trademark "Business Source License", as long as you comply with the Covenants of Licensor below.
+
+---
+
+Covenants of Licensor
+
+In consideration of the right to use this License’s text and the "Business Source License" name and trademark, Licensor covenants to MariaDB, and to all other recipients of the licensed work to be provided by Licensor:
+
+1. To specify as the Change License the GPL Version 2.0 or any later version, or a license that is compatible with GPL Version 2.0 or a later version, where "compatible" means that software provided under the Change License can be included in a program with software provided under GPL Version 2.0 or a later version. Licensor may specify additional Change Licenses without limitation.
+
+2. To either: (a) specify an additional grant of rights to use that does not impose any additional restriction on the right granted in this License, as the Additional Use Grant; or (b) insert the text "None".
+
+3. To specify a Change Date.
+
+4. Not to modify this License in any other way.
diff --git a/contracts/src/v0.8/dev/automation/2_1/README.md b/contracts/src/v0.8/automation/v2_1/README.md
similarity index 100%
rename from contracts/src/v0.8/dev/automation/2_1/README.md
rename to contracts/src/v0.8/automation/v2_1/README.md
diff --git a/contracts/src/v0.8/dev/automation/2_1/UpkeepTranscoder4_0.sol b/contracts/src/v0.8/automation/v2_1/UpkeepTranscoder4_0.sol
similarity index 94%
rename from contracts/src/v0.8/dev/automation/2_1/UpkeepTranscoder4_0.sol
rename to contracts/src/v0.8/automation/v2_1/UpkeepTranscoder4_0.sol
index 43979bd05bf..727a3dd33ad 100644
--- a/contracts/src/v0.8/dev/automation/2_1/UpkeepTranscoder4_0.sol
+++ b/contracts/src/v0.8/automation/v2_1/UpkeepTranscoder4_0.sol
@@ -1,12 +1,12 @@
-// SPDX-License-Identifier: MIT
+// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.16;
-import "../../../automation/interfaces/UpkeepTranscoderInterfaceV2.sol";
-import "../../../interfaces/TypeAndVersionInterface.sol";
+import {UpkeepTranscoderInterfaceV2} from "../interfaces/UpkeepTranscoderInterfaceV2.sol";
+import {TypeAndVersionInterface} from "../../interfaces/TypeAndVersionInterface.sol";
import {KeeperRegistryBase2_1 as R21} from "./KeeperRegistryBase2_1.sol";
-import {IAutomationForwarder} from "./interfaces/IAutomationForwarder.sol";
-import {AutomationRegistryBaseInterface, UpkeepInfo} from "../../../automation/interfaces/2_0/AutomationRegistryInterface2_0.sol";
+import {IAutomationForwarder} from "../interfaces/IAutomationForwarder.sol";
+import {AutomationRegistryBaseInterface, UpkeepInfo} from "../interfaces/v2_0/AutomationRegistryInterface2_0.sol";
enum RegistryVersion {
V12,
diff --git a/contracts/src/v0.8/dev/automation/2_1/test/AutomationForwarder.t.sol b/contracts/src/v0.8/automation/v2_1/test/AutomationForwarder.t.sol
similarity index 87%
rename from contracts/src/v0.8/dev/automation/2_1/test/AutomationForwarder.t.sol
rename to contracts/src/v0.8/automation/v2_1/test/AutomationForwarder.t.sol
index d876def8bf0..078d22d6c96 100644
--- a/contracts/src/v0.8/dev/automation/2_1/test/AutomationForwarder.t.sol
+++ b/contracts/src/v0.8/automation/v2_1/test/AutomationForwarder.t.sol
@@ -1,16 +1,16 @@
-// SPDX-License-Identifier: MIT
+// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.16;
-import {IAutomationRegistryConsumer} from "../interfaces/IAutomationRegistryConsumer.sol";
-import {IAutomationForwarder} from "../interfaces/IAutomationForwarder.sol";
+import {IAutomationRegistryConsumer} from "../../interfaces/IAutomationRegistryConsumer.sol";
+import {IAutomationForwarder} from "../../interfaces/IAutomationForwarder.sol";
import {AutomationForwarder} from "../AutomationForwarder.sol";
import {AutomationForwarderLogic} from "../AutomationForwarderLogic.sol";
-import {MockKeeperRegistry2_1} from "../mocks/MockKeeperRegistry2_1.sol";
-import {UpkeepCounter} from "../mocks/UpkeepCounter.sol";
+import {MockKeeperRegistry2_1} from "../../mocks/MockKeeperRegistry2_1.sol";
+import {UpkeepCounter} from "../../testhelpers/UpkeepCounter.sol";
import {BaseTest} from "./BaseTest.t.sol";
// in contracts directory, run
-// forge test --match-path src/v0.8/dev/automation/2_1/test/AutomationForwarder.t.sol
+// forge test --match-path src/v0.8/automation/v2_1/test/AutomationForwarder.t.sol
contract AutomationForwarderSetUp is BaseTest {
IAutomationForwarder internal forwarder;
diff --git a/contracts/src/v0.8/dev/automation/2_1/test/BaseTest.t.sol b/contracts/src/v0.8/automation/v2_1/test/BaseTest.t.sol
similarity index 86%
rename from contracts/src/v0.8/dev/automation/2_1/test/BaseTest.t.sol
rename to contracts/src/v0.8/automation/v2_1/test/BaseTest.t.sol
index 8f8e7587826..f5bc74286a4 100644
--- a/contracts/src/v0.8/dev/automation/2_1/test/BaseTest.t.sol
+++ b/contracts/src/v0.8/automation/v2_1/test/BaseTest.t.sol
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: MIT
+// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.16;
import {StructFactory} from "./StructFactory.sol";
diff --git a/contracts/src/v0.8/dev/automation/2_1/test/StructFactory.sol b/contracts/src/v0.8/automation/v2_1/test/StructFactory.sol
similarity index 77%
rename from contracts/src/v0.8/dev/automation/2_1/test/StructFactory.sol
rename to contracts/src/v0.8/automation/v2_1/test/StructFactory.sol
index b46c7797884..83bb9e89050 100644
--- a/contracts/src/v0.8/dev/automation/2_1/test/StructFactory.sol
+++ b/contracts/src/v0.8/automation/v2_1/test/StructFactory.sol
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: MIT
+// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.16;
contract StructFactory {
diff --git a/contracts/src/v0.8/dev/Flags.sol b/contracts/src/v0.8/dev/Flags.sol
index 11ffa61213d..a06a67026f3 100644
--- a/contracts/src/v0.8/dev/Flags.sol
+++ b/contracts/src/v0.8/dev/Flags.sol
@@ -1,8 +1,8 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.6;
-import "../SimpleReadAccessController.sol";
-import "../interfaces/AccessControllerInterface.sol";
+import "../shared/access/SimpleReadAccessController.sol";
+import "../shared/interfaces/AccessControllerInterface.sol";
import "../interfaces/TypeAndVersionInterface.sol";
/* dev dependencies - to be re/moved after audit */
diff --git a/contracts/src/v0.8/dev/automation/CanaryUpkeep1_2.sol b/contracts/src/v0.8/dev/automation/CanaryUpkeep1_2.sol
deleted file mode 100644
index bf711eb565f..00000000000
--- a/contracts/src/v0.8/dev/automation/CanaryUpkeep1_2.sol
+++ /dev/null
@@ -1,96 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity 0.8.6;
-
-import "../../automation/interfaces/KeeperCompatibleInterface.sol";
-import "../../automation/interfaces/1_2/KeeperRegistryInterface1_2.sol";
-import "../../shared/access/ConfirmedOwner.sol";
-
-error NoKeeperNodes();
-error InsufficientInterval();
-
-/**
- * @notice A canary upkeep which requires a different keeper to service its upkeep at an interval. This makes sure that
- * all keepers are in a healthy state.
- */
-contract CanaryUpkeep1_2 is KeeperCompatibleInterface, ConfirmedOwner {
- uint256 private s_keeperIndex;
- uint256 private s_interval;
- uint256 private s_timestamp;
- KeeperRegistryExecutableInterface private immutable i_keeperRegistry;
-
- /**
- * @param keeperRegistry address of a keeper registry
- */
- constructor(KeeperRegistryExecutableInterface keeperRegistry, uint256 interval) ConfirmedOwner(msg.sender) {
- i_keeperRegistry = keeperRegistry;
- s_timestamp = block.timestamp;
- s_interval = interval;
- s_keeperIndex = 0;
- }
-
- /**
- * @return the current keeper index
- */
- function getKeeperIndex() external view returns (uint256) {
- return s_keeperIndex;
- }
-
- /**
- * @return the current timestamp
- */
- function getTimestamp() external view returns (uint256) {
- return s_timestamp;
- }
-
- /**
- * @return the current interval
- */
- function getInterval() external view returns (uint256) {
- return s_interval;
- }
-
- /**
- * @return the keeper registry
- */
- function getKeeperRegistry() external view returns (KeeperRegistryExecutableInterface) {
- return i_keeperRegistry;
- }
-
- /**
- * @notice updates the interval
- * @param interval the new interval
- */
- function setInterval(uint256 interval) external onlyOwner {
- s_interval = interval;
- }
-
- /**
- * @notice returns true if keeper array is not empty and sufficient time has passed
- */
- function checkUpkeep(bytes calldata /* checkData */) external view override returns (bool, bytes memory) {
- bool upkeepNeeded = block.timestamp >= s_interval + s_timestamp;
- return (upkeepNeeded, bytes(""));
- }
-
- /**
- * @notice checks keepers array limit, timestamp limit, and requires transaction origin must be the anticipated keeper.
- * If all checks pass, update the keeper index and timestamp. Otherwise, revert this transaction.
- */
- function performUpkeep(bytes calldata /* performData */) external override {
- (State memory _s, Config memory _c, address[] memory keepers) = i_keeperRegistry.getState();
- if (keepers.length == 0) {
- revert NoKeeperNodes();
- }
- if (block.timestamp < s_interval + s_timestamp) {
- revert InsufficientInterval();
- }
- // if keepers array is shortened, this statement will make sure keeper index is always valid
- if (s_keeperIndex >= keepers.length) {
- s_keeperIndex = 0;
- }
-
- require(tx.origin == keepers[s_keeperIndex], "transaction origin is not the anticipated keeper.");
- s_keeperIndex = (s_keeperIndex + 1) % keepers.length;
- s_timestamp = block.timestamp;
- }
-}
diff --git a/contracts/src/v0.8/dev/interfaces/IVRFCoordinatorV2Plus.sol b/contracts/src/v0.8/dev/interfaces/IVRFCoordinatorV2Plus.sol
index ea37fb83875..0608340e674 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 00000000000..9892b88e691
--- /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 687ff9790f3..00000000000
--- 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 47b31d98bd1..49c131988a6 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/transmission/4337/Paymaster.sol b/contracts/src/v0.8/dev/transmission/ERC-4337/Paymaster.sol
similarity index 100%
rename from contracts/src/v0.8/dev/transmission/4337/Paymaster.sol
rename to contracts/src/v0.8/dev/transmission/ERC-4337/Paymaster.sol
diff --git a/contracts/src/v0.8/dev/transmission/4337/SCA.sol b/contracts/src/v0.8/dev/transmission/ERC-4337/SCA.sol
similarity index 100%
rename from contracts/src/v0.8/dev/transmission/4337/SCA.sol
rename to contracts/src/v0.8/dev/transmission/ERC-4337/SCA.sol
diff --git a/contracts/src/v0.8/dev/transmission/4337/SCALibrary.sol b/contracts/src/v0.8/dev/transmission/ERC-4337/SCALibrary.sol
similarity index 100%
rename from contracts/src/v0.8/dev/transmission/4337/SCALibrary.sol
rename to contracts/src/v0.8/dev/transmission/ERC-4337/SCALibrary.sol
diff --git a/contracts/src/v0.8/dev/transmission/4337/SmartContractAccountFactory.sol b/contracts/src/v0.8/dev/transmission/ERC-4337/SmartContractAccountFactory.sol
similarity index 100%
rename from contracts/src/v0.8/dev/transmission/4337/SmartContractAccountFactory.sol
rename to contracts/src/v0.8/dev/transmission/ERC-4337/SmartContractAccountFactory.sol
diff --git a/contracts/src/v0.8/dev/transmission/testhelpers/SmartContractAccountHelper.sol b/contracts/src/v0.8/dev/transmission/testhelpers/SmartContractAccountHelper.sol
index d11d2b55de8..108cd5477ac 100644
--- a/contracts/src/v0.8/dev/transmission/testhelpers/SmartContractAccountHelper.sol
+++ b/contracts/src/v0.8/dev/transmission/testhelpers/SmartContractAccountHelper.sol
@@ -1,6 +1,6 @@
-import "../4337/SCA.sol";
-import "../4337/SmartContractAccountFactory.sol";
-import "../4337/SCALibrary.sol";
+import "../ERC-4337/SCA.sol";
+import "../ERC-4337/SmartContractAccountFactory.sol";
+import "../ERC-4337/SCALibrary.sol";
pragma solidity ^0.8.15;
diff --git a/contracts/src/v0.8/dev/vrf/SubscriptionAPI.sol b/contracts/src/v0.8/dev/vrf/SubscriptionAPI.sol
index 3113385ecac..c4781cbde8c 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,10 +31,12 @@ 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();
// We use the subscription struct (1 word)
// at fulfillment time.
@@ -43,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
@@ -62,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
@@ -76,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);
@@ -126,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);
}
/**
@@ -157,6 +159,14 @@ abstract contract SubscriptionAPI is ConfirmedOwner, IERC677Receiver, IVRFSubscr
* @param to address to send link to
*/
function recoverFunds(address to) external onlyOwner {
+ // If LINK is not set, we cannot recover funds.
+ // It is possible that this coordinator address was funded with LINK
+ // by accident by a user but the LINK token needs to be set first
+ // before we can recover it.
+ if (address(LINK) == address(0)) {
+ revert LinkNotSet();
+ }
+
uint256 externalBalance = LINK.balanceOf(address(this));
uint256 internalBalance = uint256(s_totalBalance);
if (internalBalance > externalBalance) {
@@ -164,19 +174,21 @@ abstract contract SubscriptionAPI is ConfirmedOwner, IERC677Receiver, IVRFSubscr
}
if (internalBalance < externalBalance) {
uint256 amount = externalBalance - internalBalance;
- LINK.transfer(to, amount);
+ if (!LINK.transfer(to, amount)) {
+ revert FailedToTransferLink();
+ }
emit FundsRecovered(to, amount);
}
// If the balances are equal, nothing to be done.
}
/**
- * @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);
}
@@ -184,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.
}
@@ -197,6 +209,9 @@ abstract contract SubscriptionAPI is ConfirmedOwner, IERC677Receiver, IVRFSubscr
* @param amount amount to withdraw
*/
function oracleWithdraw(address recipient, uint96 amount) external nonReentrant {
+ if (address(LINK) == address(0)) {
+ revert LinkNotSet();
+ }
if (s_withdrawableTokens[msg.sender] < amount) {
revert InsufficientBalance();
}
@@ -208,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();
}
}
@@ -236,7 +251,7 @@ abstract contract SubscriptionAPI is ConfirmedOwner, IERC677Receiver, IVRFSubscr
if (s_subscriptionConfigs[subId].owner == address(0)) {
revert InvalidSubscription();
}
- // We do not check that the msg.sender is the subscription owner,
+ // We do not check that the sender is the subscription owner,
// anyone can fund a subscription.
uint256 oldBalance = s_subscriptions[subId].balance;
s_subscriptions[subId].balance += uint96(amount);
@@ -247,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();
}
@@ -255,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);
}
/**
@@ -270,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
@@ -314,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),
@@ -377,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++) {
@@ -391,21 +406,26 @@ 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);
- if (!LINK.transfer(to, uint256(balance))) {
- revert InsufficientBalance();
+ (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) {
+ if (!LINK.transfer(to, uint256(balance))) {
+ revert InsufficientBalance();
+ }
}
- // 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) {
@@ -418,8 +438,4 @@ abstract contract SubscriptionAPI is ConfirmedOwner, IERC677Receiver, IVRFSubscr
}
_;
}
-
- function getConsumerKey(address consumer, uint256 subId) internal pure returns (bytes32) {
- return keccak256(abi.encodePacked(subId, consumer));
- }
}
diff --git a/contracts/src/v0.8/dev/vrf/VRFConsumerBaseV2Plus.sol b/contracts/src/v0.8/dev/vrf/VRFConsumerBaseV2Plus.sol
index ed1f918212c..0e6e2b22016 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 internal 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 92%
rename from contracts/src/v0.8/dev/vrf/VRFCoordinatorV2Plus.sol
rename to contracts/src/v0.8/dev/vrf/VRFCoordinatorV2_5.sol
index f08fe8c8f24..113f098614d 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) {
@@ -653,11 +651,11 @@ contract VRFCoordinatorV2Plus is VRF, SubscriptionAPI {
revert CoordinatorNotRegistered(target);
}
- function migrate(uint256 subId, address newCoordinator) external {
+ function migrate(uint256 subId, address newCoordinator) external nonReentrant {
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,15 +665,25 @@ 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);
- require(LINK.transfer(address(newCoordinator), balance), "insufficient funds");
+ 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) {
+ require(LINK.transfer(address(newCoordinator), balance), "insufficient funds");
+ }
+
+ // despite the fact that we follow best practices this is still probably safest
+ // to prevent any re-entrancy possibilities.
+ s_config.reentrancyLock = true;
for (uint256 i = 0; i < consumers.length; i++) {
IVRFMigratableConsumerV2Plus(consumers[i]).setCoordinator(newCoordinator);
}
+ s_config.reentrancyLock = false;
+
emit MigrationCompleted(newCoordinator, subId);
}
diff --git a/contracts/src/v0.8/dev/vrf/VRFV2PlusWrapper.sol b/contracts/src/v0.8/dev/vrf/VRFV2PlusWrapper.sol
index c8cba34ec5a..edab249b3c6 100644
--- a/contracts/src/v0.8/dev/vrf/VRFV2PlusWrapper.sol
+++ b/contracts/src/v0.8/dev/vrf/VRFV2PlusWrapper.sol
@@ -19,9 +19,10 @@ contract VRFV2PlusWrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsume
event WrapperFulfillmentFailed(uint256 indexed requestId, address indexed consumer);
error LinkAlreadySet();
+ error FailedToTransferLink();
LinkTokenInterface public s_link;
- AggregatorV3Interface public s_linkEthFeed;
+ AggregatorV3Interface public s_linkNativeFeed;
ExtendedVRFCoordinatorV2PlusInterface public immutable COORDINATOR;
uint256 public immutable SUBSCRIPTION_ID;
/// @dev this is the size of a VRF v2 fulfillment's calldata abi-encoded in bytes.
@@ -64,7 +65,7 @@ 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
@@ -96,12 +97,12 @@ contract VRFV2PlusWrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsume
}
mapping(uint256 => Callback) /* requestID */ /* callback */ public s_callbacks;
- constructor(address _link, address _linkEthFeed, address _coordinator) VRFConsumerBaseV2Plus(_coordinator) {
+ 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);
@@ -124,11 +125,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);
}
/**
@@ -172,7 +173,7 @@ contract VRFV2PlusWrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsume
// Get other configuration from coordinator
(, , s_stalenessSeconds, ) = COORDINATOR.s_config();
s_fallbackWeiPerUnitLink = COORDINATOR.s_fallbackWeiPerUnitLink();
- (s_fulfillmentFlatFeeLinkPPM, s_fulfillmentFlatFeeEthPPM) = COORDINATOR.s_feeConfig();
+ (s_fulfillmentFlatFeeLinkPPM, s_fulfillmentFlatFeeNativePPM) = COORDINATOR.s_feeConfig();
}
/**
@@ -287,7 +288,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;
}
@@ -391,7 +392,9 @@ contract VRFV2PlusWrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsume
* @param _amount is the amount of LINK in Juels that should be withdrawn.
*/
function withdraw(address _recipient, uint256 _amount) external onlyOwner {
- s_link.transfer(_recipient, _amount);
+ if (!s_link.transfer(_recipient, _amount)) {
+ revert FailedToTransferLink();
+ }
}
/**
@@ -439,7 +442,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;
@@ -513,5 +516,5 @@ interface ExtendedVRFCoordinatorV2PlusInterface is IVRFCoordinatorV2Plus {
function s_fallbackWeiPerUnitLink() external view returns (int256);
- function s_feeConfig() external view returns (uint32 fulfillmentFlatFeeLinkPPM, uint32 fulfillmentFlatFeeEthPPM);
+ function s_feeConfig() external view returns (uint32 fulfillmentFlatFeeLinkPPM, uint32 fulfillmentFlatFeeNativePPM);
}
diff --git a/contracts/src/v0.8/dev/vrf/testhelpers/ExposedVRFCoordinatorV2Plus.sol b/contracts/src/v0.8/dev/vrf/testhelpers/ExposedVRFCoordinatorV2Plus.sol
deleted file mode 100644
index 82f4068112d..00000000000
--- a/contracts/src/v0.8/dev/vrf/testhelpers/ExposedVRFCoordinatorV2Plus.sol
+++ /dev/null
@@ -1,36 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.4;
-
-import "../../../vrf/VRF.sol";
-import {VRFCoordinatorV2Plus} from "../VRFCoordinatorV2Plus.sol";
-import "../../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/structs/EnumerableSet.sol";
-
-contract ExposedVRFCoordinatorV2Plus is VRFCoordinatorV2Plus {
- using EnumerableSet for EnumerableSet.UintSet;
-
- constructor(address blockhashStore) VRFCoordinatorV2Plus(blockhashStore) {}
-
- function computeRequestIdExternal(
- bytes32 keyHash,
- address sender,
- uint256 subId,
- uint64 nonce
- ) external pure returns (uint256, uint256) {
- return computeRequestId(keyHash, sender, subId, nonce);
- }
-
- function isTargetRegisteredExternal(address target) external view returns (bool) {
- return isTargetRegistered(target);
- }
-
- function getRandomnessFromProofExternal(
- Proof calldata proof,
- RequestCommitment calldata rc
- ) external view returns (Output memory) {
- return getRandomnessFromProof(proof, rc);
- }
-
- function getActiveSubscriptionIdsLength() external view returns (uint256) {
- return s_subIds.length();
- }
-}
diff --git a/contracts/src/v0.8/dev/vrf/testhelpers/ExposedVRFCoordinatorV2_5.sol b/contracts/src/v0.8/dev/vrf/testhelpers/ExposedVRFCoordinatorV2_5.sol
new file mode 100644
index 00000000000..5e54636bb17
--- /dev/null
+++ b/contracts/src/v0.8/dev/vrf/testhelpers/ExposedVRFCoordinatorV2_5.sol
@@ -0,0 +1,68 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.4;
+
+import "../../../vrf/VRF.sol";
+import {VRFCoordinatorV2_5} from "../VRFCoordinatorV2_5.sol";
+import "../../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/structs/EnumerableSet.sol";
+
+contract ExposedVRFCoordinatorV2_5 is VRFCoordinatorV2_5 {
+ using EnumerableSet for EnumerableSet.UintSet;
+
+ constructor(address blockhashStore) VRFCoordinatorV2_5(blockhashStore) {}
+
+ function computeRequestIdExternal(
+ bytes32 keyHash,
+ address sender,
+ uint256 subId,
+ uint64 nonce
+ ) external pure returns (uint256, uint256) {
+ return computeRequestId(keyHash, sender, subId, nonce);
+ }
+
+ function isTargetRegisteredExternal(address target) external view returns (bool) {
+ return isTargetRegistered(target);
+ }
+
+ function getRandomnessFromProofExternal(
+ Proof calldata proof,
+ RequestCommitment calldata rc
+ ) external view returns (Output memory) {
+ return getRandomnessFromProof(proof, rc);
+ }
+
+ function getActiveSubscriptionIdsLength() external view returns (uint256) {
+ return s_subIds.length();
+ }
+
+ function getSubscriptionConfig(uint256 subId) external view returns (SubscriptionConfig memory) {
+ return s_subscriptionConfigs[subId];
+ }
+
+ function getSubscriptionStruct(uint256 subId) external view returns (Subscription memory) {
+ return s_subscriptions[subId];
+ }
+
+ function setTotalBalanceTestingOnlyXXX(uint96 newBalance) external {
+ s_totalBalance = newBalance;
+ }
+
+ function setTotalNativeBalanceTestingOnlyXXX(uint96 newBalance) external {
+ s_totalNativeBalance = newBalance;
+ }
+
+ function setWithdrawableTokensTestingOnlyXXX(address oracle, uint96 newBalance) external {
+ s_withdrawableTokens[oracle] = newBalance;
+ }
+
+ function getWithdrawableTokensTestingOnlyXXX(address oracle) external view returns (uint96) {
+ return s_withdrawableTokens[oracle];
+ }
+
+ function setWithdrawableNativeTestingOnlyXXX(address oracle, uint96 newBalance) external {
+ s_withdrawableNative[oracle] = newBalance;
+ }
+
+ 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
new file mode 100644
index 00000000000..a8d2abfc4bc
--- /dev/null
+++ b/contracts/src/v0.8/dev/vrf/testhelpers/VRFCoordinatorV2PlusUpgradedVersion.sol
@@ -0,0 +1,722 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.4;
+
+import "../../../shared/interfaces/LinkTokenInterface.sol";
+import "../../../interfaces/BlockhashStoreInterface.sol";
+import "../../../interfaces/TypeAndVersionInterface.sol";
+import "../../interfaces/IVRFCoordinatorV2Plus.sol";
+import "../../../vrf/VRF.sol";
+import "../VRFConsumerBaseV2Plus.sol";
+import "../../../ChainSpecificUtil.sol";
+import "../SubscriptionAPI.sol";
+import "../libraries/VRFV2PlusClient.sol";
+import "../../interfaces/IVRFCoordinatorV2PlusMigration.sol";
+import "../../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/structs/EnumerableSet.sol";
+
+contract VRFCoordinatorV2PlusUpgradedVersion is
+ VRF,
+ SubscriptionAPI,
+ IVRFCoordinatorV2PlusMigration,
+ IVRFCoordinatorV2Plus
+{
+ using EnumerableSet for EnumerableSet.UintSet;
+ /// @dev should always be available
+ BlockhashStoreInterface public immutable BLOCKHASH_STORE;
+
+ // Set this maximum to 200 to give us a 56 block window to fulfill
+ // the request before requiring the block hash feeder.
+ uint16 public constant MAX_REQUEST_CONFIRMATIONS = 200;
+ uint32 public constant MAX_NUM_WORDS = 500;
+ // 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;
+ error InvalidRequestConfirmations(uint16 have, uint16 min, uint16 max);
+ error GasLimitTooBig(uint32 have, uint32 want);
+ error NumWordsTooBig(uint32 have, uint32 want);
+ error ProvingKeyAlreadyRegistered(bytes32 keyHash);
+ error NoSuchProvingKey(bytes32 keyHash);
+ error InvalidLinkWeiPrice(int256 linkWei);
+ error InsufficientGasForConsumer(uint256 have, uint256 want);
+ error NoCorrespondingRequest();
+ error IncorrectCommitment();
+ error BlockhashNotInStore(uint256 blockNum);
+ error PaymentTooLarge();
+ error InvalidExtraArgsTag();
+ /// @notice emitted when version in the request doesn't match expected version
+ error InvalidVersion(uint8 requestVersion, uint8 expectedVersion);
+ /// @notice emitted when transferred balance (msg.value) does not match the metadata in V1MigrationData
+ error InvalidNativeBalance(uint256 transferredValue, uint96 expectedValue);
+ error SubscriptionIDCollisionFound();
+
+ struct RequestCommitment {
+ uint64 blockNum;
+ uint256 subId;
+ uint32 callbackGasLimit;
+ uint32 numWords;
+ address sender;
+ bytes extraArgs;
+ }
+
+ mapping(bytes32 => address) /* keyHash */ /* oracle */ public s_provingKeys;
+ bytes32[] public s_provingKeyHashes;
+ mapping(uint256 => bytes32) /* requestID */ /* commitment */ public s_requestCommitments;
+
+ event ProvingKeyRegistered(bytes32 keyHash, address indexed oracle);
+ 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
+ );
+
+ int256 public s_fallbackWeiPerUnitLink;
+
+ FeeConfig public s_feeConfig;
+
+ struct FeeConfig {
+ // Flat fee charged per fulfillment in millionths of link
+ // So fee range is [0, 2^32/10^6].
+ uint32 fulfillmentFlatFeeLinkPPM;
+ // Flat fee charged per fulfillment in millionths of native.
+ // So fee range is [0, 2^32/10^6].
+ uint32 fulfillmentFlatFeeNativePPM;
+ }
+
+ event ConfigSet(
+ uint16 minimumRequestConfirmations,
+ uint32 maxGasLimit,
+ uint32 stalenessSeconds,
+ uint32 gasAfterPaymentCalculation,
+ int256 fallbackWeiPerUnitLink,
+ FeeConfig feeConfig
+ );
+
+ constructor(address blockhashStore) SubscriptionAPI() {
+ BLOCKHASH_STORE = BlockhashStoreInterface(blockhashStore);
+ }
+
+ /**
+ * @notice Registers a proving key to an oracle.
+ * @param oracle address of the oracle
+ * @param publicProvingKey key that oracle can use to submit vrf fulfillments
+ */
+ function registerProvingKey(address oracle, uint256[2] calldata publicProvingKey) external onlyOwner {
+ bytes32 kh = hashOfKey(publicProvingKey);
+ if (s_provingKeys[kh] != address(0)) {
+ revert ProvingKeyAlreadyRegistered(kh);
+ }
+ s_provingKeys[kh] = oracle;
+ s_provingKeyHashes.push(kh);
+ emit ProvingKeyRegistered(kh, oracle);
+ }
+
+ /**
+ * @notice Returns the proving key hash key associated with this public key
+ * @param publicKey the key to return the hash of
+ */
+ function hashOfKey(uint256[2] memory publicKey) public pure returns (bytes32) {
+ return keccak256(abi.encode(publicKey));
+ }
+
+ /**
+ * @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 native/link feed is more stale then this, use the fallback price
+ * @param gasAfterPaymentCalculation gas used in doing accounting after completing the gas measurement
+ * @param fallbackWeiPerUnitLink fallback native/link price in the case of a stale feed
+ * @param feeConfig fee configuration
+ */
+ function setConfig(
+ uint16 minimumRequestConfirmations,
+ uint32 maxGasLimit,
+ uint32 stalenessSeconds,
+ uint32 gasAfterPaymentCalculation,
+ int256 fallbackWeiPerUnitLink,
+ FeeConfig memory feeConfig
+ ) external onlyOwner {
+ if (minimumRequestConfirmations > MAX_REQUEST_CONFIRMATIONS) {
+ revert InvalidRequestConfirmations(
+ minimumRequestConfirmations,
+ minimumRequestConfirmations,
+ MAX_REQUEST_CONFIRMATIONS
+ );
+ }
+ if (fallbackWeiPerUnitLink <= 0) {
+ revert InvalidLinkWeiPrice(fallbackWeiPerUnitLink);
+ }
+ s_config = Config({
+ minimumRequestConfirmations: minimumRequestConfirmations,
+ maxGasLimit: maxGasLimit,
+ stalenessSeconds: stalenessSeconds,
+ gasAfterPaymentCalculation: gasAfterPaymentCalculation,
+ reentrancyLock: false
+ });
+ s_feeConfig = feeConfig;
+ s_fallbackWeiPerUnitLink = fallbackWeiPerUnitLink;
+ emit ConfigSet(
+ minimumRequestConfirmations,
+ maxGasLimit,
+ stalenessSeconds,
+ gasAfterPaymentCalculation,
+ fallbackWeiPerUnitLink,
+ s_feeConfig
+ );
+ }
+
+ /**
+ * @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) {
+ return (s_config.minimumRequestConfirmations, s_config.maxGasLimit, s_provingKeyHashes);
+ }
+
+ /// @dev Convert the extra args bytes into a struct
+ /// @param extraArgs The extra args bytes
+ /// @return The extra args struct
+ function _fromBytes(bytes calldata extraArgs) internal pure returns (VRFV2PlusClient.ExtraArgsV1 memory) {
+ if (extraArgs.length == 0) {
+ return VRFV2PlusClient.ExtraArgsV1({nativePayment: false});
+ }
+ if (bytes4(extraArgs) != VRFV2PlusClient.EXTRA_ARGS_V1_TAG) revert InvalidExtraArgsTag();
+ return abi.decode(extraArgs[4:], (VRFV2PlusClient.ExtraArgsV1));
+ }
+
+ /**
+ * @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.
+ * 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].
+ * 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.
+ * extraArgs - Encoded extra arguments that has a boolean flag for whether payment
+ * 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 override nonReentrant returns (uint256) {
+ // Input validation using the subscription storage.
+ if (s_subscriptionConfigs[req.subId].owner == address(0)) {
+ revert InvalidSubscription();
+ }
+ // Its important to ensure that the consumer is in fact who they say they
+ // are, otherwise they could use someone else's subscription balance.
+ // A nonce of 0 indicates consumer is not allocated to the sub.
+ uint64 currentNonce = s_consumers[msg.sender][req.subId];
+ if (currentNonce == 0) {
+ revert InvalidConsumer(req.subId, msg.sender);
+ }
+ // Input validation using the config storage word.
+ if (
+ req.requestConfirmations < s_config.minimumRequestConfirmations ||
+ req.requestConfirmations > MAX_REQUEST_CONFIRMATIONS
+ ) {
+ revert InvalidRequestConfirmations(
+ req.requestConfirmations,
+ s_config.minimumRequestConfirmations,
+ MAX_REQUEST_CONFIRMATIONS
+ );
+ }
+ // No lower bound on the requested gas limit. A user could request 0
+ // and they would simply be billed for the proof verification and wouldn't be
+ // able to do anything with the random value.
+ if (req.callbackGasLimit > s_config.maxGasLimit) {
+ revert GasLimitTooBig(req.callbackGasLimit, s_config.maxGasLimit);
+ }
+ if (req.numWords > MAX_NUM_WORDS) {
+ revert NumWordsTooBig(req.numWords, MAX_NUM_WORDS);
+ }
+ // Note we do not check whether the keyHash is valid to save gas.
+ // The consequence for users is that they can send requests
+ // for invalid keyHashes which will simply not be fulfilled.
+ uint64 nonce = currentNonce + 1;
+ (uint256 requestId, uint256 preSeed) = computeRequestId(req.keyHash, msg.sender, req.subId, nonce);
+
+ VRFV2PlusClient.ExtraArgsV1 memory extraArgs = _fromBytes(req.extraArgs);
+ bytes memory extraArgsBytes = VRFV2PlusClient._argsToBytes(extraArgs);
+ s_requestCommitments[requestId] = keccak256(
+ abi.encode(
+ requestId,
+ ChainSpecificUtil.getBlockNumber(),
+ req.subId,
+ req.callbackGasLimit,
+ req.numWords,
+ msg.sender,
+ extraArgsBytes
+ )
+ );
+ emit RandomWordsRequested(
+ req.keyHash,
+ requestId,
+ preSeed,
+ req.subId,
+ req.requestConfirmations,
+ req.callbackGasLimit,
+ req.numWords,
+ extraArgsBytes,
+ msg.sender
+ );
+ s_consumers[msg.sender][req.subId] = nonce;
+
+ return requestId;
+ }
+
+ function computeRequestId(
+ bytes32 keyHash,
+ address sender,
+ uint256 subId,
+ uint64 nonce
+ ) internal pure returns (uint256, uint256) {
+ uint256 preSeed = uint256(keccak256(abi.encode(keyHash, sender, subId, nonce)));
+ return (uint256(keccak256(abi.encode(keyHash, preSeed))), preSeed);
+ }
+
+ /**
+ * @dev calls target address with exactly gasAmount gas and data as calldata
+ * or reverts if at least gasAmount gas is not available.
+ */
+ function callWithExactGas(uint256 gasAmount, address target, bytes memory data) private returns (bool success) {
+ // solhint-disable-next-line no-inline-assembly
+ assembly {
+ let g := gas()
+ // Compute g -= GAS_FOR_CALL_EXACT_CHECK and check for underflow
+ // The gas actually passed to the callee is min(gasAmount, 63//64*gas available).
+ // We want to ensure that we revert if gasAmount > 63//64*gas available
+ // as we do not want to provide them with less, however that check itself costs
+ // gas. GAS_FOR_CALL_EXACT_CHECK ensures we have at least enough gas to be able
+ // to revert if gasAmount > 63//64*gas available.
+ if lt(g, GAS_FOR_CALL_EXACT_CHECK) {
+ revert(0, 0)
+ }
+ g := sub(g, GAS_FOR_CALL_EXACT_CHECK)
+ // if g - g//64 <= gasAmount, revert
+ // (we subtract g//64 because of EIP-150)
+ if iszero(gt(sub(g, div(g, 64)), gasAmount)) {
+ revert(0, 0)
+ }
+ // solidity calls check that a contract actually exists at the destination, so we do the same
+ if iszero(extcodesize(target)) {
+ revert(0, 0)
+ }
+ // call and return whether we succeeded. ignore return data
+ // call(gas,addr,value,argsOffset,argsLength,retOffset,retLength)
+ success := call(gasAmount, target, 0, add(data, 0x20), mload(data), 0, 0)
+ }
+ return success;
+ }
+
+ struct Output {
+ bytes32 keyHash;
+ uint256 requestId;
+ uint256 randomness;
+ }
+
+ function getRandomnessFromProof(
+ Proof memory proof,
+ RequestCommitment memory rc
+ ) internal view returns (Output memory) {
+ bytes32 keyHash = hashOfKey(proof.pk);
+ // Only registered proving keys are permitted.
+ address oracle = s_provingKeys[keyHash];
+ if (oracle == address(0)) {
+ revert NoSuchProvingKey(keyHash);
+ }
+ uint256 requestId = uint256(keccak256(abi.encode(keyHash, proof.seed)));
+ bytes32 commitment = s_requestCommitments[requestId];
+ if (commitment == 0) {
+ revert NoCorrespondingRequest();
+ }
+ if (
+ commitment !=
+ keccak256(abi.encode(requestId, rc.blockNum, rc.subId, rc.callbackGasLimit, rc.numWords, rc.sender, rc.extraArgs))
+ ) {
+ revert IncorrectCommitment();
+ }
+
+ bytes32 blockHash = ChainSpecificUtil.getBlockhash(rc.blockNum);
+ if (blockHash == bytes32(0)) {
+ blockHash = BLOCKHASH_STORE.getBlockhash(rc.blockNum);
+ if (blockHash == bytes32(0)) {
+ revert BlockhashNotInStore(rc.blockNum);
+ }
+ }
+
+ // The seed actually used by the VRF machinery, mixing in the blockhash
+ uint256 actualSeed = uint256(keccak256(abi.encodePacked(proof.seed, blockHash)));
+ uint256 randomness = VRF.randomValueFromVRFProof(proof, actualSeed); // Reverts on failure
+ return Output(keyHash, requestId, randomness);
+ }
+
+ /*
+ * @notice Fulfill a randomness request
+ * @param proof contains the proof and randomness
+ * @param rc request commitment pre-image, committed to at request time
+ * @return payment amount billed to the subscription
+ * @dev simulated offchain to determine if sufficient balance is present to fulfill the request
+ */
+ function fulfillRandomWords(Proof memory proof, RequestCommitment memory rc) external nonReentrant returns (uint96) {
+ uint256 startGas = gasleft();
+ Output memory output = getRandomnessFromProof(proof, rc);
+
+ uint256[] memory randomWords = new uint256[](rc.numWords);
+ for (uint256 i = 0; i < rc.numWords; i++) {
+ randomWords[i] = uint256(keccak256(abi.encode(output.randomness, i)));
+ }
+
+ delete s_requestCommitments[output.requestId];
+ VRFConsumerBaseV2Plus v;
+ bytes memory resp = abi.encodeWithSelector(v.rawFulfillRandomWords.selector, output.requestId, randomWords);
+ // Call with explicitly the amount of callback gas requested
+ // Important to not let them exhaust the gas budget and avoid oracle payment.
+ // Do not allow any non-view/non-pure coordinator functions to be called
+ // during the consumers callback code via reentrancyLock.
+ // Note that callWithExactGas will revert if we do not have sufficient gas
+ // to give the callee their requested amount.
+ s_config.reentrancyLock = true;
+ bool success = callWithExactGas(rc.callbackGasLimit, rc.sender, resp);
+ s_config.reentrancyLock = false;
+
+ // Increment the req count for the subscription.
+ uint64 reqCount = s_subscriptions[rc.subId].reqCount;
+ s_subscriptions[rc.subId].reqCount = reqCount + 1;
+
+ // stack too deep error
+ {
+ bool nativePayment = uint8(rc.extraArgs[rc.extraArgs.length - 1]) == 1;
+ // We want to charge users exactly for how much gas they use in their callback.
+ // The gasAfterPaymentCalculation is meant to cover these additional operations where we
+ // decrement the subscription balance and increment the oracles withdrawable balance.
+ uint96 payment = calculatePaymentAmount(
+ startGas,
+ s_config.gasAfterPaymentCalculation,
+ tx.gasprice,
+ nativePayment
+ );
+ if (nativePayment) {
+ if (s_subscriptions[rc.subId].nativeBalance < payment) {
+ revert InsufficientBalance();
+ }
+ s_subscriptions[rc.subId].nativeBalance -= payment;
+ s_withdrawableNative[s_provingKeys[output.keyHash]] += payment;
+ } else {
+ if (s_subscriptions[rc.subId].balance < payment) {
+ revert InsufficientBalance();
+ }
+ s_subscriptions[rc.subId].balance -= payment;
+ s_withdrawableTokens[s_provingKeys[output.keyHash]] += payment;
+ }
+
+ // Include payment in the event for tracking costs.
+ // event RandomWordsFulfilled(uint256 indexed requestId, uint256 outputSeed, uint96 payment, bytes extraArgs, bool success);
+ emit RandomWordsFulfilled(output.requestId, output.randomness, rc.subId, payment, success);
+
+ return payment;
+ }
+ }
+
+ function calculatePaymentAmount(
+ uint256 startGas,
+ uint256 gasAfterPaymentCalculation,
+ uint256 weiPerUnitGas,
+ bool nativePayment
+ ) internal view returns (uint96) {
+ if (nativePayment) {
+ return
+ calculatePaymentAmountNative(
+ startGas,
+ gasAfterPaymentCalculation,
+ s_feeConfig.fulfillmentFlatFeeNativePPM,
+ weiPerUnitGas
+ );
+ }
+ return
+ calculatePaymentAmountLink(
+ startGas,
+ gasAfterPaymentCalculation,
+ s_feeConfig.fulfillmentFlatFeeLinkPPM,
+ weiPerUnitGas
+ );
+ }
+
+ function calculatePaymentAmountNative(
+ uint256 startGas,
+ uint256 gasAfterPaymentCalculation,
+ uint32 fulfillmentFlatFeePPM,
+ uint256 weiPerUnitGas
+ ) internal view returns (uint96) {
+ // Will return non-zero on chains that have this enabled
+ uint256 l1CostWei = ChainSpecificUtil.getCurrentTxL1GasFees();
+ // calculate the payment without the premium
+ uint256 baseFeeWei = weiPerUnitGas * (gasAfterPaymentCalculation + startGas - gasleft());
+ // calculate the flat fee in wei
+ uint256 flatFeeWei = 1e12 * uint256(fulfillmentFlatFeePPM);
+ // return the final fee with the flat fee and l1 cost (if applicable) added
+ return uint96(baseFeeWei + flatFeeWei + l1CostWei);
+ }
+
+ // Get the amount of gas used for fulfillment
+ function calculatePaymentAmountLink(
+ uint256 startGas,
+ uint256 gasAfterPaymentCalculation,
+ uint32 fulfillmentFlatFeeLinkPPM,
+ uint256 weiPerUnitGas
+ ) internal view returns (uint96) {
+ int256 weiPerUnitLink;
+ weiPerUnitLink = getFeedData();
+ if (weiPerUnitLink <= 0) {
+ revert InvalidLinkWeiPrice(weiPerUnitLink);
+ }
+ // Will return non-zero on chains that have this enabled
+ uint256 l1CostWei = ChainSpecificUtil.getCurrentTxL1GasFees();
+ // (1e18 juels/link) ((wei/gas * gas) + l1wei) / (wei/link) = juels
+ uint256 paymentNoFee = (1e18 * (weiPerUnitGas * (gasAfterPaymentCalculation + startGas - gasleft()) + l1CostWei)) /
+ uint256(weiPerUnitLink);
+ uint256 fee = 1e12 * uint256(fulfillmentFlatFeeLinkPPM);
+ if (paymentNoFee > (1e27 - fee)) {
+ revert PaymentTooLarge(); // Payment + fee cannot be more than all of the link in existence.
+ }
+ return uint96(paymentNoFee + fee);
+ }
+
+ function getFeedData() private view returns (int256) {
+ uint32 stalenessSeconds = s_config.stalenessSeconds;
+ bool staleFallback = stalenessSeconds > 0;
+ uint256 timestamp;
+ int256 weiPerUnitLink;
+ (, weiPerUnitLink, , timestamp, ) = LINK_NATIVE_FEED.latestRoundData();
+ // solhint-disable-next-line not-rely-on-time
+ if (staleFallback && stalenessSeconds < block.timestamp - timestamp) {
+ weiPerUnitLink = s_fallbackWeiPerUnitLink;
+ }
+ 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.
+ */
+ function pendingRequestExists(uint256 subId) public view override returns (bool) {
+ SubscriptionConfig memory subConfig = s_subscriptionConfigs[subId];
+ for (uint256 i = 0; i < subConfig.consumers.length; i++) {
+ for (uint256 j = 0; j < s_provingKeyHashes.length; j++) {
+ (uint256 reqId, ) = computeRequestId(
+ s_provingKeyHashes[j],
+ subConfig.consumers[i],
+ subId,
+ s_consumers[subConfig.consumers[i]][subId]
+ );
+ if (s_requestCommitments[reqId] != 0) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * @inheritdoc IVRFSubscriptionV2Plus
+ */
+ function removeConsumer(uint256 subId, address consumer) external override onlySubOwner(subId) nonReentrant {
+ if (pendingRequestExists(subId)) {
+ revert PendingRequestExists();
+ }
+ if (s_consumers[consumer][subId] == 0) {
+ revert InvalidConsumer(subId, consumer);
+ }
+ // Note bounded by MAX_CONSUMERS
+ address[] memory consumers = s_subscriptionConfigs[subId].consumers;
+ uint256 lastConsumerIndex = consumers.length - 1;
+ for (uint256 i = 0; i < consumers.length; i++) {
+ if (consumers[i] == consumer) {
+ address last = consumers[lastConsumerIndex];
+ // Storage write to preserve last element
+ s_subscriptionConfigs[subId].consumers[i] = last;
+ // Storage remove last element
+ s_subscriptionConfigs[subId].consumers.pop();
+ break;
+ }
+ }
+ delete s_consumers[consumer][subId];
+ emit SubscriptionConsumerRemoved(subId, consumer);
+ }
+
+ /**
+ * @inheritdoc IVRFSubscriptionV2Plus
+ */
+ function cancelSubscription(uint256 subId, address to) external override onlySubOwner(subId) nonReentrant {
+ if (pendingRequestExists(subId)) {
+ revert PendingRequestExists();
+ }
+ cancelSubscriptionHelper(subId, to);
+ }
+
+ /***************************************************************************
+ * Section: Migration
+ ***************************************************************************/
+
+ address[] internal s_migrationTargets;
+
+ /// @dev Emitted when new coordinator is registered as migratable target
+ event CoordinatorRegistered(address coordinatorAddress);
+
+ /// @notice emitted when migration to new coordinator completes successfully
+ /// @param newCoordinator coordinator address after migration
+ /// @param subId subscription ID
+ event MigrationCompleted(address newCoordinator, uint256 subId);
+
+ /// @notice emitted when migrate() is called and given coordinator is not registered as migratable target
+ error CoordinatorNotRegistered(address coordinatorAddress);
+
+ /// @notice emitted when migrate() is called and given coordinator is registered as migratable target
+ error CoordinatorAlreadyRegistered(address coordinatorAddress);
+
+ /// @dev encapsulates data to be migrated from current coordinator
+ struct V1MigrationData {
+ uint8 fromVersion;
+ uint256 subId;
+ address subOwner;
+ address[] consumers;
+ uint96 linkBalance;
+ uint96 nativeBalance;
+ }
+
+ function isTargetRegistered(address target) internal view returns (bool) {
+ for (uint256 i = 0; i < s_migrationTargets.length; i++) {
+ if (s_migrationTargets[i] == target) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ function registerMigratableCoordinator(address target) external onlyOwner {
+ if (isTargetRegistered(target)) {
+ revert CoordinatorAlreadyRegistered(target);
+ }
+ s_migrationTargets.push(target);
+ emit CoordinatorRegistered(target);
+ }
+
+ function migrate(uint256 subId, address newCoordinator) external nonReentrant {
+ if (!isTargetRegistered(newCoordinator)) {
+ revert CoordinatorNotRegistered(newCoordinator);
+ }
+ (uint96 balance, uint96 nativeBalance, , address owner, address[] memory consumers) = getSubscription(subId);
+ require(owner == msg.sender, "Not subscription owner");
+ require(!pendingRequestExists(subId), "Pending request exists");
+
+ V1MigrationData memory migrationData = V1MigrationData({
+ fromVersion: migrationVersion(),
+ subId: subId,
+ subOwner: owner,
+ consumers: consumers,
+ linkBalance: balance,
+ nativeBalance: nativeBalance
+ });
+ bytes memory encodedData = abi.encode(migrationData);
+ deleteSubscription(subId);
+ 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) {
+ require(LINK.transfer(address(newCoordinator), balance), "insufficient funds");
+ }
+
+ // despite the fact that we follow best practices this is still probably safest
+ // to prevent any re-entrancy possibilities.
+ s_config.reentrancyLock = true;
+ for (uint256 i = 0; i < consumers.length; i++) {
+ IVRFMigratableConsumerV2Plus(consumers[i]).setCoordinator(newCoordinator);
+ }
+ s_config.reentrancyLock = false;
+
+ emit MigrationCompleted(newCoordinator, subId);
+ }
+
+ function migrationVersion() public pure returns (uint8 version) {
+ return 1;
+ }
+
+ /**
+ * @inheritdoc IVRFCoordinatorV2PlusMigration
+ */
+ function onMigration(bytes calldata encodedData) external payable override {
+ V1MigrationData memory migrationData = abi.decode(encodedData, (V1MigrationData));
+
+ if (migrationData.fromVersion != 1) {
+ revert InvalidVersion(migrationData.fromVersion, 1);
+ }
+
+ 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:
+ // 1. the subscription ID is calculated using inputs that cannot be replicated under different
+ // conditions.
+ // 2. once a subscription is migrated it is deleted from the previous coordinator, so it cannot
+ // be migrated again.
+ // however, we should have this check here in case the `migrate` function on
+ // future coordinators "forgets" to delete subscription data allowing re-migration of the same
+ // subscription.
+ if (s_subscriptionConfigs[migrationData.subId].owner != address(0)) {
+ revert SubscriptionIDCollisionFound();
+ }
+
+ for (uint i = 0; i < migrationData.consumers.length; i++) {
+ s_consumers[migrationData.consumers[i]][migrationData.subId] = 1;
+ }
+
+ s_subscriptions[migrationData.subId] = Subscription({
+ nativeBalance: migrationData.nativeBalance,
+ balance: migrationData.linkBalance,
+ reqCount: 0
+ });
+ s_subscriptionConfigs[migrationData.subId] = SubscriptionConfig({
+ owner: migrationData.subOwner,
+ consumers: migrationData.consumers,
+ requestedOwner: address(0)
+ });
+
+ s_totalBalance += uint96(migrationData.linkBalance);
+ 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 b44a3e3190d..52a5b864c6b 100644
--- a/contracts/src/v0.8/dev/vrf/testhelpers/VRFCoordinatorV2Plus_V2Example.sol
+++ b/contracts/src/v0.8/dev/vrf/testhelpers/VRFCoordinatorV2Plus_V2Example.sol
@@ -3,17 +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 */
@@ -42,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
);
}
@@ -76,7 +84,7 @@ contract VRFCoordinatorV2Plus_V2Example is IVRFCoordinatorV2PlusMigration, IVRFM
address subOwner;
address[] consumers;
uint96 linkBalance;
- uint96 ethBalance;
+ uint96 nativeBalance;
}
/**
@@ -93,17 +101,30 @@ 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:
+ // 1. the subscription ID is calculated using inputs that cannot be replicated under different
+ // conditions.
+ // 2. once a subscription is migrated it is deleted from the previous coordinator, so it cannot
+ // be migrated again.
+ // however, we should have this check here in case the `migrate` function on
+ // future coordinators "forgets" to delete subscription data allowing re-migration of the same
+ // subscription.
+ if (s_subscriptions[migrationData.subId].owner != address(0)) {
+ revert SubscriptionIDCollisionFound();
}
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;
}
@@ -111,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 ff9245b688e..948cc17b3f3 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/VRFV2PlusLoadTestWithMetrics.sol b/contracts/src/v0.8/dev/vrf/testhelpers/VRFV2PlusLoadTestWithMetrics.sol
new file mode 100644
index 00000000000..42296ae6bf4
--- /dev/null
+++ b/contracts/src/v0.8/dev/vrf/testhelpers/VRFV2PlusLoadTestWithMetrics.sol
@@ -0,0 +1,124 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.0;
+
+import "../../../ChainSpecificUtil.sol";
+import "../../interfaces/IVRFCoordinatorV2Plus.sol";
+import "../VRFConsumerBaseV2Plus.sol";
+import "../../../shared/access/ConfirmedOwner.sol";
+
+/**
+ * @title The VRFLoadTestExternalSubOwner contract.
+ * @notice Allows making many VRF V2 randomness requests in a single transaction for load testing.
+ */
+contract VRFV2PlusLoadTestWithMetrics is VRFConsumerBaseV2Plus {
+ uint256 public s_responseCount;
+ uint256 public s_requestCount;
+ uint256 public s_averageFulfillmentInMillions = 0; // in millions for better precision
+ uint256 public s_slowestFulfillment = 0;
+ uint256 public s_fastestFulfillment = 999;
+ uint256 public s_lastRequestId;
+ mapping(uint256 => uint256) requestHeights; // requestIds to block number when rand request was made
+
+ struct RequestStatus {
+ bool fulfilled;
+ uint256[] randomWords;
+ uint requestTimestamp;
+ uint fulfilmentTimestamp;
+ uint256 requestBlockNumber;
+ uint256 fulfilmentBlockNumber;
+ }
+
+ mapping(uint256 => RequestStatus) /* requestId */ /* requestStatus */ public s_requests;
+
+ constructor(address _vrfCoordinator) VRFConsumerBaseV2Plus(_vrfCoordinator) {}
+
+ function fulfillRandomWords(uint256 _requestId, uint256[] memory _randomWords) internal override {
+ uint256 fulfilmentBlockNumber = ChainSpecificUtil.getBlockNumber();
+ uint256 requestDelay = fulfilmentBlockNumber - requestHeights[_requestId];
+ uint256 requestDelayInMillions = requestDelay * 1_000_000;
+
+ if (requestDelay > s_slowestFulfillment) {
+ s_slowestFulfillment = requestDelay;
+ }
+ s_fastestFulfillment = requestDelay < s_fastestFulfillment ? requestDelay : s_fastestFulfillment;
+ s_averageFulfillmentInMillions = s_responseCount > 0
+ ? (s_averageFulfillmentInMillions * s_responseCount + requestDelayInMillions) / (s_responseCount + 1)
+ : requestDelayInMillions;
+
+ s_requests[_requestId].fulfilled = true;
+ s_requests[_requestId].randomWords = _randomWords;
+ s_requests[_requestId].fulfilmentTimestamp = block.timestamp;
+ s_requests[_requestId].fulfilmentBlockNumber = fulfilmentBlockNumber;
+
+ s_responseCount++;
+ }
+
+ function requestRandomWords(
+ uint256 _subId,
+ uint16 _requestConfirmations,
+ bytes32 _keyHash,
+ uint32 _callbackGasLimit,
+ bool _nativePayment,
+ uint32 _numWords,
+ uint16 _requestCount
+ ) external onlyOwner {
+ for (uint16 i = 0; i < _requestCount; i++) {
+ VRFV2PlusClient.RandomWordsRequest memory req = VRFV2PlusClient.RandomWordsRequest({
+ keyHash: _keyHash,
+ subId: _subId,
+ requestConfirmations: _requestConfirmations,
+ callbackGasLimit: _callbackGasLimit,
+ numWords: _numWords,
+ extraArgs: VRFV2PlusClient._argsToBytes(VRFV2PlusClient.ExtraArgsV1({nativePayment: _nativePayment}))
+ });
+ // Will revert if subscription is not funded.
+ uint256 requestId = s_vrfCoordinator.requestRandomWords(req);
+
+ s_lastRequestId = requestId;
+ uint256 requestBlockNumber = ChainSpecificUtil.getBlockNumber();
+ s_requests[requestId] = RequestStatus({
+ randomWords: new uint256[](0),
+ fulfilled: false,
+ requestTimestamp: block.timestamp,
+ fulfilmentTimestamp: 0,
+ requestBlockNumber: requestBlockNumber,
+ fulfilmentBlockNumber: 0
+ });
+ s_requestCount++;
+ requestHeights[requestId] = requestBlockNumber;
+ }
+ }
+
+ function reset() external {
+ s_averageFulfillmentInMillions = 0; // in millions for better precision
+ s_slowestFulfillment = 0;
+ s_fastestFulfillment = 999;
+ s_requestCount = 0;
+ s_responseCount = 0;
+ }
+
+ function getRequestStatus(
+ uint256 _requestId
+ )
+ external
+ view
+ returns (
+ bool fulfilled,
+ uint256[] memory randomWords,
+ uint requestTimestamp,
+ uint fulfilmentTimestamp,
+ uint256 requestBlockNumber,
+ uint256 fulfilmentBlockNumber
+ )
+ {
+ RequestStatus memory request = s_requests[_requestId];
+ return (
+ request.fulfilled,
+ request.randomWords,
+ request.requestTimestamp,
+ request.fulfilmentTimestamp,
+ request.requestBlockNumber,
+ request.fulfilmentBlockNumber
+ );
+ }
+}
diff --git a/contracts/src/v0.8/dev/vrf/testhelpers/VRFV2PlusMaliciousMigrator.sol b/contracts/src/v0.8/dev/vrf/testhelpers/VRFV2PlusMaliciousMigrator.sol
new file mode 100644
index 00000000000..b1dca81ebdf
--- /dev/null
+++ b/contracts/src/v0.8/dev/vrf/testhelpers/VRFV2PlusMaliciousMigrator.sol
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: UNLICENSED
+pragma solidity ^0.8.0;
+
+import "../../interfaces/IVRFMigratableConsumerV2Plus.sol";
+import "../../interfaces/IVRFCoordinatorV2Plus.sol";
+import "../libraries/VRFV2PlusClient.sol";
+
+contract VRFV2PlusMaliciousMigrator is IVRFMigratableConsumerV2Plus {
+ IVRFCoordinatorV2Plus s_vrfCoordinator;
+
+ constructor(address _vrfCoordinator) {
+ s_vrfCoordinator = IVRFCoordinatorV2Plus(_vrfCoordinator);
+ }
+
+ /**
+ * @inheritdoc IVRFMigratableConsumerV2Plus
+ */
+ function setCoordinator(address _vrfCoordinator) public override {
+ // try to re-enter, should revert
+ // args don't really matter
+ s_vrfCoordinator.requestRandomWords(
+ VRFV2PlusClient.RandomWordsRequest({
+ keyHash: bytes32(0),
+ subId: 0,
+ requestConfirmations: 0,
+ callbackGasLimit: 0,
+ numWords: 0,
+ extraArgs: ""
+ })
+ );
+ }
+}
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 00000000000..4f63bc0e32a
--- /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/src/v0.8/functions/dev/1_0_0/accessControl/interfaces/ITermsOfServiceAllowList.sol b/contracts/src/v0.8/functions/dev/1_0_0/accessControl/interfaces/ITermsOfServiceAllowList.sol
deleted file mode 100644
index b83375ee01f..00000000000
--- a/contracts/src/v0.8/functions/dev/1_0_0/accessControl/interfaces/ITermsOfServiceAllowList.sol
+++ /dev/null
@@ -1,40 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.19;
-
-// @notice A contract to handle access control of subscription management dependent on signing a Terms of Service
-interface ITermsOfServiceAllowList {
- // @notice Return the message data for the proof given to accept the Terms of Service
- // @param acceptor - The wallet address that has accepted the Terms of Service on the UI
- // @param recipient - The recipient address that the acceptor is taking responsibility for
- // @return Hash of the message data
- function getMessage(address acceptor, address recipient) external pure returns (bytes32);
-
- // @notice Check if the address is blocked for usage
- // @param sender The transaction sender's address
- // @return True or false
- function isBlockedSender(address sender) external returns (bool);
-
- // @notice Get a list of all allowed senders
- // @dev WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
- // to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
- // this function has an unbounded cost, and using it as part of a state-changing function may render the function
- // uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
- // @return addresses - all allowed addresses
- function getAllAllowedSenders() external view returns (address[] memory);
-
- // @notice Allows access to the sender based on acceptance of the Terms of Service
- // @param acceptor - The wallet address that has accepted the Terms of Service on the UI
- // @param recipient - The recipient address that the acceptor is taking responsibility for
- // @param r - ECDSA signature r data produced by the Chainlink Functions Subscription UI
- // @param s - ECDSA signature s produced by the Chainlink Functions Subscription UI
- // @param v - ECDSA signature v produced by the Chainlink Functions Subscription UI
- function acceptTermsOfService(address acceptor, address recipient, bytes32 r, bytes32 s, uint8 v) external;
-
- // @notice Removes a sender's access if already authorized, and disallows re-accepting the Terms of Service
- // @param sender - Address of the sender to block
- function blockSender(address sender) external;
-
- // @notice Re-allows a previously blocked sender to accept the Terms of Service
- // @param sender - Address of the sender to unblock
- function unblockSender(address sender) external;
-}
diff --git a/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsBilling.sol b/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsBilling.sol
deleted file mode 100644
index 00ff17ee14d..00000000000
--- a/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsBilling.sol
+++ /dev/null
@@ -1,44 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.19;
-
-// @title Chainlink Functions DON billing interface.
-interface IFunctionsBilling {
- // @notice Return the current conversion from WEI of ETH to LINK from the configured Chainlink data feed
- // @return weiPerUnitLink - The amount of WEI in one LINK
- function getWeiPerUnitLink() external view returns (uint256);
-
- // @notice Determine the fee that will be split between Node Operators for servicing a request
- // @param requestCBOR - CBOR encoded Chainlink Functions request data, use FunctionsRequest library to encode a request
- // @return fee - Cost in Juels (1e18) of LINK
- function getDONFee(bytes memory requestCBOR) external view returns (uint72);
-
- // @notice Determine the fee that will be paid to the Router owner for operating the network
- // @return fee - Cost in Juels (1e18) of LINK
- function getAdminFee() external view returns (uint72);
-
- // @notice Estimate the total cost that will be charged to a subscription to make a request: transmitter gas re-reimbursement, plus DON fee, plus Registry fee
- // @param - subscriptionId An identifier of the billing account
- // @param - data Encoded Chainlink Functions request data, use FunctionsClient API to encode a request
- // @param - callbackGasLimit Gas limit for the fulfillment callback
- // @param - gasPriceGwei The blockchain's gas price to estimate with
- // @return - billedCost Cost in Juels (1e18) of LINK
- function estimateCost(
- uint64 subscriptionId,
- bytes calldata data,
- uint32 callbackGasLimit,
- uint256 gasPriceGwei
- ) external view returns (uint96);
-
- // @notice Remove a request commitment that the Router has determined to be stale
- // @param requestId - The request ID to remove
- function deleteCommitment(bytes32 requestId) external returns (bool);
-
- // @notice Oracle withdraw LINK earned through fulfilling requests
- // @notice If amount is 0 the full balance will be withdrawn
- // @param recipient where to send the funds
- // @param amount amount to withdraw
- function oracleWithdraw(address recipient, uint96 amount) external;
-
- // @notice Withdraw all LINK earned by Oracles through fulfilling requests
- function oracleWithdrawAll() external;
-}
diff --git a/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsClient.sol b/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsClient.sol
deleted file mode 100644
index 5fbee58274e..00000000000
--- a/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsClient.sol
+++ /dev/null
@@ -1,13 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.19;
-
-// @title Chainlink Functions client interface.
-interface IFunctionsClient {
- // @notice Chainlink Functions response handler called by the Functions Router
- // during fullilment from the designated transmitter node in an OCR round.
- // @param requestId The requestId returned by FunctionsClient.sendRequest().
- // @param response Aggregated response from the request's source code.
- // @param err Aggregated error either from the request's source code or from the execution pipeline.
- // @dev Either response or error parameter will be set, but never both.
- function handleOracleFulfillment(bytes32 requestId, bytes memory response, bytes memory err) external;
-}
diff --git a/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsCoordinator.sol b/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsCoordinator.sol
deleted file mode 100644
index 63571786eb8..00000000000
--- a/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsCoordinator.sol
+++ /dev/null
@@ -1,52 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.19;
-
-import {FunctionsResponse} from "../libraries/FunctionsResponse.sol";
-
-// @title Chainlink Functions DON Coordinator interface.
-interface IFunctionsCoordinator {
- // @notice Returns the DON's threshold encryption public key used to encrypt secrets
- // @dev All nodes on the DON have separate key shares of the threshold decryption key
- // and nodes must participate in a threshold decryption OCR round to decrypt secrets
- // @return thresholdPublicKey the DON's threshold encryption public key
- function getThresholdPublicKey() external view returns (bytes memory);
-
- // @notice Sets the DON's threshold encryption public key used to encrypt secrets
- // @dev Used to rotate the key
- // @param thresholdPublicKey The new public key
- function setThresholdPublicKey(bytes calldata thresholdPublicKey) external;
-
- // @notice Returns the DON's secp256k1 public key that is used to encrypt secrets
- // @dev All nodes on the DON have the corresponding private key
- // needed to decrypt the secrets encrypted with the public key
- // @return publicKey the DON's public key
- function getDONPublicKey() external view returns (bytes memory);
-
- // @notice Sets DON's secp256k1 public key used to encrypt secrets
- // @dev Used to rotate the key
- // @param donPublicKey The new public key
- function setDONPublicKey(bytes calldata donPublicKey) external;
-
- // @notice Sets a per-node secp256k1 public key used to encrypt secrets for that node
- // @dev Callable only by contract owner and DON members
- // @param node node's address
- // @param publicKey node's public key
- function setNodePublicKey(address node, bytes calldata publicKey) external;
-
- // @notice Deletes node's public key
- // @dev Callable only by contract owner or the node itself
- // @param node node's address
- function deleteNodePublicKey(address node) external;
-
- // @notice Return two arrays of equal size containing DON members' addresses and their corresponding
- // public keys (or empty byte arrays if per-node key is not defined)
- function getAllNodePublicKeys() external view returns (address[] memory, bytes[] memory);
-
- // @notice Receives a request to be emitted to the DON for processing
- // @param request The request metadata
- // @dev see the struct for field descriptions
- // @return commitment - The parameters of the request that must be held consistent at response time
- function startRequest(
- FunctionsResponse.RequestMeta calldata request
- ) external returns (FunctionsResponse.Commitment memory commitment);
-}
diff --git a/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsRouter.sol b/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsRouter.sol
deleted file mode 100644
index ebc1dbd4538..00000000000
--- a/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsRouter.sol
+++ /dev/null
@@ -1,109 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.19;
-
-import {FunctionsResponse} from "../libraries/FunctionsResponse.sol";
-
-// @title Chainlink Functions Router interface.
-interface IFunctionsRouter {
- // @notice The identifier of the route to retrieve the address of the access control contract
- // The access control contract controls which accounts can manage subscriptions
- // @return id - bytes32 id that can be passed to the "getContractById" of the Router
- function getAllowListId() external view returns (bytes32);
-
- // @notice Set the identifier of the route to retrieve the address of the access control contract
- // The access control contract controls which accounts can manage subscriptions
- function setAllowListId(bytes32 allowListId) external;
-
- // @notice Get the flat fee (in Juels of LINK) that will be paid to the Router owner for operation of the network
- // @return adminFee
- function getAdminFee() external view returns (uint72 adminFee);
-
- // @notice Sends a request using the provided subscriptionId
- // @param subscriptionId - A unique subscription ID allocated by billing system,
- // a client can make requests from different contracts referencing the same subscription
- // @param data - CBOR encoded Chainlink Functions request data, use FunctionsClient API to encode a request
- // @param dataVersion - Gas limit for the fulfillment callback
- // @param callbackGasLimit - Gas limit for the fulfillment callback
- // @param donId - An identifier used to determine which route to send the request along
- // @return requestId - A unique request identifier
- function sendRequest(
- uint64 subscriptionId,
- bytes calldata data,
- uint16 dataVersion,
- uint32 callbackGasLimit,
- bytes32 donId
- ) external returns (bytes32);
-
- // @notice Sends a request to the proposed contracts
- // @param subscriptionId - A unique subscription ID allocated by billing system,
- // a client can make requests from different contracts referencing the same subscription
- // @param data - CBOR encoded Chainlink Functions request data, use FunctionsClient API to encode a request
- // @param dataVersion - Gas limit for the fulfillment callback
- // @param callbackGasLimit - Gas limit for the fulfillment callback
- // @param donId - An identifier used to determine which route to send the request along
- // @return requestId - A unique request identifier
- function sendRequestToProposed(
- uint64 subscriptionId,
- bytes calldata data,
- uint16 dataVersion,
- uint32 callbackGasLimit,
- bytes32 donId
- ) external returns (bytes32);
-
- // @notice Fulfill the request by:
- // - calling back the data that the Oracle returned to the client contract
- // - pay the DON for processing the request
- // @dev Only callable by the Coordinator contract that is saved in the commitment
- // @param response response data from DON consensus
- // @param err error from DON consensus
- // @param juelsPerGas - current rate of juels/gas
- // @param costWithoutFulfillment - The cost of processing the request (in Juels of LINK ), without fulfillment
- // @param transmitter - The Node that transmitted the OCR report
- // @param commitment - The parameters of the request that must be held consistent between request and response time
- // @return fulfillResult -
- // @return callbackGasCostJuels -
- function fulfill(
- bytes memory response,
- bytes memory err,
- uint96 juelsPerGas,
- uint96 costWithoutFulfillment,
- address transmitter,
- FunctionsResponse.Commitment memory commitment
- ) external returns (FunctionsResponse.FulfillResult, uint96);
-
- // @notice Validate requested gas limit is below the subscription max.
- // @param subscriptionId subscription ID
- // @param callbackGasLimit desired callback gas limit
- function isValidCallbackGasLimit(uint64 subscriptionId, uint32 callbackGasLimit) external view;
-
- // @notice Get the current contract given an ID
- // @param id A bytes32 identifier for the route
- // @return contract The current contract address
- function getContractById(bytes32 id) external view returns (address);
-
- // @notice Get the proposed next contract given an ID
- // @param id A bytes32 identifier for the route
- // @return contract The current or proposed contract address
- function getProposedContractById(bytes32 id) external view returns (address);
-
- // @notice Return the latest proprosal set
- // @return ids The identifiers of the contracts to update
- // @return to The addresses of the contracts that will be updated to
- function getProposedContractSet() external view returns (bytes32[] memory, address[] memory);
-
- // @notice Proposes one or more updates to the contract routes
- // @dev Only callable by owner
- function proposeContractsUpdate(bytes32[] memory proposalSetIds, address[] memory proposalSetAddresses) external;
-
- // @notice Updates the current contract routes to the proposed contracts
- // @dev Only callable by owner
- function updateContracts() external;
-
- // @dev Puts the system into an emergency stopped state.
- // @dev Only callable by owner
- function pause() external;
-
- // @dev Takes the system out of an emergency stopped state.
- // @dev Only callable by owner
- function unpause() external;
-}
diff --git a/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsSubscriptions.sol b/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsSubscriptions.sol
deleted file mode 100644
index 4072307edb8..00000000000
--- a/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsSubscriptions.sol
+++ /dev/null
@@ -1,133 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.19;
-
-import {FunctionsResponse} from "../libraries/FunctionsResponse.sol";
-
-// @title Chainlink Functions Subscription interface.
-interface IFunctionsSubscriptions {
- struct Subscription {
- uint96 balance; // ═════════╗ Common LINK balance that is controlled by the Router to be used for all consumer requests.
- address owner; // ══════════╝ The owner can fund/withdraw/cancel the subscription.
- uint96 blockedBalance; // ══╗ LINK balance that is reserved to pay for pending consumer requests.
- address proposedOwner; // ══╝ For safely transferring sub ownership.
- address[] consumers; // ════╸ Client contracts that can use the subscription
- bytes32 flags; // ══════════╸ Per-subscription flags
- }
-
- struct Consumer {
- bool allowed; // ══════════════╗ Owner can fund/withdraw/cancel the sub.
- uint64 initiatedRequests; // ║ The number of requests that have been started
- uint64 completedRequests; // ══╝ The number of requests that have successfully completed or timed out
- }
-
- // @notice Get details about a subscription.
- // @param subscriptionId - the ID of the subscription
- // @return subscription - see IFunctionsSubscriptions.Subscription for more information on the structure
- function getSubscription(uint64 subscriptionId) external view returns (Subscription memory);
-
- // @notice Get details about a consumer of a subscription.
- // @param client - the consumer contract address
- // @param subscriptionId - the ID of the subscription
- // @return consumer - see IFunctionsSubscriptions.Consumer for more information on the structure
- function getConsumer(address client, uint64 subscriptionId) external view returns (Consumer memory);
-
- // @notice Get details about the total amount of LINK within the system
- // @return totalBalance - total Juels of LINK held by the contract
- function getTotalBalance() external view returns (uint96);
-
- // @notice Get details about the total number of subscription accounts
- // @return count - total number of subscriptions in the system
- function getSubscriptionCount() external view returns (uint64);
-
- // @notice Time out all expired requests: unlocks funds and removes the ability for the request to be fulfilled
- // @param requestsToTimeoutByCommitment - A list of request commitments to time out
- // @dev The commitment can be found on the "OracleRequest" event created when sending the request.
- function timeoutRequests(FunctionsResponse.Commitment[] calldata requestsToTimeoutByCommitment) external;
-
- // @notice Oracle withdraw LINK earned through fulfilling requests
- // @notice If amount is 0 the full balance will be withdrawn
- // @notice Both signing and transmitting wallets will have a balance to withdraw
- // @param recipient where to send the funds
- // @param amount amount to withdraw
- function oracleWithdraw(address recipient, uint96 amount) external;
-
- // @notice Owner cancel subscription, sends remaining link directly to the subscription owner.
- // @dev Only callable by the Router Owner
- // @param subscriptionId subscription id
- // @dev notably can be called even if there are pending requests, outstanding ones may fail onchain
- function ownerCancelSubscription(uint64 subscriptionId) external;
-
- // @notice Recover link sent with transfer instead of transferAndCall.
- // @dev Only callable by the Router Owner
- // @param to address to send link to
- function recoverFunds(address to) external;
-
- // @notice Create a new subscription.
- // @return subscriptionId - A unique subscription id.
- // @dev You can manage the consumer set dynamically with addConsumer/removeConsumer.
- // @dev Note to fund the subscription, use transferAndCall. For example
- // @dev LINKTOKEN.transferAndCall(
- // @dev address(ROUTER),
- // @dev amount,
- // @dev abi.encode(subscriptionId));
- function createSubscription() external returns (uint64);
-
- // @notice Create a new subscription and add a consumer.
- // @return subscriptionId - A unique subscription id.
- // @dev You can manage the consumer set dynamically with addConsumer/removeConsumer.
- // @dev Note to fund the subscription, use transferAndCall. For example
- // @dev LINKTOKEN.transferAndCall(
- // @dev address(ROUTER),
- // @dev amount,
- // @dev abi.encode(subscriptionId));
- function createSubscriptionWithConsumer(address consumer) external returns (uint64 subscriptionId);
-
- // @notice Propose a new owner for a subscription.
- // @dev Only callable by the Subscription's owner
- // @param subscriptionId - ID of the subscription
- // @param newOwner - proposed new owner of the subscription
- function proposeSubscriptionOwnerTransfer(uint64 subscriptionId, address newOwner) external;
-
- // @notice Accept an ownership transfer.
- // @param subscriptionId - ID of the subscription
- // @dev will revert if original owner of subscriptionId has
- // not requested that msg.sender become the new owner.
- function acceptSubscriptionOwnerTransfer(uint64 subscriptionId) external;
-
- // @notice Remove a consumer from a Chainlink Functions subscription.
- // @dev Only callable by the Subscription's owner
- // @param subscriptionId - ID of the subscription
- // @param consumer - Consumer to remove from the subscription
- function removeConsumer(uint64 subscriptionId, address consumer) external;
-
- // @notice Add a consumer to a Chainlink Functions subscription.
- // @dev Only callable by the Subscription's owner
- // @param subscriptionId - ID of the subscription
- // @param consumer - New consumer which can use the subscription
- function addConsumer(uint64 subscriptionId, address consumer) external;
-
- // @notice Cancel a subscription
- // @dev Only callable by the Subscription's owner
- // @param subscriptionId - ID of the subscription
- // @param to - Where to send the remaining LINK to
- function cancelSubscription(uint64 subscriptionId, address to) external;
-
- // @notice Check to see if there exists a request commitment for all consumers for a given sub.
- // @param subscriptionId - ID of the subscription
- // @return true if there exists at least one unfulfilled request for the subscription, false
- // otherwise.
- // @dev Looping is bounded to MAX_CONSUMERS*(number of DONs).
- // @dev Used to disable subscription canceling while outstanding request are present.
- function pendingRequestExists(uint64 subscriptionId) external view returns (bool);
-
- // @notice Set subscription specific flags for a subscription.
- // Each byte of the flag is used to represent a resource tier that the subscription can utilize.
- // @param subscriptionId - ID of the subscription
- // @param flags - desired flag values
- function setFlags(uint64 subscriptionId, bytes32 flags) external;
-
- // @notice Get flags for a given subscription.
- // @param subscriptionId - ID of the subscription
- // @return flags - current flag values
- function getFlags(uint64 subscriptionId) external view returns (bytes32);
-}
diff --git a/contracts/src/v0.8/functions/dev/0_0_0/Functions.sol b/contracts/src/v0.8/functions/dev/v0_0_0/Functions.sol
similarity index 100%
rename from contracts/src/v0.8/functions/dev/0_0_0/Functions.sol
rename to contracts/src/v0.8/functions/dev/v0_0_0/Functions.sol
diff --git a/contracts/src/v0.8/functions/dev/0_0_0/FunctionsBillingRegistry.sol b/contracts/src/v0.8/functions/dev/v0_0_0/FunctionsBillingRegistry.sol
similarity index 100%
rename from contracts/src/v0.8/functions/dev/0_0_0/FunctionsBillingRegistry.sol
rename to contracts/src/v0.8/functions/dev/v0_0_0/FunctionsBillingRegistry.sol
diff --git a/contracts/src/v0.8/functions/dev/0_0_0/FunctionsClient.sol b/contracts/src/v0.8/functions/dev/v0_0_0/FunctionsClient.sol
similarity index 100%
rename from contracts/src/v0.8/functions/dev/0_0_0/FunctionsClient.sol
rename to contracts/src/v0.8/functions/dev/v0_0_0/FunctionsClient.sol
diff --git a/contracts/src/v0.8/functions/dev/0_0_0/FunctionsOracle.sol b/contracts/src/v0.8/functions/dev/v0_0_0/FunctionsOracle.sol
similarity index 100%
rename from contracts/src/v0.8/functions/dev/0_0_0/FunctionsOracle.sol
rename to contracts/src/v0.8/functions/dev/v0_0_0/FunctionsOracle.sol
diff --git a/contracts/src/v0.8/functions/dev/0_0_0/accessControl/AuthorizedOriginReceiver.sol b/contracts/src/v0.8/functions/dev/v0_0_0/accessControl/AuthorizedOriginReceiver.sol
similarity index 100%
rename from contracts/src/v0.8/functions/dev/0_0_0/accessControl/AuthorizedOriginReceiver.sol
rename to contracts/src/v0.8/functions/dev/v0_0_0/accessControl/AuthorizedOriginReceiver.sol
diff --git a/contracts/src/v0.8/functions/dev/0_0_0/accessControl/AuthorizedOriginReceiverUpgradeable.sol b/contracts/src/v0.8/functions/dev/v0_0_0/accessControl/AuthorizedOriginReceiverUpgradeable.sol
similarity index 100%
rename from contracts/src/v0.8/functions/dev/0_0_0/accessControl/AuthorizedOriginReceiverUpgradeable.sol
rename to contracts/src/v0.8/functions/dev/v0_0_0/accessControl/AuthorizedOriginReceiverUpgradeable.sol
diff --git a/contracts/src/v0.8/functions/dev/0_0_0/accessControl/AuthorizedReceiver.sol b/contracts/src/v0.8/functions/dev/v0_0_0/accessControl/AuthorizedReceiver.sol
similarity index 100%
rename from contracts/src/v0.8/functions/dev/0_0_0/accessControl/AuthorizedReceiver.sol
rename to contracts/src/v0.8/functions/dev/v0_0_0/accessControl/AuthorizedReceiver.sol
diff --git a/contracts/src/v0.8/functions/dev/0_0_0/accessControl/ConfirmedOwnerUpgradeable.sol b/contracts/src/v0.8/functions/dev/v0_0_0/accessControl/ConfirmedOwnerUpgradeable.sol
similarity index 100%
rename from contracts/src/v0.8/functions/dev/0_0_0/accessControl/ConfirmedOwnerUpgradeable.sol
rename to contracts/src/v0.8/functions/dev/v0_0_0/accessControl/ConfirmedOwnerUpgradeable.sol
diff --git a/contracts/src/v0.8/functions/dev/0_0_0/accessControl/interfaces/IAuthorizedOriginReceiver.sol b/contracts/src/v0.8/functions/dev/v0_0_0/accessControl/interfaces/IAuthorizedOriginReceiver.sol
similarity index 100%
rename from contracts/src/v0.8/functions/dev/0_0_0/accessControl/interfaces/IAuthorizedOriginReceiver.sol
rename to contracts/src/v0.8/functions/dev/v0_0_0/accessControl/interfaces/IAuthorizedOriginReceiver.sol
diff --git a/contracts/src/v0.8/functions/dev/0_0_0/accessControl/interfaces/IAuthorizedReceiver.sol b/contracts/src/v0.8/functions/dev/v0_0_0/accessControl/interfaces/IAuthorizedReceiver.sol
similarity index 100%
rename from contracts/src/v0.8/functions/dev/0_0_0/accessControl/interfaces/IAuthorizedReceiver.sol
rename to contracts/src/v0.8/functions/dev/v0_0_0/accessControl/interfaces/IAuthorizedReceiver.sol
diff --git a/contracts/src/v0.8/functions/dev/0_0_0/example/FunctionsClientExample.sol b/contracts/src/v0.8/functions/dev/v0_0_0/example/FunctionsClientExample.sol
similarity index 100%
rename from contracts/src/v0.8/functions/dev/0_0_0/example/FunctionsClientExample.sol
rename to contracts/src/v0.8/functions/dev/v0_0_0/example/FunctionsClientExample.sol
diff --git a/contracts/src/v0.8/functions/dev/0_0_0/interfaces/IFunctionsBillingRegistry.sol b/contracts/src/v0.8/functions/dev/v0_0_0/interfaces/IFunctionsBillingRegistry.sol
similarity index 100%
rename from contracts/src/v0.8/functions/dev/0_0_0/interfaces/IFunctionsBillingRegistry.sol
rename to contracts/src/v0.8/functions/dev/v0_0_0/interfaces/IFunctionsBillingRegistry.sol
diff --git a/contracts/src/v0.8/functions/dev/0_0_0/interfaces/IFunctionsClient.sol b/contracts/src/v0.8/functions/dev/v0_0_0/interfaces/IFunctionsClient.sol
similarity index 100%
rename from contracts/src/v0.8/functions/dev/0_0_0/interfaces/IFunctionsClient.sol
rename to contracts/src/v0.8/functions/dev/v0_0_0/interfaces/IFunctionsClient.sol
diff --git a/contracts/src/v0.8/functions/dev/0_0_0/interfaces/IFunctionsOracle.sol b/contracts/src/v0.8/functions/dev/v0_0_0/interfaces/IFunctionsOracle.sol
similarity index 100%
rename from contracts/src/v0.8/functions/dev/0_0_0/interfaces/IFunctionsOracle.sol
rename to contracts/src/v0.8/functions/dev/v0_0_0/interfaces/IFunctionsOracle.sol
diff --git a/contracts/src/v0.8/functions/dev/0_0_0/ocr/OCR2Abstract.sol b/contracts/src/v0.8/functions/dev/v0_0_0/ocr/OCR2Abstract.sol
similarity index 100%
rename from contracts/src/v0.8/functions/dev/0_0_0/ocr/OCR2Abstract.sol
rename to contracts/src/v0.8/functions/dev/v0_0_0/ocr/OCR2Abstract.sol
diff --git a/contracts/src/v0.8/functions/dev/0_0_0/ocr/OCR2Base.sol b/contracts/src/v0.8/functions/dev/v0_0_0/ocr/OCR2Base.sol
similarity index 100%
rename from contracts/src/v0.8/functions/dev/0_0_0/ocr/OCR2Base.sol
rename to contracts/src/v0.8/functions/dev/v0_0_0/ocr/OCR2Base.sol
diff --git a/contracts/src/v0.8/functions/dev/0_0_0/ocr/OCR2BaseUpgradeable.sol b/contracts/src/v0.8/functions/dev/v0_0_0/ocr/OCR2BaseUpgradeable.sol
similarity index 100%
rename from contracts/src/v0.8/functions/dev/0_0_0/ocr/OCR2BaseUpgradeable.sol
rename to contracts/src/v0.8/functions/dev/v0_0_0/ocr/OCR2BaseUpgradeable.sol
diff --git a/contracts/src/v0.8/functions/dev/0_0_0/ocr/README.md b/contracts/src/v0.8/functions/dev/v0_0_0/ocr/README.md
similarity index 100%
rename from contracts/src/v0.8/functions/dev/0_0_0/ocr/README.md
rename to contracts/src/v0.8/functions/dev/v0_0_0/ocr/README.md
diff --git a/contracts/src/v0.8/functions/dev/1_0_0/FunctionsBilling.sol b/contracts/src/v0.8/functions/dev/v1_0_0/FunctionsBilling.sol
similarity index 79%
rename from contracts/src/v0.8/functions/dev/1_0_0/FunctionsBilling.sol
rename to contracts/src/v0.8/functions/dev/v1_0_0/FunctionsBilling.sol
index efad1eab5e5..c616f7355d2 100644
--- a/contracts/src/v0.8/functions/dev/1_0_0/FunctionsBilling.sol
+++ b/contracts/src/v0.8/functions/dev/v1_0_0/FunctionsBilling.sol
@@ -10,17 +10,15 @@ import {FunctionsResponse} from "./libraries/FunctionsResponse.sol";
import {SafeCast} from "../../../vendor/openzeppelin-solidity/v4.8.0/contracts/utils/math/SafeCast.sol";
-/**
- * @title Functions Billing contract
- * @notice Contract that calculates payment from users to the nodes of the Decentralized Oracle Network (DON).
- * @dev THIS CONTRACT HAS NOT GONE THROUGH ANY SECURITY REVIEW. DO NOT USE IN PROD.
- */
+/// @title Functions Billing contract
+/// @notice Contract that calculates payment from users to the nodes of the Decentralized Oracle Network (DON).
+/// @dev THIS CONTRACT HAS NOT GONE THROUGH ANY SECURITY REVIEW. DO NOT USE IN PROD.
abstract contract FunctionsBilling is Routable, IFunctionsBilling {
using FunctionsResponse for FunctionsResponse.RequestMeta;
using FunctionsResponse for FunctionsResponse.Commitment;
using FunctionsResponse for FunctionsResponse.FulfillResult;
- uint32 private constant REASONABLE_GAS_PRICE_CEILING = 1_000_000;
+ uint256 private constant REASONABLE_GAS_PRICE_CEILING = 1_000_000_000_000_000; // 1 million gwei
// ================================================================
// | Request Commitment state |
// ================================================================
@@ -34,15 +32,14 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling {
// ================================================================
struct Config {
- uint32 maxCallbackGasLimit; // ══════════════════╗ Maximum amount of gas that can be given to a request's client callback
+ uint32 fulfillmentGasPriceOverEstimationBP; // ══╗ Percentage of gas price overestimation to account for changes in gas price between request and response. Held as basis points (one hundredth of 1 percentage point)
uint32 feedStalenessSeconds; // ║ How long before we consider the feed price to be stale and fallback to fallbackNativePerUnitLink.
uint32 gasOverheadBeforeCallback; // ║ Represents the average gas execution cost before the fulfillment callback. This amount is always billed for every request.
uint32 gasOverheadAfterCallback; // ║ Represents the average gas execution cost after the fulfillment callback. This amount is always billed for every request.
uint32 requestTimeoutSeconds; // ║ How many seconds it takes before we consider a request to be timed out
uint72 donFee; // ║ Additional flat fee (in Juels of LINK) that will be split between Node Operators. Max value is 2^80 - 1 == 1.2m LINK.
uint16 maxSupportedRequestDataVersion; // ═══════╝ The highest support request data version supported by the node. All lower versions should also be supported.
- uint32 fulfillmentGasPriceOverEstimationBP; // ══╗ Percentage of gas price overestimation to account for changes in gas price between request and response. Held as basis points (one hundredth of 1 percentage point)
- uint224 fallbackNativePerUnitLink; // ═══════════╝ fallback NATIVE CURRENCY / LINK conversion rate if the data feed is stale
+ uint224 fallbackNativePerUnitLink; // ═══════════╸ fallback NATIVE CURRENCY / LINK conversion rate if the data feed is stale
}
Config private s_config;
@@ -83,14 +80,14 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling {
// | Configuration |
// ================================================================
- // @notice Gets the Chainlink Coordinator's billing configuration
- // @return config
+ /// @notice Gets the Chainlink Coordinator's billing configuration
+ /// @return config
function getConfig() external view returns (Config memory) {
return s_config;
}
- // @notice Sets the Chainlink Coordinator's billing configuration
- // @param config - See the contents of the Config struct in IFunctionsBilling.Config for more information
+ /// @notice Sets the Chainlink Coordinator's billing configuration
+ /// @param config - See the contents of the Config struct in IFunctionsBilling.Config for more information
function updateConfig(Config memory config) public {
_onlyOwner();
@@ -102,17 +99,17 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling {
// | Fee Calculation |
// ================================================================
- // @inheritdoc IFunctionsBilling
+ /// @inheritdoc IFunctionsBilling
function getDONFee(bytes memory /* requestData */) public view override returns (uint72) {
return s_config.donFee;
}
- // @inheritdoc IFunctionsBilling
+ /// @inheritdoc IFunctionsBilling
function getAdminFee() public view override returns (uint72) {
return _getRouter().getAdminFee();
}
- // @inheritdoc IFunctionsBilling
+ /// @inheritdoc IFunctionsBilling
function getWeiPerUnitLink() public view returns (uint256) {
Config memory config = s_config;
(, int256 weiPerUnitLink, , uint256 timestamp, ) = s_linkToNativeFeed.latestRoundData();
@@ -126,47 +123,47 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling {
return uint256(weiPerUnitLink);
}
- function _getJuelsPerGas(uint256 gasPriceGwei) private view returns (uint96) {
+ function _getJuelsPerGas(uint256 gasPriceWei) private view returns (uint96) {
// (1e18 juels/link) * (wei/gas) / (wei/link) = juels per gas
// There are only 1e9*1e18 = 1e27 juels in existence, should not exceed uint96 (2^96 ~ 7e28)
- return SafeCast.toUint96((1e18 * gasPriceGwei) / getWeiPerUnitLink());
+ return SafeCast.toUint96((1e18 * gasPriceWei) / getWeiPerUnitLink());
}
// ================================================================
// | Cost Estimation |
// ================================================================
- // @inheritdoc IFunctionsBilling
+ /// @inheritdoc IFunctionsBilling
function estimateCost(
uint64 subscriptionId,
bytes calldata data,
uint32 callbackGasLimit,
- uint256 gasPriceGwei
+ uint256 gasPriceWei
) external view override returns (uint96) {
_getRouter().isValidCallbackGasLimit(subscriptionId, callbackGasLimit);
// Reasonable ceilings to prevent integer overflows
- if (gasPriceGwei > REASONABLE_GAS_PRICE_CEILING) {
+ if (gasPriceWei > REASONABLE_GAS_PRICE_CEILING) {
revert InvalidCalldata();
}
uint72 adminFee = getAdminFee();
uint72 donFee = getDONFee(data);
- return _calculateCostEstimate(callbackGasLimit, gasPriceGwei, donFee, adminFee);
+ return _calculateCostEstimate(callbackGasLimit, gasPriceWei, donFee, adminFee);
}
- // @notice Estimate the cost in Juels of LINK
+ /// @notice Estimate the cost in Juels of LINK
// that will be charged to a subscription to fulfill a Functions request
// Gas Price can be overestimated to account for flucuations between request and response time
function _calculateCostEstimate(
uint32 callbackGasLimit,
- uint256 gasPriceGwei,
+ uint256 gasPriceWei,
uint72 donFee,
uint72 adminFee
) internal view returns (uint96) {
uint256 executionGas = s_config.gasOverheadBeforeCallback + s_config.gasOverheadAfterCallback + callbackGasLimit;
- uint256 gasPriceWithOverestimation = gasPriceGwei +
- ((gasPriceGwei * s_config.fulfillmentGasPriceOverEstimationBP) / 10_000);
- // @NOTE: Basis Points are 1/100th of 1%, divide by 10_000 to bring back to original units
+ uint256 gasPriceWithOverestimation = gasPriceWei +
+ ((gasPriceWei * s_config.fulfillmentGasPriceOverEstimationBP) / 10_000);
+ /// @NOTE: Basis Points are 1/100th of 1%, divide by 10_000 to bring back to original units
uint96 juelsPerGas = _getJuelsPerGas(gasPriceWithOverestimation);
uint256 estimatedGasReimbursement = juelsPerGas * executionGas;
@@ -179,12 +176,10 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling {
// | Billing |
// ================================================================
- // @notice Initiate the billing process for an Functions request
- // @dev Only callable by the Functions Router
- // @param data - Encoded Chainlink Functions request data, use FunctionsClient API to encode a request
- // @param requestDataVersion - Version number of the structure of the request data
- // @param billing - Billing configuration for the request
- // @return commitment - The parameters of the request that must be held consistent at response time
+ /// @notice Initiate the billing process for an Functions request
+ /// @dev Only callable by the Functions Router
+ /// @param request - Chainlink Functions request data, see FunctionsResponse.RequestMeta for the structure
+ /// @return commitment - The parameters of the request that must be held consistent at response time
function _startBilling(
FunctionsResponse.RequestMeta memory request
) internal returns (FunctionsResponse.Commitment memory commitment) {
@@ -234,8 +229,8 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling {
return commitment;
}
- // @notice Generate a keccak hash request ID
- // @dev uses the number of requests that the consumer of a subscription has sent as a nonce
+ /// @notice Generate a keccak hash request ID
+ /// @dev uses the number of requests that the consumer of a subscription has sent as a nonce
function _computeRequestId(
address don,
address client,
@@ -245,13 +240,13 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling {
return keccak256(abi.encode(don, client, subscriptionId, nonce));
}
- // @notice Finalize billing process for an Functions request by sending a callback to the Client contract and then charging the subscription
- // @param requestId identifier for the request that was generated by the Registry in the beginBilling commitment
- // @param response response data from DON consensus
- // @param err error from DON consensus
- // @return result fulfillment result
- // @dev Only callable by a node that has been approved on the Coordinator
- // @dev simulated offchain to determine if sufficient balance is present to fulfill the request
+ /// @notice Finalize billing process for an Functions request by sending a callback to the Client contract and then charging the subscription
+ /// @param requestId identifier for the request that was generated by the Registry in the beginBilling commitment
+ /// @param response response data from DON consensus
+ /// @param err error from DON consensus
+ /// @return result fulfillment result
+ /// @dev Only callable by a node that has been approved on the Coordinator
+ /// @dev simulated offchain to determine if sufficient balance is present to fulfill the request
function _fulfillAndBill(
bytes32 requestId,
bytes memory response,
@@ -261,14 +256,14 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling {
) internal returns (FunctionsResponse.FulfillResult) {
FunctionsResponse.Commitment memory commitment = abi.decode(onchainMetadata, (FunctionsResponse.Commitment));
- if (s_requestCommitments[requestId] != keccak256(abi.encode(commitment))) {
- return FunctionsResponse.FulfillResult.INVALID_COMMITMENT;
- }
-
if (s_requestCommitments[requestId] == bytes32(0)) {
return FunctionsResponse.FulfillResult.INVALID_REQUEST_ID;
}
+ if (s_requestCommitments[requestId] != keccak256(abi.encode(commitment))) {
+ return FunctionsResponse.FulfillResult.INVALID_COMMITMENT;
+ }
+
uint96 juelsPerGas = _getJuelsPerGas(tx.gasprice);
// Gas overhead without callback
uint96 gasOverheadJuels = juelsPerGas *
@@ -306,25 +301,20 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling {
// | Request Timeout |
// ================================================================
- // @inheritdoc IFunctionsBilling
- // @dev Only callable by the Router
- // @dev Used by FunctionsRouter.sol during timeout of a request
- function deleteCommitment(bytes32 requestId) external override onlyRouter returns (bool) {
- // Ensure that commitment exists
- if (s_requestCommitments[requestId] == bytes32(0)) {
- return false;
- }
+ /// @inheritdoc IFunctionsBilling
+ /// @dev Only callable by the Router
+ /// @dev Used by FunctionsRouter.sol during timeout of a request
+ function deleteCommitment(bytes32 requestId) external override onlyRouter {
// Delete commitment
delete s_requestCommitments[requestId];
emit CommitmentDeleted(requestId);
- return true;
}
// ================================================================
// | Fund withdrawal |
// ================================================================
- // @inheritdoc IFunctionsBilling
+ /// @inheritdoc IFunctionsBilling
function oracleWithdraw(address recipient, uint96 amount) external {
_disperseFeePool();
@@ -337,8 +327,8 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling {
IFunctionsSubscriptions(address(_getRouter())).oracleWithdraw(recipient, amount);
}
- // @inheritdoc IFunctionsBilling
- // @dev Only callable by the Coordinator owner
+ /// @inheritdoc IFunctionsBilling
+ /// @dev Only callable by the Coordinator owner
function oracleWithdrawAll() external {
_onlyOwner();
_disperseFeePool();
@@ -347,9 +337,11 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling {
// Bounded by "maxNumOracles" on OCR2Abstract.sol
for (uint256 i = 0; i < transmitters.length; ++i) {
- uint96 balance = s_withdrawableTokens[msg.sender];
- s_withdrawableTokens[msg.sender] = 0;
- IFunctionsSubscriptions(address(_getRouter())).oracleWithdraw(transmitters[i], balance);
+ uint96 balance = s_withdrawableTokens[transmitters[i]];
+ if (balance > 0) {
+ s_withdrawableTokens[transmitters[i]] = 0;
+ IFunctionsSubscriptions(address(_getRouter())).oracleWithdraw(transmitters[i], balance);
+ }
}
}
diff --git a/contracts/src/v0.8/functions/dev/1_0_0/FunctionsClient.sol b/contracts/src/v0.8/functions/dev/v1_0_0/FunctionsClient.sol
similarity index 57%
rename from contracts/src/v0.8/functions/dev/1_0_0/FunctionsClient.sol
rename to contracts/src/v0.8/functions/dev/v1_0_0/FunctionsClient.sol
index b7f676c2327..ecbbbd928fe 100644
--- a/contracts/src/v0.8/functions/dev/1_0_0/FunctionsClient.sol
+++ b/contracts/src/v0.8/functions/dev/v1_0_0/FunctionsClient.sol
@@ -6,8 +6,8 @@ import {IFunctionsClient} from "./interfaces/IFunctionsClient.sol";
import {FunctionsRequest} from "./libraries/FunctionsRequest.sol";
-// @title The Chainlink Functions client contract
-// @notice Contract developers can inherit this contract in order to make Chainlink Functions requests
+/// @title The Chainlink Functions client contract
+/// @notice Contract developers can inherit this contract in order to make Chainlink Functions requests
abstract contract FunctionsClient is IFunctionsClient {
using FunctionsRequest for FunctionsRequest.Request;
@@ -22,11 +22,11 @@ abstract contract FunctionsClient is IFunctionsClient {
i_router = IFunctionsRouter(router);
}
- // @notice Sends a Chainlink Functions request
- // @param data The CBOR encoded bytes data for a Functions request
- // @param subscriptionId The subscription ID that will be charged to service the request
- // @param callbackGasLimit the amount of gas that will be available for the fulfillment callback
- // @return requestId The generated request ID for this request
+ /// @notice Sends a Chainlink Functions request
+ /// @param data The CBOR encoded bytes data for a Functions request
+ /// @param subscriptionId The subscription ID that will be charged to service the request
+ /// @param callbackGasLimit the amount of gas that will be available for the fulfillment callback
+ /// @return requestId The generated request ID for this request
function _sendRequest(
bytes memory data,
uint64 subscriptionId,
@@ -44,18 +44,19 @@ abstract contract FunctionsClient is IFunctionsClient {
return requestId;
}
- // @notice User defined function to handle a response from the DON
- // @param requestId The request ID, returned by sendRequest()
- // @param response Aggregated response from the execution of the user's source code
- // @param err Aggregated error from the execution of the user code or from the execution pipeline
- // @dev Either response or error parameter will be set, but never both
+ /// @notice User defined function to handle a response from the DON
+ /// @param requestId The request ID, returned by sendRequest()
+ /// @param response Aggregated response from the execution of the user's source code
+ /// @param err Aggregated error from the execution of the user code or from the execution pipeline
+ /// @dev Either response or error parameter will be set, but never both
function fulfillRequest(bytes32 requestId, bytes memory response, bytes memory err) internal virtual;
- // @inheritdoc IFunctionsClient
+ /// @inheritdoc IFunctionsClient
function handleOracleFulfillment(bytes32 requestId, bytes memory response, bytes memory err) external override {
if (msg.sender != address(i_router)) {
revert OnlyRouterCanFulfill();
}
fulfillRequest(requestId, response, err);
+ emit RequestFulfilled(requestId);
}
}
diff --git a/contracts/src/v0.8/functions/dev/1_0_0/FunctionsCoordinator.sol b/contracts/src/v0.8/functions/dev/v1_0_0/FunctionsCoordinator.sol
similarity index 71%
rename from contracts/src/v0.8/functions/dev/1_0_0/FunctionsCoordinator.sol
rename to contracts/src/v0.8/functions/dev/v1_0_0/FunctionsCoordinator.sol
index 46df61cd916..540b382d652 100644
--- a/contracts/src/v0.8/functions/dev/1_0_0/FunctionsCoordinator.sol
+++ b/contracts/src/v0.8/functions/dev/v1_0_0/FunctionsCoordinator.sol
@@ -9,15 +9,15 @@ import {FunctionsBilling} from "./FunctionsBilling.sol";
import {OCR2Base} from "./ocr/OCR2Base.sol";
import {FunctionsResponse} from "./libraries/FunctionsResponse.sol";
-// @title Functions Coordinator contract
-// @notice Contract that nodes of a Decentralized Oracle Network (DON) interact with
-// @dev THIS CONTRACT HAS NOT GONE THROUGH ANY SECURITY REVIEW. DO NOT USE IN PROD.
+/// @title Functions Coordinator contract
+/// @notice Contract that nodes of a Decentralized Oracle Network (DON) interact with
+/// @dev THIS CONTRACT HAS NOT GONE THROUGH ANY SECURITY REVIEW. DO NOT USE IN PROD.
contract FunctionsCoordinator is OCR2Base, IFunctionsCoordinator, FunctionsBilling {
using FunctionsResponse for FunctionsResponse.RequestMeta;
using FunctionsResponse for FunctionsResponse.Commitment;
using FunctionsResponse for FunctionsResponse.FulfillResult;
- // @inheritdoc ITypeAndVersion
+ /// @inheritdoc ITypeAndVersion
string public constant override typeAndVersion = "Functions Coordinator v1.0.0";
event OracleRequest(
@@ -39,7 +39,6 @@ contract FunctionsCoordinator is OCR2Base, IFunctionsCoordinator, FunctionsBilli
error UnauthorizedPublicKeyChange();
bytes private s_donPublicKey;
- mapping(address signerAddress => bytes publicKey) private s_nodePublicKeys;
bytes private s_thresholdPublicKey;
constructor(
@@ -48,7 +47,7 @@ contract FunctionsCoordinator is OCR2Base, IFunctionsCoordinator, FunctionsBilli
address linkToNativeFeed
) OCR2Base(true) FunctionsBilling(router, config, linkToNativeFeed) {}
- // @inheritdoc IFunctionsCoordinator
+ /// @inheritdoc IFunctionsCoordinator
function getThresholdPublicKey() external view override returns (bytes memory) {
if (s_thresholdPublicKey.length == 0) {
revert EmptyPublicKey();
@@ -56,7 +55,7 @@ contract FunctionsCoordinator is OCR2Base, IFunctionsCoordinator, FunctionsBilli
return s_thresholdPublicKey;
}
- // @inheritdoc IFunctionsCoordinator
+ /// @inheritdoc IFunctionsCoordinator
function setThresholdPublicKey(bytes calldata thresholdPublicKey) external override onlyOwner {
if (thresholdPublicKey.length == 0) {
revert EmptyPublicKey();
@@ -64,7 +63,7 @@ contract FunctionsCoordinator is OCR2Base, IFunctionsCoordinator, FunctionsBilli
s_thresholdPublicKey = thresholdPublicKey;
}
- // @inheritdoc IFunctionsCoordinator
+ /// @inheritdoc IFunctionsCoordinator
function getDONPublicKey() external view override returns (bytes memory) {
if (s_donPublicKey.length == 0) {
revert EmptyPublicKey();
@@ -72,7 +71,7 @@ contract FunctionsCoordinator is OCR2Base, IFunctionsCoordinator, FunctionsBilli
return s_donPublicKey;
}
- // @inheritdoc IFunctionsCoordinator
+ /// @inheritdoc IFunctionsCoordinator
function setDONPublicKey(bytes calldata donPublicKey) external override onlyOwner {
if (donPublicKey.length == 0) {
revert EmptyPublicKey();
@@ -80,7 +79,7 @@ contract FunctionsCoordinator is OCR2Base, IFunctionsCoordinator, FunctionsBilli
s_donPublicKey = donPublicKey;
}
- // @dev check if node is in current transmitter list
+ /// @dev check if node is in current transmitter list
function _isTransmitter(address node) internal view returns (bool) {
address[] memory nodes = s_transmitters;
// Bounded by "maxNumOracles" on OCR2Abstract.sol
@@ -92,40 +91,7 @@ contract FunctionsCoordinator is OCR2Base, IFunctionsCoordinator, FunctionsBilli
return false;
}
- // @inheritdoc IFunctionsCoordinator
- function setNodePublicKey(address node, bytes calldata publicKey) external override {
- // Owner can set anything. Transmitters can set only their own key.
- if (!(msg.sender == owner() || (_isTransmitter(msg.sender) && msg.sender == node))) {
- revert UnauthorizedPublicKeyChange();
- }
- s_nodePublicKeys[node] = publicKey;
- }
-
- // @inheritdoc IFunctionsCoordinator
- function deleteNodePublicKey(address node) external override {
- // Owner can delete anything. Others can delete only their own key.
- if (msg.sender != owner() && msg.sender != node) {
- revert UnauthorizedPublicKeyChange();
- }
- delete s_nodePublicKeys[node];
- }
-
- // @inheritdoc IFunctionsCoordinator
- function getAllNodePublicKeys() external view override returns (address[] memory, bytes[] memory) {
- address[] memory nodes = s_transmitters;
- bytes[] memory keys = new bytes[](nodes.length);
- // Bounded by "maxNumOracles" on OCR2Abstract.sol
- for (uint256 i = 0; i < nodes.length; ++i) {
- bytes memory nodePublicKey = s_nodePublicKeys[nodes[i]];
- if (nodePublicKey.length == 0) {
- revert EmptyPublicKey();
- }
- keys[i] = nodePublicKey;
- }
- return (nodes, keys);
- }
-
- // @inheritdoc IFunctionsCoordinator
+ /// @inheritdoc IFunctionsCoordinator
function startRequest(
FunctionsResponse.RequestMeta calldata request
) external override onlyRouter returns (FunctionsResponse.Commitment memory commitment) {
@@ -147,19 +113,19 @@ contract FunctionsCoordinator is OCR2Base, IFunctionsCoordinator, FunctionsBilli
return commitment;
}
- // DON fees are pooled together. If the OCR configuration is going to change, these need to be distributed.
+ /// @dev DON fees are pooled together. If the OCR configuration is going to change, these need to be distributed.
function _beforeSetConfig(uint8 /* _f */, bytes memory /* _onchainConfig */) internal override {
if (_getTransmitters().length > 0) {
_disperseFeePool();
}
}
- // Used by FunctionsBilling.sol
+ /// @dev Used by FunctionsBilling.sol
function _getTransmitters() internal view override returns (address[] memory) {
return s_transmitters;
}
- // Report hook called within OCR2Base.sol
+ /// @dev Report hook called within OCR2Base.sol
function _report(
uint256 /*initialGas*/,
address /*transmitter*/,
@@ -205,7 +171,7 @@ contract FunctionsCoordinator is OCR2Base, IFunctionsCoordinator, FunctionsBilli
}
}
- // Used in FunctionsBilling.sol
+ /// @dev Used in FunctionsBilling.sol
function _onlyOwner() internal view override {
_validateOwnership();
}
diff --git a/contracts/src/v0.8/functions/dev/1_0_0/FunctionsRouter.sol b/contracts/src/v0.8/functions/dev/v1_0_0/FunctionsRouter.sol
similarity index 81%
rename from contracts/src/v0.8/functions/dev/1_0_0/FunctionsRouter.sol
rename to contracts/src/v0.8/functions/dev/v1_0_0/FunctionsRouter.sol
index 46f6929fabc..41cd90341f3 100644
--- a/contracts/src/v0.8/functions/dev/1_0_0/FunctionsRouter.sol
+++ b/contracts/src/v0.8/functions/dev/v1_0_0/FunctionsRouter.sol
@@ -62,6 +62,7 @@ contract FunctionsRouter is IFunctionsRouter, FunctionsSubscriptions, Pausable,
error SenderMustAcceptTermsOfService(address sender);
error InvalidGasFlagValue(uint8 value);
error GasLimitTooBig(uint32 limit);
+ error DuplicateRequestId(bytes32 requestId);
struct CallbackResult {
bool success; // ══════╸ Whether the callback succeeded or not
@@ -84,11 +85,13 @@ contract FunctionsRouter is IFunctionsRouter, FunctionsSubscriptions, Pausable,
// | Configuration state |
// ================================================================
struct Config {
- uint16 maxConsumersPerSubscription; // ══════╗ Maximum number of consumers which can be added to a single subscription. This bound ensures we are able to loop over all subscription consumers as needed, without exceeding gas limits. Should a user require more consumers, they can use multiple subscriptions.
- uint72 adminFee; // ║ Flat fee (in Juels of LINK) that will be paid to the Router owner for operation of the network
- bytes4 handleOracleFulfillmentSelector; // ║ The function selector that is used when calling back to the Client contract
- uint16 gasForCallExactCheck; // ═════════════╝ Used during calling back to the client. Ensures we have at least enough gas to be able to revert if gasAmount > 63//64*gas available.
- uint32[] maxCallbackGasLimits; // ═══════════╸ List of max callback gas limits used by flag with GAS_FLAG_INDEX
+ uint16 maxConsumersPerSubscription; // ═════════╗ Maximum number of consumers which can be added to a single subscription. This bound ensures we are able to loop over all subscription consumers as needed, without exceeding gas limits. Should a user require more consumers, they can use multiple subscriptions.
+ uint72 adminFee; // ║ Flat fee (in Juels of LINK) that will be paid to the Router owner for operation of the network
+ bytes4 handleOracleFulfillmentSelector; // ║ The function selector that is used when calling back to the Client contract
+ uint16 gasForCallExactCheck; // ════════════════╝ Used during calling back to the client. Ensures we have at least enough gas to be able to revert if gasAmount > 63//64*gas available.
+ uint32[] maxCallbackGasLimits; // ══════════════╸ List of max callback gas limits used by flag with GAS_FLAG_INDEX
+ uint16 subscriptionDepositMinimumRequests; //═══╗ Amount of requests that must be completed before the full subscription balance will be released when closing a subscription account.
+ uint72 subscriptionDepositJuels; // ════════════╝ Amount of subscription funds that are held as a deposit until Config.subscriptionDepositMinimumRequests are made using the subscription.
}
Config private s_config;
@@ -134,20 +137,20 @@ contract FunctionsRouter is IFunctionsRouter, FunctionsSubscriptions, Pausable,
// | Configuration |
// ================================================================
- // @notice The identifier of the route to retrieve the address of the access control contract
+ /// @notice The identifier of the route to retrieve the address of the access control contract
// The access control contract controls which accounts can manage subscriptions
- // @return id - bytes32 id that can be passed to the "getContractById" of the Router
+ /// @return id - bytes32 id that can be passed to the "getContractById" of the Router
function getConfig() external view returns (Config memory) {
return s_config;
}
- // @notice The router configuration
+ /// @notice The router configuration
function updateConfig(Config memory config) public onlyOwner {
s_config = config;
emit ConfigUpdated(config);
}
- // @inheritdoc IFunctionsRouter
+ /// @inheritdoc IFunctionsRouter
function isValidCallbackGasLimit(uint64 subscriptionId, uint32 callbackGasLimit) public view {
uint8 callbackGasLimitsIndexSelector = uint8(getFlags(subscriptionId)[MAX_CALLBACK_GAS_LIMIT_FLAGS_INDEX]);
if (callbackGasLimitsIndexSelector >= s_config.maxCallbackGasLimits.length) {
@@ -159,31 +162,36 @@ contract FunctionsRouter is IFunctionsRouter, FunctionsSubscriptions, Pausable,
}
}
- // @inheritdoc IFunctionsRouter
+ /// @inheritdoc IFunctionsRouter
function getAdminFee() external view override returns (uint72) {
return s_config.adminFee;
}
- // @inheritdoc IFunctionsRouter
+ /// @inheritdoc IFunctionsRouter
function getAllowListId() external view override returns (bytes32) {
return s_allowListId;
}
- // @inheritdoc IFunctionsRouter
+ /// @inheritdoc IFunctionsRouter
function setAllowListId(bytes32 allowListId) external override onlyOwner {
s_allowListId = allowListId;
}
- // Used within FunctionsSubscriptions.sol
+ /// @dev Used within FunctionsSubscriptions.sol
function _getMaxConsumers() internal view override returns (uint16) {
return s_config.maxConsumersPerSubscription;
}
+ /// @dev Used within FunctionsSubscriptions.sol
+ function _getSubscriptionDepositDetails() internal view override returns (uint16, uint72) {
+ return (s_config.subscriptionDepositMinimumRequests, s_config.subscriptionDepositJuels);
+ }
+
// ================================================================
// | Requests |
// ================================================================
- // @inheritdoc IFunctionsRouter
+ /// @inheritdoc IFunctionsRouter
function sendRequest(
uint64 subscriptionId,
bytes calldata data,
@@ -195,7 +203,7 @@ contract FunctionsRouter is IFunctionsRouter, FunctionsSubscriptions, Pausable,
return _sendRequest(donId, coordinator, subscriptionId, data, dataVersion, callbackGasLimit);
}
- // @inheritdoc IFunctionsRouter
+ /// @inheritdoc IFunctionsRouter
function sendRequestToProposed(
uint64 subscriptionId,
bytes calldata data,
@@ -226,6 +234,7 @@ contract FunctionsRouter is IFunctionsRouter, FunctionsSubscriptions, Pausable,
Subscription memory subscription = getSubscription(subscriptionId);
Consumer memory consumer = getConsumer(msg.sender, subscriptionId);
+ uint72 adminFee = s_config.adminFee;
// Forward request to DON
FunctionsResponse.Commitment memory commitment = coordinator.startRequest(
@@ -236,7 +245,7 @@ contract FunctionsRouter is IFunctionsRouter, FunctionsSubscriptions, Pausable,
dataVersion: dataVersion,
flags: getFlags(subscriptionId),
callbackGasLimit: callbackGasLimit,
- adminFee: s_config.adminFee,
+ adminFee: adminFee,
initiatedRequests: consumer.initiatedRequests,
completedRequests: consumer.completedRequests,
availableBalance: subscription.balance - subscription.blockedBalance,
@@ -244,11 +253,16 @@ contract FunctionsRouter is IFunctionsRouter, FunctionsSubscriptions, Pausable,
})
);
+ // Do not allow setting a comittment for a requestId that already exists
+ if (s_requestCommitments[commitment.requestId] != bytes32(0)) {
+ revert DuplicateRequestId(commitment.requestId);
+ }
+
// Store a commitment about the request
s_requestCommitments[commitment.requestId] = keccak256(
abi.encode(
FunctionsResponse.Commitment({
- adminFee: s_config.adminFee,
+ adminFee: adminFee,
coordinator: address(coordinator),
client: msg.sender,
subscriptionId: subscriptionId,
@@ -285,7 +299,7 @@ contract FunctionsRouter is IFunctionsRouter, FunctionsSubscriptions, Pausable,
// | Responses |
// ================================================================
- // @inheritdoc IFunctionsRouter
+ /// @inheritdoc IFunctionsRouter
function fulfill(
bytes memory response,
bytes memory err,
@@ -300,23 +314,27 @@ contract FunctionsRouter is IFunctionsRouter, FunctionsSubscriptions, Pausable,
revert OnlyCallableFromCoordinator();
}
- if (s_requestCommitments[commitment.requestId] == bytes32(0)) {
- resultCode = FunctionsResponse.FulfillResult.INVALID_REQUEST_ID;
- emit RequestNotProcessed(commitment.requestId, commitment.coordinator, transmitter, resultCode);
- return (resultCode, 0);
- }
+ {
+ bytes32 commitmentHash = s_requestCommitments[commitment.requestId];
- if (keccak256(abi.encode(commitment)) != s_requestCommitments[commitment.requestId]) {
- resultCode = FunctionsResponse.FulfillResult.INVALID_COMMITMENT;
- emit RequestNotProcessed(commitment.requestId, commitment.coordinator, transmitter, resultCode);
- return (resultCode, 0);
- }
+ if (commitmentHash == bytes32(0)) {
+ resultCode = FunctionsResponse.FulfillResult.INVALID_REQUEST_ID;
+ emit RequestNotProcessed(commitment.requestId, commitment.coordinator, transmitter, resultCode);
+ return (resultCode, 0);
+ }
+
+ if (keccak256(abi.encode(commitment)) != commitmentHash) {
+ resultCode = FunctionsResponse.FulfillResult.INVALID_COMMITMENT;
+ emit RequestNotProcessed(commitment.requestId, commitment.coordinator, transmitter, resultCode);
+ return (resultCode, 0);
+ }
- // Check that the transmitter has supplied enough gas for the callback to succeed
- if (gasleft() < commitment.callbackGasLimit + commitment.gasOverheadAfterCallback) {
- resultCode = FunctionsResponse.FulfillResult.INSUFFICIENT_GAS_PROVIDED;
- emit RequestNotProcessed(commitment.requestId, commitment.coordinator, transmitter, resultCode);
- return (resultCode, 0);
+ // Check that the transmitter has supplied enough gas for the callback to succeed
+ if (gasleft() < commitment.callbackGasLimit + commitment.gasOverheadAfterCallback) {
+ resultCode = FunctionsResponse.FulfillResult.INSUFFICIENT_GAS_PROVIDED;
+ emit RequestNotProcessed(commitment.requestId, commitment.coordinator, transmitter, resultCode);
+ return (resultCode, 0);
+ }
}
{
@@ -383,6 +401,18 @@ contract FunctionsRouter is IFunctionsRouter, FunctionsSubscriptions, Pausable,
uint32 callbackGasLimit,
address client
) private returns (CallbackResult memory) {
+ bool destinationNoLongerExists;
+ // solhint-disable-next-line no-inline-assembly
+ assembly {
+ // solidity calls check that a contract actually exists at the destination, so we do the same
+ destinationNoLongerExists := iszero(extcodesize(client))
+ }
+ if (destinationNoLongerExists) {
+ // Return without attempting callback
+ // The subscription will still be charged to reimburse transmitter's gas overhead
+ return CallbackResult({success: false, gasUsed: 0, returnData: new bytes(0)});
+ }
+
bytes memory encodedCallback = abi.encodeWithSelector(
s_config.handleOracleFulfillmentSelector,
requestId,
@@ -404,13 +434,6 @@ contract FunctionsRouter is IFunctionsRouter, FunctionsSubscriptions, Pausable,
// solhint-disable-next-line no-inline-assembly
assembly {
- // solidity calls check that a contract actually exists at the destination, so we do the same
- // Note we do this check prior to measuring gas so gasForCallExactCheck (our "cushion")
- // doesn't need to account for it.
- if iszero(extcodesize(client)) {
- revert(0, 0)
- }
-
let g := gas()
// Compute g -= gasForCallExactCheck and check for underflow
// The gas actually passed to the callee is _min(gasAmount, 63//64*gas available).
@@ -451,7 +474,7 @@ contract FunctionsRouter is IFunctionsRouter, FunctionsSubscriptions, Pausable,
// | Route methods |
// ================================================================
- // @inheritdoc IRouterBase
+ /// @inheritdoc IFunctionsRouter
function getContractById(bytes32 id) public view override returns (address) {
address currentImplementation = s_route[id];
if (currentImplementation == address(0)) {
@@ -460,7 +483,7 @@ contract FunctionsRouter is IFunctionsRouter, FunctionsSubscriptions, Pausable,
return currentImplementation;
}
- // @inheritdoc IRouterBase
+ /// @inheritdoc IFunctionsRouter
function getProposedContractById(bytes32 id) public view override returns (address) {
// Iterations will not exceed MAX_PROPOSAL_SET_LENGTH
for (uint8 i = 0; i < s_proposedContractSet.ids.length; ++i) {
@@ -475,12 +498,12 @@ contract FunctionsRouter is IFunctionsRouter, FunctionsSubscriptions, Pausable,
// | Contract Proposal methods |
// ================================================================
- // @inheritdoc IRouterBase
+ /// @inheritdoc IFunctionsRouter
function getProposedContractSet() external view override returns (bytes32[] memory, address[] memory) {
return (s_proposedContractSet.ids, s_proposedContractSet.to);
}
- // @inheritdoc IRouterBase
+ /// @inheritdoc IFunctionsRouter
function proposeContractsUpdate(
bytes32[] memory proposedContractSetIds,
address[] memory proposedContractSetAddresses
@@ -501,21 +524,18 @@ contract FunctionsRouter is IFunctionsRouter, FunctionsSubscriptions, Pausable,
) {
revert InvalidProposal();
}
- }
-
- s_proposedContractSet = ContractProposalSet({ids: proposedContractSetIds, to: proposedContractSetAddresses});
- // NOTE: iterations of this loop will not exceed MAX_PROPOSAL_SET_LENGTH
- for (uint256 i = 0; i < proposedContractSetIds.length; ++i) {
emit ContractProposed({
- proposedContractSetId: proposedContractSetIds[i],
- proposedContractSetFromAddress: s_route[proposedContractSetIds[i]],
- proposedContractSetToAddress: proposedContractSetAddresses[i]
+ proposedContractSetId: id,
+ proposedContractSetFromAddress: s_route[id],
+ proposedContractSetToAddress: proposedContract
});
}
+
+ s_proposedContractSet = ContractProposalSet({ids: proposedContractSetIds, to: proposedContractSetAddresses});
}
- // @inheritdoc IRouterBase
+ /// @inheritdoc IFunctionsRouter
function updateContracts() external override onlyOwner {
// Iterations will not exceed MAX_PROPOSAL_SET_LENGTH
for (uint256 i = 0; i < s_proposedContractSet.ids.length; ++i) {
@@ -533,17 +553,17 @@ contract FunctionsRouter is IFunctionsRouter, FunctionsSubscriptions, Pausable,
// ================================================================
// Favoring internal functions over actual modifiers to reduce contract size
- // Used within FunctionsSubscriptions.sol
+ /// @dev Used within FunctionsSubscriptions.sol
function _whenNotPaused() internal view override {
_requireNotPaused();
}
- // Used within FunctionsSubscriptions.sol
+ /// @dev Used within FunctionsSubscriptions.sol
function _onlyRouterOwner() internal view override {
_validateOwnership();
}
- // Used within FunctionsSubscriptions.sol
+ /// @dev Used within FunctionsSubscriptions.sol
function _onlySenderThatAcceptedToS() internal view override {
address currentImplementation = s_route[s_allowListId];
if (currentImplementation == address(0)) {
@@ -555,12 +575,12 @@ contract FunctionsRouter is IFunctionsRouter, FunctionsSubscriptions, Pausable,
}
}
- // @inheritdoc IRouterBase
+ /// @inheritdoc IFunctionsRouter
function pause() external override onlyOwner {
_pause();
}
- // @inheritdoc IRouterBase
+ /// @inheritdoc IFunctionsRouter
function unpause() external override onlyOwner {
_unpause();
}
diff --git a/contracts/src/v0.8/functions/dev/1_0_0/FunctionsSubscriptions.sol b/contracts/src/v0.8/functions/dev/v1_0_0/FunctionsSubscriptions.sol
similarity index 79%
rename from contracts/src/v0.8/functions/dev/1_0_0/FunctionsSubscriptions.sol
rename to contracts/src/v0.8/functions/dev/v1_0_0/FunctionsSubscriptions.sol
index cabe8b0d284..864225fd38c 100644
--- a/contracts/src/v0.8/functions/dev/1_0_0/FunctionsSubscriptions.sol
+++ b/contracts/src/v0.8/functions/dev/v1_0_0/FunctionsSubscriptions.sol
@@ -13,9 +13,9 @@ import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.0/contracts/tok
import {SafeERC20} from "../../../vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/utils/SafeERC20.sol";
import {SafeCast} from "../../../vendor/openzeppelin-solidity/v4.8.0/contracts/utils/math/SafeCast.sol";
-// @title Functions Subscriptions contract
-// @notice Contract that coordinates payment from users to the nodes of the Decentralized Oracle Network (DON).
-// @dev THIS CONTRACT HAS NOT GONE THROUGH ANY SECURITY REVIEW. DO NOT USE IN PROD.
+/// @title Functions Subscriptions contract
+/// @notice Contract that coordinates payment from users to the nodes of the Decentralized Oracle Network (DON).
+/// @dev THIS CONTRACT HAS NOT GONE THROUGH ANY SECURITY REVIEW. DO NOT USE IN PROD.
abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, IERC677Receiver {
using SafeERC20 for IERC20;
using FunctionsResponse for FunctionsResponse.Commitment;
@@ -24,7 +24,7 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, IERC677Rece
// | Balance state |
// ================================================================
// link token address
- address internal immutable i_linkToken;
+ IERC20 internal immutable i_linkToken;
// s_totalLinkBalance tracks the total LINK sent to/from
// this contract through onTokenTransfer, cancelSubscription and oracleWithdraw.
@@ -32,7 +32,7 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, IERC677Rece
// sent tokens using transfer and so we may need to use recoverFunds.
uint96 private s_totalLinkBalance;
- // @dev NOP balances are held as a single amount. The breakdown is held by the Coordinator.
+ /// @dev NOP balances are held as a single amount. The breakdown is held by the Coordinator.
mapping(address coordinator => uint96 balanceJuelsLink) private s_withdrawableTokens;
// ================================================================
@@ -42,7 +42,7 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, IERC677Rece
// loop through all the current subscriptions via .getSubscription().
uint64 private s_currentSubscriptionId;
- mapping(uint64 subscriptionId => IFunctionsSubscriptions.Subscription) private s_subscriptions;
+ mapping(uint64 subscriptionId => Subscription) private s_subscriptions;
// Maintains the list of keys in s_consumers.
// We do this for 2 reasons:
@@ -50,7 +50,7 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, IERC677Rece
// 2. To be able to return the list of all consumers in getSubscription.
// Note that we need the s_consumers map to be able to directly check if a
// consumer is valid without reading all the consumers from storage.
- mapping(address consumer => mapping(uint64 subscriptionId => IFunctionsSubscriptions.Consumer)) private s_consumers;
+ mapping(address consumer => mapping(uint64 subscriptionId => Consumer)) private s_consumers;
event SubscriptionCreated(uint64 indexed subscriptionId, address owner);
event SubscriptionFunded(uint64 indexed subscriptionId, uint256 oldBalance, uint256 newBalance);
@@ -70,7 +70,6 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, IERC677Rece
error MustBeSubscriptionOwner();
error TimeoutNotExceeded();
error MustBeProposedOwner(address proposedOwner);
- error TotalBalanceInvariantViolated(uint256 totalBalance, uint256 deductionAttempt); // Should never happen
event FundsRecovered(address to, uint256 amount);
// ================================================================
@@ -90,15 +89,15 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, IERC677Rece
// | Initialization |
// ================================================================
constructor(address link) {
- i_linkToken = link;
+ i_linkToken = IERC20(link);
}
// ================================================================
// | Request/Response |
// ================================================================
- // @notice Sets a request as in-flight
- // @dev Only callable within the Router
+ /// @notice Sets a request as in-flight
+ /// @dev Only callable within the Router
function _markRequestInFlight(address client, uint64 subscriptionId, uint96 estimatedTotalCostJuels) internal {
// Earmark subscription funds
s_subscriptions[subscriptionId].blockedBalance += estimatedTotalCostJuels;
@@ -107,8 +106,8 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, IERC677Rece
s_consumers[client][subscriptionId].initiatedRequests += 1;
}
- // @notice Moves funds from one subscription account to another.
- // @dev Only callable by the Coordinator contract that is saved in the request commitment
+ /// @notice Moves funds from one subscription account to another.
+ /// @dev Only callable by the Coordinator contract that is saved in the request commitment
function _pay(
uint64 subscriptionId,
uint96 estimatedTotalCostJuels,
@@ -121,16 +120,17 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, IERC677Rece
uint96 callbackGasCostJuels = juelsPerGas * gasUsed;
uint96 totalCostJuels = costWithoutCallbackJuels + adminFee + callbackGasCostJuels;
- // Charge the subscription
- if (s_subscriptions[subscriptionId].balance < totalCostJuels) {
+ if (
+ s_subscriptions[subscriptionId].balance < totalCostJuels ||
+ s_subscriptions[subscriptionId].blockedBalance < estimatedTotalCostJuels
+ ) {
revert InsufficientBalance(s_subscriptions[subscriptionId].balance);
}
+
+ // Charge the subscription
s_subscriptions[subscriptionId].balance -= totalCostJuels;
// Unblock earmarked funds
- if (s_subscriptions[subscriptionId].blockedBalance < estimatedTotalCostJuels) {
- revert InsufficientBalance(s_subscriptions[subscriptionId].balance);
- }
s_subscriptions[subscriptionId].blockedBalance -= estimatedTotalCostJuels;
// Pay the DON's fees and gas reimbursement
@@ -149,21 +149,21 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, IERC677Rece
// | Owner methods |
// ================================================================
- // @inheritdoc IFunctionsSubscriptions
+ /// @inheritdoc IFunctionsSubscriptions
function ownerCancelSubscription(uint64 subscriptionId) external override {
_onlyRouterOwner();
_isExistingSubscription(subscriptionId);
- _cancelSubscriptionHelper(subscriptionId, s_subscriptions[subscriptionId].owner);
+ _cancelSubscriptionHelper(subscriptionId, s_subscriptions[subscriptionId].owner, false);
}
- // @inheritdoc IFunctionsSubscriptions
+ /// @inheritdoc IFunctionsSubscriptions
function recoverFunds(address to) external override {
_onlyRouterOwner();
- uint256 externalBalance = IERC20(i_linkToken).balanceOf(address(this));
+ uint256 externalBalance = i_linkToken.balanceOf(address(this));
uint256 internalBalance = uint256(s_totalLinkBalance);
if (internalBalance < externalBalance) {
uint256 amount = externalBalance - internalBalance;
- IERC20(i_linkToken).safeTransfer(to, amount);
+ i_linkToken.safeTransfer(to, amount);
emit FundsRecovered(to, amount);
}
// If the balances are equal, nothing to be done.
@@ -173,7 +173,7 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, IERC677Rece
// | Fund withdrawal |
// ================================================================
- // @inheritdoc IFunctionsSubscriptions
+ /// @inheritdoc IFunctionsSubscriptions
function oracleWithdraw(address recipient, uint96 amount) external override {
_whenNotPaused();
@@ -184,18 +184,15 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, IERC677Rece
if (currentBalance < amount) {
revert InsufficientBalance(currentBalance);
}
- if (s_totalLinkBalance < amount) {
- revert TotalBalanceInvariantViolated(s_totalLinkBalance, amount);
- }
s_withdrawableTokens[msg.sender] -= amount;
s_totalLinkBalance -= amount;
- IERC20(i_linkToken).safeTransfer(recipient, amount);
+ i_linkToken.safeTransfer(recipient, amount);
}
- // @notice Owner withdraw LINK earned through admin fees
- // @notice If amount is 0 the full balance will be withdrawn
- // @param recipient where to send the funds
- // @param amount amount to withdraw
+ /// @notice Owner withdraw LINK earned through admin fees
+ /// @notice If amount is 0 the full balance will be withdrawn
+ /// @param recipient where to send the funds
+ /// @param amount amount to withdraw
function ownerWithdraw(address recipient, uint96 amount) external {
_onlyRouterOwner();
if (amount == 0) {
@@ -205,13 +202,10 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, IERC677Rece
if (currentBalance < amount) {
revert InsufficientBalance(currentBalance);
}
- if (s_totalLinkBalance < amount) {
- revert TotalBalanceInvariantViolated(s_totalLinkBalance, amount);
- }
s_withdrawableTokens[address(this)] -= amount;
s_totalLinkBalance -= amount;
- IERC20(i_linkToken).safeTransfer(recipient, amount);
+ i_linkToken.safeTransfer(recipient, amount);
}
// ================================================================
@@ -219,11 +213,11 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, IERC677Rece
// ================================================================
// This function is to be invoked when using LINK.transferAndCall
- // @dev Note to fund the subscription, use transferAndCall. For example
- // @dev LINKTOKEN.transferAndCall(
- // @dev address(ROUTER),
- // @dev amount,
- // @dev abi.encode(subscriptionId));
+ /// @dev Note to fund the subscription, use transferAndCall. For example
+ /// @dev LINKTOKEN.transferAndCall(
+ /// @dev address(ROUTER),
+ /// @dev amount,
+ /// @dev abi.encode(subscriptionId));
function onTokenTransfer(address /* sender */, uint256 amount, bytes calldata data) external override {
_whenNotPaused();
if (msg.sender != address(i_linkToken)) {
@@ -248,42 +242,63 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, IERC677Rece
// | Subscription management |
// ================================================================
- // @inheritdoc IFunctionsSubscriptions
+ /// @inheritdoc IFunctionsSubscriptions
function getTotalBalance() external view override returns (uint96) {
return s_totalLinkBalance;
}
- // @inheritdoc IFunctionsSubscriptions
+ /// @inheritdoc IFunctionsSubscriptions
function getSubscriptionCount() external view override returns (uint64) {
return s_currentSubscriptionId;
}
- // @inheritdoc IFunctionsSubscriptions
+ /// @inheritdoc IFunctionsSubscriptions
function getSubscription(uint64 subscriptionId) public view override returns (Subscription memory) {
_isExistingSubscription(subscriptionId);
return s_subscriptions[subscriptionId];
}
- // @inheritdoc IFunctionsSubscriptions
+ /// @inheritdoc IFunctionsSubscriptions
+ function getSubscriptionsInRange(
+ uint64 subscriptionIdStart,
+ uint64 subscriptionIdEnd
+ ) external view override returns (Subscription[] memory subscriptions) {
+ if (
+ subscriptionIdStart > subscriptionIdEnd ||
+ subscriptionIdEnd > s_currentSubscriptionId ||
+ s_currentSubscriptionId == 0
+ ) {
+ revert InvalidCalldata();
+ }
+
+ subscriptions = new Subscription[]((subscriptionIdEnd - subscriptionIdStart) + 1);
+ for (uint256 i = 0; i <= subscriptionIdEnd - subscriptionIdStart; ++i) {
+ subscriptions[i] = s_subscriptions[uint64(subscriptionIdStart + i)];
+ }
+
+ return subscriptions;
+ }
+
+ /// @inheritdoc IFunctionsSubscriptions
function getConsumer(address client, uint64 subscriptionId) public view override returns (Consumer memory) {
return s_consumers[client][subscriptionId];
}
- // Used within this file & FunctionsRouter.sol
+ /// @dev Used within this file & FunctionsRouter.sol
function _isExistingSubscription(uint64 subscriptionId) internal view {
if (s_subscriptions[subscriptionId].owner == address(0)) {
revert InvalidSubscription();
}
}
- // Used within FunctionsRouter.sol
+ /// @dev Used within FunctionsRouter.sol
function _isAllowedConsumer(address client, uint64 subscriptionId) internal view {
if (!s_consumers[client][subscriptionId].allowed) {
revert InvalidConsumer();
}
}
- // @inheritdoc IFunctionsSubscriptions
+ /// @inheritdoc IFunctionsSubscriptions
function createSubscription() external override returns (uint64 subscriptionId) {
_whenNotPaused();
_onlySenderThatAcceptedToS();
@@ -303,7 +318,7 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, IERC677Rece
return subscriptionId;
}
- // @inheritdoc IFunctionsSubscriptions
+ /// @inheritdoc IFunctionsSubscriptions
function createSubscriptionWithConsumer(address consumer) external override returns (uint64 subscriptionId) {
_whenNotPaused();
_onlySenderThatAcceptedToS();
@@ -327,7 +342,7 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, IERC677Rece
return subscriptionId;
}
- // @inheritdoc IFunctionsSubscriptions
+ /// @inheritdoc IFunctionsSubscriptions
function proposeSubscriptionOwnerTransfer(uint64 subscriptionId, address newOwner) external override {
_whenNotPaused();
_onlySubscriptionOwner(subscriptionId);
@@ -341,7 +356,7 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, IERC677Rece
emit SubscriptionOwnerTransferRequested(subscriptionId, msg.sender, newOwner);
}
- // @inheritdoc IFunctionsSubscriptions
+ /// @inheritdoc IFunctionsSubscriptions
function acceptSubscriptionOwnerTransfer(uint64 subscriptionId) external override {
_whenNotPaused();
_onlySenderThatAcceptedToS();
@@ -356,16 +371,14 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, IERC677Rece
emit SubscriptionOwnerTransferred(subscriptionId, previousOwner, msg.sender);
}
- // @inheritdoc IFunctionsSubscriptions
+ /// @inheritdoc IFunctionsSubscriptions
function removeConsumer(uint64 subscriptionId, address consumer) external override {
_whenNotPaused();
_onlySubscriptionOwner(subscriptionId);
_onlySenderThatAcceptedToS();
Consumer memory consumerData = s_consumers[consumer][subscriptionId];
- if (!consumerData.allowed) {
- revert InvalidConsumer();
- }
+ _isAllowedConsumer(consumer, subscriptionId);
if (consumerData.initiatedRequests != consumerData.completedRequests) {
revert CannotRemoveWithPendingRequests();
}
@@ -384,10 +397,10 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, IERC677Rece
emit SubscriptionConsumerRemoved(subscriptionId, consumer);
}
- // overriden in FunctionsRouter.sol
+ /// @dev Overriden in FunctionsRouter.sol
function _getMaxConsumers() internal view virtual returns (uint16);
- // @inheritdoc IFunctionsSubscriptions
+ /// @inheritdoc IFunctionsSubscriptions
function addConsumer(uint64 subscriptionId, address consumer) external override {
_whenNotPaused();
_onlySubscriptionOwner(subscriptionId);
@@ -395,7 +408,7 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, IERC677Rece
// Already maxed, cannot add any more consumers.
uint16 maximumConsumers = _getMaxConsumers();
- if (s_subscriptions[subscriptionId].consumers.length == maximumConsumers) {
+ if (s_subscriptions[subscriptionId].consumers.length >= maximumConsumers) {
revert TooManyConsumers(maximumConsumers);
}
if (s_consumers[consumer][subscriptionId].allowed) {
@@ -410,36 +423,55 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, IERC677Rece
emit SubscriptionConsumerAdded(subscriptionId, consumer);
}
- // @inheritdoc IFunctionsSubscriptions
- function cancelSubscription(uint64 subscriptionId, address to) external override {
- _whenNotPaused();
- _onlySubscriptionOwner(subscriptionId);
- _onlySenderThatAcceptedToS();
-
- if (pendingRequestExists(subscriptionId)) {
- revert CannotRemoveWithPendingRequests();
- }
+ /// @dev Overriden in FunctionsRouter.sol
+ function _getSubscriptionDepositDetails() internal virtual returns (uint16, uint72);
- _cancelSubscriptionHelper(subscriptionId, to);
- }
-
- function _cancelSubscriptionHelper(uint64 subscriptionId, address to) private {
+ function _cancelSubscriptionHelper(uint64 subscriptionId, address toAddress, bool checkDepositRefundability) private {
Subscription memory subscription = s_subscriptions[subscriptionId];
uint96 balance = subscription.balance;
+ uint64 completedRequests = 0;
+
// NOTE: loop iterations are bounded by config.maxConsumers
// If no consumers, does nothing.
for (uint256 i = 0; i < subscription.consumers.length; ++i) {
- delete s_consumers[subscription.consumers[i]][subscriptionId];
+ address consumer = subscription.consumers[i];
+ completedRequests += s_consumers[consumer][subscriptionId].completedRequests;
+ delete s_consumers[consumer][subscriptionId];
}
delete s_subscriptions[subscriptionId];
- s_totalLinkBalance -= balance;
- IERC20(i_linkToken).safeTransfer(to, uint256(balance));
+ (uint16 subscriptionDepositMinimumRequests, uint72 subscriptionDepositJuels) = _getSubscriptionDepositDetails();
+
+ // If subscription has not made enough requests, deposit will be forfeited
+ if (checkDepositRefundability && completedRequests < subscriptionDepositMinimumRequests) {
+ uint96 deposit = subscriptionDepositJuels > balance ? balance : subscriptionDepositJuels;
+ if (deposit > 0) {
+ s_withdrawableTokens[address(this)] += deposit;
+ balance -= deposit;
+ }
+ }
+
+ if (balance > 0) {
+ s_totalLinkBalance -= balance;
+ i_linkToken.safeTransfer(toAddress, uint256(balance));
+ }
+ emit SubscriptionCanceled(subscriptionId, toAddress, balance);
+ }
+
+ /// @inheritdoc IFunctionsSubscriptions
+ function cancelSubscription(uint64 subscriptionId, address to) external override {
+ _whenNotPaused();
+ _onlySubscriptionOwner(subscriptionId);
+ _onlySenderThatAcceptedToS();
+
+ if (pendingRequestExists(subscriptionId)) {
+ revert CannotRemoveWithPendingRequests();
+ }
- emit SubscriptionCanceled(subscriptionId, to, balance);
+ _cancelSubscriptionHelper(subscriptionId, to, true);
}
- // @inheritdoc IFunctionsSubscriptions
+ /// @inheritdoc IFunctionsSubscriptions
function pendingRequestExists(uint64 subscriptionId) public view override returns (bool) {
address[] memory consumers = s_subscriptions[subscriptionId].consumers;
// NOTE: loop iterations are bounded by config.maxConsumers
@@ -452,14 +484,14 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, IERC677Rece
return false;
}
- // @inheritdoc IFunctionsSubscriptions
+ /// @inheritdoc IFunctionsSubscriptions
function setFlags(uint64 subscriptionId, bytes32 flags) external override {
_onlyRouterOwner();
_isExistingSubscription(subscriptionId);
s_subscriptions[subscriptionId].flags = flags;
}
- // @inheritdoc IFunctionsSubscriptions
+ /// @inheritdoc IFunctionsSubscriptions
function getFlags(uint64 subscriptionId) public view returns (bytes32) {
return s_subscriptions[subscriptionId].flags;
}
@@ -468,7 +500,7 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, IERC677Rece
// | Request Timeout |
// ================================================================
- // @inheritdoc IFunctionsSubscriptions
+ /// @inheritdoc IFunctionsSubscriptions
function timeoutRequests(FunctionsResponse.Commitment[] calldata requestsToTimeoutByCommitment) external override {
_whenNotPaused();
@@ -513,12 +545,12 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, IERC677Rece
}
}
- // Overriden in FunctionsRouter.sol
+ /// @dev Overriden in FunctionsRouter.sol
function _onlySenderThatAcceptedToS() internal virtual;
- // Overriden in FunctionsRouter.sol
+ /// @dev Overriden in FunctionsRouter.sol
function _onlyRouterOwner() internal virtual;
- // Overriden in FunctionsRouter.sol
+ /// @dev Overriden in FunctionsRouter.sol
function _whenNotPaused() internal virtual;
}
diff --git a/contracts/src/v0.8/functions/dev/1_0_0/Routable.sol b/contracts/src/v0.8/functions/dev/v1_0_0/Routable.sol
similarity index 70%
rename from contracts/src/v0.8/functions/dev/1_0_0/Routable.sol
rename to contracts/src/v0.8/functions/dev/v1_0_0/Routable.sol
index 8c09eba5d79..b50b1e603f9 100644
--- a/contracts/src/v0.8/functions/dev/1_0_0/Routable.sol
+++ b/contracts/src/v0.8/functions/dev/v1_0_0/Routable.sol
@@ -4,9 +4,9 @@ pragma solidity ^0.8.19;
import {ITypeAndVersion} from "../../../shared/interfaces/ITypeAndVersion.sol";
import {IOwnableFunctionsRouter} from "./interfaces/IOwnableFunctionsRouter.sol";
-// @title This abstract should be inherited by contracts that will be used
-// as the destinations to a route (id=>contract) on the Router.
-// It provides a Router getter and modifiers
+/// @title This abstract should be inherited by contracts that will be used
+/// as the destinations to a route (id=>contract) on the Router.
+/// It provides a Router getter and modifiers.
abstract contract Routable is ITypeAndVersion {
IOwnableFunctionsRouter private immutable i_router;
@@ -14,7 +14,7 @@ abstract contract Routable is ITypeAndVersion {
error OnlyCallableByRouter();
error OnlyCallableByRouterOwner();
- // @dev Initializes the contract.
+ /// @dev Initializes the contract.
constructor(address router) {
if (router == address(0)) {
revert RouterMustBeSet();
@@ -22,12 +22,12 @@ abstract contract Routable is ITypeAndVersion {
i_router = IOwnableFunctionsRouter(router);
}
- // @notice Return the Router
+ /// @notice Return the Router
function _getRouter() internal view returns (IOwnableFunctionsRouter router) {
return i_router;
}
- // @notice Reverts if called by anyone other than the router.
+ /// @notice Reverts if called by anyone other than the router.
modifier onlyRouter() {
if (msg.sender != address(i_router)) {
revert OnlyCallableByRouter();
@@ -35,7 +35,7 @@ abstract contract Routable is ITypeAndVersion {
_;
}
- // @notice Reverts if called by anyone other than the router owner.
+ /// @notice Reverts if called by anyone other than the router owner.
modifier onlyRouterOwner() {
if (msg.sender != i_router.owner()) {
revert OnlyCallableByRouterOwner();
diff --git a/contracts/src/v0.8/functions/dev/1_0_0/accessControl/TermsOfServiceAllowList.sol b/contracts/src/v0.8/functions/dev/v1_0_0/accessControl/TermsOfServiceAllowList.sol
similarity index 88%
rename from contracts/src/v0.8/functions/dev/1_0_0/accessControl/TermsOfServiceAllowList.sol
rename to contracts/src/v0.8/functions/dev/v1_0_0/accessControl/TermsOfServiceAllowList.sol
index 2ce107c9861..c4bd524b522 100644
--- a/contracts/src/v0.8/functions/dev/1_0_0/accessControl/TermsOfServiceAllowList.sol
+++ b/contracts/src/v0.8/functions/dev/v1_0_0/accessControl/TermsOfServiceAllowList.sol
@@ -10,12 +10,12 @@ import {ConfirmedOwner} from "../../../../shared/access/ConfirmedOwner.sol";
import {Address} from "../../../../vendor/openzeppelin-solidity/v4.8.0/contracts/utils/Address.sol";
import {EnumerableSet} from "../../../../vendor/openzeppelin-solidity/v4.8.0/contracts/utils/structs/EnumerableSet.sol";
-// @notice A contract to handle access control of subscription management dependent on signing a Terms of Service
+/// @notice A contract to handle access control of subscription management dependent on signing a Terms of Service
contract TermsOfServiceAllowList is ITermsOfServiceAllowList, IAccessController, ITypeAndVersion, ConfirmedOwner {
using Address for address;
using EnumerableSet for EnumerableSet.AddressSet;
- // @inheritdoc ITypeAndVersion
+ /// @inheritdoc ITypeAndVersion
string public constant override typeAndVersion = "Functions Terms of Service Allow List v1.0.0";
EnumerableSet.AddressSet private s_allowedSenders;
@@ -53,14 +53,14 @@ contract TermsOfServiceAllowList is ITermsOfServiceAllowList, IAccessController,
// | Configuration |
// ================================================================
- // @notice Gets the contracts's configuration
- // @return config
+ /// @notice Gets the contracts's configuration
+ /// @return config
function getConfig() external view returns (Config memory) {
return s_config;
}
- // @notice Sets the contracts's configuration
- // @param config - See the contents of the TermsOfServiceAllowList.Config struct for more information
+ /// @notice Sets the contracts's configuration
+ /// @param config - See the contents of the TermsOfServiceAllowList.Config struct for more information
function updateConfig(Config memory config) public onlyOwner {
s_config = config;
emit ConfigUpdated(config);
@@ -70,12 +70,12 @@ contract TermsOfServiceAllowList is ITermsOfServiceAllowList, IAccessController,
// | Allow methods |
// ================================================================
- // @inheritdoc ITermsOfServiceAllowList
+ /// @inheritdoc ITermsOfServiceAllowList
function getMessage(address acceptor, address recipient) public pure override returns (bytes32) {
return keccak256(abi.encodePacked(acceptor, recipient));
}
- // @inheritdoc ITermsOfServiceAllowList
+ /// @inheritdoc ITermsOfServiceAllowList
function acceptTermsOfService(address acceptor, address recipient, bytes32 r, bytes32 s, uint8 v) external override {
if (s_blockedSenders[recipient]) {
revert RecipientIsBlocked();
@@ -102,12 +102,12 @@ contract TermsOfServiceAllowList is ITermsOfServiceAllowList, IAccessController,
emit AddedAccess(recipient);
}
- // @inheritdoc ITermsOfServiceAllowList
+ /// @inheritdoc ITermsOfServiceAllowList
function getAllAllowedSenders() external view override returns (address[] memory) {
return s_allowedSenders.values();
}
- // @inheritdoc IAccessController
+ /// @inheritdoc IAccessController
function hasAccess(address user, bytes calldata /* data */) external view override returns (bool) {
if (!s_config.enabled) {
return true;
@@ -119,7 +119,7 @@ contract TermsOfServiceAllowList is ITermsOfServiceAllowList, IAccessController,
// | Block methods |
// ================================================================
- // @inheritdoc ITermsOfServiceAllowList
+ /// @inheritdoc ITermsOfServiceAllowList
function isBlockedSender(address sender) external view override returns (bool) {
if (!s_config.enabled) {
return false;
@@ -127,14 +127,14 @@ contract TermsOfServiceAllowList is ITermsOfServiceAllowList, IAccessController,
return s_blockedSenders[sender];
}
- // @inheritdoc ITermsOfServiceAllowList
+ /// @inheritdoc ITermsOfServiceAllowList
function blockSender(address sender) external override onlyOwner {
s_allowedSenders.remove(sender);
s_blockedSenders[sender] = true;
emit BlockedAccess(sender);
}
- // @inheritdoc ITermsOfServiceAllowList
+ /// @inheritdoc ITermsOfServiceAllowList
function unblockSender(address sender) external override onlyOwner {
s_blockedSenders[sender] = false;
emit UnblockedAccess(sender);
diff --git a/contracts/src/v0.8/functions/dev/v1_0_0/accessControl/interfaces/ITermsOfServiceAllowList.sol b/contracts/src/v0.8/functions/dev/v1_0_0/accessControl/interfaces/ITermsOfServiceAllowList.sol
new file mode 100644
index 00000000000..af4daa18bc3
--- /dev/null
+++ b/contracts/src/v0.8/functions/dev/v1_0_0/accessControl/interfaces/ITermsOfServiceAllowList.sol
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.19;
+
+/// @notice A contract to handle access control of subscription management dependent on signing a Terms of Service
+interface ITermsOfServiceAllowList {
+ /// @notice Return the message data for the proof given to accept the Terms of Service
+ /// @param acceptor - The wallet address that has accepted the Terms of Service on the UI
+ /// @param recipient - The recipient address that the acceptor is taking responsibility for
+ /// @return Hash of the message data
+ function getMessage(address acceptor, address recipient) external pure returns (bytes32);
+
+ /// @notice Check if the address is blocked for usage
+ /// @param sender The transaction sender's address
+ /// @return True or false
+ function isBlockedSender(address sender) external returns (bool);
+
+ /// @notice Get a list of all allowed senders
+ /// @dev WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
+ /// to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
+ /// this function has an unbounded cost, and using it as part of a state-changing function may render the function
+ /// uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
+ /// @return addresses - all allowed addresses
+ function getAllAllowedSenders() external view returns (address[] memory);
+
+ /// @notice Allows access to the sender based on acceptance of the Terms of Service
+ /// @param acceptor - The wallet address that has accepted the Terms of Service on the UI
+ /// @param recipient - The recipient address that the acceptor is taking responsibility for
+ /// @param r - ECDSA signature r data produced by the Chainlink Functions Subscription UI
+ /// @param s - ECDSA signature s produced by the Chainlink Functions Subscription UI
+ /// @param v - ECDSA signature v produced by the Chainlink Functions Subscription UI
+ function acceptTermsOfService(address acceptor, address recipient, bytes32 r, bytes32 s, uint8 v) external;
+
+ /// @notice Removes a sender's access if already authorized, and disallows re-accepting the Terms of Service
+ /// @param sender - Address of the sender to block
+ function blockSender(address sender) external;
+
+ /// @notice Re-allows a previously blocked sender to accept the Terms of Service
+ /// @param sender - Address of the sender to unblock
+ function unblockSender(address sender) external;
+}
diff --git a/contracts/src/v0.8/functions/dev/1_0_0/example/FunctionsClientExample.sol b/contracts/src/v0.8/functions/dev/v1_0_0/example/FunctionsClientExample.sol
similarity index 75%
rename from contracts/src/v0.8/functions/dev/1_0_0/example/FunctionsClientExample.sol
rename to contracts/src/v0.8/functions/dev/v1_0_0/example/FunctionsClientExample.sol
index 5feee704ef5..f0f154c07b2 100644
--- a/contracts/src/v0.8/functions/dev/1_0_0/example/FunctionsClientExample.sol
+++ b/contracts/src/v0.8/functions/dev/v1_0_0/example/FunctionsClientExample.sol
@@ -5,9 +5,7 @@ import {FunctionsClient} from "../FunctionsClient.sol";
import {ConfirmedOwner} from "../../../../shared/access/ConfirmedOwner.sol";
import {FunctionsRequest} from "../libraries/FunctionsRequest.sol";
-/**
- * @title Chainlink Functions example Client contract implementation
- */
+/// @title Chainlink Functions example Client contract implementation
contract FunctionsClientExample is FunctionsClient, ConfirmedOwner {
using FunctionsRequest for FunctionsRequest.Request;
@@ -23,13 +21,11 @@ contract FunctionsClientExample is FunctionsClient, ConfirmedOwner {
constructor(address router) FunctionsClient(router) ConfirmedOwner(msg.sender) {}
- /**
- * @notice Send a simple request
- * @param source JavaScript source code
- * @param encryptedSecretsReferences Encrypted secrets payload
- * @param args List of arguments accessible from within the source code
- * @param subscriptionId Billing ID
- */
+ /// @notice Send a simple request
+ /// @param source JavaScript source code
+ /// @param encryptedSecretsReferences Encrypted secrets payload
+ /// @param args List of arguments accessible from within the source code
+ /// @param subscriptionId Billing ID
function sendRequest(
string calldata source,
bytes calldata encryptedSecretsReferences,
@@ -44,13 +40,11 @@ contract FunctionsClientExample is FunctionsClient, ConfirmedOwner {
s_lastRequestId = _sendRequest(req.encodeCBOR(), subscriptionId, MAX_CALLBACK_GAS, jobId);
}
- /**
- * @notice Store latest result/error
- * @param requestId The request ID, returned by sendRequest()
- * @param response Aggregated response from the user code
- * @param err Aggregated error from the user code or from the execution pipeline
- * Either response or error parameter will be set, but never both
- */
+ /// @notice Store latest result/error
+ /// @param requestId The request ID, returned by sendRequest()
+ /// @param response Aggregated response from the user code
+ /// @param err Aggregated error from the user code or from the execution pipeline
+ /// @dev Either response or error parameter will be set, but never both
function fulfillRequest(bytes32 requestId, bytes memory response, bytes memory err) internal override {
if (s_lastRequestId != requestId) {
revert UnexpectedRequestID(requestId);
diff --git a/contracts/src/v0.8/functions/dev/v1_0_0/interfaces/IFunctionsBilling.sol b/contracts/src/v0.8/functions/dev/v1_0_0/interfaces/IFunctionsBilling.sol
new file mode 100644
index 00000000000..6291d05e57c
--- /dev/null
+++ b/contracts/src/v0.8/functions/dev/v1_0_0/interfaces/IFunctionsBilling.sol
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.19;
+
+/// @title Chainlink Functions DON billing interface.
+interface IFunctionsBilling {
+ /// @notice Return the current conversion from WEI of ETH to LINK from the configured Chainlink data feed
+ /// @return weiPerUnitLink - The amount of WEI in one LINK
+ function getWeiPerUnitLink() external view returns (uint256);
+
+ /// @notice Determine the fee that will be split between Node Operators for servicing a request
+ /// @param requestCBOR - CBOR encoded Chainlink Functions request data, use FunctionsRequest library to encode a request
+ /// @return fee - Cost in Juels (1e18) of LINK
+ function getDONFee(bytes memory requestCBOR) external view returns (uint72);
+
+ /// @notice Determine the fee that will be paid to the Router owner for operating the network
+ /// @return fee - Cost in Juels (1e18) of LINK
+ function getAdminFee() external view returns (uint72);
+
+ /// @notice Estimate the total cost that will be charged to a subscription to make a request: transmitter gas re-reimbursement, plus DON fee, plus Registry fee
+ /// @param - subscriptionId An identifier of the billing account
+ /// @param - data Encoded Chainlink Functions request data, use FunctionsClient API to encode a request
+ /// @param - callbackGasLimit Gas limit for the fulfillment callback
+ /// @param - gasPriceWei The blockchain's gas price to estimate with
+ /// @return - billedCost Cost in Juels (1e18) of LINK
+ function estimateCost(
+ uint64 subscriptionId,
+ bytes calldata data,
+ uint32 callbackGasLimit,
+ uint256 gasPriceWei
+ ) external view returns (uint96);
+
+ /// @notice Remove a request commitment that the Router has determined to be stale
+ /// @param requestId - The request ID to remove
+ function deleteCommitment(bytes32 requestId) external;
+
+ /// @notice Oracle withdraw LINK earned through fulfilling requests
+ /// @notice If amount is 0 the full balance will be withdrawn
+ /// @param recipient where to send the funds
+ /// @param amount amount to withdraw
+ function oracleWithdraw(address recipient, uint96 amount) external;
+
+ /// @notice Withdraw all LINK earned by Oracles through fulfilling requests
+ function oracleWithdrawAll() external;
+}
diff --git a/contracts/src/v0.8/functions/dev/v1_0_0/interfaces/IFunctionsClient.sol b/contracts/src/v0.8/functions/dev/v1_0_0/interfaces/IFunctionsClient.sol
new file mode 100644
index 00000000000..f28a41666b5
--- /dev/null
+++ b/contracts/src/v0.8/functions/dev/v1_0_0/interfaces/IFunctionsClient.sol
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.19;
+
+/// @title Chainlink Functions client interface.
+interface IFunctionsClient {
+ /// @notice Chainlink Functions response handler called by the Functions Router
+ /// during fullilment from the designated transmitter node in an OCR round.
+ /// @param requestId The requestId returned by FunctionsClient.sendRequest().
+ /// @param response Aggregated response from the request's source code.
+ /// @param err Aggregated error either from the request's source code or from the execution pipeline.
+ /// @dev Either response or error parameter will be set, but never both.
+ function handleOracleFulfillment(bytes32 requestId, bytes memory response, bytes memory err) external;
+}
diff --git a/contracts/src/v0.8/functions/dev/v1_0_0/interfaces/IFunctionsCoordinator.sol b/contracts/src/v0.8/functions/dev/v1_0_0/interfaces/IFunctionsCoordinator.sol
new file mode 100644
index 00000000000..4e2bd703dc4
--- /dev/null
+++ b/contracts/src/v0.8/functions/dev/v1_0_0/interfaces/IFunctionsCoordinator.sol
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.19;
+
+import {FunctionsResponse} from "../libraries/FunctionsResponse.sol";
+
+/// @title Chainlink Functions DON Coordinator interface.
+interface IFunctionsCoordinator {
+ /// @notice Returns the DON's threshold encryption public key used to encrypt secrets
+ /// @dev All nodes on the DON have separate key shares of the threshold decryption key
+ /// and nodes must participate in a threshold decryption OCR round to decrypt secrets
+ /// @return thresholdPublicKey the DON's threshold encryption public key
+ function getThresholdPublicKey() external view returns (bytes memory);
+
+ /// @notice Sets the DON's threshold encryption public key used to encrypt secrets
+ /// @dev Used to rotate the key
+ /// @param thresholdPublicKey The new public key
+ function setThresholdPublicKey(bytes calldata thresholdPublicKey) external;
+
+ /// @notice Returns the DON's secp256k1 public key that is used to encrypt secrets
+ /// @dev All nodes on the DON have the corresponding private key
+ /// needed to decrypt the secrets encrypted with the public key
+ /// @return publicKey the DON's public key
+ function getDONPublicKey() external view returns (bytes memory);
+
+ /// @notice Sets DON's secp256k1 public key used to encrypt secrets
+ /// @dev Used to rotate the key
+ /// @param donPublicKey The new public key
+ function setDONPublicKey(bytes calldata donPublicKey) external;
+
+ /// @notice Receives a request to be emitted to the DON for processing
+ /// @param request The request metadata
+ /// @dev see the struct for field descriptions
+ /// @return commitment - The parameters of the request that must be held consistent at response time
+ function startRequest(
+ FunctionsResponse.RequestMeta calldata request
+ ) external returns (FunctionsResponse.Commitment memory commitment);
+}
diff --git a/contracts/src/v0.8/functions/dev/v1_0_0/interfaces/IFunctionsRouter.sol b/contracts/src/v0.8/functions/dev/v1_0_0/interfaces/IFunctionsRouter.sol
new file mode 100644
index 00000000000..5f93aac873e
--- /dev/null
+++ b/contracts/src/v0.8/functions/dev/v1_0_0/interfaces/IFunctionsRouter.sol
@@ -0,0 +1,109 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.19;
+
+import {FunctionsResponse} from "../libraries/FunctionsResponse.sol";
+
+/// @title Chainlink Functions Router interface.
+interface IFunctionsRouter {
+ /// @notice The identifier of the route to retrieve the address of the access control contract
+ /// The access control contract controls which accounts can manage subscriptions
+ /// @return id - bytes32 id that can be passed to the "getContractById" of the Router
+ function getAllowListId() external view returns (bytes32);
+
+ /// @notice Set the identifier of the route to retrieve the address of the access control contract
+ /// The access control contract controls which accounts can manage subscriptions
+ function setAllowListId(bytes32 allowListId) external;
+
+ /// @notice Get the flat fee (in Juels of LINK) that will be paid to the Router owner for operation of the network
+ /// @return adminFee
+ function getAdminFee() external view returns (uint72 adminFee);
+
+ /// @notice Sends a request using the provided subscriptionId
+ /// @param subscriptionId - A unique subscription ID allocated by billing system,
+ /// a client can make requests from different contracts referencing the same subscription
+ /// @param data - CBOR encoded Chainlink Functions request data, use FunctionsClient API to encode a request
+ /// @param dataVersion - Gas limit for the fulfillment callback
+ /// @param callbackGasLimit - Gas limit for the fulfillment callback
+ /// @param donId - An identifier used to determine which route to send the request along
+ /// @return requestId - A unique request identifier
+ function sendRequest(
+ uint64 subscriptionId,
+ bytes calldata data,
+ uint16 dataVersion,
+ uint32 callbackGasLimit,
+ bytes32 donId
+ ) external returns (bytes32);
+
+ /// @notice Sends a request to the proposed contracts
+ /// @param subscriptionId - A unique subscription ID allocated by billing system,
+ /// a client can make requests from different contracts referencing the same subscription
+ /// @param data - CBOR encoded Chainlink Functions request data, use FunctionsClient API to encode a request
+ /// @param dataVersion - Gas limit for the fulfillment callback
+ /// @param callbackGasLimit - Gas limit for the fulfillment callback
+ /// @param donId - An identifier used to determine which route to send the request along
+ /// @return requestId - A unique request identifier
+ function sendRequestToProposed(
+ uint64 subscriptionId,
+ bytes calldata data,
+ uint16 dataVersion,
+ uint32 callbackGasLimit,
+ bytes32 donId
+ ) external returns (bytes32);
+
+ /// @notice Fulfill the request by:
+ /// - calling back the data that the Oracle returned to the client contract
+ /// - pay the DON for processing the request
+ /// @dev Only callable by the Coordinator contract that is saved in the commitment
+ /// @param response response data from DON consensus
+ /// @param err error from DON consensus
+ /// @param juelsPerGas - current rate of juels/gas
+ /// @param costWithoutFulfillment - The cost of processing the request (in Juels of LINK ), without fulfillment
+ /// @param transmitter - The Node that transmitted the OCR report
+ /// @param commitment - The parameters of the request that must be held consistent between request and response time
+ /// @return fulfillResult -
+ /// @return callbackGasCostJuels -
+ function fulfill(
+ bytes memory response,
+ bytes memory err,
+ uint96 juelsPerGas,
+ uint96 costWithoutFulfillment,
+ address transmitter,
+ FunctionsResponse.Commitment memory commitment
+ ) external returns (FunctionsResponse.FulfillResult, uint96);
+
+ /// @notice Validate requested gas limit is below the subscription max.
+ /// @param subscriptionId subscription ID
+ /// @param callbackGasLimit desired callback gas limit
+ function isValidCallbackGasLimit(uint64 subscriptionId, uint32 callbackGasLimit) external view;
+
+ /// @notice Get the current contract given an ID
+ /// @param id A bytes32 identifier for the route
+ /// @return contract The current contract address
+ function getContractById(bytes32 id) external view returns (address);
+
+ /// @notice Get the proposed next contract given an ID
+ /// @param id A bytes32 identifier for the route
+ /// @return contract The current or proposed contract address
+ function getProposedContractById(bytes32 id) external view returns (address);
+
+ /// @notice Return the latest proprosal set
+ /// @return ids The identifiers of the contracts to update
+ /// @return to The addresses of the contracts that will be updated to
+ function getProposedContractSet() external view returns (bytes32[] memory, address[] memory);
+
+ /// @notice Proposes one or more updates to the contract routes
+ /// @dev Only callable by owner
+ function proposeContractsUpdate(bytes32[] memory proposalSetIds, address[] memory proposalSetAddresses) external;
+
+ /// @notice Updates the current contract routes to the proposed contracts
+ /// @dev Only callable by owner
+ function updateContracts() external;
+
+ /// @dev Puts the system into an emergency stopped state.
+ /// @dev Only callable by owner
+ function pause() external;
+
+ /// @dev Takes the system out of an emergency stopped state.
+ /// @dev Only callable by owner
+ function unpause() external;
+}
diff --git a/contracts/src/v0.8/functions/dev/v1_0_0/interfaces/IFunctionsSubscriptions.sol b/contracts/src/v0.8/functions/dev/v1_0_0/interfaces/IFunctionsSubscriptions.sol
new file mode 100644
index 00000000000..eafd6f4fe99
--- /dev/null
+++ b/contracts/src/v0.8/functions/dev/v1_0_0/interfaces/IFunctionsSubscriptions.sol
@@ -0,0 +1,140 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.19;
+
+import {FunctionsResponse} from "../libraries/FunctionsResponse.sol";
+
+/// @title Chainlink Functions Subscription interface.
+interface IFunctionsSubscriptions {
+ struct Subscription {
+ uint96 balance; // ═════════╗ Common LINK balance that is controlled by the Router to be used for all consumer requests.
+ address owner; // ══════════╝ The owner can fund/withdraw/cancel the subscription.
+ uint96 blockedBalance; // ══╗ LINK balance that is reserved to pay for pending consumer requests.
+ address proposedOwner; // ══╝ For safely transferring sub ownership.
+ address[] consumers; // ════╸ Client contracts that can use the subscription
+ bytes32 flags; // ══════════╸ Per-subscription flags
+ }
+
+ struct Consumer {
+ bool allowed; // ══════════════╗ Owner can fund/withdraw/cancel the sub.
+ uint64 initiatedRequests; // ║ The number of requests that have been started
+ uint64 completedRequests; // ══╝ The number of requests that have successfully completed or timed out
+ }
+
+ /// @notice Get details about a subscription.
+ /// @param subscriptionId - the ID of the subscription
+ /// @return subscription - see IFunctionsSubscriptions.Subscription for more information on the structure
+ function getSubscription(uint64 subscriptionId) external view returns (Subscription memory);
+
+ /// @notice Retrieve details about multiple subscriptions using an inclusive range
+ /// @param subscriptionIdStart - the ID of the subscription to start the range at
+ /// @param subscriptionIdEnd - the ID of the subscription to end the range at
+ /// @return subscriptions - see IFunctionsSubscriptions.Subscription for more information on the structure
+ function getSubscriptionsInRange(
+ uint64 subscriptionIdStart,
+ uint64 subscriptionIdEnd
+ ) external view returns (Subscription[] memory);
+
+ /// @notice Get details about a consumer of a subscription.
+ /// @param client - the consumer contract address
+ /// @param subscriptionId - the ID of the subscription
+ /// @return consumer - see IFunctionsSubscriptions.Consumer for more information on the structure
+ function getConsumer(address client, uint64 subscriptionId) external view returns (Consumer memory);
+
+ /// @notice Get details about the total amount of LINK within the system
+ /// @return totalBalance - total Juels of LINK held by the contract
+ function getTotalBalance() external view returns (uint96);
+
+ /// @notice Get details about the total number of subscription accounts
+ /// @return count - total number of subscriptions in the system
+ function getSubscriptionCount() external view returns (uint64);
+
+ /// @notice Time out all expired requests: unlocks funds and removes the ability for the request to be fulfilled
+ /// @param requestsToTimeoutByCommitment - A list of request commitments to time out
+ /// @dev The commitment can be found on the "OracleRequest" event created when sending the request.
+ function timeoutRequests(FunctionsResponse.Commitment[] calldata requestsToTimeoutByCommitment) external;
+
+ /// @notice Oracle withdraw LINK earned through fulfilling requests
+ /// @notice If amount is 0 the full balance will be withdrawn
+ /// @notice Both signing and transmitting wallets will have a balance to withdraw
+ /// @param recipient where to send the funds
+ /// @param amount amount to withdraw
+ function oracleWithdraw(address recipient, uint96 amount) external;
+
+ /// @notice Owner cancel subscription, sends remaining link directly to the subscription owner.
+ /// @dev Only callable by the Router Owner
+ /// @param subscriptionId subscription id
+ /// @dev notably can be called even if there are pending requests, outstanding ones may fail onchain
+ function ownerCancelSubscription(uint64 subscriptionId) external;
+
+ /// @notice Recover link sent with transfer instead of transferAndCall.
+ /// @dev Only callable by the Router Owner
+ /// @param to address to send link to
+ function recoverFunds(address to) external;
+
+ /// @notice Create a new subscription.
+ /// @return subscriptionId - A unique subscription id.
+ /// @dev You can manage the consumer set dynamically with addConsumer/removeConsumer.
+ /// @dev Note to fund the subscription, use transferAndCall. For example
+ /// @dev LINKTOKEN.transferAndCall(
+ /// @dev address(ROUTER),
+ /// @dev amount,
+ /// @dev abi.encode(subscriptionId));
+ function createSubscription() external returns (uint64);
+
+ /// @notice Create a new subscription and add a consumer.
+ /// @return subscriptionId - A unique subscription id.
+ /// @dev You can manage the consumer set dynamically with addConsumer/removeConsumer.
+ /// @dev Note to fund the subscription, use transferAndCall. For example
+ /// @dev LINKTOKEN.transferAndCall(
+ /// @dev address(ROUTER),
+ /// @dev amount,
+ /// @dev abi.encode(subscriptionId));
+ function createSubscriptionWithConsumer(address consumer) external returns (uint64 subscriptionId);
+
+ /// @notice Propose a new owner for a subscription.
+ /// @dev Only callable by the Subscription's owner
+ /// @param subscriptionId - ID of the subscription
+ /// @param newOwner - proposed new owner of the subscription
+ function proposeSubscriptionOwnerTransfer(uint64 subscriptionId, address newOwner) external;
+
+ /// @notice Accept an ownership transfer.
+ /// @param subscriptionId - ID of the subscription
+ /// @dev will revert if original owner of subscriptionId has not requested that msg.sender become the new owner.
+ function acceptSubscriptionOwnerTransfer(uint64 subscriptionId) external;
+
+ /// @notice Remove a consumer from a Chainlink Functions subscription.
+ /// @dev Only callable by the Subscription's owner
+ /// @param subscriptionId - ID of the subscription
+ /// @param consumer - Consumer to remove from the subscription
+ function removeConsumer(uint64 subscriptionId, address consumer) external;
+
+ /// @notice Add a consumer to a Chainlink Functions subscription.
+ /// @dev Only callable by the Subscription's owner
+ /// @param subscriptionId - ID of the subscription
+ /// @param consumer - New consumer which can use the subscription
+ function addConsumer(uint64 subscriptionId, address consumer) external;
+
+ /// @notice Cancel a subscription
+ /// @dev Only callable by the Subscription's owner
+ /// @param subscriptionId - ID of the subscription
+ /// @param to - Where to send the remaining LINK to
+ function cancelSubscription(uint64 subscriptionId, address to) external;
+
+ /// @notice Check to see if there exists a request commitment for all consumers for a given sub.
+ /// @param subscriptionId - ID of the subscription
+ /// @return true if there exists at least one unfulfilled request for the subscription, false otherwise.
+ /// @dev Looping is bounded to MAX_CONSUMERS*(number of DONs).
+ /// @dev Used to disable subscription canceling while outstanding request are present.
+ function pendingRequestExists(uint64 subscriptionId) external view returns (bool);
+
+ /// @notice Set subscription specific flags for a subscription.
+ /// Each byte of the flag is used to represent a resource tier that the subscription can utilize.
+ /// @param subscriptionId - ID of the subscription
+ /// @param flags - desired flag values
+ function setFlags(uint64 subscriptionId, bytes32 flags) external;
+
+ /// @notice Get flags for a given subscription.
+ /// @param subscriptionId - ID of the subscription
+ /// @return flags - current flag values
+ function getFlags(uint64 subscriptionId) external view returns (bytes32);
+}
diff --git a/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IOwnableFunctionsRouter.sol b/contracts/src/v0.8/functions/dev/v1_0_0/interfaces/IOwnableFunctionsRouter.sol
similarity index 79%
rename from contracts/src/v0.8/functions/dev/1_0_0/interfaces/IOwnableFunctionsRouter.sol
rename to contracts/src/v0.8/functions/dev/v1_0_0/interfaces/IOwnableFunctionsRouter.sol
index 5a2f85fd32e..39b84a930aa 100644
--- a/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IOwnableFunctionsRouter.sol
+++ b/contracts/src/v0.8/functions/dev/v1_0_0/interfaces/IOwnableFunctionsRouter.sol
@@ -4,7 +4,7 @@ pragma solidity ^0.8.19;
import {IFunctionsRouter} from "./IFunctionsRouter.sol";
import {IOwnable} from "../../../../shared/interfaces/IOwnable.sol";
-// @title Chainlink Functions Router interface with Ownability.
+/// @title Chainlink Functions Router interface with Ownability.
interface IOwnableFunctionsRouter is IOwnable, IFunctionsRouter {
}
diff --git a/contracts/src/v0.8/functions/dev/1_0_0/libraries/FunctionsRequest.sol b/contracts/src/v0.8/functions/dev/v1_0_0/libraries/FunctionsRequest.sol
similarity index 72%
rename from contracts/src/v0.8/functions/dev/1_0_0/libraries/FunctionsRequest.sol
rename to contracts/src/v0.8/functions/dev/v1_0_0/libraries/FunctionsRequest.sol
index 0a669588ed0..efc3a811e6a 100644
--- a/contracts/src/v0.8/functions/dev/1_0_0/libraries/FunctionsRequest.sol
+++ b/contracts/src/v0.8/functions/dev/v1_0_0/libraries/FunctionsRequest.sol
@@ -3,7 +3,7 @@ pragma solidity ^0.8.19;
import {CBOR} from "../../../../vendor/solidity-cborutils/v2.0.0/CBOR.sol";
-// @title Library for encoding the input data of a Functions request into CBOR
+/// @title Library for encoding the input data of a Functions request into CBOR
library FunctionsRequest {
using CBOR for CBOR.CBORBuffer;
@@ -27,7 +27,6 @@ library FunctionsRequest {
CodeLanguage language; // ════════════╸ The coding language that the source code is written in
string source; // ════════════════════╸ Raw source code for Request.codeLocation of Location.Inline, URL for Request.codeLocation of Location.Remote, or slot decimal number for Request.codeLocation of Location.DONHosted
bytes encryptedSecretsReference; // ══╸ Encrypted URLs for Request.secretsLocation of Location.Remote (use addSecretsReference()), or CBOR encoded slotid+version for Request.secretsLocation of Location.DONHosted (use addDONHostedSecrets())
- bytes requestSignature; // ═══════════╸ Signature generated by the subscription owner's EOA
string[] args; // ════════════════════╸ String arguments that will be passed into the source code
bytes[] bytesArgs; // ════════════════╸ Bytes arguments that will be passed into the source code
}
@@ -37,9 +36,9 @@ library FunctionsRequest {
error EmptyArgs();
error NoInlineSecrets();
- // @notice Encodes a Request to CBOR encoded bytes
- // @param self The request to encode
- // @return CBOR encoded bytes
+ /// @notice Encodes a Request to CBOR encoded bytes
+ /// @param self The request to encode
+ /// @return CBOR encoded bytes
function encodeCBOR(Request memory self) internal pure returns (bytes memory) {
CBOR.CBORBuffer memory buffer = CBOR.create(DEFAULT_BUFFER_SIZE);
@@ -52,11 +51,6 @@ library FunctionsRequest {
buffer.writeString("source");
buffer.writeString(self.source);
- if (self.requestSignature.length > 0) {
- buffer.writeString("requestSignature");
- buffer.writeBytes(self.requestSignature);
- }
-
if (self.args.length > 0) {
buffer.writeString("args");
buffer.startArray();
@@ -88,12 +82,12 @@ library FunctionsRequest {
return buffer.buf.buf;
}
- // @notice Initializes a Chainlink Functions Request
- // @dev Sets the codeLocation and code on the request
- // @param self The uninitialized request
- // @param codeLocation The user provided source code location
- // @param language The programming language of the user code
- // @param source The user provided source code or a url
+ /// @notice Initializes a Chainlink Functions Request
+ /// @dev Sets the codeLocation and code on the request
+ /// @param self The uninitialized request
+ /// @param codeLocation The user provided source code location
+ /// @param language The programming language of the user code
+ /// @param source The user provided source code or a url
function initializeRequest(
Request memory self,
Location codeLocation,
@@ -107,17 +101,17 @@ library FunctionsRequest {
self.source = source;
}
- // @notice Initializes a Chainlink Functions Request
- // @dev Simplified version of initializeRequest for PoC
- // @param self The uninitialized request
- // @param javaScriptSource The user provided JS code (must not be empty)
+ /// @notice Initializes a Chainlink Functions Request
+ /// @dev Simplified version of initializeRequest for PoC
+ /// @param self The uninitialized request
+ /// @param javaScriptSource The user provided JS code (must not be empty)
function initializeRequestForInlineJavaScript(Request memory self, string memory javaScriptSource) internal pure {
initializeRequest(self, Location.Inline, CodeLanguage.JavaScript, javaScriptSource);
}
- // @notice Adds Remote user encrypted secrets to a Request
- // @param self The initialized request
- // @param encryptedSecretsReference Encrypted comma-separated string of URLs pointing to off-chain secrets
+ /// @notice Adds Remote user encrypted secrets to a Request
+ /// @param self The initialized request
+ /// @param encryptedSecretsReference Encrypted comma-separated string of URLs pointing to off-chain secrets
function addSecretsReference(Request memory self, bytes memory encryptedSecretsReference) internal pure {
if (encryptedSecretsReference.length == 0) revert EmptySecrets();
@@ -125,10 +119,10 @@ library FunctionsRequest {
self.encryptedSecretsReference = encryptedSecretsReference;
}
- // @notice Adds DON-hosted secrets reference to a Request
- // @param self The initialized request
- // @param slotID Slot ID of the user's secrets hosted on DON
- // @param version User data version (for the slotID)
+ /// @notice Adds DON-hosted secrets reference to a Request
+ /// @param self The initialized request
+ /// @param slotID Slot ID of the user's secrets hosted on DON
+ /// @param version User data version (for the slotID)
function addDONHostedSecrets(Request memory self, uint8 slotID, uint64 version) internal pure {
CBOR.CBORBuffer memory buffer = CBOR.create(DEFAULT_BUFFER_SIZE);
@@ -141,18 +135,18 @@ library FunctionsRequest {
self.encryptedSecretsReference = buffer.buf.buf;
}
- // @notice Sets args for the user run function
- // @param self The initialized request
- // @param args The array of string args (must not be empty)
+ /// @notice Sets args for the user run function
+ /// @param self The initialized request
+ /// @param args The array of string args (must not be empty)
function setArgs(Request memory self, string[] memory args) internal pure {
if (args.length == 0) revert EmptyArgs();
self.args = args;
}
- // @notice Sets bytes args for the user run function
- // @param self The initialized request
- // @param args The array of bytes args (must not be empty)
+ /// @notice Sets bytes args for the user run function
+ /// @param self The initialized request
+ /// @param args The array of bytes args (must not be empty)
function setBytesArgs(Request memory self, bytes[] memory args) internal pure {
if (args.length == 0) revert EmptyArgs();
diff --git a/contracts/src/v0.8/functions/dev/1_0_0/libraries/FunctionsResponse.sol b/contracts/src/v0.8/functions/dev/v1_0_0/libraries/FunctionsResponse.sol
similarity index 97%
rename from contracts/src/v0.8/functions/dev/1_0_0/libraries/FunctionsResponse.sol
rename to contracts/src/v0.8/functions/dev/v1_0_0/libraries/FunctionsResponse.sol
index 71e731b2e33..31a33169226 100644
--- a/contracts/src/v0.8/functions/dev/1_0_0/libraries/FunctionsResponse.sol
+++ b/contracts/src/v0.8/functions/dev/v1_0_0/libraries/FunctionsResponse.sol
@@ -3,7 +3,7 @@ pragma solidity ^0.8.19;
import {IFunctionsSubscriptions} from "../interfaces/IFunctionsSubscriptions.sol";
-// @title Library of types that are used for fulfillment of a Functions request
+/// @title Library of types that are used for fulfillment of a Functions request
library FunctionsResponse {
// Used to send request information from the Router to the Coordinator
struct RequestMeta {
diff --git a/contracts/src/v0.8/functions/dev/v1_0_0/mocks/FunctionsV1EventsMock.sol b/contracts/src/v0.8/functions/dev/v1_0_0/mocks/FunctionsV1EventsMock.sol
new file mode 100644
index 00000000000..68b51f89019
--- /dev/null
+++ b/contracts/src/v0.8/functions/dev/v1_0_0/mocks/FunctionsV1EventsMock.sol
@@ -0,0 +1,181 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.19;
+
+contract FunctionsV1EventsMock {
+ struct Config {
+ uint16 maxConsumersPerSubscription;
+ uint72 adminFee;
+ bytes4 handleOracleFulfillmentSelector;
+ uint16 gasForCallExactCheck;
+ uint32[] maxCallbackGasLimits;
+ }
+ event ConfigUpdated(Config param1);
+ event ContractProposed(
+ bytes32 proposedContractSetId,
+ address proposedContractSetFromAddress,
+ address proposedContractSetToAddress
+ );
+ event ContractUpdated(bytes32 id, address from, address to);
+ event FundsRecovered(address to, uint256 amount);
+ event OwnershipTransferRequested(address indexed from, address indexed to);
+ event OwnershipTransferred(address indexed from, address indexed to);
+ event Paused(address account);
+ event RequestNotProcessed(bytes32 indexed requestId, address coordinator, address transmitter, uint8 resultCode);
+ event RequestProcessed(
+ bytes32 indexed requestId,
+ uint64 indexed subscriptionId,
+ uint96 totalCostJuels,
+ address transmitter,
+ uint8 resultCode,
+ bytes response,
+ bytes err,
+ bytes callbackReturnData
+ );
+ event RequestStart(
+ bytes32 indexed requestId,
+ bytes32 indexed donId,
+ uint64 indexed subscriptionId,
+ address subscriptionOwner,
+ address requestingContract,
+ address requestInitiator,
+ bytes data,
+ uint16 dataVersion,
+ uint32 callbackGasLimit,
+ uint96 estimatedTotalCostJuels
+ );
+ event RequestTimedOut(bytes32 indexed requestId);
+ event SubscriptionCanceled(uint64 indexed subscriptionId, address fundsRecipient, uint256 fundsAmount);
+ event SubscriptionConsumerAdded(uint64 indexed subscriptionId, address consumer);
+ event SubscriptionConsumerRemoved(uint64 indexed subscriptionId, address consumer);
+ event SubscriptionCreated(uint64 indexed subscriptionId, address owner);
+ event SubscriptionFunded(uint64 indexed subscriptionId, uint256 oldBalance, uint256 newBalance);
+ event SubscriptionOwnerTransferRequested(uint64 indexed subscriptionId, address from, address to);
+ event SubscriptionOwnerTransferred(uint64 indexed subscriptionId, address from, address to);
+ event Unpaused(address account);
+
+ function emitConfigUpdated(Config memory param1) public {
+ emit ConfigUpdated(param1);
+ }
+
+ function emitContractProposed(
+ bytes32 proposedContractSetId,
+ address proposedContractSetFromAddress,
+ address proposedContractSetToAddress
+ ) public {
+ emit ContractProposed(proposedContractSetId, proposedContractSetFromAddress, proposedContractSetToAddress);
+ }
+
+ function emitContractUpdated(bytes32 id, address from, address to) public {
+ emit ContractUpdated(id, from, to);
+ }
+
+ function emitFundsRecovered(address to, uint256 amount) public {
+ emit FundsRecovered(to, amount);
+ }
+
+ function emitOwnershipTransferRequested(address from, address to) public {
+ emit OwnershipTransferRequested(from, to);
+ }
+
+ function emitOwnershipTransferred(address from, address to) public {
+ emit OwnershipTransferred(from, to);
+ }
+
+ function emitPaused(address account) public {
+ emit Paused(account);
+ }
+
+ function emitRequestNotProcessed(
+ bytes32 requestId,
+ address coordinator,
+ address transmitter,
+ uint8 resultCode
+ ) public {
+ emit RequestNotProcessed(requestId, coordinator, transmitter, resultCode);
+ }
+
+ function emitRequestProcessed(
+ bytes32 requestId,
+ uint64 subscriptionId,
+ uint96 totalCostJuels,
+ address transmitter,
+ uint8 resultCode,
+ bytes memory response,
+ bytes memory err,
+ bytes memory callbackReturnData
+ ) public {
+ emit RequestProcessed(
+ requestId,
+ subscriptionId,
+ totalCostJuels,
+ transmitter,
+ resultCode,
+ response,
+ err,
+ callbackReturnData
+ );
+ }
+
+ function emitRequestStart(
+ bytes32 requestId,
+ bytes32 donId,
+ uint64 subscriptionId,
+ address subscriptionOwner,
+ address requestingContract,
+ address requestInitiator,
+ bytes memory data,
+ uint16 dataVersion,
+ uint32 callbackGasLimit,
+ uint96 estimatedTotalCostJuels
+ ) public {
+ emit RequestStart(
+ requestId,
+ donId,
+ subscriptionId,
+ subscriptionOwner,
+ requestingContract,
+ requestInitiator,
+ data,
+ dataVersion,
+ callbackGasLimit,
+ estimatedTotalCostJuels
+ );
+ }
+
+ function emitRequestTimedOut(bytes32 requestId) public {
+ emit RequestTimedOut(requestId);
+ }
+
+ function emitSubscriptionCanceled(uint64 subscriptionId, address fundsRecipient, uint256 fundsAmount) public {
+ emit SubscriptionCanceled(subscriptionId, fundsRecipient, fundsAmount);
+ }
+
+ function emitSubscriptionConsumerAdded(uint64 subscriptionId, address consumer) public {
+ emit SubscriptionConsumerAdded(subscriptionId, consumer);
+ }
+
+ function emitSubscriptionConsumerRemoved(uint64 subscriptionId, address consumer) public {
+ emit SubscriptionConsumerRemoved(subscriptionId, consumer);
+ }
+
+ function emitSubscriptionCreated(uint64 subscriptionId, address owner) public {
+ emit SubscriptionCreated(subscriptionId, owner);
+ }
+
+ function emitSubscriptionFunded(uint64 subscriptionId, uint256 oldBalance, uint256 newBalance) public {
+ emit SubscriptionFunded(subscriptionId, oldBalance, newBalance);
+ }
+
+ function emitSubscriptionOwnerTransferRequested(uint64 subscriptionId, address from, address to) public {
+ emit SubscriptionOwnerTransferRequested(subscriptionId, from, to);
+ }
+
+ function emitSubscriptionOwnerTransferred(uint64 subscriptionId, address from, address to) public {
+ emit SubscriptionOwnerTransferred(subscriptionId, from, to);
+ }
+
+ function emitUnpaused(address account) public {
+ emit Unpaused(account);
+ }
+}
diff --git a/contracts/src/v0.8/functions/dev/1_0_0/ocr/OCR2Abstract.sol b/contracts/src/v0.8/functions/dev/v1_0_0/ocr/OCR2Abstract.sol
similarity index 100%
rename from contracts/src/v0.8/functions/dev/1_0_0/ocr/OCR2Abstract.sol
rename to contracts/src/v0.8/functions/dev/v1_0_0/ocr/OCR2Abstract.sol
diff --git a/contracts/src/v0.8/functions/dev/1_0_0/ocr/OCR2Base.sol b/contracts/src/v0.8/functions/dev/v1_0_0/ocr/OCR2Base.sol
similarity index 100%
rename from contracts/src/v0.8/functions/dev/1_0_0/ocr/OCR2Base.sol
rename to contracts/src/v0.8/functions/dev/v1_0_0/ocr/OCR2Base.sol
diff --git a/contracts/src/v0.8/functions/tests/1_0_0/FunctionsCoordinator.t.sol b/contracts/src/v0.8/functions/tests/1_0_0/FunctionsCoordinator.t.sol
deleted file mode 100644
index c6d560fffc6..00000000000
--- a/contracts/src/v0.8/functions/tests/1_0_0/FunctionsCoordinator.t.sol
+++ /dev/null
@@ -1,219 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.19;
-
-// ================================================================
-// | Functions Coordinator |
-// ================================================================
-
-/// @notice #constructor
-contract FunctionsCoordinator_Constructor {
-
-}
-
-/// @notice #getThresholdPublicKey
-contract FunctionsCoordinator_GetThresholdPublicKey {
-
-}
-
-/// @notice #setThresholdPublicKey
-contract FunctionsCoordinator_SetThresholdPublicKey {
-
-}
-
-/// @notice #getDONPublicKey
-contract FunctionsCoordinator_GetDONPublicKey {
-
-}
-
-/// @notice #setDONPublicKey
-contract FunctionsCoordinator__SetDONPublicKey {
-
-}
-
-/// @notice #_isTransmitter
-contract FunctionsCoordinator_IsTransmitter {
-
-}
-
-/// @notice #setNodePublicKey
-contract FunctionsCoordinator_SetNodePublicKey {
-
-}
-
-/// @notice #deleteNodePublicKey
-contract FunctionsCoordinator_DeleteNodePublicKey {
-
-}
-
-/// @notice #getAllNodePublicKeys
-contract FunctionsCoordinator_GetAllNodePublicKeys {
-
-}
-
-/// @notice #startRequest
-contract FunctionsCoordinator_StartRequest {
-
-}
-
-/// @notice #_beforeSetConfig
-contract FunctionsCoordinator__BeforeSetConfig {
-
-}
-
-/// @notice #_getTransmitters
-contract FunctionsCoordinator__GetTransmitters {
-
-}
-
-/// @notice #_report
-contract FunctionsCoordinator__Report {
-
-}
-
-/// @notice #_onlyOwner
-contract FunctionsCoordinator__OnlyOwner {
-
-}
-
-// ================================================================
-// | Functions Billing |
-// ================================================================
-
-/// @notice #constructor
-contract FunctionsBilling_Constructor {
-
-}
-
-/// @notice #getConfig
-contract FunctionsBilling_GetConfig {
-
-}
-
-/// @notice #updateConfig
-contract FunctionsBilling_UpdateConfig {
-
-}
-
-/// @notice #getDONFee
-contract FunctionsBilling_GetDONFee {
-
-}
-
-/// @notice #getAdminFee
-contract FunctionsBilling_GetAdminFee {
-
-}
-
-/// @notice #getWeiPerUnitLink
-contract FunctionsBilling_GetWeiPerUnitLink {
-
-}
-
-/// @notice #_getJuelsPerGas
-contract FunctionsBilling__GetJuelsPerGas {
-
-}
-
-/// @notice #estimateCost
-contract FunctionsBilling_EstimateCost {
-
-}
-
-/// @notice #_calculateCostEstimate
-contract FunctionsBilling__CalculateCostEstimate {
-
-}
-
-/// @notice #_startBilling
-contract FunctionsBilling__StartBilling {
-
-}
-
-/// @notice #_computeRequestId
-contract FunctionsBilling__ComputeRequestId {
-
-}
-
-/// @notice #_fulfillAndBill
-contract FunctionsBilling__FulfillAndBill {
-
-}
-
-/// @notice #deleteCommitment
-contract FunctionsBilling_DeleteCommitment {
-
-}
-
-/// @notice #oracleWithdraw
-contract FunctionsBilling_OracleWithdraw {
-
-}
-
-/// @notice #oracleWithdrawAll
-contract FunctionsBilling_OracleWithdrawAll {
-
-}
-
-/// @notice #_getTransmitters
-contract FunctionsBilling__GetTransmitters {
-
-}
-
-/// @notice #_disperseFeePool
-contract FunctionsBilling__DisperseFeePool {
-
-}
-
-// ================================================================
-// | OCR2Base |
-// ================================================================
-
-/// @notice #constructor
-contract OCR2Base_Constructor {
-
-}
-
-/// @notice #checkConfigValid
-contract OCR2Base_CheckConfigValid {
-
-}
-
-/// @notice #latestConfigDigestAndEpoch
-contract OCR2Base_LatestConfigDigestAndEpoch {
-
-}
-
-/// @notice #setConfig
-contract OCR2Base_SetConfig {
-
-}
-
-/// @notice #configDigestFromConfigData
-contract OCR2Base_ConfigDigestFromConfigData {
-
-}
-
-/// @notice #latestConfigDetails
-contract OCR2Base_LatestConfigDetails {
-
-}
-
-/// @notice #transmitters
-contract OCR2Base_Transmitters {
-
-}
-
-/// @notice #_report
-contract OCR2Base__Report {
-
-}
-
-/// @notice #requireExpectedMsgDataLength
-contract OCR2Base_RequireExpectedMsgDataLength {
-
-}
-
-/// @notice #transmit
-contract OCR2Base_Transmit {
-
-}
diff --git a/contracts/src/v0.8/functions/tests/1_0_0/FunctionsRouter.t.sol b/contracts/src/v0.8/functions/tests/1_0_0/FunctionsRouter.t.sol
deleted file mode 100644
index 649c06f9eed..00000000000
--- a/contracts/src/v0.8/functions/tests/1_0_0/FunctionsRouter.t.sol
+++ /dev/null
@@ -1,180 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.19;
-
-import {FunctionsRouter} from "../../dev/1_0_0/FunctionsRouter.sol";
-import {FunctionsSubscriptions} from "../../dev/1_0_0/FunctionsSubscriptions.sol";
-
-import {FunctionsRouterSetup, FunctionsOwnerAcceptTermsOfService} from "./Setup.t.sol";
-
-// ================================================================
-// | Functions Router |
-// ================================================================
-
-/// @notice #constructor
-contract FunctionsRouter_Constructor {
-
-}
-
-/// @notice #getConfig
-contract FunctionsRouter_GetConfig {
-
-}
-
-/// @notice #updateConfig
-contract FunctionsRouter_UpdateConfig {
-
-}
-
-/// @notice #isValidCallbackGasLimit
-contract FunctionsRouter_IsValidCallbackGasLimit {
-
-}
-
-/// @notice #getAdminFee
-contract FunctionsRouter_GetAdminFee {
-
-}
-
-/// @notice #getAllowListId
-contract FunctionsRouter_GetAllowListId {
-
-}
-
-/// @notice #setAllowListId
-contract FunctionsRouter_SetAllowListId {
-
-}
-
-/// @notice #_getMaxConsumers
-contract FunctionsRouter__GetMaxConsumers {
-
-}
-
-/// @notice #sendRequest
-contract FunctionsRouter_SendRequest {
-
-}
-
-/// @notice #sendRequestToProposed
-contract FunctionsRouter_SendRequestToProposed {
-
-}
-
-/// @notice #_sendRequest
-contract FunctionsRouter__SendRequest {
-
-}
-
-/// @notice #fulfill
-contract FunctionsRouter_Fulfill {
-
-}
-
-/// @notice #_callback
-contract FunctionsRouter__Callback {
-
-}
-
-/// @notice #getContractById
-contract FunctionsRouter_GetContractById {
-
-}
-
-/// @notice #getProposedContractById
-contract FunctionsRouter_GetProposedContractById {
-
-}
-
-/// @notice #getProposedContractSet
-contract FunctionsRouter_GetProposedContractSet {
-
-}
-
-/// @notice #proposeContractsUpdate
-contract FunctionsRouter_ProposeContractsUpdate {
-
-}
-
-/// @notice #updateContracts
-contract FunctionsRouter_UpdateContracts {
-
-}
-
-/// @notice #_whenNotPaused
-contract FunctionsRouter__WhenNotPaused {
-
-}
-
-/// @notice #_onlyRouterOwner
-contract FunctionsRouter__OnlyRouterOwner {
-
-}
-
-/// @notice #_onlySenderThatAcceptedToS
-contract FunctionsRouter__OnlySenderThatAcceptedToS {
-
-}
-
-/// @notice #pause
-contract FunctionsRouter_Pause is FunctionsRouterSetup {
- function setUp() public virtual override {
- FunctionsRouterSetup.setUp();
- }
-
- event Paused(address account);
-
- function test_Pause_RevertIfNotOwner() public {
- // Send as stranger
- vm.stopPrank();
- vm.startPrank(STRANGER_ADDRESS);
-
- vm.expectRevert("Only callable by owner");
- s_functionsRouter.pause();
- }
-
- function test_Pause_Success() public {
- // topic0 (always checked), NOT topic1 (false), NOT topic2 (false), NOT topic3 (false), and data (true).
- vm.expectEmit(false, false, false, true);
- emit Paused(OWNER_ADDRESS);
-
- s_functionsRouter.pause();
-
- bool isPaused = s_functionsRouter.paused();
- assertEq(isPaused, true);
-
- vm.expectRevert("Pausable: paused");
- s_functionsRouter.createSubscription();
- }
-}
-
-/// @notice #unpause
-contract FunctionsRouter_Unpause is FunctionsRouterSetup {
- function setUp() public virtual override {
- FunctionsRouterSetup.setUp();
- s_functionsRouter.pause();
- }
-
- event Unpaused(address account);
-
- function test_Unpause_RevertIfNotOwner() public {
- // Send as stranger
- vm.stopPrank();
- vm.startPrank(STRANGER_ADDRESS);
-
- vm.expectRevert("Only callable by owner");
- s_functionsRouter.unpause();
- }
-
- function test_Unpause_Success() public {
- // topic0 (always checked), NOT topic1 (false), NOT topic2 (false), NOT topic3 (false), and data (true).
- vm.expectEmit(false, false, false, true);
- emit Unpaused(OWNER_ADDRESS);
-
- s_functionsRouter.unpause();
-
- bool isPaused = s_functionsRouter.paused();
- assertEq(isPaused, false);
-
- s_functionsRouter.createSubscription();
- }
-}
diff --git a/contracts/src/v0.8/functions/tests/1_0_0/FunctionsSubscriptions.t.sol b/contracts/src/v0.8/functions/tests/1_0_0/FunctionsSubscriptions.t.sol
deleted file mode 100644
index ab77a33691d..00000000000
--- a/contracts/src/v0.8/functions/tests/1_0_0/FunctionsSubscriptions.t.sol
+++ /dev/null
@@ -1,188 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.19;
-
-import {FunctionsRouter} from "../../dev/1_0_0/FunctionsRouter.sol";
-import {FunctionsSubscriptions} from "../../dev/1_0_0/FunctionsSubscriptions.sol";
-
-import {FunctionsRouterSetup, FunctionsOwnerAcceptTermsOfService} from "./Setup.t.sol";
-
-// ================================================================
-// | Functions Subscriptions |
-// ================================================================
-
-/// @notice #constructor
-contract FunctionsSubscriptions_Constructor {
-
-}
-
-/// @notice #_markRequestInFlight
-contract FunctionsSubscriptions__MarkRequestInFlight {
-
-}
-
-/// @notice #_pay
-contract FunctionsSubscriptions__Pay {
-
-}
-
-/// @notice #ownerCancelSubscription
-contract FunctionsSubscriptions_OwnerCancelSubscription {
-
-}
-
-/// @notice #recoverFunds
-contract FunctionsSubscriptions_RecoverFunds {
-
-}
-
-/// @notice #oracleWithdraw
-contract FunctionsSubscriptions_OracleWithdraw {
-
-}
-
-/// @notice #ownerWithdraw
-contract FunctionsSubscriptions_OwnerWithdraw {
-
-}
-
-/// @notice #onTokenTransfer
-contract FunctionsSubscriptions_OnTokenTransfer {
-
-}
-
-/// @notice #getTotalBalance
-contract FunctionsSubscriptions_GetTotalBalance {
-
-}
-
-/// @notice #getSubscriptionCount
-contract FunctionsSubscriptions_GetSubscriptionCount {
-
-}
-
-/// @notice #getSubscription
-contract FunctionsSubscriptions_GetSubscription {
-
-}
-
-/// @notice #getConsumer
-contract FunctionsSubscriptions_GetConsumer {
-
-}
-
-/// @notice #_isExistingSubscription
-contract FunctionsSubscriptions__IsExistingSubscription {
-
-}
-
-/// @notice #_isAllowedConsumer
-contract FunctionsSubscriptions__IsAllowedConsumer {
-
-}
-
-/// @notice #createSubscription
-contract FunctionsSubscriptions_createSubscription is FunctionsOwnerAcceptTermsOfService {
- function setUp() public virtual override {
- FunctionsOwnerAcceptTermsOfService.setUp();
- }
-
- event SubscriptionCreated(uint64 indexed subscriptionId, address owner);
-
- function test_CreateSubscription_Success() public {
- vm.expectEmit(true, false, false, true);
- emit SubscriptionCreated(1, OWNER_ADDRESS);
- uint64 firstCallSubscriptionId = s_functionsRouter.createSubscription();
- assertEq(firstCallSubscriptionId, 1);
-
- vm.expectEmit(true, false, false, true);
- emit SubscriptionCreated(2, OWNER_ADDRESS);
- uint64 secondCallSubscriptionId = s_functionsRouter.createSubscription();
- assertEq(secondCallSubscriptionId, 2);
-
- vm.expectEmit(true, false, false, true);
- emit SubscriptionCreated(3, OWNER_ADDRESS);
- uint64 thirdCallSubscriptionId = s_functionsRouter.createSubscription();
- assertEq(thirdCallSubscriptionId, 3);
- }
-
- function test_CreateSubscription_RevertIfPaused() public {
- s_functionsRouter.pause();
-
- vm.expectRevert("Pausable: paused");
- s_functionsRouter.createSubscription();
- }
-
- function test_CreateSubscription_RevertIfNotAllowedSender() public {
- // Send as stranger, who has not accepted Terms of Service
- vm.stopPrank();
- vm.startPrank(STRANGER_ADDRESS);
-
- vm.expectRevert(abi.encodeWithSelector(FunctionsRouter.SenderMustAcceptTermsOfService.selector, STRANGER_ADDRESS));
- s_functionsRouter.createSubscription();
- }
-}
-
-/// @notice #createSubscriptionWithConsumer
-contract FunctionsSubscriptions_CreateSubscriptionWithConsumer {
-
-}
-
-/// @notice #proposeSubscriptionOwnerTransfer
-contract FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer {
-
-}
-
-/// @notice #acceptSubscriptionOwnerTransfer
-contract FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer {
-
-}
-
-/// @notice #removeConsumer
-contract FunctionsSubscriptions_RemoveConsumer {
-
-}
-
-/// @notice #_getMaxConsumers
-contract FunctionsSubscriptions__GetMaxConsumers {
-
-}
-
-/// @notice #addConsumer
-contract FunctionsSubscriptions_AddConsumer {
-
-}
-
-/// @notice #cancelSubscription
-contract FunctionsSubscriptions_CancelSubscription {
-
-}
-
-/// @notice #_cancelSubscriptionHelper
-contract FunctionsSubscriptions__CancelSubscriptionHelper {
-
-}
-
-/// @notice #pendingRequestExists
-contract FunctionsSubscriptions_PendingRequestExists {
-
-}
-
-/// @notice #setFlags
-contract FunctionsSubscriptions_SetFlags {
-
-}
-
-/// @notice #getFlags
-contract FunctionsSubscriptions_GetFlags {
-
-}
-
-/// @notice #timeoutRequests
-contract FunctionsSubscriptions_TimeoutRequests {
-
-}
-
-/// @notice #_onlySubscriptionOwner
-contract FunctionsSubscriptions__OnlySubscriptionOwner {
-
-}
diff --git a/contracts/src/v0.8/functions/tests/1_0_0/FunctionsTermsOfServiceAllowList.t.sol b/contracts/src/v0.8/functions/tests/1_0_0/FunctionsTermsOfServiceAllowList.t.sol
deleted file mode 100644
index af6fa6dcca5..00000000000
--- a/contracts/src/v0.8/functions/tests/1_0_0/FunctionsTermsOfServiceAllowList.t.sol
+++ /dev/null
@@ -1,52 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.19;
-
-/// @notice #constructor
-contract FunctionsTermsOfServiceAllowList_Constructor {
-
-}
-
-/// @notice #getConfig
-contract FunctionsTermsOfServiceAllowList_GetConfig {
-
-}
-
-/// @notice #updateConfig
-contract FunctionsTermsOfServiceAllowList_UpdateConfig {
-
-}
-
-/// @notice #getMessage
-contract FunctionsTermsOfServiceAllowList_GetMessage {
-
-}
-
-/// @notice #acceptTermsOfService
-contract FunctionsTermsOfServiceAllowList_AcceptTermsOfService {
-
-}
-
-/// @notice #getAllAllowedSenders
-contract FunctionsTermsOfServiceAllowList_GetAllAllowedSenders {
-
-}
-
-/// @notice #hasAccess
-contract FunctionsTermsOfServiceAllowList_HasAccess {
-
-}
-
-/// @notice #isBlockedSender
-contract FunctionsTermsOfServiceAllowList_IsBlockedSender {
-
-}
-
-/// @notice #blockSender
-contract FunctionsTermsOfServiceAllowList_BlockSender {
-
-}
-
-/// @notice #unblockSender
-contract FunctionsTermsOfServiceAllowList_UnblockSender {
-
-}
diff --git a/contracts/src/v0.8/functions/tests/1_0_0/Setup.t.sol b/contracts/src/v0.8/functions/tests/1_0_0/Setup.t.sol
deleted file mode 100644
index 56addcabd79..00000000000
--- a/contracts/src/v0.8/functions/tests/1_0_0/Setup.t.sol
+++ /dev/null
@@ -1,102 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.19;
-
-import {BaseTest} from "./BaseTest.t.sol";
-import {FunctionsRouter} from "../../dev/1_0_0/FunctionsRouter.sol";
-import {FunctionsCoordinator} from "../../dev/1_0_0/FunctionsCoordinator.sol";
-import {FunctionsBilling} from "../../dev/1_0_0/FunctionsBilling.sol";
-import {MockV3Aggregator} from "../../../tests/MockV3Aggregator.sol";
-import {TermsOfServiceAllowList} from "../../dev/1_0_0/accessControl/TermsOfServiceAllowList.sol";
-
-contract FunctionsRouterSetup is BaseTest {
- FunctionsRouter internal s_functionsRouter;
- FunctionsCoordinator internal s_functionsCoordinator;
- MockV3Aggregator internal s_linkEthFeed;
- TermsOfServiceAllowList internal s_termsOfServiceAllowList;
-
- uint16 internal s_maxConsumersPerSubscription = 100;
- uint72 internal s_adminFee = 100;
- bytes4 internal s_handleOracleFulfillmentSelector = 0x0ca76175;
-
- address internal s_linkToken = 0x01BE23585060835E02B77ef475b0Cc51aA1e0709;
-
- int256 internal LINK_ETH_RATE = 6000000000000000;
-
- uint256 internal TOS_SIGNER_PRIVATE_KEY = 0x3;
- address internal TOS_SIGNER = vm.addr(TOS_SIGNER_PRIVATE_KEY);
-
- function setUp() public virtual override {
- BaseTest.setUp();
- s_functionsRouter = new FunctionsRouter(s_linkToken, getRouterConfig());
- s_linkEthFeed = new MockV3Aggregator(0, LINK_ETH_RATE);
- s_functionsCoordinator = new FunctionsCoordinator(
- address(s_functionsRouter),
- getCoordinatorConfig(),
- address(s_linkEthFeed)
- );
- s_termsOfServiceAllowList = new TermsOfServiceAllowList(getTermsOfServiceConfig());
- }
-
- function getRouterConfig() public view returns (FunctionsRouter.Config memory) {
- uint32[] memory maxCallbackGasLimits = new uint32[](3);
- maxCallbackGasLimits[0] = 300_000;
- maxCallbackGasLimits[1] = 500_000;
- maxCallbackGasLimits[2] = 1_000_000;
-
- return
- FunctionsRouter.Config({
- maxConsumersPerSubscription: s_maxConsumersPerSubscription,
- adminFee: s_adminFee,
- handleOracleFulfillmentSelector: s_handleOracleFulfillmentSelector,
- maxCallbackGasLimits: maxCallbackGasLimits,
- gasForCallExactCheck: 5000
- });
- }
-
- function getCoordinatorConfig() public pure returns (FunctionsBilling.Config memory) {
- return
- FunctionsBilling.Config({
- maxCallbackGasLimit: 0, // NOTE: unused , TODO: remove
- feedStalenessSeconds: 24 * 60 * 60, // 1 day
- gasOverheadAfterCallback: 44_615, // TODO: update
- gasOverheadBeforeCallback: 44_615, // TODO: update
- requestTimeoutSeconds: 60 * 5, // 5 minutes
- donFee: 100,
- maxSupportedRequestDataVersion: 1,
- fulfillmentGasPriceOverEstimationBP: 5000,
- fallbackNativePerUnitLink: 5000000000000000
- });
- }
-
- function getTermsOfServiceConfig() public view returns (TermsOfServiceAllowList.Config memory) {
- return TermsOfServiceAllowList.Config({enabled: true, signerPublicKey: TOS_SIGNER});
- }
-}
-
-contract FunctionsSetupRoutes is FunctionsRouterSetup {
- function setUp() public virtual override {
- FunctionsRouterSetup.setUp();
-
- bytes32 allowListId = s_functionsRouter.getAllowListId();
- bytes32[] memory proposedContractSetIds = new bytes32[](2);
- proposedContractSetIds[0] = bytes32("1");
- proposedContractSetIds[1] = allowListId;
- address[] memory proposedContractSetAddresses = new address[](2);
- proposedContractSetAddresses[0] = address(s_functionsCoordinator);
- proposedContractSetAddresses[1] = address(s_termsOfServiceAllowList);
-
- s_functionsRouter.proposeContractsUpdate(proposedContractSetIds, proposedContractSetAddresses);
- s_functionsRouter.updateContracts();
- }
-}
-
-contract FunctionsOwnerAcceptTermsOfService is FunctionsSetupRoutes {
- function setUp() public virtual override {
- FunctionsSetupRoutes.setUp();
-
- bytes32 message = s_termsOfServiceAllowList.getMessage(OWNER_ADDRESS, OWNER_ADDRESS);
- bytes32 prefixedMessage = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", message));
- (uint8 v, bytes32 r, bytes32 s) = vm.sign(TOS_SIGNER_PRIVATE_KEY, prefixedMessage);
- s_termsOfServiceAllowList.acceptTermsOfService(OWNER_ADDRESS, OWNER_ADDRESS, r, s, v);
- }
-}
diff --git a/contracts/src/v0.8/functions/tests/1_0_0/testhelpers/FunctionsLoadTestClient.sol b/contracts/src/v0.8/functions/tests/1_0_0/testhelpers/FunctionsLoadTestClient.sol
deleted file mode 100644
index 7aa46e9ba06..00000000000
--- a/contracts/src/v0.8/functions/tests/1_0_0/testhelpers/FunctionsLoadTestClient.sol
+++ /dev/null
@@ -1,71 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.19;
-
-import {FunctionsClient} from "../../../dev/1_0_0/FunctionsClient.sol";
-import {ConfirmedOwner} from "../../../../shared/access/ConfirmedOwner.sol";
-import {FunctionsRequest} from "../../../dev/1_0_0/libraries/FunctionsRequest.sol";
-
-/**
- * @title Chainlink Functions load test client implementation
- */
-contract FunctionsLoadTestClient is FunctionsClient, ConfirmedOwner {
- using FunctionsRequest for FunctionsRequest.Request;
-
- uint32 public constant MAX_CALLBACK_GAS = 70_000;
-
- bytes32 public s_lastRequestId;
- bytes32 public s_lastResponse;
- bytes32 public s_lastError;
- uint32 public s_lastResponseLength;
- uint32 public s_lastErrorLength;
-
- constructor(address router) FunctionsClient(router) ConfirmedOwner(msg.sender) {}
-
- /**
- * @notice Send a simple request
- * @param source JavaScript source code
- * @param encryptedSecretsReferences Encrypted secrets payload
- * @param args List of arguments accessible from within the source code
- * @param subscriptionId Billing ID
- */
- function sendRequest(
- string calldata source,
- bytes calldata encryptedSecretsReferences,
- string[] calldata args,
- uint64 subscriptionId,
- bytes32 jobId
- ) external onlyOwner {
- FunctionsRequest.Request memory req;
- req.initializeRequestForInlineJavaScript(source);
- if (encryptedSecretsReferences.length > 0) req.addSecretsReference(encryptedSecretsReferences);
- if (args.length > 0) req.setArgs(args);
- s_lastRequestId = _sendRequest(req.encodeCBOR(), subscriptionId, MAX_CALLBACK_GAS, jobId);
- }
-
- /**
- * @notice Store latest result/error
- * @param requestId The request ID, returned by sendRequest()
- * @param response Aggregated response from the user code
- * @param err Aggregated error from the user code or from the execution pipeline
- * Either response or error parameter will be set, but never both
- */
- function fulfillRequest(bytes32 requestId, bytes memory response, bytes memory err) internal override {
- // Save only the first 32 bytes of response/error to always fit within MAX_CALLBACK_GAS
- s_lastRequestId = requestId;
- s_lastResponse = bytesToBytes32(response);
- s_lastResponseLength = uint32(response.length);
- s_lastError = bytesToBytes32(err);
- s_lastErrorLength = uint32(err.length);
- }
-
- function bytesToBytes32(bytes memory b) private pure returns (bytes32 out) {
- uint256 maxLen = 32;
- if (b.length < 32) {
- maxLen = b.length;
- }
- for (uint256 i = 0; i < maxLen; ++i) {
- out |= bytes32(b[i]) >> (i * 8);
- }
- return out;
- }
-}
diff --git a/contracts/src/v0.8/functions/tests/0_0_0/BaseTest.t.sol b/contracts/src/v0.8/functions/tests/v0_0_0/BaseTest.t.sol
similarity index 100%
rename from contracts/src/v0.8/functions/tests/0_0_0/BaseTest.t.sol
rename to contracts/src/v0.8/functions/tests/v0_0_0/BaseTest.t.sol
diff --git a/contracts/src/v0.8/functions/tests/0_0_0/FunctionsOracle.t.sol b/contracts/src/v0.8/functions/tests/v0_0_0/FunctionsOracle.t.sol
similarity index 97%
rename from contracts/src/v0.8/functions/tests/0_0_0/FunctionsOracle.t.sol
rename to contracts/src/v0.8/functions/tests/v0_0_0/FunctionsOracle.t.sol
index cf1880d851a..ab175c3c45d 100644
--- a/contracts/src/v0.8/functions/tests/0_0_0/FunctionsOracle.t.sol
+++ b/contracts/src/v0.8/functions/tests/v0_0_0/FunctionsOracle.t.sol
@@ -3,7 +3,7 @@ pragma solidity ^0.8.6;
import {BaseTest} from "./BaseTest.t.sol";
import {FunctionsOracle, FunctionsOracleWithInit} from "./testhelpers/FunctionsOracleWithInit.sol";
import {FunctionsBillingRegistryWithInit} from "./testhelpers/FunctionsBillingRegistryWithInit.sol";
-import {ConfirmedOwnerUpgradeable} from "../../dev/0_0_0/accessControl/ConfirmedOwnerUpgradeable.sol";
+import {ConfirmedOwnerUpgradeable} from "../../dev/v0_0_0/accessControl/ConfirmedOwnerUpgradeable.sol";
// import {LinkToken} from "../../../../src/v0.4/LinkToken.sol";
// import {MockV3Aggregator} from "../../../../src/v0.7/tests/MockV3Aggregator.sol";
diff --git a/contracts/src/v0.8/functions/tests/0_0_0/testhelpers/AuthorizedOriginReceiverTestHelper.sol b/contracts/src/v0.8/functions/tests/v0_0_0/testhelpers/AuthorizedOriginReceiverTestHelper.sol
similarity index 87%
rename from contracts/src/v0.8/functions/tests/0_0_0/testhelpers/AuthorizedOriginReceiverTestHelper.sol
rename to contracts/src/v0.8/functions/tests/v0_0_0/testhelpers/AuthorizedOriginReceiverTestHelper.sol
index 6411a08631c..0c592ae81c6 100644
--- a/contracts/src/v0.8/functions/tests/0_0_0/testhelpers/AuthorizedOriginReceiverTestHelper.sol
+++ b/contracts/src/v0.8/functions/tests/v0_0_0/testhelpers/AuthorizedOriginReceiverTestHelper.sol
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
-import "../../../dev/0_0_0/accessControl/AuthorizedOriginReceiver.sol";
+import "../../../dev/v0_0_0/accessControl/AuthorizedOriginReceiver.sol";
contract AuthorizedOriginReceiverTestHelper is AuthorizedOriginReceiver {
bool private s_canSetAuthorizedSenders = true;
diff --git a/contracts/src/v0.8/functions/tests/0_0_0/testhelpers/AuthorizedReceiverTestHelper.sol b/contracts/src/v0.8/functions/tests/v0_0_0/testhelpers/AuthorizedReceiverTestHelper.sol
similarity index 88%
rename from contracts/src/v0.8/functions/tests/0_0_0/testhelpers/AuthorizedReceiverTestHelper.sol
rename to contracts/src/v0.8/functions/tests/v0_0_0/testhelpers/AuthorizedReceiverTestHelper.sol
index f5b881b38b9..ee541013f45 100644
--- a/contracts/src/v0.8/functions/tests/0_0_0/testhelpers/AuthorizedReceiverTestHelper.sol
+++ b/contracts/src/v0.8/functions/tests/v0_0_0/testhelpers/AuthorizedReceiverTestHelper.sol
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
-import "../../../dev/0_0_0/accessControl/AuthorizedReceiver.sol";
+import "../../../dev/v0_0_0/accessControl/AuthorizedReceiver.sol";
contract AuthorizedReceiverTestHelper is AuthorizedReceiver {
bool private s_canSetAuthorizedSenders = true;
diff --git a/contracts/src/v0.8/functions/tests/0_0_0/testhelpers/FunctionsBillingRegistryWithInit.sol b/contracts/src/v0.8/functions/tests/v0_0_0/testhelpers/FunctionsBillingRegistryWithInit.sol
similarity index 72%
rename from contracts/src/v0.8/functions/tests/0_0_0/testhelpers/FunctionsBillingRegistryWithInit.sol
rename to contracts/src/v0.8/functions/tests/v0_0_0/testhelpers/FunctionsBillingRegistryWithInit.sol
index ffbc0ae703e..0ace817fa52 100644
--- a/contracts/src/v0.8/functions/tests/0_0_0/testhelpers/FunctionsBillingRegistryWithInit.sol
+++ b/contracts/src/v0.8/functions/tests/v0_0_0/testhelpers/FunctionsBillingRegistryWithInit.sol
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.6;
-import {FunctionsBillingRegistry} from "../../../dev/0_0_0/FunctionsBillingRegistry.sol";
+import {FunctionsBillingRegistry} from "../../../dev/v0_0_0/FunctionsBillingRegistry.sol";
contract FunctionsBillingRegistryWithInit is FunctionsBillingRegistry {
constructor(address link, address linkEthFeed, address oracle) {
diff --git a/contracts/src/v0.8/functions/tests/0_0_0/testhelpers/FunctionsClientTestHelper.sol b/contracts/src/v0.8/functions/tests/v0_0_0/testhelpers/FunctionsClientTestHelper.sol
similarity index 95%
rename from contracts/src/v0.8/functions/tests/0_0_0/testhelpers/FunctionsClientTestHelper.sol
rename to contracts/src/v0.8/functions/tests/v0_0_0/testhelpers/FunctionsClientTestHelper.sol
index 78c1107a0b0..89366510da7 100644
--- a/contracts/src/v0.8/functions/tests/0_0_0/testhelpers/FunctionsClientTestHelper.sol
+++ b/contracts/src/v0.8/functions/tests/v0_0_0/testhelpers/FunctionsClientTestHelper.sol
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.6;
-import {FunctionsClient, Functions} from "../../../dev/0_0_0/FunctionsClient.sol";
+import {FunctionsClient, Functions} from "../../../dev/v0_0_0/FunctionsClient.sol";
contract FunctionsClientTestHelper is FunctionsClient {
using Functions for Functions.Request;
diff --git a/contracts/src/v0.8/functions/tests/0_0_0/testhelpers/FunctionsOracleHelper.sol b/contracts/src/v0.8/functions/tests/v0_0_0/testhelpers/FunctionsOracleHelper.sol
similarity index 100%
rename from contracts/src/v0.8/functions/tests/0_0_0/testhelpers/FunctionsOracleHelper.sol
rename to contracts/src/v0.8/functions/tests/v0_0_0/testhelpers/FunctionsOracleHelper.sol
diff --git a/contracts/src/v0.8/functions/tests/0_0_0/testhelpers/FunctionsOracleMigrationHelper.sol b/contracts/src/v0.8/functions/tests/v0_0_0/testhelpers/FunctionsOracleMigrationHelper.sol
similarity index 100%
rename from contracts/src/v0.8/functions/tests/0_0_0/testhelpers/FunctionsOracleMigrationHelper.sol
rename to contracts/src/v0.8/functions/tests/v0_0_0/testhelpers/FunctionsOracleMigrationHelper.sol
diff --git a/contracts/src/v0.8/functions/tests/0_0_0/testhelpers/FunctionsOracleOriginalHelper.sol b/contracts/src/v0.8/functions/tests/v0_0_0/testhelpers/FunctionsOracleOriginalHelper.sol
similarity index 100%
rename from contracts/src/v0.8/functions/tests/0_0_0/testhelpers/FunctionsOracleOriginalHelper.sol
rename to contracts/src/v0.8/functions/tests/v0_0_0/testhelpers/FunctionsOracleOriginalHelper.sol
diff --git a/contracts/src/v0.8/functions/tests/0_0_0/testhelpers/FunctionsOracleUpgradeableHelper.sol b/contracts/src/v0.8/functions/tests/v0_0_0/testhelpers/FunctionsOracleUpgradeableHelper.sol
similarity index 91%
rename from contracts/src/v0.8/functions/tests/0_0_0/testhelpers/FunctionsOracleUpgradeableHelper.sol
rename to contracts/src/v0.8/functions/tests/v0_0_0/testhelpers/FunctionsOracleUpgradeableHelper.sol
index 66404faedf0..d11d22372db 100644
--- a/contracts/src/v0.8/functions/tests/0_0_0/testhelpers/FunctionsOracleUpgradeableHelper.sol
+++ b/contracts/src/v0.8/functions/tests/v0_0_0/testhelpers/FunctionsOracleUpgradeableHelper.sol
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.6;
-import {FunctionsOracle} from "../../../dev/0_0_0/FunctionsOracle.sol";
+import {FunctionsOracle} from "../../../dev/v0_0_0/FunctionsOracle.sol";
contract FunctionsOracleUpgradeableHelper is FunctionsOracle {
function callValidateReport(bytes calldata report) external pure returns (bool isValid) {
diff --git a/contracts/src/v0.8/functions/tests/0_0_0/testhelpers/FunctionsOracleWithInit.sol b/contracts/src/v0.8/functions/tests/v0_0_0/testhelpers/FunctionsOracleWithInit.sol
similarity index 67%
rename from contracts/src/v0.8/functions/tests/0_0_0/testhelpers/FunctionsOracleWithInit.sol
rename to contracts/src/v0.8/functions/tests/v0_0_0/testhelpers/FunctionsOracleWithInit.sol
index 1ef0107de8e..c5b913e9e97 100644
--- a/contracts/src/v0.8/functions/tests/0_0_0/testhelpers/FunctionsOracleWithInit.sol
+++ b/contracts/src/v0.8/functions/tests/v0_0_0/testhelpers/FunctionsOracleWithInit.sol
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.6;
-import {FunctionsOracle} from "../../../dev/0_0_0/FunctionsOracle.sol";
+import {FunctionsOracle} from "../../../dev/v0_0_0/FunctionsOracle.sol";
contract FunctionsOracleWithInit is FunctionsOracle {
constructor() {
diff --git a/contracts/src/v0.8/functions/tests/0_0_0/testhelpers/FunctionsTestHelper.sol b/contracts/src/v0.8/functions/tests/v0_0_0/testhelpers/FunctionsTestHelper.sol
similarity index 95%
rename from contracts/src/v0.8/functions/tests/0_0_0/testhelpers/FunctionsTestHelper.sol
rename to contracts/src/v0.8/functions/tests/v0_0_0/testhelpers/FunctionsTestHelper.sol
index c4ba893bd12..5c942936d4a 100644
--- a/contracts/src/v0.8/functions/tests/0_0_0/testhelpers/FunctionsTestHelper.sol
+++ b/contracts/src/v0.8/functions/tests/v0_0_0/testhelpers/FunctionsTestHelper.sol
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.6;
-import {Functions} from "../../../dev/0_0_0/Functions.sol";
+import {Functions} from "../../../dev/v0_0_0/Functions.sol";
contract FunctionsTestHelper {
using Functions for Functions.Request;
diff --git a/contracts/src/v0.8/functions/tests/0_0_0/testhelpers/mocks/AuthorizedOriginReceiverInterface.sol b/contracts/src/v0.8/functions/tests/v0_0_0/testhelpers/mocks/AuthorizedOriginReceiverInterface.sol
similarity index 100%
rename from contracts/src/v0.8/functions/tests/0_0_0/testhelpers/mocks/AuthorizedOriginReceiverInterface.sol
rename to contracts/src/v0.8/functions/tests/v0_0_0/testhelpers/mocks/AuthorizedOriginReceiverInterface.sol
diff --git a/contracts/src/v0.8/functions/tests/0_0_0/testhelpers/mocks/AuthorizedOriginReceiverUpgradeable.sol b/contracts/src/v0.8/functions/tests/v0_0_0/testhelpers/mocks/AuthorizedOriginReceiverUpgradeable.sol
similarity index 100%
rename from contracts/src/v0.8/functions/tests/0_0_0/testhelpers/mocks/AuthorizedOriginReceiverUpgradeable.sol
rename to contracts/src/v0.8/functions/tests/v0_0_0/testhelpers/mocks/AuthorizedOriginReceiverUpgradeable.sol
diff --git a/contracts/src/v0.8/functions/tests/0_0_0/testhelpers/mocks/AuthorizedReceiver.sol b/contracts/src/v0.8/functions/tests/v0_0_0/testhelpers/mocks/AuthorizedReceiver.sol
similarity index 100%
rename from contracts/src/v0.8/functions/tests/0_0_0/testhelpers/mocks/AuthorizedReceiver.sol
rename to contracts/src/v0.8/functions/tests/v0_0_0/testhelpers/mocks/AuthorizedReceiver.sol
diff --git a/contracts/src/v0.8/functions/tests/0_0_0/testhelpers/mocks/AuthorizedReceiverInterface.sol b/contracts/src/v0.8/functions/tests/v0_0_0/testhelpers/mocks/AuthorizedReceiverInterface.sol
similarity index 100%
rename from contracts/src/v0.8/functions/tests/0_0_0/testhelpers/mocks/AuthorizedReceiverInterface.sol
rename to contracts/src/v0.8/functions/tests/v0_0_0/testhelpers/mocks/AuthorizedReceiverInterface.sol
diff --git a/contracts/src/v0.8/functions/tests/0_0_0/testhelpers/mocks/ConfirmedOwnerUpgradeable.sol b/contracts/src/v0.8/functions/tests/v0_0_0/testhelpers/mocks/ConfirmedOwnerUpgradeable.sol
similarity index 100%
rename from contracts/src/v0.8/functions/tests/0_0_0/testhelpers/mocks/ConfirmedOwnerUpgradeable.sol
rename to contracts/src/v0.8/functions/tests/v0_0_0/testhelpers/mocks/ConfirmedOwnerUpgradeable.sol
diff --git a/contracts/src/v0.8/functions/tests/0_0_0/testhelpers/mocks/FunctionsBillingRegistryInterface.sol b/contracts/src/v0.8/functions/tests/v0_0_0/testhelpers/mocks/FunctionsBillingRegistryInterface.sol
similarity index 100%
rename from contracts/src/v0.8/functions/tests/0_0_0/testhelpers/mocks/FunctionsBillingRegistryInterface.sol
rename to contracts/src/v0.8/functions/tests/v0_0_0/testhelpers/mocks/FunctionsBillingRegistryInterface.sol
diff --git a/contracts/src/v0.8/functions/tests/0_0_0/testhelpers/mocks/FunctionsBillingRegistryMigration.sol b/contracts/src/v0.8/functions/tests/v0_0_0/testhelpers/mocks/FunctionsBillingRegistryMigration.sol
similarity index 100%
rename from contracts/src/v0.8/functions/tests/0_0_0/testhelpers/mocks/FunctionsBillingRegistryMigration.sol
rename to contracts/src/v0.8/functions/tests/v0_0_0/testhelpers/mocks/FunctionsBillingRegistryMigration.sol
diff --git a/contracts/src/v0.8/functions/tests/0_0_0/testhelpers/mocks/FunctionsBillingRegistryOriginal.sol b/contracts/src/v0.8/functions/tests/v0_0_0/testhelpers/mocks/FunctionsBillingRegistryOriginal.sol
similarity index 100%
rename from contracts/src/v0.8/functions/tests/0_0_0/testhelpers/mocks/FunctionsBillingRegistryOriginal.sol
rename to contracts/src/v0.8/functions/tests/v0_0_0/testhelpers/mocks/FunctionsBillingRegistryOriginal.sol
diff --git a/contracts/src/v0.8/functions/tests/0_0_0/testhelpers/mocks/FunctionsClientInterface.sol b/contracts/src/v0.8/functions/tests/v0_0_0/testhelpers/mocks/FunctionsClientInterface.sol
similarity index 100%
rename from contracts/src/v0.8/functions/tests/0_0_0/testhelpers/mocks/FunctionsClientInterface.sol
rename to contracts/src/v0.8/functions/tests/v0_0_0/testhelpers/mocks/FunctionsClientInterface.sol
diff --git a/contracts/src/v0.8/functions/tests/0_0_0/testhelpers/mocks/FunctionsOracleInterface.sol b/contracts/src/v0.8/functions/tests/v0_0_0/testhelpers/mocks/FunctionsOracleInterface.sol
similarity index 100%
rename from contracts/src/v0.8/functions/tests/0_0_0/testhelpers/mocks/FunctionsOracleInterface.sol
rename to contracts/src/v0.8/functions/tests/v0_0_0/testhelpers/mocks/FunctionsOracleInterface.sol
diff --git a/contracts/src/v0.8/functions/tests/0_0_0/testhelpers/mocks/FunctionsOracleMigration.sol b/contracts/src/v0.8/functions/tests/v0_0_0/testhelpers/mocks/FunctionsOracleMigration.sol
similarity index 100%
rename from contracts/src/v0.8/functions/tests/0_0_0/testhelpers/mocks/FunctionsOracleMigration.sol
rename to contracts/src/v0.8/functions/tests/v0_0_0/testhelpers/mocks/FunctionsOracleMigration.sol
diff --git a/contracts/src/v0.8/functions/tests/0_0_0/testhelpers/mocks/FunctionsOracleOriginal.sol b/contracts/src/v0.8/functions/tests/v0_0_0/testhelpers/mocks/FunctionsOracleOriginal.sol
similarity index 100%
rename from contracts/src/v0.8/functions/tests/0_0_0/testhelpers/mocks/FunctionsOracleOriginal.sol
rename to contracts/src/v0.8/functions/tests/v0_0_0/testhelpers/mocks/FunctionsOracleOriginal.sol
diff --git a/contracts/src/v0.8/functions/tests/0_0_0/testhelpers/mocks/OCR2Abstract.sol b/contracts/src/v0.8/functions/tests/v0_0_0/testhelpers/mocks/OCR2Abstract.sol
similarity index 100%
rename from contracts/src/v0.8/functions/tests/0_0_0/testhelpers/mocks/OCR2Abstract.sol
rename to contracts/src/v0.8/functions/tests/v0_0_0/testhelpers/mocks/OCR2Abstract.sol
diff --git a/contracts/src/v0.8/functions/tests/0_0_0/testhelpers/mocks/OCR2BaseUpgradeable.sol b/contracts/src/v0.8/functions/tests/v0_0_0/testhelpers/mocks/OCR2BaseUpgradeable.sol
similarity index 100%
rename from contracts/src/v0.8/functions/tests/0_0_0/testhelpers/mocks/OCR2BaseUpgradeable.sol
rename to contracts/src/v0.8/functions/tests/v0_0_0/testhelpers/mocks/OCR2BaseUpgradeable.sol
diff --git a/contracts/src/v0.8/functions/tests/1_0_0/BaseTest.t.sol b/contracts/src/v0.8/functions/tests/v1_0_0/BaseTest.t.sol
similarity index 81%
rename from contracts/src/v0.8/functions/tests/1_0_0/BaseTest.t.sol
rename to contracts/src/v0.8/functions/tests/v1_0_0/BaseTest.t.sol
index 13994f88f71..b012732897f 100644
--- a/contracts/src/v0.8/functions/tests/1_0_0/BaseTest.t.sol
+++ b/contracts/src/v0.8/functions/tests/v1_0_0/BaseTest.t.sol
@@ -11,11 +11,15 @@ contract BaseTest is Test {
uint256 internal STRANGER_PRIVATE_KEY = 0x2;
address internal STRANGER_ADDRESS = vm.addr(STRANGER_PRIVATE_KEY);
+ uint256 TX_GASPRICE_START = 3000000000; // 3 gwei
+
+ uint72 constant JUELS_PER_LINK = 1e18;
+
function setUp() public virtual {
// BaseTest.setUp is often called multiple times from tests' setUp due to inheritance.
if (s_baseTestInitialized) return;
s_baseTestInitialized = true;
// Set msg.sender to OWNER until stopPrank is called
- vm.startPrank(OWNER_ADDRESS);
+ vm.startPrank(OWNER_ADDRESS, OWNER_ADDRESS);
}
}
diff --git a/contracts/src/v0.8/functions/tests/1_0_0/FunctionsClient.t.sol b/contracts/src/v0.8/functions/tests/v1_0_0/FunctionsClient.t.sol
similarity index 100%
rename from contracts/src/v0.8/functions/tests/1_0_0/FunctionsClient.t.sol
rename to contracts/src/v0.8/functions/tests/v1_0_0/FunctionsClient.t.sol
diff --git a/contracts/src/v0.8/functions/tests/v1_0_0/FunctionsCoordinator.t.sol b/contracts/src/v0.8/functions/tests/v1_0_0/FunctionsCoordinator.t.sol
new file mode 100644
index 00000000000..088de631d06
--- /dev/null
+++ b/contracts/src/v0.8/functions/tests/v1_0_0/FunctionsCoordinator.t.sol
@@ -0,0 +1,317 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.19;
+
+import {FunctionsCoordinator} from "../../dev/v1_0_0/FunctionsCoordinator.sol";
+import {FunctionsBilling} from "../../dev/v1_0_0/FunctionsBilling.sol";
+import {FunctionsRequest} from "../../dev/v1_0_0/libraries/FunctionsRequest.sol";
+
+import {FunctionsSubscriptionSetup, FunctionsMultipleFulfillmentsSetup} from "./Setup.t.sol";
+
+// ================================================================
+// | Functions Coordinator |
+// ================================================================
+
+/// @notice #constructor
+contract FunctionsCoordinator_Constructor {
+
+}
+
+/// @notice #getThresholdPublicKey
+contract FunctionsCoordinator_GetThresholdPublicKey {
+
+}
+
+/// @notice #setThresholdPublicKey
+contract FunctionsCoordinator_SetThresholdPublicKey {
+
+}
+
+/// @notice #getDONPublicKey
+contract FunctionsCoordinator_GetDONPublicKey {
+
+}
+
+/// @notice #setDONPublicKey
+contract FunctionsCoordinator__SetDONPublicKey {
+
+}
+
+/// @notice #_isTransmitter
+contract FunctionsCoordinator_IsTransmitter {
+
+}
+
+/// @notice #setNodePublicKey
+contract FunctionsCoordinator_SetNodePublicKey {
+
+}
+
+/// @notice #deleteNodePublicKey
+contract FunctionsCoordinator_DeleteNodePublicKey {
+
+}
+
+/// @notice #getAllNodePublicKeys
+contract FunctionsCoordinator_GetAllNodePublicKeys {
+
+}
+
+/// @notice #startRequest
+contract FunctionsCoordinator_StartRequest {
+
+}
+
+/// @notice #_beforeSetConfig
+contract FunctionsCoordinator__BeforeSetConfig {
+
+}
+
+/// @notice #_getTransmitters
+contract FunctionsCoordinator__GetTransmitters {
+
+}
+
+/// @notice #_report
+contract FunctionsCoordinator__Report {
+
+}
+
+/// @notice #_onlyOwner
+contract FunctionsCoordinator__OnlyOwner {
+
+}
+
+// ================================================================
+// | Functions Billing |
+// ================================================================
+
+/// @notice #constructor
+contract FunctionsBilling_Constructor {
+
+}
+
+/// @notice #getConfig
+contract FunctionsBilling_GetConfig {
+
+}
+
+/// @notice #updateConfig
+contract FunctionsBilling_UpdateConfig {
+
+}
+
+/// @notice #getDONFee
+contract FunctionsBilling_GetDONFee {
+
+}
+
+/// @notice #getAdminFee
+contract FunctionsBilling_GetAdminFee {
+
+}
+
+/// @notice #getWeiPerUnitLink
+contract FunctionsBilling_GetWeiPerUnitLink {
+
+}
+
+/// @notice #_getJuelsPerGas
+contract FunctionsBilling__GetJuelsPerGas {
+
+}
+
+/// @notice #estimateCost
+contract FunctionsBilling_EstimateCost is FunctionsSubscriptionSetup {
+ function setUp() public virtual override {
+ FunctionsSubscriptionSetup.setUp();
+
+ // Get cost estimate as stranger
+ vm.stopPrank();
+ vm.startPrank(STRANGER_ADDRESS);
+ }
+
+ uint256 private constant REASONABLE_GAS_PRICE_CEILING = 1_000_000_000_000_000; // 1 million gwei
+
+ function test_EstimateCost_RevertsIfGasPriceAboveCeiling() public {
+ // Build minimal valid request data
+ string memory sourceCode = "return 'hello world';";
+ FunctionsRequest.Request memory request;
+ FunctionsRequest.initializeRequest(
+ request,
+ FunctionsRequest.Location.Inline,
+ FunctionsRequest.CodeLanguage.JavaScript,
+ sourceCode
+ );
+ bytes memory requestData = FunctionsRequest.encodeCBOR(request);
+
+ uint32 callbackGasLimit = 5_500;
+ uint256 gasPriceWei = REASONABLE_GAS_PRICE_CEILING + 1;
+
+ vm.expectRevert(FunctionsBilling.InvalidCalldata.selector);
+
+ s_functionsCoordinator.estimateCost(s_subscriptionId, requestData, callbackGasLimit, gasPriceWei);
+ }
+
+ function test_EstimateCost_Success() public {
+ // Build minimal valid request data
+ string memory sourceCode = "return 'hello world';";
+ FunctionsRequest.Request memory request;
+ FunctionsRequest.initializeRequest(
+ request,
+ FunctionsRequest.Location.Inline,
+ FunctionsRequest.CodeLanguage.JavaScript,
+ sourceCode
+ );
+ bytes memory requestData = FunctionsRequest.encodeCBOR(request);
+
+ uint32 callbackGasLimit = 5_500;
+ uint256 gasPriceWei = 1;
+
+ uint96 costEstimate = s_functionsCoordinator.estimateCost(
+ s_subscriptionId,
+ requestData,
+ callbackGasLimit,
+ gasPriceWei
+ );
+ uint96 expectedCostEstimate = 10873200;
+ assertEq(costEstimate, expectedCostEstimate);
+ }
+}
+
+/// @notice #_calculateCostEstimate
+contract FunctionsBilling__CalculateCostEstimate {
+
+}
+
+/// @notice #_startBilling
+contract FunctionsBilling__StartBilling {
+
+}
+
+/// @notice #_computeRequestId
+contract FunctionsBilling__ComputeRequestId {
+
+}
+
+/// @notice #_fulfillAndBill
+contract FunctionsBilling__FulfillAndBill {
+
+}
+
+/// @notice #deleteCommitment
+contract FunctionsBilling_DeleteCommitment {
+
+}
+
+/// @notice #oracleWithdraw
+contract FunctionsBilling_OracleWithdraw {
+
+}
+
+/// @notice #oracleWithdrawAll
+contract FunctionsBilling_OracleWithdrawAll is FunctionsMultipleFulfillmentsSetup {
+ function setUp() public virtual override {
+ // Use no DON fee so that a transmitter has a balance of 0
+ s_donFee = 0;
+
+ FunctionsMultipleFulfillmentsSetup.setUp();
+ }
+
+ function test_OracleWithdrawAll_RevertIfNotOwner() public {
+ // Send as stranger
+ vm.stopPrank();
+ vm.startPrank(STRANGER_ADDRESS);
+
+ vm.expectRevert("Only callable by owner");
+ s_functionsCoordinator.oracleWithdrawAll();
+ }
+
+ function test_OracleWithdrawAll_SuccessPaysTransmittersWithBalance() public {
+ uint256 transmitter1BalanceBefore = s_linkToken.balanceOf(NOP_TRANSMITTER_ADDRESS_1);
+ assertEq(transmitter1BalanceBefore, 0);
+ uint256 transmitter2BalanceBefore = s_linkToken.balanceOf(NOP_TRANSMITTER_ADDRESS_2);
+ assertEq(transmitter2BalanceBefore, 0);
+ uint256 transmitter3BalanceBefore = s_linkToken.balanceOf(NOP_TRANSMITTER_ADDRESS_3);
+ assertEq(transmitter3BalanceBefore, 0);
+ uint256 transmitter4BalanceBefore = s_linkToken.balanceOf(NOP_TRANSMITTER_ADDRESS_4);
+ assertEq(transmitter4BalanceBefore, 0);
+
+ s_functionsCoordinator.oracleWithdrawAll();
+
+ uint96 expectedTransmitterBalance = s_fulfillmentCoordinatorBalance / 3;
+
+ uint256 transmitter1BalanceAfter = s_linkToken.balanceOf(NOP_TRANSMITTER_ADDRESS_1);
+ assertEq(transmitter1BalanceAfter, expectedTransmitterBalance);
+ uint256 transmitter2BalanceAfter = s_linkToken.balanceOf(NOP_TRANSMITTER_ADDRESS_2);
+ assertEq(transmitter2BalanceAfter, expectedTransmitterBalance);
+ uint256 transmitter3BalanceAfter = s_linkToken.balanceOf(NOP_TRANSMITTER_ADDRESS_3);
+ assertEq(transmitter3BalanceAfter, expectedTransmitterBalance);
+ // Transmitter 4 has no balance
+ uint256 transmitter4BalanceAfter = s_linkToken.balanceOf(NOP_TRANSMITTER_ADDRESS_4);
+ assertEq(transmitter4BalanceAfter, 0);
+ }
+}
+
+/// @notice #_getTransmitters
+contract FunctionsBilling__GetTransmitters {
+
+}
+
+/// @notice #_disperseFeePool
+contract FunctionsBilling__DisperseFeePool {
+
+}
+
+// ================================================================
+// | OCR2Base |
+// ================================================================
+
+/// @notice #constructor
+contract OCR2Base_Constructor {
+
+}
+
+/// @notice #checkConfigValid
+contract OCR2Base_CheckConfigValid {
+
+}
+
+/// @notice #latestConfigDigestAndEpoch
+contract OCR2Base_LatestConfigDigestAndEpoch {
+
+}
+
+/// @notice #setConfig
+contract OCR2Base_SetConfig {
+
+}
+
+/// @notice #configDigestFromConfigData
+contract OCR2Base_ConfigDigestFromConfigData {
+
+}
+
+/// @notice #latestConfigDetails
+contract OCR2Base_LatestConfigDetails {
+
+}
+
+/// @notice #transmitters
+contract OCR2Base_Transmitters {
+
+}
+
+/// @notice #_report
+contract OCR2Base__Report {
+
+}
+
+/// @notice #requireExpectedMsgDataLength
+contract OCR2Base_RequireExpectedMsgDataLength {
+
+}
+
+/// @notice #transmit
+contract OCR2Base_Transmit {
+
+}
diff --git a/contracts/src/v0.8/functions/tests/1_0_0/FunctionsRequest.t.sol b/contracts/src/v0.8/functions/tests/v1_0_0/FunctionsRequest.t.sol
similarity index 100%
rename from contracts/src/v0.8/functions/tests/1_0_0/FunctionsRequest.t.sol
rename to contracts/src/v0.8/functions/tests/v1_0_0/FunctionsRequest.t.sol
diff --git a/contracts/src/v0.8/functions/tests/v1_0_0/FunctionsRouter.t.sol b/contracts/src/v0.8/functions/tests/v1_0_0/FunctionsRouter.t.sol
new file mode 100644
index 00000000000..1a858c28df6
--- /dev/null
+++ b/contracts/src/v0.8/functions/tests/v1_0_0/FunctionsRouter.t.sol
@@ -0,0 +1,1601 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.19;
+
+import {FunctionsRouter} from "../../dev/v1_0_0/FunctionsRouter.sol";
+import {FunctionsSubscriptions} from "../../dev/v1_0_0/FunctionsSubscriptions.sol";
+import {FunctionsCoordinator} from "../../dev/v1_0_0/FunctionsCoordinator.sol";
+import {FunctionsBilling} from "../../dev/v1_0_0/FunctionsBilling.sol";
+import {FunctionsRequest} from "../../dev/v1_0_0/libraries/FunctionsRequest.sol";
+import {FunctionsResponse} from "../../dev/v1_0_0/libraries/FunctionsResponse.sol";
+import {FunctionsCoordinatorTestHelper} from "./testhelpers/FunctionsCoordinatorTestHelper.sol";
+import {FunctionsClientTestHelper} from "./testhelpers/FunctionsClientTestHelper.sol";
+
+import {FunctionsRouterSetup, FunctionsRoutesSetup, FunctionsSubscriptionSetup, FunctionsClientRequestSetup} from "./Setup.t.sol";
+
+import "forge-std/Vm.sol";
+
+// ================================================================
+// | Functions Router |
+// ================================================================
+
+/// @notice #constructor
+contract FunctionsRouter_Constructor is FunctionsRouterSetup {
+ function test_Constructor_Success() public {
+ assertEq(s_functionsRouter.typeAndVersion(), "Functions Router v1.0.0");
+ assertEq(s_functionsRouter.owner(), OWNER_ADDRESS);
+ }
+}
+
+/// @notice #getConfig
+contract FunctionsRouter_GetConfig is FunctionsRouterSetup {
+ function test_GetConfig_Success() public {
+ // Send as stranger
+ vm.stopPrank();
+ vm.startPrank(STRANGER_ADDRESS);
+
+ FunctionsRouter.Config memory config = s_functionsRouter.getConfig();
+ assertEq(config.maxConsumersPerSubscription, getRouterConfig().maxConsumersPerSubscription);
+ assertEq(config.adminFee, getRouterConfig().adminFee);
+ assertEq(config.handleOracleFulfillmentSelector, getRouterConfig().handleOracleFulfillmentSelector);
+ assertEq(config.maxCallbackGasLimits[0], getRouterConfig().maxCallbackGasLimits[0]);
+ assertEq(config.maxCallbackGasLimits[1], getRouterConfig().maxCallbackGasLimits[1]);
+ assertEq(config.maxCallbackGasLimits[2], getRouterConfig().maxCallbackGasLimits[2]);
+ assertEq(config.gasForCallExactCheck, getRouterConfig().gasForCallExactCheck);
+ assertEq(config.subscriptionDepositMinimumRequests, getRouterConfig().subscriptionDepositMinimumRequests);
+ assertEq(config.subscriptionDepositJuels, getRouterConfig().subscriptionDepositJuels);
+ }
+}
+
+/// @notice #updateConfig
+contract FunctionsRouter_UpdateConfig is FunctionsRouterSetup {
+ FunctionsRouter.Config internal configToSet;
+
+ function setUp() public virtual override {
+ FunctionsRouterSetup.setUp();
+
+ uint32[] memory maxCallbackGasLimits = new uint32[](4);
+ maxCallbackGasLimits[0] = 300_000;
+ maxCallbackGasLimits[1] = 500_000;
+ maxCallbackGasLimits[2] = 1_000_000;
+ maxCallbackGasLimits[3] = 3_000_000;
+
+ configToSet = FunctionsRouter.Config({
+ maxConsumersPerSubscription: s_maxConsumersPerSubscription,
+ adminFee: s_adminFee,
+ handleOracleFulfillmentSelector: s_handleOracleFulfillmentSelector,
+ maxCallbackGasLimits: maxCallbackGasLimits,
+ gasForCallExactCheck: 5000,
+ subscriptionDepositMinimumRequests: 10,
+ subscriptionDepositJuels: 5 * 1e18
+ });
+ }
+
+ function test_UpdateConfig_RevertIfNotOwner() public {
+ // Send as stranger
+ vm.stopPrank();
+ vm.startPrank(STRANGER_ADDRESS);
+
+ vm.expectRevert("Only callable by owner");
+ s_functionsRouter.updateConfig(configToSet);
+ }
+
+ event ConfigUpdated(FunctionsRouter.Config config);
+
+ function test_UpdateConfig_Success() public {
+ // topic0 (function signature, always checked), NOT topic1 (false), NOT topic2 (false), NOT topic3 (false), and data (true).
+ bool checkTopic1 = false;
+ bool checkTopic2 = false;
+ bool checkTopic3 = false;
+ bool checkData = true;
+ vm.expectEmit(checkTopic1, checkTopic2, checkTopic3, checkData);
+ emit ConfigUpdated(configToSet);
+
+ s_functionsRouter.updateConfig(configToSet);
+
+ FunctionsRouter.Config memory config = s_functionsRouter.getConfig();
+ assertEq(config.maxConsumersPerSubscription, configToSet.maxConsumersPerSubscription);
+ assertEq(config.adminFee, configToSet.adminFee);
+ assertEq(config.handleOracleFulfillmentSelector, configToSet.handleOracleFulfillmentSelector);
+ assertEq(config.maxCallbackGasLimits[0], configToSet.maxCallbackGasLimits[0]);
+ assertEq(config.maxCallbackGasLimits[1], configToSet.maxCallbackGasLimits[1]);
+ assertEq(config.maxCallbackGasLimits[2], configToSet.maxCallbackGasLimits[2]);
+ assertEq(config.maxCallbackGasLimits[3], configToSet.maxCallbackGasLimits[3]);
+ assertEq(config.gasForCallExactCheck, configToSet.gasForCallExactCheck);
+ }
+}
+
+/// @notice #isValidCallbackGasLimit
+contract FunctionsRouter_IsValidCallbackGasLimit is FunctionsSubscriptionSetup {
+ function test_IsValidCallbackGasLimit_RevertInvalidConfig() public {
+ // Set an invalid maxCallbackGasLimit flag
+ bytes32 flagsToSet = 0x5a00000000000000000000000000000000000000000000000000000000000000;
+ s_functionsRouter.setFlags(s_subscriptionId, flagsToSet);
+
+ vm.expectRevert(abi.encodeWithSelector(FunctionsRouter.InvalidGasFlagValue.selector, 90));
+ s_functionsRouter.isValidCallbackGasLimit(s_subscriptionId, 0);
+ }
+
+ function test_IsValidCallbackGasLimit_RevertGasLimitTooBig() public {
+ uint8 MAX_CALLBACK_GAS_LIMIT_FLAGS_INDEX = 0;
+ bytes32 subscriptionFlags = s_functionsRouter.getFlags(s_subscriptionId);
+ uint8 callbackGasLimitsIndexSelector = uint8(subscriptionFlags[MAX_CALLBACK_GAS_LIMIT_FLAGS_INDEX]);
+
+ FunctionsRouter.Config memory config = s_functionsRouter.getConfig();
+ uint32[] memory _maxCallbackGasLimits = config.maxCallbackGasLimits;
+ uint32 maxCallbackGasLimit = _maxCallbackGasLimits[callbackGasLimitsIndexSelector];
+
+ vm.expectRevert(abi.encodeWithSelector(FunctionsRouter.GasLimitTooBig.selector, maxCallbackGasLimit));
+ s_functionsRouter.isValidCallbackGasLimit(s_subscriptionId, maxCallbackGasLimit + 1);
+ }
+
+ function test_IsValidCallbackGasLimit_Success() public view {
+ uint8 MAX_CALLBACK_GAS_LIMIT_FLAGS_INDEX = 0;
+ bytes32 subscriptionFlags = s_functionsRouter.getFlags(s_subscriptionId);
+ uint8 callbackGasLimitsIndexSelector = uint8(subscriptionFlags[MAX_CALLBACK_GAS_LIMIT_FLAGS_INDEX]);
+
+ FunctionsRouter.Config memory config = s_functionsRouter.getConfig();
+ uint32[] memory _maxCallbackGasLimits = config.maxCallbackGasLimits;
+ uint32 maxCallbackGasLimit = _maxCallbackGasLimits[callbackGasLimitsIndexSelector];
+
+ s_functionsRouter.isValidCallbackGasLimit(s_subscriptionId, maxCallbackGasLimit);
+ }
+}
+
+/// @notice #getAdminFee
+contract FunctionsRouter_GetAdminFee is FunctionsRouterSetup {
+ function test_GetAdminFee_Success() public {
+ // Send as stranger
+ vm.stopPrank();
+ vm.startPrank(STRANGER_ADDRESS);
+
+ uint72 adminFee = s_functionsRouter.getAdminFee();
+ assertEq(adminFee, getRouterConfig().adminFee);
+ }
+}
+
+/// @notice #getAllowListId
+contract FunctionsRouter_GetAllowListId is FunctionsRouterSetup {
+ function test_GetAllowListId_Success() public {
+ // Send as stranger
+ vm.stopPrank();
+ vm.startPrank(STRANGER_ADDRESS);
+
+ bytes32 defaultAllowListId = bytes32(0);
+
+ bytes32 allowListId = s_functionsRouter.getAllowListId();
+ assertEq(allowListId, defaultAllowListId);
+ }
+}
+
+/// @notice #setAllowListId
+contract FunctionsRouter_SetAllowListId is FunctionsRouterSetup {
+ function test_UpdateConfig_RevertIfNotOwner() public {
+ // Send as stranger
+ vm.stopPrank();
+ vm.startPrank(STRANGER_ADDRESS);
+
+ bytes32 routeIdToSet = bytes32("allowList");
+
+ vm.expectRevert("Only callable by owner");
+ s_functionsRouter.setAllowListId(routeIdToSet);
+ }
+
+ function test_SetAllowListId_Success() public {
+ bytes32 routeIdToSet = bytes32("allowList");
+ s_functionsRouter.setAllowListId(routeIdToSet);
+ bytes32 allowListId = s_functionsRouter.getAllowListId();
+ assertEq(allowListId, routeIdToSet);
+ }
+}
+
+/// @notice #_getMaxConsumers
+contract FunctionsRouter__GetMaxConsumers is FunctionsRouterSetup {
+ // TODO: make contract internal function helper
+}
+
+/// @notice #sendRequest
+contract FunctionsRouter_SendRequest is FunctionsSubscriptionSetup {
+ function setUp() public virtual override {
+ FunctionsSubscriptionSetup.setUp();
+
+ // Add sending wallet as a subscription consumer
+ s_functionsRouter.addConsumer(s_subscriptionId, OWNER_ADDRESS);
+ }
+
+ function test_SendRequest_RevertIfInvalidDonId() public {
+ // Build minimal valid request data
+ string memory sourceCode = "return 'hello world';";
+ FunctionsRequest.Request memory request;
+ FunctionsRequest.initializeRequest(
+ request,
+ FunctionsRequest.Location.Inline,
+ FunctionsRequest.CodeLanguage.JavaScript,
+ sourceCode
+ );
+ bytes memory requestData = FunctionsRequest.encodeCBOR(request);
+
+ bytes32 invalidDonId = bytes32("this does not exist");
+
+ vm.expectRevert(abi.encodeWithSelector(FunctionsRouter.RouteNotFound.selector, invalidDonId));
+ s_functionsRouter.sendRequest(
+ s_subscriptionId,
+ requestData,
+ FunctionsRequest.REQUEST_DATA_VERSION,
+ 5_000,
+ invalidDonId
+ );
+ }
+
+ function test_SendRequest_RevertIfIncorrectDonId() public {
+ // Build minimal valid request data
+ string memory sourceCode = "return 'hello world';";
+ FunctionsRequest.Request memory request;
+ FunctionsRequest.initializeRequest(
+ request,
+ FunctionsRequest.Location.Inline,
+ FunctionsRequest.CodeLanguage.JavaScript,
+ sourceCode
+ );
+ bytes memory requestData = FunctionsRequest.encodeCBOR(request);
+
+ bytes32 incorrectDonId = s_functionsRouter.getAllowListId();
+
+ // Low level revert from incorrect call
+ vm.expectRevert();
+ s_functionsRouter.sendRequest(
+ s_subscriptionId,
+ requestData,
+ FunctionsRequest.REQUEST_DATA_VERSION,
+ 5_000,
+ incorrectDonId
+ );
+ }
+
+ function test_SendRequest_RevertIfPaused() public {
+ s_functionsRouter.pause();
+
+ // Build minimal valid request data
+ string memory sourceCode = "return 'hello world';";
+ FunctionsRequest.Request memory request;
+ FunctionsRequest.initializeRequest(
+ request,
+ FunctionsRequest.Location.Inline,
+ FunctionsRequest.CodeLanguage.JavaScript,
+ sourceCode
+ );
+ bytes memory requestData = FunctionsRequest.encodeCBOR(request);
+
+ vm.expectRevert("Pausable: paused");
+ s_functionsRouter.sendRequest(s_subscriptionId, requestData, FunctionsRequest.REQUEST_DATA_VERSION, 5000, s_donId);
+ }
+
+ function test_SendRequest_RevertIfNoSubscription() public {
+ // Build minimal valid request data
+ string memory sourceCode = "return 'hello world';";
+ FunctionsRequest.Request memory request;
+ FunctionsRequest.initializeRequest(
+ request,
+ FunctionsRequest.Location.Inline,
+ FunctionsRequest.CodeLanguage.JavaScript,
+ sourceCode
+ );
+ bytes memory requestData = FunctionsRequest.encodeCBOR(request);
+
+ uint64 invalidSubscriptionId = 123456789;
+
+ vm.expectRevert(FunctionsSubscriptions.InvalidSubscription.selector);
+ s_functionsRouter.sendRequest(
+ invalidSubscriptionId,
+ requestData,
+ FunctionsRequest.REQUEST_DATA_VERSION,
+ 5000,
+ s_donId
+ );
+ }
+
+ function test_SendRequest_RevertIfConsumerNotAllowed() public {
+ // Remove sending wallet as a subscription consumer
+ s_functionsRouter.removeConsumer(s_subscriptionId, OWNER_ADDRESS);
+
+ // Build minimal valid request data
+ string memory sourceCode = "return 'hello world';";
+ FunctionsRequest.Request memory request;
+ FunctionsRequest.initializeRequest(
+ request,
+ FunctionsRequest.Location.Inline,
+ FunctionsRequest.CodeLanguage.JavaScript,
+ sourceCode
+ );
+ bytes memory requestData = FunctionsRequest.encodeCBOR(request);
+
+ vm.expectRevert(FunctionsSubscriptions.InvalidConsumer.selector);
+ s_functionsRouter.sendRequest(s_subscriptionId, requestData, FunctionsRequest.REQUEST_DATA_VERSION, 5000, s_donId);
+ }
+
+ function test_SendRequest_RevertIfInvalidCallbackGasLimit() public {
+ // Build minimal valid request data
+ string memory sourceCode = "return 'hello world';";
+ FunctionsRequest.Request memory request;
+ FunctionsRequest.initializeRequest(
+ request,
+ FunctionsRequest.Location.Inline,
+ FunctionsRequest.CodeLanguage.JavaScript,
+ sourceCode
+ );
+ bytes memory requestData = FunctionsRequest.encodeCBOR(request);
+
+ uint8 MAX_CALLBACK_GAS_LIMIT_FLAGS_INDEX = 0;
+ bytes32 subscriptionFlags = s_functionsRouter.getFlags(s_subscriptionId);
+ uint8 callbackGasLimitsIndexSelector = uint8(subscriptionFlags[MAX_CALLBACK_GAS_LIMIT_FLAGS_INDEX]);
+
+ FunctionsRouter.Config memory config = s_functionsRouter.getConfig();
+ uint32[] memory _maxCallbackGasLimits = config.maxCallbackGasLimits;
+ uint32 maxCallbackGasLimit = _maxCallbackGasLimits[callbackGasLimitsIndexSelector];
+
+ vm.expectRevert(abi.encodeWithSelector(FunctionsRouter.GasLimitTooBig.selector, maxCallbackGasLimit));
+ s_functionsRouter.sendRequest(
+ s_subscriptionId,
+ requestData,
+ FunctionsRequest.REQUEST_DATA_VERSION,
+ 500_000,
+ s_donId
+ );
+ }
+
+ function test_SendRequest_RevertIfEmptyData() public {
+ // Build invalid request data
+ bytes memory emptyRequestData = new bytes(0);
+
+ vm.expectRevert(FunctionsRouter.EmptyRequestData.selector);
+ s_functionsRouter.sendRequest(
+ s_subscriptionId,
+ emptyRequestData,
+ FunctionsRequest.REQUEST_DATA_VERSION,
+ 5_000,
+ s_donId
+ );
+ }
+
+ function test_SendRequest_RevertIfInsufficientSubscriptionBalance() public {
+ // Create new subscription that does not have any funding
+ uint64 subscriptionId = s_functionsRouter.createSubscription();
+ s_functionsRouter.addConsumer(subscriptionId, address(OWNER_ADDRESS));
+
+ // Build minimal valid request data
+ string memory sourceCode = "return 'hello world';";
+ FunctionsRequest.Request memory request;
+ FunctionsRequest.initializeRequest(
+ request,
+ FunctionsRequest.Location.Inline,
+ FunctionsRequest.CodeLanguage.JavaScript,
+ sourceCode
+ );
+ bytes memory requestData = FunctionsRequest.encodeCBOR(request);
+
+ uint32 callbackGasLimit = 5000;
+ vm.expectRevert(FunctionsBilling.InsufficientBalance.selector);
+
+ s_functionsRouter.sendRequest(
+ subscriptionId,
+ requestData,
+ FunctionsRequest.REQUEST_DATA_VERSION,
+ callbackGasLimit,
+ s_donId
+ );
+ }
+
+ function test_SendRequest_RevertIfDuplicateRequestId() public {
+ // Build minimal valid request data
+ string memory sourceCode = "return 'hello world';";
+ FunctionsRequest.Request memory request;
+ FunctionsRequest.initializeRequest(
+ request,
+ FunctionsRequest.Location.Inline,
+ FunctionsRequest.CodeLanguage.JavaScript,
+ sourceCode
+ );
+ uint32 callbackGasLimit = 5_000;
+ bytes memory requestData = FunctionsRequest.encodeCBOR(request);
+
+ // Send a first request that will remain pending
+ bytes32 requestId = s_functionsRouter.sendRequest(
+ s_subscriptionId,
+ requestData,
+ FunctionsRequest.REQUEST_DATA_VERSION,
+ callbackGasLimit,
+ s_donId
+ );
+
+ // Mock the Coordinator to always give back the first requestId
+ FunctionsResponse.Commitment memory mockCommitment = FunctionsResponse.Commitment({
+ adminFee: s_adminFee,
+ coordinator: address(s_functionsCoordinator),
+ client: OWNER_ADDRESS,
+ subscriptionId: s_subscriptionId,
+ callbackGasLimit: callbackGasLimit,
+ estimatedTotalCostJuels: 0,
+ timeoutTimestamp: uint32(block.timestamp + getCoordinatorConfig().requestTimeoutSeconds),
+ requestId: requestId,
+ donFee: s_donFee,
+ gasOverheadBeforeCallback: getCoordinatorConfig().gasOverheadBeforeCallback,
+ gasOverheadAfterCallback: getCoordinatorConfig().gasOverheadAfterCallback
+ });
+
+ vm.mockCall(
+ address(s_functionsCoordinator),
+ abi.encodeWithSelector(FunctionsCoordinator.startRequest.selector),
+ abi.encode(mockCommitment)
+ );
+
+ vm.expectRevert(abi.encodeWithSelector(FunctionsRouter.DuplicateRequestId.selector, requestId));
+ s_functionsRouter.sendRequest(
+ s_subscriptionId,
+ requestData,
+ FunctionsRequest.REQUEST_DATA_VERSION,
+ callbackGasLimit,
+ s_donId
+ );
+ }
+
+ event RequestStart(
+ bytes32 indexed requestId,
+ bytes32 indexed donId,
+ uint64 indexed subscriptionId,
+ address subscriptionOwner,
+ address requestingContract,
+ address requestInitiator,
+ bytes data,
+ uint16 dataVersion,
+ uint32 callbackGasLimit,
+ uint96 estimatedTotalCostJuels
+ );
+
+ function test_SendRequest_Success() public {
+ // Build minimal valid request data
+ string memory sourceCode = "return 'hello world';";
+ FunctionsRequest.Request memory request;
+ FunctionsRequest.initializeRequest(
+ request,
+ FunctionsRequest.Location.Inline,
+ FunctionsRequest.CodeLanguage.JavaScript,
+ sourceCode
+ );
+ bytes memory requestData = FunctionsRequest.encodeCBOR(request);
+
+ uint32 callbackGasLimit = 5000;
+
+ bytes32 expectedRequestId = keccak256(
+ abi.encode(address(s_functionsCoordinator), OWNER_ADDRESS, s_subscriptionId, 1)
+ );
+
+ uint96 costEstimate = s_functionsCoordinator.estimateCost(
+ s_subscriptionId,
+ requestData,
+ callbackGasLimit,
+ tx.gasprice
+ );
+
+ vm.recordLogs();
+
+ // topic0 (function signature, always checked), topic1 (true), topic2 (true), topic3 (true), and data (true).
+ bool checkTopic1 = true;
+ bool checkTopic2 = true;
+ bool checkTopic3 = true;
+ bool checkData = true;
+ vm.expectEmit(checkTopic1, checkTopic2, checkTopic3, checkData);
+ emit RequestStart({
+ requestId: expectedRequestId,
+ donId: s_donId,
+ subscriptionId: s_subscriptionId,
+ subscriptionOwner: OWNER_ADDRESS,
+ requestingContract: OWNER_ADDRESS,
+ requestInitiator: OWNER_ADDRESS,
+ data: requestData,
+ dataVersion: FunctionsRequest.REQUEST_DATA_VERSION,
+ callbackGasLimit: callbackGasLimit,
+ estimatedTotalCostJuels: costEstimate
+ });
+
+ bytes32 requestIdFromReturn = s_functionsRouter.sendRequest(
+ s_subscriptionId,
+ requestData,
+ FunctionsRequest.REQUEST_DATA_VERSION,
+ callbackGasLimit,
+ s_donId
+ );
+
+ // Get requestId from RequestStart event log topic 1
+ Vm.Log[] memory entries = vm.getRecordedLogs();
+ bytes32 requestIdFromEvent = entries[2].topics[1];
+
+ assertEq(requestIdFromReturn, requestIdFromEvent);
+ }
+}
+
+/// @notice #sendRequestToProposed
+contract FunctionsRouter_SendRequestToProposed is FunctionsSubscriptionSetup {
+ FunctionsCoordinatorTestHelper internal s_functionsCoordinator2; // TODO: use actual FunctionsCoordinator instead of helper
+
+ function setUp() public virtual override {
+ FunctionsSubscriptionSetup.setUp();
+
+ // Add sending wallet as a subscription consumer
+ s_functionsRouter.addConsumer(s_subscriptionId, OWNER_ADDRESS);
+
+ // Deploy new Coordinator contract
+ s_functionsCoordinator2 = new FunctionsCoordinatorTestHelper(
+ address(s_functionsRouter),
+ getCoordinatorConfig(),
+ address(s_linkEthFeed)
+ );
+
+ // Propose new Coordinator contract
+ bytes32[] memory proposedContractSetIds = new bytes32[](1);
+ proposedContractSetIds[0] = s_donId;
+ address[] memory proposedContractSetAddresses = new address[](1);
+ proposedContractSetAddresses[0] = address(s_functionsCoordinator2);
+
+ s_functionsRouter.proposeContractsUpdate(proposedContractSetIds, proposedContractSetAddresses);
+ }
+
+ function test_SendRequestToProposed_RevertIfInvalidDonId() public {
+ // Build minimal valid request data
+ string memory sourceCode = "return 'hello world';";
+ FunctionsRequest.Request memory request;
+ FunctionsRequest.initializeRequest(
+ request,
+ FunctionsRequest.Location.Inline,
+ FunctionsRequest.CodeLanguage.JavaScript,
+ sourceCode
+ );
+ bytes memory requestData = FunctionsRequest.encodeCBOR(request);
+
+ bytes32 invalidDonId = bytes32("this does not exist");
+
+ vm.expectRevert(abi.encodeWithSelector(FunctionsRouter.RouteNotFound.selector, invalidDonId));
+ s_functionsRouter.sendRequestToProposed(
+ s_subscriptionId,
+ requestData,
+ FunctionsRequest.REQUEST_DATA_VERSION,
+ 5_000,
+ invalidDonId
+ );
+ }
+
+ function test_SendRequestToProposed_RevertIfIncorrectDonId() public {
+ // Build minimal valid request data
+ string memory sourceCode = "return 'hello world';";
+ FunctionsRequest.Request memory request;
+ FunctionsRequest.initializeRequest(
+ request,
+ FunctionsRequest.Location.Inline,
+ FunctionsRequest.CodeLanguage.JavaScript,
+ sourceCode
+ );
+ bytes memory requestData = FunctionsRequest.encodeCBOR(request);
+
+ bytes32 incorrectDonId = s_functionsRouter.getAllowListId();
+
+ // Low level revert from incorrect call
+ vm.expectRevert();
+ s_functionsRouter.sendRequestToProposed(
+ s_subscriptionId,
+ requestData,
+ FunctionsRequest.REQUEST_DATA_VERSION,
+ 5_000,
+ incorrectDonId
+ );
+ }
+
+ function test_SendRequestToProposed_RevertIfPaused() public {
+ s_functionsRouter.pause();
+
+ // Build minimal valid request data
+ string memory sourceCode = "return 'hello world';";
+ FunctionsRequest.Request memory request;
+ FunctionsRequest.initializeRequest(
+ request,
+ FunctionsRequest.Location.Inline,
+ FunctionsRequest.CodeLanguage.JavaScript,
+ sourceCode
+ );
+ bytes memory requestData = FunctionsRequest.encodeCBOR(request);
+
+ vm.expectRevert("Pausable: paused");
+ s_functionsRouter.sendRequestToProposed(
+ s_subscriptionId,
+ requestData,
+ FunctionsRequest.REQUEST_DATA_VERSION,
+ 5000,
+ s_donId
+ );
+ }
+
+ function test_SendRequestToProposed_RevertIfNoSubscription() public {
+ // Build minimal valid request data
+ string memory sourceCode = "return 'hello world';";
+ FunctionsRequest.Request memory request;
+ FunctionsRequest.initializeRequest(
+ request,
+ FunctionsRequest.Location.Inline,
+ FunctionsRequest.CodeLanguage.JavaScript,
+ sourceCode
+ );
+ bytes memory requestData = FunctionsRequest.encodeCBOR(request);
+
+ uint64 invalidSubscriptionId = 123456789;
+
+ vm.expectRevert(FunctionsSubscriptions.InvalidSubscription.selector);
+ s_functionsRouter.sendRequestToProposed(
+ invalidSubscriptionId,
+ requestData,
+ FunctionsRequest.REQUEST_DATA_VERSION,
+ 5000,
+ s_donId
+ );
+ }
+
+ function test_SendRequestToProposed_RevertIfConsumerNotAllowed() public {
+ // Remove sending wallet as a subscription consumer
+ s_functionsRouter.removeConsumer(s_subscriptionId, OWNER_ADDRESS);
+
+ // Build minimal valid request data
+ string memory sourceCode = "return 'hello world';";
+ FunctionsRequest.Request memory request;
+ FunctionsRequest.initializeRequest(
+ request,
+ FunctionsRequest.Location.Inline,
+ FunctionsRequest.CodeLanguage.JavaScript,
+ sourceCode
+ );
+ bytes memory requestData = FunctionsRequest.encodeCBOR(request);
+
+ vm.expectRevert(FunctionsSubscriptions.InvalidConsumer.selector);
+ s_functionsRouter.sendRequestToProposed(
+ s_subscriptionId,
+ requestData,
+ FunctionsRequest.REQUEST_DATA_VERSION,
+ 5000,
+ s_donId
+ );
+ }
+
+ function test_SendRequestToProposed_RevertIfInvalidCallbackGasLimit() public {
+ // Build minimal valid request data
+ string memory sourceCode = "return 'hello world';";
+ FunctionsRequest.Request memory request;
+ FunctionsRequest.initializeRequest(
+ request,
+ FunctionsRequest.Location.Inline,
+ FunctionsRequest.CodeLanguage.JavaScript,
+ sourceCode
+ );
+ bytes memory requestData = FunctionsRequest.encodeCBOR(request);
+
+ uint8 MAX_CALLBACK_GAS_LIMIT_FLAGS_INDEX = 0;
+ bytes32 subscriptionFlags = s_functionsRouter.getFlags(s_subscriptionId);
+ uint8 callbackGasLimitsIndexSelector = uint8(subscriptionFlags[MAX_CALLBACK_GAS_LIMIT_FLAGS_INDEX]);
+
+ FunctionsRouter.Config memory config = s_functionsRouter.getConfig();
+ uint32[] memory _maxCallbackGasLimits = config.maxCallbackGasLimits;
+ uint32 maxCallbackGasLimit = _maxCallbackGasLimits[callbackGasLimitsIndexSelector];
+
+ vm.expectRevert(abi.encodeWithSelector(FunctionsRouter.GasLimitTooBig.selector, maxCallbackGasLimit));
+ s_functionsRouter.sendRequestToProposed(
+ s_subscriptionId,
+ requestData,
+ FunctionsRequest.REQUEST_DATA_VERSION,
+ 500_000,
+ s_donId
+ );
+ }
+
+ function test_SendRequestToProposed_RevertIfEmptyData() public {
+ // Build invalid request data
+ bytes memory emptyRequestData = new bytes(0);
+
+ vm.expectRevert(FunctionsRouter.EmptyRequestData.selector);
+ s_functionsRouter.sendRequestToProposed(
+ s_subscriptionId,
+ emptyRequestData,
+ FunctionsRequest.REQUEST_DATA_VERSION,
+ 5_000,
+ s_donId
+ );
+ }
+
+ function test_SendRequest_RevertIfInsufficientSubscriptionBalance() public {
+ // Create new subscription that does not have any funding
+ uint64 subscriptionId = s_functionsRouter.createSubscription();
+ s_functionsRouter.addConsumer(subscriptionId, address(OWNER_ADDRESS));
+
+ // Build minimal valid request data
+ string memory sourceCode = "return 'hello world';";
+ FunctionsRequest.Request memory request;
+ FunctionsRequest.initializeRequest(
+ request,
+ FunctionsRequest.Location.Inline,
+ FunctionsRequest.CodeLanguage.JavaScript,
+ sourceCode
+ );
+ bytes memory requestData = FunctionsRequest.encodeCBOR(request);
+
+ uint32 callbackGasLimit = 5000;
+ vm.expectRevert(FunctionsBilling.InsufficientBalance.selector);
+
+ s_functionsRouter.sendRequestToProposed(
+ subscriptionId,
+ requestData,
+ FunctionsRequest.REQUEST_DATA_VERSION,
+ callbackGasLimit,
+ s_donId
+ );
+ }
+
+ event RequestStart(
+ bytes32 indexed requestId,
+ bytes32 indexed donId,
+ uint64 indexed subscriptionId,
+ address subscriptionOwner,
+ address requestingContract,
+ address requestInitiator,
+ bytes data,
+ uint16 dataVersion,
+ uint32 callbackGasLimit,
+ uint96 estimatedTotalCostJuels
+ );
+
+ function test_SendRequestToProposed_Success() public {
+ // Build minimal valid request data
+ string memory sourceCode = "return 'hello world';";
+ FunctionsRequest.Request memory request;
+ FunctionsRequest.initializeRequest(
+ request,
+ FunctionsRequest.Location.Inline,
+ FunctionsRequest.CodeLanguage.JavaScript,
+ sourceCode
+ );
+ bytes memory requestData = FunctionsRequest.encodeCBOR(request);
+
+ uint32 callbackGasLimit = 5000;
+
+ bytes32 expectedRequestId = keccak256(
+ abi.encode(address(s_functionsCoordinator2), OWNER_ADDRESS, s_subscriptionId, 1)
+ );
+
+ uint96 costEstimate = s_functionsCoordinator2.estimateCost(
+ s_subscriptionId,
+ requestData,
+ callbackGasLimit,
+ tx.gasprice
+ );
+
+ vm.recordLogs();
+
+ // topic0 (function signature, always checked), topic1 (true), topic2 (true), topic3 (true), and data (true).
+ bool checkTopic1 = true;
+ bool checkTopic2 = true;
+ bool checkTopic3 = true;
+ bool checkData = true;
+ vm.expectEmit(checkTopic1, checkTopic2, checkTopic3, checkData);
+ emit RequestStart({
+ requestId: expectedRequestId,
+ donId: s_donId,
+ subscriptionId: s_subscriptionId,
+ subscriptionOwner: OWNER_ADDRESS,
+ requestingContract: OWNER_ADDRESS,
+ requestInitiator: OWNER_ADDRESS,
+ data: requestData,
+ dataVersion: FunctionsRequest.REQUEST_DATA_VERSION,
+ callbackGasLimit: callbackGasLimit,
+ estimatedTotalCostJuels: costEstimate
+ });
+
+ bytes32 requestIdFromReturn = s_functionsRouter.sendRequestToProposed(
+ s_subscriptionId,
+ requestData,
+ FunctionsRequest.REQUEST_DATA_VERSION,
+ callbackGasLimit,
+ s_donId
+ );
+
+ // Get requestId from RequestStart event log topic 1
+ Vm.Log[] memory entries = vm.getRecordedLogs();
+ bytes32 requestIdFromEvent = entries[2].topics[1];
+
+ assertEq(requestIdFromReturn, requestIdFromEvent);
+ }
+}
+
+/// @notice #_sendRequest
+contract FunctionsRouter__SendRequest is FunctionsRouterSetup {
+ // TODO: make contract internal function helper
+}
+
+/// @notice #fulfill
+contract FunctionsRouter_Fulfill is FunctionsClientRequestSetup {
+ function test_Fulfill_RevertIfPaused() public {
+ s_functionsRouter.pause();
+
+ uint256 requestToFulfill = 1;
+
+ uint256[] memory requestNumberKeys = new uint256[](1);
+ requestNumberKeys[0] = requestToFulfill;
+
+ string[] memory results = new string[](1);
+ string memory response = "hello world!";
+ results[0] = response;
+
+ bytes[] memory errors = new bytes[](1);
+ bytes memory err = new bytes(0);
+ errors[0] = err;
+
+ vm.expectRevert("Pausable: paused");
+ _reportAndStore(requestNumberKeys, results, errors, NOP_TRANSMITTER_ADDRESS_1, false);
+ }
+
+ function test_Fulfill_RevertIfNotCommittedCoordinator() public {
+ // Send as stranger
+ vm.stopPrank();
+ vm.startPrank(STRANGER_ADDRESS);
+
+ bytes memory response = bytes("hello world!");
+ bytes memory err = new bytes(0);
+ uint96 juelsPerGas = 0;
+ uint96 costWithoutCallback = 0;
+ address transmitter = NOP_TRANSMITTER_ADDRESS_1;
+ FunctionsResponse.Commitment memory commitment = s_requests[1].commitment;
+
+ vm.expectRevert(FunctionsRouter.OnlyCallableFromCoordinator.selector);
+ s_functionsRouter.fulfill(response, err, juelsPerGas, costWithoutCallback, transmitter, commitment);
+ }
+
+ event RequestNotProcessed(
+ bytes32 indexed requestId,
+ address coordinator,
+ address transmitter,
+ FunctionsResponse.FulfillResult resultCode
+ );
+
+ function test_Fulfill_RequestNotProcessedInvalidRequestId() public {
+ // Send as committed Coordinator
+ vm.stopPrank();
+ vm.startPrank(address(s_functionsCoordinator));
+
+ bytes memory response = bytes("hello world!");
+ bytes memory err = new bytes(0);
+ uint96 juelsPerGas = 0;
+ uint96 costWithoutCallback = 0;
+ address transmitter = NOP_TRANSMITTER_ADDRESS_1;
+ FunctionsResponse.Commitment memory commitment = s_requests[1].commitment;
+ // Modify request commitment to have a invalid requestId
+ bytes32 invalidRequestId = bytes32("this does not exist");
+ commitment.requestId = invalidRequestId;
+
+ // topic0 (function signature, always checked), NOT topic1 (false), NOT topic2 (false), NOT topic3 (false), and data (true).
+ bool checkTopic1 = false;
+ bool checkTopic2 = false;
+ bool checkTopic3 = false;
+ bool checkData = true;
+ vm.expectEmit(checkTopic1, checkTopic2, checkTopic3, checkData);
+ emit RequestNotProcessed({
+ requestId: s_requests[1].requestId,
+ coordinator: address(s_functionsCoordinator),
+ transmitter: NOP_TRANSMITTER_ADDRESS_1,
+ resultCode: FunctionsResponse.FulfillResult.INVALID_REQUEST_ID
+ });
+
+ (FunctionsResponse.FulfillResult resultCode, uint96 callbackGasCostJuels) = s_functionsRouter.fulfill(
+ response,
+ err,
+ juelsPerGas,
+ costWithoutCallback,
+ transmitter,
+ commitment
+ );
+
+ assertEq(uint(resultCode), uint(FunctionsResponse.FulfillResult.INVALID_REQUEST_ID));
+ assertEq(callbackGasCostJuels, 0);
+ }
+
+ function test_Fulfill_RequestNotProcessedInvalidCommitment() public {
+ // Send as committed Coordinator
+ vm.stopPrank();
+ vm.startPrank(address(s_functionsCoordinator));
+
+ bytes memory response = bytes("hello world!");
+ bytes memory err = new bytes(0);
+ uint96 juelsPerGas = 0;
+ uint96 costWithoutCallback = 0;
+ address transmitter = NOP_TRANSMITTER_ADDRESS_1;
+ FunctionsResponse.Commitment memory commitment = s_requests[1].commitment;
+ // Modify request commitment to have charge more than quoted
+ commitment.estimatedTotalCostJuels = 10 * JUELS_PER_LINK; // 10 LINK
+
+ // topic0 (function signature, always checked), NOT topic1 (false), NOT topic2 (false), NOT topic3 (false), and data (true).
+ bool checkTopic1 = false;
+ bool checkTopic2 = false;
+ bool checkTopic3 = false;
+ bool checkData = true;
+ vm.expectEmit(checkTopic1, checkTopic2, checkTopic3, checkData);
+ emit RequestNotProcessed({
+ requestId: s_requests[1].requestId,
+ coordinator: address(s_functionsCoordinator),
+ transmitter: NOP_TRANSMITTER_ADDRESS_1,
+ resultCode: FunctionsResponse.FulfillResult.INVALID_COMMITMENT
+ });
+
+ (FunctionsResponse.FulfillResult resultCode, uint96 callbackGasCostJuels) = s_functionsRouter.fulfill(
+ response,
+ err,
+ juelsPerGas,
+ costWithoutCallback,
+ transmitter,
+ commitment
+ );
+
+ assertEq(uint(resultCode), uint(FunctionsResponse.FulfillResult.INVALID_COMMITMENT));
+ assertEq(callbackGasCostJuels, 0);
+ }
+
+ function test_Fulfill_RequestNotProcessedInsufficientGas() public {
+ uint256 requestToFulfill = 1;
+
+ uint256[] memory requestNumberKeys = new uint256[](1);
+ requestNumberKeys[0] = requestToFulfill;
+
+ string[] memory results = new string[](1);
+ string memory response = "hello world!";
+ results[0] = response;
+
+ bytes[] memory errors = new bytes[](1);
+ bytes memory err = new bytes(0);
+ errors[0] = err;
+
+ uint32 callbackGasLimit = s_requests[requestToFulfill].requestData.callbackGasLimit;
+ // Coordinator sends enough gas that would get through callback and payment, but fail after
+ uint256 gasToUse = getCoordinatorConfig().gasOverheadBeforeCallback + callbackGasLimit + 100000;
+
+ // topic0 (function signature, always checked), topic1 (true), NOT topic2 (false), NOT topic3 (false), and data (true).
+ bool checkTopic1RequestId = true;
+ bool checkTopic2 = false;
+ bool checkTopic3 = false;
+ bool checkData = true;
+ vm.expectEmit(checkTopic1RequestId, checkTopic2, checkTopic3, checkData);
+ emit RequestNotProcessed({
+ requestId: s_requests[requestToFulfill].requestId,
+ coordinator: address(s_functionsCoordinator),
+ transmitter: NOP_TRANSMITTER_ADDRESS_1,
+ resultCode: FunctionsResponse.FulfillResult.INSUFFICIENT_GAS_PROVIDED
+ });
+
+ _reportAndStore(requestNumberKeys, results, errors, NOP_TRANSMITTER_ADDRESS_1, false, 1, gasToUse);
+ }
+
+ function test_Fulfill_RequestNotProcessedSubscriptionBalanceInvariant() public {
+ // Find the storage slot that the Subscription is on
+ vm.record();
+ s_functionsRouter.getSubscription(s_subscriptionId);
+ (bytes32[] memory reads, ) = vm.accesses(address(s_functionsRouter));
+ // The first read is from '_isExistingSubscription' which checks Subscription.owner on slot 0
+ // Slot 0 is shared with the Subscription.balance
+ uint256 slot = uint256(reads[0]);
+
+ // The request has already been initiated, forcibly lower the subscription's balance by clearing out slot 0
+ uint96 balance = 1;
+ address owner = address(0);
+ bytes32 data = bytes32(abi.encodePacked(balance, owner)); // TODO: make this more accurate
+ vm.store(address(s_functionsRouter), bytes32(uint256(slot)), data);
+
+ uint256 requestToFulfill = 1;
+
+ uint256[] memory requestNumberKeys = new uint256[](1);
+ requestNumberKeys[0] = requestToFulfill;
+
+ string[] memory results = new string[](1);
+ string memory response = "hello world!";
+ results[0] = response;
+
+ bytes[] memory errors = new bytes[](1);
+ bytes memory err = new bytes(0);
+ errors[0] = err;
+
+ // topic0 (function signature, always checked), topic1 (true), NOT topic2 (false), NOT topic3 (false), and data (true).
+ bool checkTopic1RequestId = true;
+ bool checkTopic2 = false;
+ bool checkTopic3 = false;
+ bool checkData = true;
+ vm.expectEmit(checkTopic1RequestId, checkTopic2, checkTopic3, checkData);
+ emit RequestNotProcessed({
+ requestId: s_requests[requestToFulfill].requestId,
+ coordinator: address(s_functionsCoordinator),
+ transmitter: NOP_TRANSMITTER_ADDRESS_1,
+ resultCode: FunctionsResponse.FulfillResult.SUBSCRIPTION_BALANCE_INVARIANT_VIOLATION
+ });
+
+ _reportAndStore(requestNumberKeys, results, errors, NOP_TRANSMITTER_ADDRESS_1, false);
+ }
+
+ function test_Fulfill_RequestNotProcessedCostExceedsCommitment() public {
+ // Use higher juelsPerGas than request time
+ // 10x the gas price
+ vm.txGasPrice(TX_GASPRICE_START * 10);
+
+ uint256 requestToFulfill = 1;
+
+ uint256[] memory requestNumberKeys = new uint256[](1);
+ requestNumberKeys[0] = requestToFulfill;
+
+ string[] memory results = new string[](1);
+ string memory response = "hello world!";
+ results[0] = response;
+
+ bytes[] memory errors = new bytes[](1);
+ bytes memory err = new bytes(0);
+ errors[0] = err;
+
+ // topic0 (function signature, always checked), topic1 (true), NOT topic2 (false), NOT topic3 (false), and data (true).
+ bool checkTopic1RequestId = true;
+ bool checkTopic2 = false;
+ bool checkTopic3 = false;
+ bool checkData = true;
+ vm.expectEmit(checkTopic1RequestId, checkTopic2, checkTopic3, checkData);
+ emit RequestNotProcessed({
+ requestId: s_requests[requestToFulfill].requestId,
+ coordinator: address(s_functionsCoordinator),
+ transmitter: NOP_TRANSMITTER_ADDRESS_1,
+ resultCode: FunctionsResponse.FulfillResult.COST_EXCEEDS_COMMITMENT
+ });
+
+ _reportAndStore(requestNumberKeys, results, errors, NOP_TRANSMITTER_ADDRESS_1, false);
+ }
+
+ event RequestProcessed(
+ bytes32 indexed requestId,
+ uint64 indexed subscriptionId,
+ uint96 totalCostJuels,
+ address transmitter,
+ FunctionsResponse.FulfillResult resultCode,
+ bytes response,
+ bytes err,
+ bytes callbackReturnData
+ );
+
+ FunctionsClientTestHelper internal s_clientWithFailingCallback;
+
+ function test_Fulfill_SuccessUserCallbackReverts() public {
+ // Deploy Client with failing callback
+ s_clientWithFailingCallback = new FunctionsClientTestHelper(address(s_functionsRouter));
+ s_clientWithFailingCallback.setRevertFulfillRequest(true);
+
+ // Add Client as a subscription consumer
+ s_functionsRouter.addConsumer(s_subscriptionId, address(s_clientWithFailingCallback));
+
+ // Send a minimal request
+ uint256 requestKey = 99;
+
+ string memory sourceCode = "return 'hello world';";
+ uint32 callbackGasLimit = 5500;
+
+ vm.recordLogs();
+ bytes32 requestId = s_clientWithFailingCallback.sendSimpleRequestWithJavaScript(
+ sourceCode,
+ s_subscriptionId,
+ s_donId,
+ callbackGasLimit
+ );
+
+ // Get commitment data from OracleRequest event log
+ Vm.Log[] memory entries = vm.getRecordedLogs();
+ (, , , , , , , FunctionsResponse.Commitment memory _commitment) = abi.decode(
+ entries[0].data,
+ (address, uint64, address, bytes, uint16, bytes32, uint64, FunctionsResponse.Commitment)
+ );
+
+ s_requests[requestKey] = Request({
+ requestData: RequestData({
+ sourceCode: sourceCode,
+ secrets: new bytes(0),
+ args: new string[](0),
+ bytesArgs: new bytes[](0),
+ callbackGasLimit: callbackGasLimit
+ }),
+ requestId: requestId,
+ commitment: _commitment
+ });
+
+ // Fulfill
+ uint256 requestToFulfill = requestKey;
+
+ uint256[] memory requestNumberKeys = new uint256[](1);
+ requestNumberKeys[0] = requestToFulfill;
+
+ string[] memory results = new string[](1);
+ string memory response = "hello world";
+ results[0] = response;
+
+ bytes[] memory errors = new bytes[](1);
+ bytes memory err = new bytes(0);
+ errors[0] = err;
+
+ // topic0 (function signature, always checked), topic1 (true), NOT topic2 (false), NOT topic3 (false), and data (true).
+ bool checkTopic1RequestId = false;
+ bool checkTopic2 = false;
+ bool checkTopic3 = false;
+ bool checkData = true;
+ vm.expectEmit(checkTopic1RequestId, checkTopic2, checkTopic3, checkData);
+ emit RequestProcessed({
+ requestId: requestId,
+ subscriptionId: s_subscriptionId,
+ totalCostJuels: _getExpectedCost(1379), // gasUsed is manually taken
+ transmitter: NOP_TRANSMITTER_ADDRESS_1,
+ resultCode: FunctionsResponse.FulfillResult.USER_CALLBACK_ERROR,
+ response: bytes(response),
+ err: err,
+ callbackReturnData: vm.parseBytes(
+ "0x08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000f61736b656420746f207265766572740000000000000000000000000000000000"
+ ) // TODO: build this programatically
+ });
+
+ _reportAndStore(requestNumberKeys, results, errors, NOP_TRANSMITTER_ADDRESS_1, true, 1);
+ }
+
+ function test_Fulfill_SuccessUserCallbackRunsOutOfGas() public {
+ // Send request #2 with no callback gas
+ string memory sourceCode = "return 'hello world';";
+ bytes memory secrets = new bytes(0);
+ string[] memory args = new string[](0);
+ bytes[] memory bytesArgs = new bytes[](0);
+ uint32 callbackGasLimit = 0;
+ _sendAndStoreRequest(2, sourceCode, secrets, args, bytesArgs, callbackGasLimit);
+
+ uint256 requestToFulfill = 2;
+
+ uint256[] memory requestNumberKeys = new uint256[](1);
+ requestNumberKeys[0] = requestToFulfill;
+
+ string[] memory results = new string[](1);
+ string memory response = "hello world!";
+ results[0] = response;
+
+ bytes[] memory errors = new bytes[](1);
+ bytes memory err = new bytes(0);
+ errors[0] = err;
+
+ // topic0 (function signature, always checked), topic1: request ID(true), NOT topic2 (false), NOT topic3 (false), and data (true).
+ vm.expectEmit(true, false, false, true);
+ emit RequestProcessed({
+ requestId: s_requests[requestToFulfill].requestId,
+ subscriptionId: s_subscriptionId,
+ totalCostJuels: _getExpectedCost(137), // gasUsed is manually taken
+ transmitter: NOP_TRANSMITTER_ADDRESS_1,
+ resultCode: FunctionsResponse.FulfillResult.USER_CALLBACK_ERROR,
+ response: bytes(response),
+ err: err,
+ callbackReturnData: new bytes(0)
+ });
+
+ _reportAndStore(requestNumberKeys, results, errors, NOP_TRANSMITTER_ADDRESS_1, true, 1);
+ }
+
+ function test_Fulfill_SuccessClientNoLongerExists() public {
+ // Delete the Client contract in the time between request and fulfillment
+ vm.etch(address(s_functionsClient), new bytes(0));
+
+ uint256 requestToFulfill = 1;
+
+ uint256[] memory requestNumberKeys = new uint256[](1);
+ requestNumberKeys[0] = requestToFulfill;
+
+ string[] memory results = new string[](1);
+ string memory response = "hello world!";
+ results[0] = response;
+
+ bytes[] memory errors = new bytes[](1);
+ bytes memory err = new bytes(0);
+ errors[0] = err;
+
+ // topic0 (function signature, always checked), topic1 (true), topic2 (true), NOT topic3 (false), and data (true).
+ bool checkTopic1RequestId = true;
+ bool checkTopic2SubscriptionId = true;
+ bool checkTopic3 = false;
+ bool checkData = true;
+ vm.expectEmit(checkTopic1RequestId, checkTopic2SubscriptionId, checkTopic3, checkData);
+ emit RequestProcessed({
+ requestId: s_requests[requestToFulfill].requestId,
+ subscriptionId: s_subscriptionId,
+ totalCostJuels: _getExpectedCost(0), // gasUsed is manually taken
+ transmitter: NOP_TRANSMITTER_ADDRESS_1,
+ resultCode: FunctionsResponse.FulfillResult.USER_CALLBACK_ERROR,
+ response: bytes(response),
+ err: err,
+ callbackReturnData: new bytes(0)
+ });
+
+ _reportAndStore(requestNumberKeys, results, errors, NOP_TRANSMITTER_ADDRESS_1, true, 1);
+ }
+
+ function test_Fulfill_SuccessFulfilled() public {
+ // Fulfill request 1
+ uint256 requestToFulfill = 1;
+
+ uint256[] memory requestNumberKeys = new uint256[](1);
+ requestNumberKeys[0] = requestToFulfill;
+ string[] memory results = new string[](1);
+ string memory response = "hello world!";
+ results[0] = response;
+ bytes[] memory errors = new bytes[](1);
+ bytes memory err = new bytes(0);
+ errors[0] = err;
+
+ // topic0 (function signature, always checked), topic1 (true), NOT topic2 (false), NOT topic3 (false), and data (true).
+ bool checkTopic1RequestId = true;
+ bool checkTopic2 = false;
+ bool checkTopic3 = false;
+ bool checkData = true;
+ vm.expectEmit(checkTopic1RequestId, checkTopic2, checkTopic3, checkData);
+ emit RequestProcessed({
+ requestId: s_requests[requestToFulfill].requestId,
+ subscriptionId: s_subscriptionId,
+ totalCostJuels: _getExpectedCost(5371), // gasUsed is manually taken
+ transmitter: NOP_TRANSMITTER_ADDRESS_1,
+ resultCode: FunctionsResponse.FulfillResult.FULFILLED,
+ response: bytes(response),
+ err: err,
+ callbackReturnData: new bytes(0)
+ });
+ _reportAndStore(requestNumberKeys, results, errors);
+ }
+}
+
+/// @notice #_callback
+contract FunctionsRouter__Callback is FunctionsRouterSetup {
+ // TODO: make contract internal function helper
+}
+
+/// @notice #getContractById
+contract FunctionsRouter_GetContractById is FunctionsRoutesSetup {
+ function test_GetContractById_RevertIfRouteDoesNotExist() public {
+ // Send as stranger
+ vm.stopPrank();
+ vm.startPrank(STRANGER_ADDRESS);
+
+ bytes32 invalidRouteId = bytes32("this does not exist");
+
+ vm.expectRevert(abi.encodeWithSelector(FunctionsRouter.RouteNotFound.selector, invalidRouteId));
+ s_functionsRouter.getContractById(invalidRouteId);
+ }
+
+ function test_GetContractById_SuccessIfRouteExists() public {
+ // Send as stranger
+ vm.stopPrank();
+ vm.startPrank(STRANGER_ADDRESS);
+
+ address routeDestination = s_functionsRouter.getContractById(s_donId);
+ assertEq(routeDestination, address(s_functionsCoordinator));
+ }
+}
+
+/// @notice #getProposedContractById
+contract FunctionsRouter_GetProposedContractById is FunctionsRoutesSetup {
+ FunctionsCoordinatorTestHelper internal s_functionsCoordinator2; // TODO: use actual FunctionsCoordinator instead of helper
+
+ function setUp() public virtual override {
+ FunctionsRoutesSetup.setUp();
+
+ // Deploy new Coordinator contract
+ s_functionsCoordinator2 = new FunctionsCoordinatorTestHelper(
+ address(s_functionsRouter),
+ getCoordinatorConfig(),
+ address(s_linkEthFeed)
+ );
+
+ // Propose new Coordinator contract
+ bytes32[] memory proposedContractSetIds = new bytes32[](1);
+ proposedContractSetIds[0] = s_donId;
+ address[] memory proposedContractSetAddresses = new address[](1);
+ proposedContractSetAddresses[0] = address(s_functionsCoordinator2);
+
+ s_functionsRouter.proposeContractsUpdate(proposedContractSetIds, proposedContractSetAddresses);
+ }
+
+ function test_GetProposedContractById_RevertIfRouteDoesNotExist() public {
+ // Send as stranger
+ vm.stopPrank();
+ vm.startPrank(STRANGER_ADDRESS);
+
+ bytes32 invalidRouteId = bytes32("this does not exist");
+
+ vm.expectRevert(abi.encodeWithSelector(FunctionsRouter.RouteNotFound.selector, invalidRouteId));
+ s_functionsRouter.getProposedContractById(invalidRouteId);
+ }
+
+ function test_GetProposedContractById_SuccessIfRouteExists() public {
+ // Send as stranger
+ vm.stopPrank();
+ vm.startPrank(STRANGER_ADDRESS);
+
+ address routeDestination = s_functionsRouter.getProposedContractById(s_donId);
+ assertEq(routeDestination, address(s_functionsCoordinator2));
+ }
+}
+
+/// @notice #getProposedContractSet
+contract FunctionsRouter_GetProposedContractSet is FunctionsRoutesSetup {
+ FunctionsCoordinatorTestHelper internal s_functionsCoordinator2; // TODO: use actual FunctionsCoordinator instead of helper
+ bytes32[] s_proposedContractSetIds;
+ address[] s_proposedContractSetAddresses;
+
+ function setUp() public virtual override {
+ FunctionsRoutesSetup.setUp();
+
+ // Deploy new Coordinator contract
+ s_functionsCoordinator2 = new FunctionsCoordinatorTestHelper(
+ address(s_functionsRouter),
+ getCoordinatorConfig(),
+ address(s_linkEthFeed)
+ );
+
+ // Propose new Coordinator contract
+ s_proposedContractSetIds = new bytes32[](1);
+ s_proposedContractSetIds[0] = s_donId;
+ s_proposedContractSetAddresses = new address[](1);
+ s_proposedContractSetAddresses[0] = address(s_functionsCoordinator2);
+
+ s_functionsRouter.proposeContractsUpdate(s_proposedContractSetIds, s_proposedContractSetAddresses);
+ }
+
+ function test_GetProposedContractSet_Success() public {
+ // Send as stranger
+ vm.stopPrank();
+ vm.startPrank(STRANGER_ADDRESS);
+
+ (bytes32[] memory proposedContractSetIds, address[] memory proposedContractSetAddresses) = s_functionsRouter
+ .getProposedContractSet();
+
+ assertEq(proposedContractSetIds.length, 1);
+ assertEq(proposedContractSetIds[0], s_donId);
+ assertEq(proposedContractSetIds.length, 1);
+ assertEq(proposedContractSetAddresses[0], address(s_functionsCoordinator2));
+ }
+}
+
+/// @notice #proposeContractsUpdate
+contract FunctionsRouter_ProposeContractsUpdate is FunctionsRoutesSetup {
+ FunctionsCoordinatorTestHelper internal s_functionsCoordinator2; // TODO: use actual FunctionsCoordinator instead of helper
+ bytes32[] s_proposedContractSetIds;
+ address[] s_proposedContractSetAddresses;
+
+ function setUp() public virtual override {
+ FunctionsRoutesSetup.setUp();
+
+ // Deploy new Coordinator contract
+ s_functionsCoordinator2 = new FunctionsCoordinatorTestHelper(
+ address(s_functionsRouter),
+ getCoordinatorConfig(),
+ address(s_linkEthFeed)
+ );
+
+ // Propose new Coordinator contract
+ s_proposedContractSetIds = new bytes32[](1);
+ s_proposedContractSetIds[0] = s_donId;
+ s_proposedContractSetAddresses = new address[](1);
+ s_proposedContractSetAddresses[0] = address(s_functionsCoordinator2);
+ }
+
+ function test_ProposeContractsUpdate_RevertIfNotOwner() public {
+ // Send as stranger
+ vm.stopPrank();
+ vm.startPrank(STRANGER_ADDRESS);
+
+ vm.expectRevert("Only callable by owner");
+ s_functionsRouter.proposeContractsUpdate(s_proposedContractSetIds, s_proposedContractSetAddresses);
+ }
+
+ function test_ProposeContractsUpdate_RevertIfLengthMismatch() public {
+ bytes32[] memory proposedContractSetIds = new bytes32[](1);
+ proposedContractSetIds[0] = s_donId;
+ address[] memory proposedContractSetAddresses = new address[](1);
+
+ vm.expectRevert(FunctionsRouter.InvalidProposal.selector);
+ s_functionsRouter.proposeContractsUpdate(proposedContractSetIds, proposedContractSetAddresses);
+ }
+
+ function test_ProposeContractsUpdate_RevertIfExceedsMaxProposal() public {
+ uint8 MAX_PROPOSAL_SET_LENGTH = 8;
+ uint8 INVALID_PROPOSAL_SET_LENGTH = MAX_PROPOSAL_SET_LENGTH + 1;
+
+ // Generate some mock data
+ bytes32[] memory proposedContractSetIds = new bytes32[](INVALID_PROPOSAL_SET_LENGTH);
+ for (uint256 i = 0; i < INVALID_PROPOSAL_SET_LENGTH; ++i) {
+ proposedContractSetIds[i] = bytes32(uint256(i + 111));
+ }
+ address[] memory proposedContractSetAddresses = new address[](INVALID_PROPOSAL_SET_LENGTH);
+ for (uint256 i = 0; i < INVALID_PROPOSAL_SET_LENGTH; ++i) {
+ proposedContractSetAddresses[i] = address(uint160(uint(keccak256(abi.encodePacked(i + 111)))));
+ }
+
+ vm.expectRevert(FunctionsRouter.InvalidProposal.selector);
+ s_functionsRouter.proposeContractsUpdate(proposedContractSetIds, proposedContractSetAddresses);
+ }
+
+ function test_ProposeContractsUpdate_RevertIfEmptyAddress() public {
+ bytes32[] memory proposedContractSetIds = new bytes32[](1);
+ proposedContractSetIds[0] = s_donId;
+ address[] memory proposedContractSetAddresses = new address[](1);
+ proposedContractSetAddresses[0] = address(0);
+
+ vm.expectRevert(FunctionsRouter.InvalidProposal.selector);
+ s_functionsRouter.proposeContractsUpdate(proposedContractSetIds, proposedContractSetAddresses);
+ }
+
+ function test_ProposeContractsUpdate_RevertIfNotNewContract() public {
+ bytes32[] memory proposedContractSetIds = new bytes32[](1);
+ proposedContractSetIds[0] = s_donId;
+ address[] memory proposedContractSetAddresses = new address[](1);
+ proposedContractSetAddresses[0] = address(s_functionsCoordinator);
+
+ vm.expectRevert(FunctionsRouter.InvalidProposal.selector);
+ s_functionsRouter.proposeContractsUpdate(proposedContractSetIds, proposedContractSetAddresses);
+ }
+
+ event ContractProposed(
+ bytes32 proposedContractSetId,
+ address proposedContractSetFromAddress,
+ address proposedContractSetToAddress
+ );
+
+ function test_ProposeContractsUpdate_Success() public {
+ // topic0 (function signature, always checked), NOT topic1 (false), NOT topic2 (false), NOT topic3 (false), and data (true).
+ bool checkTopic1 = false;
+ bool checkTopic2 = false;
+ bool checkTopic3 = false;
+ bool checkData = true;
+ vm.expectEmit(checkTopic1, checkTopic2, checkTopic3, checkData);
+ emit ContractProposed({
+ proposedContractSetId: s_proposedContractSetIds[0],
+ proposedContractSetFromAddress: address(s_functionsCoordinator),
+ proposedContractSetToAddress: s_proposedContractSetAddresses[0]
+ });
+
+ s_functionsRouter.proposeContractsUpdate(s_proposedContractSetIds, s_proposedContractSetAddresses);
+ }
+}
+
+/// @notice #updateContracts
+contract FunctionsRouter_UpdateContracts is FunctionsRoutesSetup {
+ FunctionsCoordinatorTestHelper internal s_functionsCoordinator2; // TODO: use actual FunctionsCoordinator instead of helper
+ bytes32[] s_proposedContractSetIds;
+ address[] s_proposedContractSetAddresses;
+
+ function setUp() public virtual override {
+ FunctionsRoutesSetup.setUp();
+
+ // Deploy new Coordinator contract
+ s_functionsCoordinator2 = new FunctionsCoordinatorTestHelper(
+ address(s_functionsRouter),
+ getCoordinatorConfig(),
+ address(s_linkEthFeed)
+ );
+
+ // Propose new Coordinator contract
+ s_proposedContractSetIds = new bytes32[](1);
+ s_proposedContractSetIds[0] = s_donId;
+ s_proposedContractSetAddresses = new address[](1);
+ s_proposedContractSetAddresses[0] = address(s_functionsCoordinator2);
+
+ s_functionsRouter.proposeContractsUpdate(s_proposedContractSetIds, s_proposedContractSetAddresses);
+ }
+
+ function test_UpdateContracts_RevertIfNotOwner() public {
+ // Send as stranger
+ vm.stopPrank();
+ vm.startPrank(STRANGER_ADDRESS);
+
+ vm.expectRevert("Only callable by owner");
+ s_functionsRouter.updateContracts();
+ }
+
+ event ContractUpdated(bytes32 id, address from, address to);
+
+ function test_UpdateContracts_Success() public {
+ // topic0 (function signature, always checked), NOT topic1 (false), NOT topic2 (false), NOT topic3 (false), and data (true).
+ bool checkTopic1 = false;
+ bool checkTopic2 = false;
+ bool checkTopic3 = false;
+ bool checkData = true;
+ vm.expectEmit(checkTopic1, checkTopic2, checkTopic3, checkData);
+ emit ContractUpdated({
+ id: s_proposedContractSetIds[0],
+ from: address(s_functionsCoordinator),
+ to: s_proposedContractSetAddresses[0]
+ });
+
+ s_functionsRouter.updateContracts();
+
+ (bytes32[] memory proposedContractSetIds, address[] memory proposedContractSetAddresses) = s_functionsRouter
+ .getProposedContractSet();
+
+ assertEq(proposedContractSetIds.length, 0);
+ assertEq(proposedContractSetAddresses.length, 0);
+ }
+}
+
+/// @notice #_whenNotPaused
+contract FunctionsRouter__WhenNotPaused is FunctionsRouterSetup {
+ // TODO: make contract internal function helper
+}
+
+/// @notice #_onlyRouterOwner
+contract FunctionsRouter__OnlyRouterOwner is FunctionsRouterSetup {
+ // TODO: make contract internal function helper
+}
+
+/// @notice #_onlySenderThatAcceptedToS
+contract FunctionsRouter__OnlySenderThatAcceptedToS is FunctionsRouterSetup {
+ // TODO: make contract internal function helper
+}
+
+/// @notice #pause
+contract FunctionsRouter_Pause is FunctionsRouterSetup {
+ function setUp() public virtual override {
+ FunctionsRouterSetup.setUp();
+ }
+
+ event Paused(address account);
+
+ function test_Pause_RevertIfNotOwner() public {
+ // Send as stranger
+ vm.stopPrank();
+ vm.startPrank(STRANGER_ADDRESS);
+
+ vm.expectRevert("Only callable by owner");
+ s_functionsRouter.pause();
+ }
+
+ function test_Pause_Success() public {
+ // topic0 (always checked), NOT topic1 (false), NOT topic2 (false), NOT topic3 (false), and data (true).
+ vm.expectEmit(false, false, false, true);
+ emit Paused(OWNER_ADDRESS);
+
+ s_functionsRouter.pause();
+
+ bool isPaused = s_functionsRouter.paused();
+ assertEq(isPaused, true);
+
+ vm.expectRevert("Pausable: paused");
+ s_functionsRouter.createSubscription();
+ }
+}
+
+/// @notice #unpause
+contract FunctionsRouter_Unpause is FunctionsRouterSetup {
+ function setUp() public virtual override {
+ FunctionsRouterSetup.setUp();
+ s_functionsRouter.pause();
+ }
+
+ event Unpaused(address account);
+
+ function test_Unpause_RevertIfNotOwner() public {
+ // Send as stranger
+ vm.stopPrank();
+ vm.startPrank(STRANGER_ADDRESS);
+
+ vm.expectRevert("Only callable by owner");
+ s_functionsRouter.unpause();
+ }
+
+ function test_Unpause_Success() public {
+ // topic0 (always checked), NOT topic1 (false), NOT topic2 (false), NOT topic3 (false), and data (true).
+ vm.expectEmit(false, false, false, true);
+ emit Unpaused(OWNER_ADDRESS);
+
+ s_functionsRouter.unpause();
+
+ bool isPaused = s_functionsRouter.paused();
+ assertEq(isPaused, false);
+
+ s_functionsRouter.createSubscription();
+ }
+}
diff --git a/contracts/src/v0.8/functions/tests/v1_0_0/FunctionsSubscriptions.t.sol b/contracts/src/v0.8/functions/tests/v1_0_0/FunctionsSubscriptions.t.sol
new file mode 100644
index 00000000000..ea5ec0dd683
--- /dev/null
+++ b/contracts/src/v0.8/functions/tests/v1_0_0/FunctionsSubscriptions.t.sol
@@ -0,0 +1,1263 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.19;
+
+import {BaseTest} from "./BaseTest.t.sol";
+import {FunctionsRouter} from "../../dev/v1_0_0/FunctionsRouter.sol";
+import {FunctionsSubscriptions} from "../../dev/v1_0_0/FunctionsSubscriptions.sol";
+import {FunctionsResponse} from "../../dev/v1_0_0/libraries/FunctionsResponse.sol";
+
+import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/IERC20.sol";
+
+import {FunctionsRouterSetup, FunctionsOwnerAcceptTermsOfServiceSetup, FunctionsClientSetup, FunctionsSubscriptionSetup, FunctionsClientRequestSetup, FunctionsFulfillmentSetup} from "./Setup.t.sol";
+
+import "forge-std/Vm.sol";
+
+// ================================================================
+// | Functions Subscriptions |
+// ================================================================
+
+contract FunctionsSubscriptions_Constructor_Helper is FunctionsSubscriptions {
+ constructor(address link) FunctionsSubscriptions(link) {}
+
+ function getLinkToken() public view returns (IERC20) {
+ return IERC20(i_linkToken);
+ }
+
+ // overrides
+ function _getMaxConsumers() internal pure override returns (uint16) {
+ return 0;
+ }
+
+ function _getSubscriptionDepositDetails() internal pure override returns (uint16, uint72) {
+ return (0, 0);
+ }
+
+ function _onlySenderThatAcceptedToS() internal override {}
+
+ function _onlyRouterOwner() internal override {}
+
+ function _whenNotPaused() internal override {}
+}
+
+/// @notice #constructor
+contract FunctionsSubscriptions_Constructor is BaseTest {
+ FunctionsSubscriptions_Constructor_Helper s_subscriptionsHelper;
+ address internal s_linkToken = 0x01BE23585060835E02B77ef475b0Cc51aA1e0709;
+
+ function setUp() public virtual override {
+ BaseTest.setUp();
+ s_subscriptionsHelper = new FunctionsSubscriptions_Constructor_Helper(s_linkToken);
+ }
+
+ function test_Constructor_Success() public {
+ assertEq(address(s_linkToken), address(s_subscriptionsHelper.getLinkToken()));
+ }
+}
+
+/// @notice #_markRequestInFlight
+contract FunctionsSubscriptions__MarkRequestInFlight {
+ // TODO: make contract internal function helper
+}
+
+/// @notice #_pay
+contract FunctionsSubscriptions__Pay {
+ // TODO: make contract internal function helper
+}
+
+/// @notice #ownerCancelSubscription
+contract FunctionsSubscriptions_OwnerCancelSubscription is FunctionsSubscriptionSetup {
+ function test_OwnerCancelSubscription_RevertIfNotOwner() public {
+ // Send as stranger
+ vm.stopPrank();
+ vm.startPrank(STRANGER_ADDRESS);
+
+ vm.expectRevert("Only callable by owner");
+ s_functionsRouter.ownerCancelSubscription(s_subscriptionId);
+ }
+
+ function test_OwnerCancelSubscription_RevertIfNoSubscription() public {
+ vm.expectRevert(FunctionsSubscriptions.InvalidSubscription.selector);
+ uint64 invalidSubscriptionId = 123456789;
+ s_functionsRouter.ownerCancelSubscription(invalidSubscriptionId);
+ }
+
+ function test_OwnerCancelSubscription_SuccessSubOwnerRefunded() public {
+ uint256 subscriptionOwnerBalanceBefore = s_linkToken.balanceOf(OWNER_ADDRESS);
+ s_functionsRouter.ownerCancelSubscription(s_subscriptionId);
+ uint256 subscriptionOwnerBalanceAfter = s_linkToken.balanceOf(OWNER_ADDRESS);
+ assertEq(subscriptionOwnerBalanceBefore + s_subscriptionInitialFunding, subscriptionOwnerBalanceAfter);
+ }
+
+ function test_OwnerCancelSubscription_SuccessWhenRequestInFlight() public {
+ // send request
+ string memory sourceCode = "return 'hello world';";
+ bytes memory secrets;
+ string[] memory args = new string[](0);
+ bytes[] memory bytesArgs = new bytes[](0);
+
+ s_functionsClient.sendRequest(s_donId, sourceCode, secrets, args, bytesArgs, s_subscriptionId, 5000);
+ s_functionsRouter.ownerCancelSubscription(s_subscriptionId);
+ }
+
+ function test_OwnerCancelSubscription_SuccessDeletesSubscription() public {
+ s_functionsRouter.ownerCancelSubscription(s_subscriptionId);
+ // Subscription should no longer exist
+ vm.expectRevert(FunctionsSubscriptions.InvalidSubscription.selector);
+ s_functionsRouter.getSubscription(s_subscriptionId);
+ }
+
+ event SubscriptionCanceled(uint64 indexed subscriptionId, address fundsRecipient, uint256 fundsAmount);
+
+ function test_OwnerCancelSubscription_Success() public {
+ uint256 subscriptionOwnerBalanceBefore = s_linkToken.balanceOf(OWNER_ADDRESS);
+
+ // topic0 (function signature, always checked), topic1 (true), NOT topic2 (false), NOT topic3 (false), and data (true).
+ bool checkTopic1SubscriptionId = true;
+ bool checkTopic2 = false;
+ bool checkTopic3 = false;
+ bool checkData = true;
+ vm.expectEmit(checkTopic1SubscriptionId, checkTopic2, checkTopic3, checkData);
+ emit SubscriptionCanceled(s_subscriptionId, OWNER_ADDRESS, s_subscriptionInitialFunding);
+
+ s_functionsRouter.ownerCancelSubscription(s_subscriptionId);
+
+ uint256 subscriptionOwnerBalanceAfter = s_linkToken.balanceOf(OWNER_ADDRESS);
+ assertEq(subscriptionOwnerBalanceBefore + s_subscriptionInitialFunding, subscriptionOwnerBalanceAfter);
+ }
+}
+
+/// @notice #recoverFunds
+contract FunctionsSubscriptions_RecoverFunds is FunctionsRouterSetup {
+ event FundsRecovered(address to, uint256 amount);
+
+ function test_RecoverFunds_Success() public {
+ uint256 fundsTransferred = 1 * 1e18; // 1 LINK
+ s_linkToken.transfer(address(s_functionsRouter), fundsTransferred);
+
+ // topic0 (function signature, always checked), NOT topic1 (false), NOT topic2 (false), NOT topic3 (false), and data (true).
+ bool checkTopic1 = false;
+ bool checkTopic2 = false;
+ bool checkTopic3 = false;
+ bool checkData = true;
+ vm.expectEmit(checkTopic1, checkTopic2, checkTopic3, checkData);
+ emit FundsRecovered(OWNER_ADDRESS, fundsTransferred);
+
+ uint256 subscriptionOwnerBalanceBefore = s_linkToken.balanceOf(OWNER_ADDRESS);
+ s_functionsRouter.recoverFunds(OWNER_ADDRESS);
+ uint256 subscriptionOwnerBalanceAfter = s_linkToken.balanceOf(OWNER_ADDRESS);
+ assertEq(subscriptionOwnerBalanceBefore + fundsTransferred, subscriptionOwnerBalanceAfter);
+ }
+
+ function test_OwnerCancelSubscription_RevertIfNotOwner() public {
+ // Send as stranger
+ vm.stopPrank();
+ vm.startPrank(STRANGER_ADDRESS);
+
+ vm.expectRevert("Only callable by owner");
+ s_functionsRouter.recoverFunds(OWNER_ADDRESS);
+ }
+}
+
+/// @notice #oracleWithdraw
+contract FunctionsSubscriptions_OracleWithdraw is FunctionsFulfillmentSetup {
+ function test_OracleWithdraw_RevertIfPaused() public {
+ s_functionsRouter.pause();
+
+ // Subscription payable balances are set to the Coordinator
+ // Send as Coordinator contract
+ vm.stopPrank();
+ vm.startPrank(address(s_functionsCoordinator));
+
+ vm.expectRevert("Pausable: paused");
+
+ uint96 amountToWithdraw = 1; // more than 0
+ s_functionsRouter.oracleWithdraw(NOP_TRANSMITTER_ADDRESS_1, amountToWithdraw);
+ }
+
+ function test_OracleWithdraw_RevertIfNoAmount() public {
+ // Subscription payable balances are set to the Coordinator
+ // Send as Coordinator contract
+ vm.stopPrank();
+ vm.startPrank(address(s_functionsCoordinator));
+
+ vm.expectRevert(FunctionsSubscriptions.InvalidCalldata.selector);
+
+ uint96 amountToWithdraw = 0;
+ s_functionsRouter.oracleWithdraw(NOP_TRANSMITTER_ADDRESS_1, amountToWithdraw);
+ }
+
+ function test_OracleWithdraw_RevertIfAmountMoreThanBalance() public {
+ // Subscription payable balances are set to the Coordinator
+ // Send as Coordinator contract
+ vm.stopPrank();
+ vm.startPrank(address(s_functionsCoordinator));
+
+ vm.expectRevert(
+ abi.encodeWithSelector(FunctionsSubscriptions.InsufficientBalance.selector, s_fulfillmentCoordinatorBalance)
+ );
+
+ uint96 amountToWithdraw = s_fulfillmentCoordinatorBalance + 1;
+ s_functionsRouter.oracleWithdraw(NOP_TRANSMITTER_ADDRESS_1, amountToWithdraw);
+ }
+
+ function test_OracleWithdraw_RevertIfBalanceInvariant() public {
+ // Subscription payable balances are set to the Coordinator
+ // Send as Coordinator contract
+ // vm.stopPrank();
+ // vm.startPrank(address(s_functionsCoordinator));
+ // TODO: Use internal function helper contract to modify s_totalLinkBalance
+ // uint96 amountToWithdraw = s_fulfillmentCoordinatorBalance;
+ // vm.expectRevert(abi.encodeWithSelector(FunctionsSubscriptions.TotalBalanceInvariantViolated.selector, 0, amountToWithdraw));
+ // s_functionsRouter.oracleWithdraw(NOP_TRANSMITTER_ADDRESS_1, amountToWithdraw);
+ }
+
+ function test_OracleWithdraw_SuccessPaysRecipient() public {
+ // Subscription payable balances are set to the Coordinator
+ // Send as Coordinator contract
+ vm.stopPrank();
+ vm.startPrank(address(s_functionsCoordinator));
+
+ uint256 transmitterBalanceBefore = s_linkToken.balanceOf(NOP_TRANSMITTER_ADDRESS_1);
+
+ uint96 amountToWithdraw = s_fulfillmentCoordinatorBalance;
+ s_functionsRouter.oracleWithdraw(NOP_TRANSMITTER_ADDRESS_1, amountToWithdraw);
+
+ uint256 transmitterBalanceAfter = s_linkToken.balanceOf(NOP_TRANSMITTER_ADDRESS_1);
+ assertEq(transmitterBalanceBefore + s_fulfillmentCoordinatorBalance, transmitterBalanceAfter);
+ }
+
+ function test_OracleWithdraw_SuccessSetsBalanceToZero() public {
+ // Subscription payable balances are set to the Coordinator
+ // Send as Coordinator contract
+ vm.stopPrank();
+ vm.startPrank(address(s_functionsCoordinator));
+
+ uint96 amountToWithdraw = s_fulfillmentCoordinatorBalance;
+ s_functionsRouter.oracleWithdraw(NOP_TRANSMITTER_ADDRESS_1, amountToWithdraw);
+
+ // Attempt to withdraw 1 Juel after withdrawing full balance
+ vm.expectRevert(abi.encodeWithSelector(FunctionsSubscriptions.InsufficientBalance.selector, 0));
+ s_functionsRouter.oracleWithdraw(NOP_TRANSMITTER_ADDRESS_1, 1);
+ }
+}
+
+/// @notice #ownerWithdraw
+contract FunctionsSubscriptions_OwnerWithdraw is FunctionsFulfillmentSetup {
+ function test_OwnerWithdraw_RevertIfNotOwner() public {
+ // Send as stranger
+ vm.stopPrank();
+ vm.startPrank(STRANGER_ADDRESS);
+
+ vm.expectRevert("Only callable by owner");
+ s_functionsRouter.recoverFunds(OWNER_ADDRESS);
+ }
+
+ function test_OwnerWithdraw_RevertIfAmountMoreThanBalance() public {
+ vm.expectRevert(
+ abi.encodeWithSelector(FunctionsSubscriptions.InsufficientBalance.selector, s_fulfillmentRouterOwnerBalance)
+ );
+
+ uint96 amountToWithdraw = s_fulfillmentRouterOwnerBalance + 1;
+ s_functionsRouter.ownerWithdraw(OWNER_ADDRESS, amountToWithdraw);
+ }
+
+ function test_OwnerWithdraw_RevertIfBalanceInvariant() public {
+ // TODO: Use internal function helper contract to modify s_totalLinkBalance
+ // uint96 amountToWithdraw = s_fulfillmentRouterOwnerBalance;
+ // vm.expectRevert(abi.encodeWithSelector(FunctionsSubscriptions.TotalBalanceInvariantViolated.selector, 0, amountToWithdraw));
+ // s_functionsRouter.ownerWithdraw(OWNER_ADDRESS, amountToWithdraw);
+ }
+
+ function test_OwnerWithdraw_SuccessIfNoAmount() public {
+ uint256 balanceBefore = s_linkToken.balanceOf(OWNER_ADDRESS);
+ uint96 amountToWithdraw = 0;
+ s_functionsRouter.ownerWithdraw(OWNER_ADDRESS, amountToWithdraw);
+ uint256 balanceAfter = s_linkToken.balanceOf(OWNER_ADDRESS);
+ assertEq(balanceBefore + s_fulfillmentRouterOwnerBalance, balanceAfter);
+ }
+
+ function test_OwnerWithdraw_SuccessPaysRecipient() public {
+ uint256 balanceBefore = s_linkToken.balanceOf(STRANGER_ADDRESS);
+
+ uint96 amountToWithdraw = s_fulfillmentRouterOwnerBalance;
+ s_functionsRouter.ownerWithdraw(STRANGER_ADDRESS, amountToWithdraw);
+
+ uint256 balanceAfter = s_linkToken.balanceOf(STRANGER_ADDRESS);
+ assertEq(balanceBefore + s_fulfillmentRouterOwnerBalance, balanceAfter);
+ }
+
+ function test_OwnerWithdraw_SuccessSetsBalanceToZero() public {
+ uint96 amountToWithdraw = s_fulfillmentRouterOwnerBalance;
+ s_functionsRouter.ownerWithdraw(OWNER_ADDRESS, amountToWithdraw);
+
+ // Attempt to withdraw 1 Juel after withdrawing full balance
+ vm.expectRevert(abi.encodeWithSelector(FunctionsSubscriptions.InsufficientBalance.selector, 0));
+ s_functionsRouter.ownerWithdraw(OWNER_ADDRESS, 1);
+ }
+}
+
+/// @notice #onTokenTransfer
+contract FunctionsSubscriptions_OnTokenTransfer is FunctionsSubscriptionSetup {
+ function test_OnTokenTransfer_RevertIfPaused() public {
+ s_functionsRouter.pause();
+ vm.expectRevert("Pausable: paused");
+ uint96 fundingAmount = 100;
+ s_linkToken.transferAndCall(address(s_functionsRouter), fundingAmount, abi.encode(s_subscriptionId));
+ }
+
+ function test_OnTokenTransfer_RevertIfCallerIsNotLink() public {
+ vm.expectRevert(FunctionsSubscriptions.OnlyCallableFromLink.selector);
+ uint96 fundingAmount = 100;
+ s_functionsRouter.onTokenTransfer(address(s_functionsRouter), fundingAmount, abi.encode(s_subscriptionId));
+ }
+
+ function test_OnTokenTransfer_RevertIfCallerIsNoCalldata() public {
+ vm.expectRevert(FunctionsSubscriptions.InvalidCalldata.selector);
+ uint96 fundingAmount = 100;
+ s_linkToken.transferAndCall(address(s_functionsRouter), fundingAmount, new bytes(0));
+ }
+
+ function test_OnTokenTransfer_RevertIfCallerIsNoSubscription() public {
+ vm.expectRevert(FunctionsSubscriptions.InvalidSubscription.selector);
+ uint96 fundingAmount = 100;
+ uint64 invalidSubscriptionId = 123456789;
+ s_linkToken.transferAndCall(address(s_functionsRouter), fundingAmount, abi.encode(invalidSubscriptionId));
+ }
+
+ function test_OnTokenTransfer_Success() public {
+ uint96 fundingAmount = 100;
+ uint96 subscriptionBalanceBefore = s_functionsRouter.getSubscription(s_subscriptionId).balance;
+ s_linkToken.transferAndCall(address(s_functionsRouter), fundingAmount, abi.encode(s_subscriptionId));
+ uint96 subscriptionBalanceAfter = s_functionsRouter.getSubscription(s_subscriptionId).balance;
+ assertEq(subscriptionBalanceBefore + fundingAmount, subscriptionBalanceAfter);
+ }
+}
+
+/// @notice #getTotalBalance
+contract FunctionsSubscriptions_GetTotalBalance is FunctionsSubscriptionSetup {
+ function test_GetTotalBalance_Success() public {
+ // Send as stranger
+ vm.stopPrank();
+ vm.startPrank(STRANGER_ADDRESS);
+
+ uint96 totalBalance = s_functionsRouter.getTotalBalance();
+ assertEq(totalBalance, s_subscriptionInitialFunding);
+ }
+}
+
+/// @notice #getSubscriptionCount
+contract FunctionsSubscriptions_GetSubscriptionCount is FunctionsSubscriptionSetup {
+ function test_GetSubscriptionCount_Success() public {
+ // Send as stranger
+ vm.stopPrank();
+ vm.startPrank(STRANGER_ADDRESS);
+
+ uint96 subscriptionCount = s_functionsRouter.getSubscriptionCount();
+ // One subscription was made during setup
+ assertEq(subscriptionCount, 1);
+ }
+}
+
+/// @notice #getSubscriptionsInRange
+contract FunctionsSubscriptions_GetSubscriptionsInRange is FunctionsSubscriptionSetup {
+ function setUp() public virtual override {
+ FunctionsSubscriptionSetup.setUp();
+
+ // Create 2 more subscriptions
+ /* uint64 subscriptionId2 = */ s_functionsRouter.createSubscription();
+ uint64 subscriptionId3 = s_functionsRouter.createSubscription();
+
+ // Give each one unique state
+ // #1 subscriptionId for requests, #2 empty, #3 proposedOwner of stranger
+ s_functionsRouter.proposeSubscriptionOwnerTransfer(subscriptionId3, STRANGER_ADDRESS);
+ }
+
+ function test_GetSubscriptionsInRange_RevertIfStartIsAfterEnd() public {
+ // Send as stranger
+ vm.stopPrank();
+ vm.startPrank(STRANGER_ADDRESS);
+
+ vm.expectRevert(FunctionsSubscriptions.InvalidCalldata.selector);
+
+ s_functionsRouter.getSubscriptionsInRange(1, 0);
+ }
+
+ function test_GetSubscriptionsInRange_RevertIfEndIsAfterLastSubscription() public {
+ // Send as stranger
+ vm.stopPrank();
+ vm.startPrank(STRANGER_ADDRESS);
+
+ uint64 lastSubscriptionId = s_functionsRouter.getSubscriptionCount();
+ vm.expectRevert(FunctionsSubscriptions.InvalidCalldata.selector);
+ s_functionsRouter.getSubscriptionsInRange(1, lastSubscriptionId + 1);
+ }
+
+ function test_GetSubscriptionsInRange_Success() public {
+ // Send as stranger
+ vm.stopPrank();
+ vm.startPrank(STRANGER_ADDRESS);
+
+ uint64 lastSubscriptionId = s_functionsRouter.getSubscriptionCount();
+ FunctionsSubscriptions.Subscription[] memory subscriptions = s_functionsRouter.getSubscriptionsInRange(
+ s_subscriptionId,
+ lastSubscriptionId
+ );
+
+ assertEq(subscriptions.length, 3);
+
+ // Check subscription 1
+ assertEq(subscriptions[0].balance, s_subscriptionInitialFunding);
+ assertEq(subscriptions[0].owner, OWNER_ADDRESS);
+ assertEq(subscriptions[0].blockedBalance, 0);
+ assertEq(subscriptions[0].proposedOwner, address(0));
+ assertEq(subscriptions[0].consumers[0], address(s_functionsClient));
+ assertEq(subscriptions[0].flags, bytes32(0));
+
+ // Check subscription 2
+ assertEq(subscriptions[1].balance, 0);
+ assertEq(subscriptions[1].owner, OWNER_ADDRESS);
+ assertEq(subscriptions[1].blockedBalance, 0);
+ assertEq(subscriptions[1].proposedOwner, address(0));
+ assertEq(subscriptions[1].consumers.length, 0);
+ assertEq(subscriptions[1].flags, bytes32(0));
+
+ // Check subscription 3
+ assertEq(subscriptions[2].balance, 0);
+ assertEq(subscriptions[2].owner, OWNER_ADDRESS);
+ assertEq(subscriptions[2].blockedBalance, 0);
+ assertEq(subscriptions[2].proposedOwner, address(STRANGER_ADDRESS));
+ assertEq(subscriptions[2].consumers.length, 0);
+ assertEq(subscriptions[2].flags, bytes32(0));
+ }
+}
+
+/// @notice #getSubscription
+contract FunctionsSubscriptions_GetSubscription is FunctionsSubscriptionSetup {
+ function test_GetSubscription_Success() public {
+ // Send as stranger
+ vm.stopPrank();
+ vm.startPrank(STRANGER_ADDRESS);
+
+ FunctionsSubscriptions.Subscription memory subscription = s_functionsRouter.getSubscription(s_subscriptionId);
+
+ assertEq(subscription.balance, s_subscriptionInitialFunding);
+ assertEq(subscription.owner, OWNER_ADDRESS);
+ assertEq(subscription.blockedBalance, 0);
+ assertEq(subscription.proposedOwner, address(0));
+ assertEq(subscription.consumers[0], address(s_functionsClient));
+ assertEq(subscription.flags, bytes32(0));
+ }
+}
+
+/// @notice #getConsumer
+contract FunctionsSubscriptions_GetConsumer is FunctionsSubscriptionSetup {
+ function test_GetConsumer_Success() public {
+ // Send as stranger
+ vm.stopPrank();
+ vm.startPrank(STRANGER_ADDRESS);
+
+ FunctionsSubscriptions.Consumer memory consumer = s_functionsRouter.getConsumer(
+ address(s_functionsClient),
+ s_subscriptionId
+ );
+
+ assertEq(consumer.allowed, true);
+ assertEq(consumer.initiatedRequests, 0);
+ assertEq(consumer.completedRequests, 0);
+ }
+}
+
+/// @notice #_isExistingSubscription
+contract FunctionsSubscriptions__IsExistingSubscription is FunctionsSubscriptionSetup {
+ // TODO: make contract internal function helper
+}
+
+/// @notice #_isAllowedConsumer
+contract FunctionsSubscriptions__IsAllowedConsumer {
+ // TODO: make contract internal function helper
+}
+
+/// @notice #createSubscription
+contract FunctionsSubscriptions_createSubscription is FunctionsOwnerAcceptTermsOfServiceSetup {
+ event SubscriptionCreated(uint64 indexed subscriptionId, address owner);
+
+ function test_CreateSubscription_Success() public {
+ // topic0 (function signature, always checked), topic1 (true), NOT topic2 (false), NOT topic3 (false), and data (true).
+ bool checkTopic1 = true;
+ bool checkTopic2 = false;
+ bool checkTopic3 = false;
+ bool checkData = true;
+
+ vm.expectEmit(checkTopic1, checkTopic2, checkTopic3, checkData);
+ emit SubscriptionCreated(1, OWNER_ADDRESS);
+ uint64 firstCallSubscriptionId = s_functionsRouter.createSubscription();
+ assertEq(firstCallSubscriptionId, 1);
+
+ vm.expectEmit(checkTopic1, checkTopic2, checkTopic3, checkData);
+ emit SubscriptionCreated(2, OWNER_ADDRESS);
+ uint64 secondCallSubscriptionId = s_functionsRouter.createSubscription();
+ assertEq(secondCallSubscriptionId, 2);
+
+ vm.expectEmit(checkTopic1, checkTopic2, checkTopic3, checkData);
+ emit SubscriptionCreated(3, OWNER_ADDRESS);
+ uint64 thirdCallSubscriptionId = s_functionsRouter.createSubscription();
+ assertEq(thirdCallSubscriptionId, 3);
+ }
+
+ function test_CreateSubscription_RevertIfPaused() public {
+ s_functionsRouter.pause();
+
+ vm.expectRevert("Pausable: paused");
+ s_functionsRouter.createSubscription();
+ }
+
+ function test_CreateSubscription_RevertIfNotAllowedSender() public {
+ // Send as stranger, who has not accepted Terms of Service
+ vm.stopPrank();
+ vm.startPrank(STRANGER_ADDRESS);
+
+ vm.expectRevert(abi.encodeWithSelector(FunctionsRouter.SenderMustAcceptTermsOfService.selector, STRANGER_ADDRESS));
+ s_functionsRouter.createSubscription();
+ }
+}
+
+/// @notice #createSubscriptionWithConsumer
+contract FunctionsSubscriptions_CreateSubscriptionWithConsumer is FunctionsClientSetup {
+ event SubscriptionCreated(uint64 indexed subscriptionId, address owner);
+ event SubscriptionConsumerAdded(uint64 indexed subscriptionId, address consumer);
+
+ function test_CreateSubscriptionWithConsumer_Success() public {
+ // topic0 (function signature, always checked), topic1 (true), NOT topic2 (false), NOT topic3 (false), and data (true).
+ bool checkTopic1 = true;
+ bool checkTopic2 = false;
+ bool checkTopic3 = false;
+ bool checkData = true;
+
+ vm.expectEmit(checkTopic1, checkTopic2, checkTopic3, checkData);
+ emit SubscriptionCreated(1, OWNER_ADDRESS);
+ vm.expectEmit(checkTopic1, checkTopic2, checkTopic3, checkData);
+ emit SubscriptionConsumerAdded(1, address(s_functionsClient));
+ uint64 firstCallSubscriptionId = s_functionsRouter.createSubscriptionWithConsumer(address(s_functionsClient));
+ assertEq(firstCallSubscriptionId, 1);
+ assertEq(s_functionsRouter.getSubscription(firstCallSubscriptionId).consumers[0], address(s_functionsClient));
+
+ vm.expectEmit(checkTopic1, checkTopic2, checkTopic3, checkData);
+ emit SubscriptionCreated(2, OWNER_ADDRESS);
+ vm.expectEmit(checkTopic1, checkTopic2, checkTopic3, checkData);
+ emit SubscriptionConsumerAdded(2, address(s_functionsClient));
+ uint64 secondCallSubscriptionId = s_functionsRouter.createSubscriptionWithConsumer(address(s_functionsClient));
+ assertEq(secondCallSubscriptionId, 2);
+ assertEq(s_functionsRouter.getSubscription(secondCallSubscriptionId).consumers[0], address(s_functionsClient));
+
+ vm.expectEmit(checkTopic1, checkTopic2, checkTopic3, checkData);
+ emit SubscriptionCreated(3, OWNER_ADDRESS);
+ vm.expectEmit(checkTopic1, checkTopic2, checkTopic3, checkData);
+ emit SubscriptionConsumerAdded(3, address(s_functionsClient));
+ uint64 thirdCallSubscriptionId = s_functionsRouter.createSubscriptionWithConsumer(address(s_functionsClient));
+ assertEq(thirdCallSubscriptionId, 3);
+ assertEq(s_functionsRouter.getSubscription(thirdCallSubscriptionId).consumers[0], address(s_functionsClient));
+ }
+
+ function test_CreateSubscriptionWithConsumer_RevertIfPaused() public {
+ s_functionsRouter.pause();
+
+ vm.expectRevert("Pausable: paused");
+ s_functionsRouter.createSubscriptionWithConsumer(address(s_functionsClient));
+ }
+
+ function test_CreateSubscriptionWithConsumer_RevertIfNotAllowedSender() public {
+ // Send as stranger, who has not accepted Terms of Service
+ vm.stopPrank();
+ vm.startPrank(STRANGER_ADDRESS);
+
+ vm.expectRevert(abi.encodeWithSelector(FunctionsRouter.SenderMustAcceptTermsOfService.selector, STRANGER_ADDRESS));
+ s_functionsRouter.createSubscriptionWithConsumer(address(s_functionsClient));
+ }
+}
+
+/// @notice #proposeSubscriptionOwnerTransfer
+contract FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer is FunctionsSubscriptionSetup {
+ uint256 internal NEW_OWNER_PRIVATE_KEY_WITH_TOS = 0x3;
+ address internal NEW_OWNER_ADDRESS_WITH_TOS = vm.addr(NEW_OWNER_PRIVATE_KEY_WITH_TOS);
+ uint256 internal NEW_OWNER_PRIVATE_KEY_WITHOUT_TOS = 0x4;
+ address internal NEW_OWNER_ADDRESS_WITHOUT_TOS = vm.addr(NEW_OWNER_PRIVATE_KEY_WITHOUT_TOS);
+
+ function setUp() public virtual override {
+ FunctionsSubscriptionSetup.setUp();
+
+ // Accept ToS as new owner
+ vm.stopPrank();
+ vm.startPrank(NEW_OWNER_ADDRESS_WITH_TOS);
+ bytes32 message = s_termsOfServiceAllowList.getMessage(NEW_OWNER_ADDRESS_WITH_TOS, NEW_OWNER_ADDRESS_WITH_TOS);
+ bytes32 prefixedMessage = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", message));
+ (uint8 v, bytes32 r, bytes32 s) = vm.sign(TOS_SIGNER_PRIVATE_KEY, prefixedMessage);
+ s_termsOfServiceAllowList.acceptTermsOfService(NEW_OWNER_ADDRESS_WITH_TOS, NEW_OWNER_ADDRESS_WITH_TOS, r, s, v);
+
+ vm.stopPrank();
+ vm.startPrank(OWNER_ADDRESS);
+ }
+
+ function test_ProposeSubscriptionOwnerTransfer_RevertIfPaused() public {
+ s_functionsRouter.pause();
+
+ vm.expectRevert("Pausable: paused");
+ s_functionsRouter.proposeSubscriptionOwnerTransfer(s_subscriptionId, NEW_OWNER_ADDRESS_WITH_TOS);
+ }
+
+ function test_ProposeSubscriptionOwnerTransfer_RevertIfNoSubscription() public {
+ vm.expectRevert(FunctionsSubscriptions.InvalidSubscription.selector);
+ uint64 invalidSubscriptionId = 123456789;
+ s_functionsRouter.proposeSubscriptionOwnerTransfer(invalidSubscriptionId, NEW_OWNER_ADDRESS_WITH_TOS);
+ }
+
+ function test_ProposeSubscriptionOwnerTransfer_RevertIfNotSubscriptionOwner() public {
+ // Send as non-owner, who has accepted Terms of Service
+ vm.stopPrank();
+ vm.startPrank(NEW_OWNER_ADDRESS_WITH_TOS);
+
+ vm.expectRevert(FunctionsSubscriptions.MustBeSubscriptionOwner.selector);
+ s_functionsRouter.proposeSubscriptionOwnerTransfer(s_subscriptionId, NEW_OWNER_ADDRESS_WITH_TOS);
+ }
+
+ function test_ProposeSubscriptionOwnerTransfer_RevertIfNotAllowedSender() public {
+ // Remove owner from Allow List
+ s_termsOfServiceAllowList.blockSender(OWNER_ADDRESS);
+
+ vm.expectRevert(abi.encodeWithSelector(FunctionsRouter.SenderMustAcceptTermsOfService.selector, OWNER_ADDRESS));
+ s_functionsRouter.proposeSubscriptionOwnerTransfer(s_subscriptionId, NEW_OWNER_ADDRESS_WITH_TOS);
+ }
+
+ function test_ProposeSubscriptionOwnerTransfer_RevertIfEmptyNewOwner() public {
+ address EMPTY_ADDRESS = address(0);
+ vm.expectRevert(FunctionsSubscriptions.InvalidCalldata.selector);
+ s_functionsRouter.proposeSubscriptionOwnerTransfer(s_subscriptionId, EMPTY_ADDRESS);
+ }
+
+ function test_ProposeSubscriptionOwnerTransfer_RevertIfInvalidNewOwner() public {
+ s_functionsRouter.proposeSubscriptionOwnerTransfer(s_subscriptionId, NEW_OWNER_ADDRESS_WITH_TOS);
+ vm.expectRevert(FunctionsSubscriptions.InvalidCalldata.selector);
+ s_functionsRouter.proposeSubscriptionOwnerTransfer(s_subscriptionId, NEW_OWNER_ADDRESS_WITH_TOS);
+ }
+
+ event SubscriptionOwnerTransferRequested(uint64 indexed subscriptionId, address from, address to);
+
+ function test_ProposeSubscriptionOwnerTransfer_Success() public {
+ // topic0 (function signature, always checked), topic1 (true), NOT topic2 (false), NOT topic3 (false), and data (true).
+ bool checkTopic1 = true;
+ bool checkTopic2 = false;
+ bool checkTopic3 = false;
+ bool checkData = true;
+
+ vm.expectEmit(checkTopic1, checkTopic2, checkTopic3, checkData);
+ emit SubscriptionOwnerTransferRequested(s_subscriptionId, OWNER_ADDRESS, NEW_OWNER_ADDRESS_WITH_TOS);
+ s_functionsRouter.proposeSubscriptionOwnerTransfer(s_subscriptionId, NEW_OWNER_ADDRESS_WITH_TOS);
+ assertEq(s_functionsRouter.getSubscription(s_subscriptionId).proposedOwner, NEW_OWNER_ADDRESS_WITH_TOS);
+ }
+}
+
+/// @notice #acceptSubscriptionOwnerTransfer
+contract FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer is FunctionsSubscriptionSetup {
+ uint256 internal NEW_OWNER_PRIVATE_KEY_WITH_TOS = 0x3;
+ address internal NEW_OWNER_ADDRESS_WITH_TOS = vm.addr(NEW_OWNER_PRIVATE_KEY_WITH_TOS);
+ uint256 internal NEW_OWNER_PRIVATE_KEY_WITHOUT_TOS = 0x4;
+ address internal NEW_OWNER_ADDRESS_WITHOUT_TOS = vm.addr(NEW_OWNER_PRIVATE_KEY_WITHOUT_TOS);
+
+ function setUp() public virtual override {
+ FunctionsSubscriptionSetup.setUp();
+
+ // Accept ToS as new owner
+ vm.stopPrank();
+ vm.startPrank(NEW_OWNER_ADDRESS_WITH_TOS);
+ bytes32 message = s_termsOfServiceAllowList.getMessage(NEW_OWNER_ADDRESS_WITH_TOS, NEW_OWNER_ADDRESS_WITH_TOS);
+ bytes32 prefixedMessage = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", message));
+ (uint8 v, bytes32 r, bytes32 s) = vm.sign(TOS_SIGNER_PRIVATE_KEY, prefixedMessage);
+ s_termsOfServiceAllowList.acceptTermsOfService(NEW_OWNER_ADDRESS_WITH_TOS, NEW_OWNER_ADDRESS_WITH_TOS, r, s, v);
+
+ vm.stopPrank();
+ vm.startPrank(OWNER_ADDRESS);
+ }
+
+ function test_AcceptSubscriptionOwnerTransfer_RevertIfPaused() public {
+ s_functionsRouter.proposeSubscriptionOwnerTransfer(s_subscriptionId, NEW_OWNER_ADDRESS_WITH_TOS);
+ s_functionsRouter.pause();
+
+ // Send as new owner, who has accepted Terms of Service
+ vm.stopPrank();
+ vm.startPrank(NEW_OWNER_ADDRESS_WITH_TOS);
+
+ vm.expectRevert("Pausable: paused");
+ s_functionsRouter.acceptSubscriptionOwnerTransfer(s_subscriptionId);
+ }
+
+ function test_AcceptSubscriptionOwnerTransfer_RevertIfNotAllowedSender() public {
+ s_functionsRouter.proposeSubscriptionOwnerTransfer(s_subscriptionId, NEW_OWNER_ADDRESS_WITHOUT_TOS);
+
+ // Send as new owner, who has NOT accepted Terms of Service
+ vm.stopPrank();
+ vm.startPrank(NEW_OWNER_ADDRESS_WITHOUT_TOS);
+
+ vm.expectRevert(
+ abi.encodeWithSelector(FunctionsRouter.SenderMustAcceptTermsOfService.selector, NEW_OWNER_ADDRESS_WITHOUT_TOS)
+ );
+ s_functionsRouter.acceptSubscriptionOwnerTransfer(s_subscriptionId);
+ }
+
+ function test_AcceptSubscriptionOwnerTransfer_RevertIfSenderBecomesBlocked() public {
+ // Propose an address that is allowed to accept ownership
+ s_functionsRouter.proposeSubscriptionOwnerTransfer(s_subscriptionId, NEW_OWNER_ADDRESS_WITH_TOS);
+ bool hasAccess = s_termsOfServiceAllowList.hasAccess(NEW_OWNER_ADDRESS_WITH_TOS, new bytes(0));
+ assertEq(hasAccess, true);
+
+ // Revoke access
+ s_termsOfServiceAllowList.blockSender(NEW_OWNER_ADDRESS_WITH_TOS);
+
+ // Send as blocked address
+ vm.stopPrank();
+ vm.startPrank(NEW_OWNER_ADDRESS_WITH_TOS);
+
+ vm.expectRevert(
+ abi.encodeWithSelector(FunctionsRouter.SenderMustAcceptTermsOfService.selector, NEW_OWNER_ADDRESS_WITH_TOS)
+ );
+ s_functionsRouter.acceptSubscriptionOwnerTransfer(s_subscriptionId);
+ }
+
+ function test_AcceptSubscriptionOwnerTransfer_RevertIfSenderIsNotNewOwner() public {
+ s_functionsRouter.proposeSubscriptionOwnerTransfer(s_subscriptionId, STRANGER_ADDRESS);
+
+ // Send as someone who is not hte proposed new owner
+ vm.stopPrank();
+ vm.startPrank(NEW_OWNER_ADDRESS_WITH_TOS);
+
+ vm.expectRevert(abi.encodeWithSelector(FunctionsSubscriptions.MustBeProposedOwner.selector, STRANGER_ADDRESS));
+ s_functionsRouter.acceptSubscriptionOwnerTransfer(s_subscriptionId);
+ }
+
+ event SubscriptionOwnerTransferred(uint64 indexed subscriptionId, address from, address to);
+
+ function test_AcceptSubscriptionOwnerTransfer_Success() public {
+ s_functionsRouter.proposeSubscriptionOwnerTransfer(s_subscriptionId, NEW_OWNER_ADDRESS_WITH_TOS);
+
+ // Send as new owner, who has accepted Terms of Service
+ vm.stopPrank();
+ vm.startPrank(NEW_OWNER_ADDRESS_WITH_TOS);
+
+ // topic0 (function signature, always checked), NOT topic1 (false), NOT topic2 (false), NOT topic3 (false), and data (true).
+ bool checkTopic1 = false;
+ bool checkTopic2 = false;
+ bool checkTopic3 = false;
+ bool checkData = true;
+ vm.expectEmit(checkTopic1, checkTopic2, checkTopic3, checkData);
+ emit SubscriptionOwnerTransferred(s_subscriptionId, OWNER_ADDRESS, NEW_OWNER_ADDRESS_WITH_TOS);
+
+ s_functionsRouter.acceptSubscriptionOwnerTransfer(s_subscriptionId);
+
+ FunctionsSubscriptions.Subscription memory subscription = s_functionsRouter.getSubscription(s_subscriptionId);
+ assertEq(subscription.owner, NEW_OWNER_ADDRESS_WITH_TOS);
+ assertEq(subscription.proposedOwner, address(0));
+ }
+}
+
+/// @notice #removeConsumer
+contract FunctionsSubscriptions_RemoveConsumer is FunctionsSubscriptionSetup {
+ function test_RemoveConsumer_RevertIfPaused() public {
+ s_functionsRouter.pause();
+
+ vm.expectRevert("Pausable: paused");
+ s_functionsRouter.removeConsumer(s_subscriptionId, address(s_functionsClient));
+ }
+
+ function test_RemoveConsumer_RevertIfNoSubscription() public {
+ vm.expectRevert(FunctionsSubscriptions.InvalidSubscription.selector);
+ uint64 invalidSubscriptionId = 123456789;
+ s_functionsRouter.removeConsumer(invalidSubscriptionId, address(s_functionsClient));
+ }
+
+ function test_RemoveConsumer_RevertIfNotSubscriptionOwner() public {
+ // Accept ToS as stranger
+ vm.stopPrank();
+ vm.startPrank(STRANGER_ADDRESS);
+ bytes32 message = s_termsOfServiceAllowList.getMessage(STRANGER_ADDRESS, STRANGER_ADDRESS);
+ bytes32 prefixedMessage = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", message));
+ (uint8 v, bytes32 r, bytes32 s) = vm.sign(TOS_SIGNER_PRIVATE_KEY, prefixedMessage);
+ s_termsOfServiceAllowList.acceptTermsOfService(STRANGER_ADDRESS, STRANGER_ADDRESS, r, s, v);
+
+ // Send as non-subscription owner, who has accepted Terms of Service
+ vm.stopPrank();
+ vm.startPrank(STRANGER_ADDRESS);
+
+ vm.expectRevert(FunctionsSubscriptions.MustBeSubscriptionOwner.selector);
+ s_functionsRouter.removeConsumer(s_subscriptionId, address(s_functionsClient));
+ }
+
+ function test_RemoveConsumer_RevertIfNotAllowedSender() public {
+ // Remove owner from Allow List
+ s_termsOfServiceAllowList.blockSender(OWNER_ADDRESS);
+
+ vm.expectRevert(abi.encodeWithSelector(FunctionsRouter.SenderMustAcceptTermsOfService.selector, OWNER_ADDRESS));
+ s_functionsRouter.removeConsumer(s_subscriptionId, address(s_functionsClient));
+ }
+
+ function test_RemoveConsumer_RevertIfInvalidConsumer() public {
+ vm.expectRevert(FunctionsSubscriptions.InvalidConsumer.selector);
+ s_functionsRouter.removeConsumer(s_subscriptionId, address(0));
+ }
+
+ function test_RemoveConsumer_RevertIfPendingRequests() public {
+ // Send a minimal request
+ string memory sourceCode = "return 'hello world';";
+ bytes memory secrets;
+ string[] memory args = new string[](0);
+ bytes[] memory bytesArgs = new bytes[](0);
+
+ s_functionsClient.sendRequest(s_donId, sourceCode, secrets, args, bytesArgs, s_subscriptionId, 5000);
+
+ vm.expectRevert(FunctionsSubscriptions.CannotRemoveWithPendingRequests.selector);
+ s_functionsRouter.removeConsumer(s_subscriptionId, address(s_functionsClient));
+ }
+
+ event SubscriptionConsumerRemoved(uint64 indexed subscriptionId, address consumer);
+
+ function test_RemoveConsumer_Success() public {
+ // topic0 (function signature, always checked), NOT topic1 (false), NOT topic2 (false), NOT topic3 (false), and data (true).
+ bool checkTopic1 = false;
+ bool checkTopic2 = false;
+ bool checkTopic3 = false;
+ bool checkData = true;
+ vm.expectEmit(checkTopic1, checkTopic2, checkTopic3, checkData);
+ emit SubscriptionConsumerRemoved(s_subscriptionId, address(s_functionsClient));
+ s_functionsRouter.removeConsumer(s_subscriptionId, address(s_functionsClient));
+
+ FunctionsSubscriptions.Subscription memory subscription = s_functionsRouter.getSubscription(s_subscriptionId);
+ assertEq(subscription.consumers, new address[](0));
+ }
+}
+
+/// @notice #_getMaxConsumers
+contract FunctionsSubscriptions__GetMaxConsumers is FunctionsRouterSetup {
+ // TODO: make contract internal function helper
+}
+
+/// @notice #addConsumer
+contract FunctionsSubscriptions_AddConsumer is FunctionsSubscriptionSetup {
+ function test_AddConsumer_RevertIfPaused() public {
+ s_functionsRouter.pause();
+
+ vm.expectRevert("Pausable: paused");
+ s_functionsRouter.addConsumer(s_subscriptionId, address(1));
+ }
+
+ function test_AddConsumer_RevertIfNoSubscription() public {
+ vm.expectRevert(FunctionsSubscriptions.InvalidSubscription.selector);
+ uint64 invalidSubscriptionId = 123456789;
+ s_functionsRouter.addConsumer(invalidSubscriptionId, address(1));
+ }
+
+ function test_AddConsumer_RevertIfNotSubscriptionOwner() public {
+ // Accept ToS as stranger
+ vm.stopPrank();
+ vm.startPrank(STRANGER_ADDRESS);
+ bytes32 message = s_termsOfServiceAllowList.getMessage(STRANGER_ADDRESS, STRANGER_ADDRESS);
+ bytes32 prefixedMessage = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", message));
+ (uint8 v, bytes32 r, bytes32 s) = vm.sign(TOS_SIGNER_PRIVATE_KEY, prefixedMessage);
+ s_termsOfServiceAllowList.acceptTermsOfService(STRANGER_ADDRESS, STRANGER_ADDRESS, r, s, v);
+
+ // Send as non-subscription owner, who has accepted Terms of Service
+ vm.stopPrank();
+ vm.startPrank(STRANGER_ADDRESS);
+
+ vm.expectRevert(FunctionsSubscriptions.MustBeSubscriptionOwner.selector);
+ s_functionsRouter.addConsumer(s_subscriptionId, address(1));
+ }
+
+ function test_AddConsumer_RevertIfNotAllowedSender() public {
+ // Remove owner from Allow List
+ s_termsOfServiceAllowList.blockSender(OWNER_ADDRESS);
+
+ vm.expectRevert(abi.encodeWithSelector(FunctionsRouter.SenderMustAcceptTermsOfService.selector, OWNER_ADDRESS));
+ s_functionsRouter.addConsumer(s_subscriptionId, address(1));
+ }
+
+ function test_AddConsumer_RevertIfMaximumConsumers() public {
+ // Fill Consumers to s_maxConsumersPerSubscription
+ // Already has one from setup
+ s_functionsRouter.addConsumer(s_subscriptionId, address(1));
+ s_functionsRouter.addConsumer(s_subscriptionId, address(2));
+
+ vm.expectRevert(
+ abi.encodeWithSelector(FunctionsSubscriptions.TooManyConsumers.selector, s_maxConsumersPerSubscription)
+ );
+ s_functionsRouter.addConsumer(s_subscriptionId, address(3));
+ }
+
+ function test_AddConsumer_RevertIfMaximumConsumersAfterConfigUpdate() public {
+ // Fill Consumers to s_maxConsumersPerSubscription
+ // Already has one from setup
+ s_functionsRouter.addConsumer(s_subscriptionId, address(1));
+ s_functionsRouter.addConsumer(s_subscriptionId, address(2));
+
+ // Lower maxConsumersPerSubscription
+ s_maxConsumersPerSubscription = 1;
+ FunctionsRouter.Config memory newRouterConfig = getRouterConfig();
+ s_functionsRouter.updateConfig(newRouterConfig);
+
+ // .AddConsumer should still revert
+ vm.expectRevert(
+ abi.encodeWithSelector(FunctionsSubscriptions.TooManyConsumers.selector, s_maxConsumersPerSubscription)
+ );
+ s_functionsRouter.addConsumer(s_subscriptionId, address(3));
+ }
+
+ event SubscriptionConsumerAdded(uint64 indexed subscriptionId, address consumer);
+
+ function test_AddConsumer_Success() public {
+ // topic0 (function signature, always checked), NOT topic1 (false), NOT topic2 (false), NOT topic3 (false), and data (true).
+ bool checkTopic1 = false;
+ bool checkTopic2 = false;
+ bool checkTopic3 = false;
+ bool checkData = true;
+ vm.expectEmit(checkTopic1, checkTopic2, checkTopic3, checkData);
+ emit SubscriptionConsumerAdded(s_subscriptionId, address(1));
+ s_functionsRouter.addConsumer(s_subscriptionId, address(1));
+
+ FunctionsSubscriptions.Subscription memory subscription = s_functionsRouter.getSubscription(s_subscriptionId);
+ assertEq(subscription.consumers[1], address(1));
+ FunctionsSubscriptions.Consumer memory consumer = s_functionsRouter.getConsumer(address(1), s_subscriptionId);
+ assertEq(consumer.allowed, true);
+ }
+}
+
+/// @notice #cancelSubscription
+contract FunctionsSubscriptions_CancelSubscription is FunctionsSubscriptionSetup {
+ function test_CancelSubscription_RevertIfPaused() public {
+ s_functionsRouter.pause();
+
+ vm.expectRevert("Pausable: paused");
+ s_functionsRouter.cancelSubscription(s_subscriptionId, OWNER_ADDRESS);
+ }
+
+ function test_CancelSubscription_RevertIfNoSubscription() public {
+ vm.expectRevert(FunctionsSubscriptions.InvalidSubscription.selector);
+ uint64 invalidSubscriptionId = 123456789;
+ s_functionsRouter.cancelSubscription(invalidSubscriptionId, OWNER_ADDRESS);
+ }
+
+ function test_CancelSubscription_RevertIfNotSubscriptionOwner() public {
+ // Accept ToS as stranger
+ vm.stopPrank();
+ vm.startPrank(STRANGER_ADDRESS);
+ bytes32 message = s_termsOfServiceAllowList.getMessage(STRANGER_ADDRESS, STRANGER_ADDRESS);
+ bytes32 prefixedMessage = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", message));
+ (uint8 v, bytes32 r, bytes32 s) = vm.sign(TOS_SIGNER_PRIVATE_KEY, prefixedMessage);
+ s_termsOfServiceAllowList.acceptTermsOfService(STRANGER_ADDRESS, STRANGER_ADDRESS, r, s, v);
+
+ // Send as non-subscription owner, who has accepted Terms of Service
+ vm.stopPrank();
+ vm.startPrank(STRANGER_ADDRESS);
+
+ vm.expectRevert(FunctionsSubscriptions.MustBeSubscriptionOwner.selector);
+ s_functionsRouter.cancelSubscription(s_subscriptionId, OWNER_ADDRESS);
+ }
+
+ function test_CancelSubscription_RevertIfNotAllowedSender() public {
+ // Remove owner from Allow List
+ s_termsOfServiceAllowList.blockSender(OWNER_ADDRESS);
+
+ vm.expectRevert(abi.encodeWithSelector(FunctionsRouter.SenderMustAcceptTermsOfService.selector, OWNER_ADDRESS));
+ s_functionsRouter.cancelSubscription(s_subscriptionId, OWNER_ADDRESS);
+ }
+
+ function test_CancelSubscription_RevertIfPendingRequests() public {
+ // Send a minimal request
+ string memory sourceCode = "return 'hello world';";
+ bytes memory secrets;
+ string[] memory args = new string[](0);
+ bytes[] memory bytesArgs = new bytes[](0);
+
+ s_functionsClient.sendRequest(s_donId, sourceCode, secrets, args, bytesArgs, s_subscriptionId, 5000);
+
+ vm.expectRevert(FunctionsSubscriptions.CannotRemoveWithPendingRequests.selector);
+ s_functionsRouter.cancelSubscription(s_subscriptionId, OWNER_ADDRESS);
+ }
+
+ event SubscriptionCanceled(uint64 indexed subscriptionId, address fundsRecipient, uint256 fundsAmount);
+
+ function test_CancelSubscription_SuccessForfeitAllBalanceAsDeposit() public {
+ // No requests have been completed
+ assertEq(s_functionsRouter.getConsumer(address(s_functionsClient), s_subscriptionId).completedRequests, 0);
+ // Subscription balance is less than deposit amount
+ assertLe(s_functionsRouter.getSubscription(s_subscriptionId).balance, s_subscriptionDepositJuels);
+
+ uint256 subscriptionOwnerBalanceBefore = s_linkToken.balanceOf(OWNER_ADDRESS);
+
+ uint96 expectedRefund = 0;
+
+ // topic0 (function signature, always checked), NOT topic1 (false), NOT topic2 (false), NOT topic3 (false), and data (true).
+ bool checkTopic1 = false;
+ bool checkTopic2 = false;
+ bool checkTopic3 = false;
+ bool checkData = true;
+ vm.expectEmit(checkTopic1, checkTopic2, checkTopic3, checkData);
+ emit SubscriptionCanceled(s_subscriptionId, OWNER_ADDRESS, expectedRefund);
+
+ s_functionsRouter.cancelSubscription(s_subscriptionId, OWNER_ADDRESS);
+
+ uint256 subscriptionOwnerBalanceAfter = s_linkToken.balanceOf(OWNER_ADDRESS);
+ assertEq(subscriptionOwnerBalanceBefore + expectedRefund, subscriptionOwnerBalanceAfter);
+
+ // Subscription should no longer exist
+ vm.expectRevert(FunctionsSubscriptions.InvalidSubscription.selector);
+ s_functionsRouter.getSubscription(s_subscriptionId);
+
+ // Router owner should have expectedDepositWithheld to withdraw
+ uint96 expectedDepositWithheld = s_subscriptionInitialFunding;
+ uint256 balanceBeforeWithdraw = s_linkToken.balanceOf(STRANGER_ADDRESS);
+ s_functionsRouter.ownerWithdraw(STRANGER_ADDRESS, 0);
+ uint256 balanceAfterWithdraw = s_linkToken.balanceOf(STRANGER_ADDRESS);
+ assertEq(balanceBeforeWithdraw + expectedDepositWithheld, balanceAfterWithdraw);
+ }
+
+ function test_CancelSubscription_SuccessForfeitSomeBalanceAsDeposit() public {
+ // No requests have been completed
+ assertEq(s_functionsRouter.getConsumer(address(s_functionsClient), s_subscriptionId).completedRequests, 0);
+ // Subscription balance is more than deposit amount, double fund the subscription
+ s_linkToken.transferAndCall(address(s_functionsRouter), s_subscriptionInitialFunding, abi.encode(s_subscriptionId));
+ assertGe(s_functionsRouter.getSubscription(s_subscriptionId).balance, s_subscriptionDepositJuels);
+
+ uint256 subscriptionOwnerBalanceBefore = s_linkToken.balanceOf(OWNER_ADDRESS);
+
+ uint96 expectedRefund = (s_subscriptionInitialFunding * 2) - s_subscriptionDepositJuels;
+ // topic0 (function signature, always checked), NOT topic1 (false), NOT topic2 (false), NOT topic3 (false), and data (true).
+ bool checkTopic1 = false;
+ bool checkTopic2 = false;
+ bool checkTopic3 = false;
+ bool checkData = true;
+ vm.expectEmit(checkTopic1, checkTopic2, checkTopic3, checkData);
+ emit SubscriptionCanceled(s_subscriptionId, OWNER_ADDRESS, expectedRefund);
+
+ s_functionsRouter.cancelSubscription(s_subscriptionId, OWNER_ADDRESS);
+
+ uint256 subscriptionOwnerBalanceAfter = s_linkToken.balanceOf(OWNER_ADDRESS);
+ assertEq(subscriptionOwnerBalanceBefore + expectedRefund, subscriptionOwnerBalanceAfter);
+
+ // Subscription should no longer exist
+ vm.expectRevert(FunctionsSubscriptions.InvalidSubscription.selector);
+ s_functionsRouter.getSubscription(s_subscriptionId);
+
+ // Router owner should have expectedDepositWithheld to withdraw
+ uint96 expectedDepositWithheld = s_subscriptionDepositJuels;
+ uint256 balanceBeforeWithdraw = s_linkToken.balanceOf(STRANGER_ADDRESS);
+ s_functionsRouter.ownerWithdraw(STRANGER_ADDRESS, 0);
+ uint256 balanceAfterWithdraw = s_linkToken.balanceOf(STRANGER_ADDRESS);
+ assertEq(balanceBeforeWithdraw + expectedDepositWithheld, balanceAfterWithdraw);
+ }
+
+ function test_CancelSubscription_SuccessRecieveDeposit() public {
+ // Complete 1 request = subscriptionDepositMinimumRequests
+ vm.recordLogs();
+ bytes32 requestId = s_functionsClient.sendRequest(
+ s_donId,
+ "return 'hello world';",
+ new bytes(0),
+ new string[](0),
+ new bytes[](0),
+ s_subscriptionId,
+ 5500
+ );
+
+ // Get commitment data from OracleRequest event log
+ Vm.Log[] memory entries = vm.getRecordedLogs();
+ (, , , , , , , FunctionsResponse.Commitment memory commitment) = abi.decode(
+ entries[0].data,
+ (address, uint64, address, bytes, uint16, bytes32, uint64, FunctionsResponse.Commitment)
+ );
+
+ // Send as transmitter 1
+ vm.stopPrank();
+ vm.startPrank(NOP_TRANSMITTER_ADDRESS_1);
+
+ // Build report
+ bytes32[] memory requestIds = new bytes32[](1);
+ requestIds[0] = requestId;
+ bytes[] memory results = new bytes[](1);
+ results[0] = bytes("hello world!");
+ bytes[] memory errors = new bytes[](1);
+ // No error
+ bytes[] memory onchainMetadata = new bytes[](1);
+ onchainMetadata[0] = abi.encode(commitment);
+ bytes[] memory offchainMetadata = new bytes[](1);
+ // No offchain metadata
+ bytes memory report = abi.encode(requestIds, results, errors, onchainMetadata, offchainMetadata);
+
+ // Build signers
+ address[31] memory signers;
+ signers[0] = NOP_SIGNER_ADDRESS_1;
+
+ // Send report
+ vm.recordLogs();
+ s_functionsCoordinator.callReportWithSigners(report, signers);
+
+ // Get actual cost from RequestProcessed event log
+ Vm.Log[] memory entries2 = vm.getRecordedLogs();
+ (uint96 totalCostJuels, , , , , ) = abi.decode(
+ entries2[2].data,
+ (uint96, address, FunctionsResponse.FulfillResult, bytes, bytes, bytes)
+ );
+
+ // Return to sending as owner
+ vm.stopPrank();
+ vm.startPrank(OWNER_ADDRESS);
+
+ uint256 subscriptionOwnerBalanceBefore = s_linkToken.balanceOf(OWNER_ADDRESS);
+
+ uint96 expectedRefund = s_subscriptionInitialFunding - totalCostJuels;
+ // topic0 (function signature, always checked), NOT topic1 (false), NOT topic2 (false), NOT topic3 (false), and data (true).
+ bool checkTopic1 = false;
+ bool checkTopic2 = false;
+ bool checkTopic3 = false;
+ bool checkData = true;
+ vm.expectEmit(checkTopic1, checkTopic2, checkTopic3, checkData);
+ emit SubscriptionCanceled(s_subscriptionId, OWNER_ADDRESS, expectedRefund);
+
+ s_functionsRouter.cancelSubscription(s_subscriptionId, OWNER_ADDRESS);
+
+ uint256 subscriptionOwnerBalanceAfter = s_linkToken.balanceOf(OWNER_ADDRESS);
+ assertEq(subscriptionOwnerBalanceBefore + expectedRefund, subscriptionOwnerBalanceAfter);
+
+ // Subscription should no longer exist
+ vm.expectRevert(FunctionsSubscriptions.InvalidSubscription.selector);
+ s_functionsRouter.getSubscription(s_subscriptionId);
+ }
+}
+
+/// @notice #_cancelSubscriptionHelper
+contract FunctionsSubscriptions__CancelSubscriptionHelper {
+ // TODO: make contract internal function helper
+}
+
+/// @notice #pendingRequestExists
+contract FunctionsSubscriptions_PendingRequestExists is FunctionsFulfillmentSetup {
+ function test_PendingRequestExists_SuccessFalseIfNoPendingRequests() public {
+ bool hasPendingRequests = s_functionsRouter.pendingRequestExists(s_subscriptionId);
+ assertEq(hasPendingRequests, false);
+ }
+
+ function test_PendingRequestExists_SuccessTrueIfPendingRequests() public {
+ // Send a minimal request
+ string memory sourceCode = "return 'hello world';";
+ bytes memory secrets;
+ string[] memory args = new string[](0);
+ bytes[] memory bytesArgs = new bytes[](0);
+
+ s_functionsClient.sendRequest(s_donId, sourceCode, secrets, args, bytesArgs, s_subscriptionId, 5000);
+
+ bool hasPendingRequests = s_functionsRouter.pendingRequestExists(s_subscriptionId);
+ assertEq(hasPendingRequests, true);
+ }
+}
+
+/// @notice #setFlags
+contract FunctionsSubscriptions_SetFlags is FunctionsSubscriptionSetup {
+ function test_SetFlags_RevertIfNotOwner() public {
+ // Send as stranger
+ vm.stopPrank();
+ vm.startPrank(STRANGER_ADDRESS);
+
+ vm.expectRevert("Only callable by owner");
+ bytes32 flagsToSet = bytes32("1");
+ s_functionsRouter.setFlags(s_subscriptionId, flagsToSet);
+ }
+
+ function test_SetFlags_RevertIfNoSubscription() public {
+ vm.expectRevert(FunctionsSubscriptions.InvalidSubscription.selector);
+ uint64 invalidSubscriptionId = 123456789;
+ bytes32 flagsToSet = bytes32("1");
+ s_functionsRouter.setFlags(invalidSubscriptionId, flagsToSet);
+ }
+
+ function test_SetFlags_Success() public {
+ bytes32 flagsToSet = bytes32("1");
+ s_functionsRouter.setFlags(s_subscriptionId, flagsToSet);
+ bytes32 flags = s_functionsRouter.getFlags(s_subscriptionId);
+ assertEq(flags, flagsToSet);
+ }
+}
+
+/// @notice #getFlags
+contract FunctionsSubscriptions_GetFlags is FunctionsSubscriptionSetup {
+ function test_GetFlags_Success() public {
+ // Set flags
+ bytes32 flagsToSet = bytes32("1");
+ s_functionsRouter.setFlags(s_subscriptionId, flagsToSet);
+
+ // Send as stranger
+ vm.stopPrank();
+ vm.startPrank(STRANGER_ADDRESS);
+
+ bytes32 flags = s_functionsRouter.getFlags(s_subscriptionId);
+ assertEq(flags, flagsToSet);
+ }
+}
+
+/// @notice #timeoutRequests
+contract FunctionsSubscriptions_TimeoutRequests is FunctionsClientRequestSetup {
+ function test_TimeoutRequests_RevertIfPaused() public {
+ s_functionsRouter.pause();
+
+ vm.expectRevert("Pausable: paused");
+ FunctionsResponse.Commitment[] memory commitments = new FunctionsResponse.Commitment[](1);
+ commitments[0] = s_requests[1].commitment;
+ s_functionsRouter.timeoutRequests(commitments);
+ }
+
+ function test_TimeoutRequests_RevertInvalidRequest() public {
+ // Modify the commitment so that it doesn't match
+ s_requests[1].commitment.donFee = 123456789;
+ FunctionsResponse.Commitment[] memory commitments = new FunctionsResponse.Commitment[](1);
+ commitments[0] = s_requests[1].commitment;
+ vm.expectRevert(FunctionsSubscriptions.InvalidCalldata.selector);
+ s_functionsRouter.timeoutRequests(commitments);
+ }
+
+ function test_TimeoutRequests_RevertIfTimeoutNotExceeded() public {
+ vm.expectRevert(FunctionsSubscriptions.TimeoutNotExceeded.selector);
+ FunctionsResponse.Commitment[] memory commitments = new FunctionsResponse.Commitment[](1);
+ commitments[0] = s_requests[1].commitment;
+ s_functionsRouter.timeoutRequests(commitments);
+ }
+
+ event RequestTimedOut(bytes32 indexed requestId);
+
+ function test_TimeoutRequests_Success() public {
+ uint64 consumerCompletedRequestsBefore = s_functionsRouter
+ .getConsumer(address(s_functionsClient), s_subscriptionId)
+ .completedRequests;
+
+ // topic0 (function signature, always checked), NOT topic1 (false), NOT topic2 (false), NOT topic3 (false), and data (true).
+ bool checkTopic1 = false;
+ bool checkTopic2 = false;
+ bool checkTopic3 = false;
+ bool checkData = true;
+ vm.expectEmit(checkTopic1, checkTopic2, checkTopic3, checkData);
+ emit RequestTimedOut(s_requests[1].requestId);
+
+ // Jump ahead in time past timeout timestamp
+ vm.warp(s_requests[1].commitment.timeoutTimestamp + 1);
+
+ FunctionsResponse.Commitment[] memory commitments = new FunctionsResponse.Commitment[](1);
+ commitments[0] = s_requests[1].commitment;
+ s_functionsRouter.timeoutRequests(commitments);
+
+ // Releases blocked balance and increments completed requests
+ uint96 subscriptionBlockedBalanceAfter = s_functionsRouter.getSubscription(s_subscriptionId).blockedBalance;
+ assertEq(0, subscriptionBlockedBalanceAfter);
+ uint64 consumerCompletedRequestsAfter = s_functionsRouter
+ .getConsumer(address(s_functionsClient), s_subscriptionId)
+ .completedRequests;
+ assertEq(consumerCompletedRequestsBefore + 1, consumerCompletedRequestsAfter);
+ }
+}
+
+// @notice #_onlySubscriptionOwner
+contract FunctionsSubscriptions__OnlySubscriptionOwner {
+ // TODO: make contract internal function helper
+}
diff --git a/contracts/src/v0.8/functions/tests/v1_0_0/FunctionsTermsOfServiceAllowList.t.sol b/contracts/src/v0.8/functions/tests/v1_0_0/FunctionsTermsOfServiceAllowList.t.sol
new file mode 100644
index 00000000000..d8f03ba3ebf
--- /dev/null
+++ b/contracts/src/v0.8/functions/tests/v1_0_0/FunctionsTermsOfServiceAllowList.t.sol
@@ -0,0 +1,343 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.19;
+
+import {TermsOfServiceAllowList} from "../../dev/v1_0_0/accessControl/TermsOfServiceAllowList.sol";
+import {FunctionsClientTestHelper} from "./testhelpers/FunctionsClientTestHelper.sol";
+
+import {FunctionsRoutesSetup, FunctionsOwnerAcceptTermsOfServiceSetup} from "./Setup.t.sol";
+
+/// @notice #constructor
+contract FunctionsTermsOfServiceAllowList_Constructor is FunctionsRoutesSetup {
+ function test_Constructor_Success() public {
+ assertEq(s_termsOfServiceAllowList.typeAndVersion(), "Functions Terms of Service Allow List v1.0.0");
+ assertEq(s_termsOfServiceAllowList.owner(), OWNER_ADDRESS);
+ }
+}
+
+/// @notice #getConfig
+contract FunctionsTermsOfServiceAllowList_GetConfig is FunctionsRoutesSetup {
+ function test_GetConfig_Success() public {
+ // Send as stranger
+ vm.stopPrank();
+ vm.startPrank(STRANGER_ADDRESS);
+
+ TermsOfServiceAllowList.Config memory config = s_termsOfServiceAllowList.getConfig();
+ assertEq(config.enabled, getTermsOfServiceConfig().enabled);
+ assertEq(config.signerPublicKey, getTermsOfServiceConfig().signerPublicKey);
+ }
+}
+
+/// @notice #updateConfig
+contract FunctionsTermsOfServiceAllowList_UpdateConfig is FunctionsRoutesSetup {
+ function test_UpdateConfig_RevertIfNotOwner() public {
+ // Send as stranger
+ vm.stopPrank();
+ vm.startPrank(STRANGER_ADDRESS);
+
+ vm.expectRevert("Only callable by owner");
+ s_termsOfServiceAllowList.updateConfig(
+ TermsOfServiceAllowList.Config({enabled: true, signerPublicKey: STRANGER_ADDRESS})
+ );
+ }
+
+ event ConfigUpdated(TermsOfServiceAllowList.Config config);
+
+ function test_UpdateConfig_Success() public {
+ TermsOfServiceAllowList.Config memory configToSet = TermsOfServiceAllowList.Config({
+ enabled: false,
+ signerPublicKey: TOS_SIGNER
+ });
+
+ // topic0 (function signature, always checked), NOT topic1 (false), NOT topic2 (false), NOT topic3 (false), and data (true).
+ bool checkTopic1 = false;
+ bool checkTopic2 = false;
+ bool checkTopic3 = false;
+ bool checkData = true;
+ vm.expectEmit(checkTopic1, checkTopic2, checkTopic3, checkData);
+ emit ConfigUpdated(configToSet);
+
+ s_termsOfServiceAllowList.updateConfig(configToSet);
+
+ TermsOfServiceAllowList.Config memory config = s_termsOfServiceAllowList.getConfig();
+ assertEq(config.enabled, configToSet.enabled);
+ assertEq(config.signerPublicKey, configToSet.signerPublicKey);
+ }
+}
+
+/// @notice #getMessage
+contract FunctionsTermsOfServiceAllowList_GetMessage is FunctionsRoutesSetup {
+ function test_GetMessage_Success() public {
+ // Send as stranger
+ vm.stopPrank();
+ vm.startPrank(STRANGER_ADDRESS);
+
+ bytes32 message = s_termsOfServiceAllowList.getMessage(STRANGER_ADDRESS, STRANGER_ADDRESS);
+
+ assertEq(message, keccak256(abi.encodePacked(STRANGER_ADDRESS, STRANGER_ADDRESS)));
+ }
+}
+
+/// @notice #acceptTermsOfService
+contract FunctionsTermsOfServiceAllowList_AcceptTermsOfService is FunctionsRoutesSetup {
+ function test_AcceptTermsOfService_RevertIfBlockedSender() public {
+ s_termsOfServiceAllowList.blockSender(STRANGER_ADDRESS);
+
+ // Send as stranger
+ vm.stopPrank();
+ vm.startPrank(STRANGER_ADDRESS);
+
+ bytes32 message = s_termsOfServiceAllowList.getMessage(STRANGER_ADDRESS, STRANGER_ADDRESS);
+ bytes32 prefixedMessage = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", message));
+ (uint8 v, bytes32 r, bytes32 s) = vm.sign(TOS_SIGNER_PRIVATE_KEY, prefixedMessage);
+
+ vm.expectRevert(TermsOfServiceAllowList.RecipientIsBlocked.selector);
+
+ s_termsOfServiceAllowList.acceptTermsOfService(STRANGER_ADDRESS, STRANGER_ADDRESS, r, s, v);
+ }
+
+ function test_AcceptTermsOfService_RevertIfInvalidSigner() public {
+ // Send as stranger
+ vm.stopPrank();
+ vm.startPrank(STRANGER_ADDRESS);
+
+ bytes32 message = s_termsOfServiceAllowList.getMessage(STRANGER_ADDRESS, STRANGER_ADDRESS);
+ bytes32 prefixedMessage = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", message));
+ (uint8 v, bytes32 r, bytes32 s) = vm.sign(STRANGER_PRIVATE_KEY, prefixedMessage);
+
+ vm.expectRevert(TermsOfServiceAllowList.InvalidSignature.selector);
+
+ s_termsOfServiceAllowList.acceptTermsOfService(STRANGER_ADDRESS, STRANGER_ADDRESS, r, s, v);
+ }
+
+ function test_AcceptTermsOfService_RevertIfRecipientIsNotSender() public {
+ // Send as stranger
+ vm.stopPrank();
+ vm.startPrank(STRANGER_ADDRESS);
+
+ bytes32 message = s_termsOfServiceAllowList.getMessage(OWNER_ADDRESS, STRANGER_ADDRESS);
+ bytes32 prefixedMessage = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", message));
+ (uint8 v, bytes32 r, bytes32 s) = vm.sign(TOS_SIGNER_PRIVATE_KEY, prefixedMessage);
+
+ vm.expectRevert(TermsOfServiceAllowList.InvalidUsage.selector);
+
+ s_termsOfServiceAllowList.acceptTermsOfService(OWNER_ADDRESS, STRANGER_ADDRESS, r, s, v);
+ }
+
+ function test_AcceptTermsOfService_RevertIfAcceptorIsNotSender() public {
+ // Send as stranger
+ vm.stopPrank();
+ vm.startPrank(STRANGER_ADDRESS);
+
+ bytes32 message = s_termsOfServiceAllowList.getMessage(STRANGER_ADDRESS, OWNER_ADDRESS);
+ bytes32 prefixedMessage = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", message));
+ (uint8 v, bytes32 r, bytes32 s) = vm.sign(TOS_SIGNER_PRIVATE_KEY, prefixedMessage);
+
+ vm.expectRevert(TermsOfServiceAllowList.InvalidUsage.selector);
+
+ s_termsOfServiceAllowList.acceptTermsOfService(STRANGER_ADDRESS, OWNER_ADDRESS, r, s, v);
+ }
+
+ function test_AcceptTermsOfService_RevertIfRecipientContractIsNotSender() public {
+ FunctionsClientTestHelper s_functionsClientHelper = new FunctionsClientTestHelper(address(s_functionsRouter));
+
+ // Send as externally owned account
+ vm.stopPrank();
+ vm.startPrank(STRANGER_ADDRESS);
+
+ // Attempt to accept for a contract account
+ bytes32 message = s_termsOfServiceAllowList.getMessage(STRANGER_ADDRESS, address(s_functionsClientHelper));
+ bytes32 prefixedMessage = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", message));
+ (uint8 v, bytes32 r, bytes32 s) = vm.sign(TOS_SIGNER_PRIVATE_KEY, prefixedMessage);
+
+ vm.expectRevert(TermsOfServiceAllowList.InvalidUsage.selector);
+
+ s_termsOfServiceAllowList.acceptTermsOfService(STRANGER_ADDRESS, address(s_functionsClientHelper), r, s, v);
+ }
+
+ event AddedAccess(address user);
+
+ function test_AcceptTermsOfService_SuccessIfAcceptingForSelf() public {
+ // Send as stranger
+ vm.stopPrank();
+ vm.startPrank(STRANGER_ADDRESS);
+
+ bytes32 message = s_termsOfServiceAllowList.getMessage(STRANGER_ADDRESS, STRANGER_ADDRESS);
+ bytes32 prefixedMessage = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", message));
+ (uint8 v, bytes32 r, bytes32 s) = vm.sign(TOS_SIGNER_PRIVATE_KEY, prefixedMessage);
+
+ // topic0 (function signature, always checked), NOT topic1 (false), NOT topic2 (false), NOT topic3 (false), and data (true).
+ bool checkTopic1 = false;
+ bool checkTopic2 = false;
+ bool checkTopic3 = false;
+ bool checkData = true;
+ vm.expectEmit(checkTopic1, checkTopic2, checkTopic3, checkData);
+ emit AddedAccess(STRANGER_ADDRESS);
+
+ s_termsOfServiceAllowList.acceptTermsOfService(STRANGER_ADDRESS, STRANGER_ADDRESS, r, s, v);
+
+ assertEq(s_termsOfServiceAllowList.hasAccess(STRANGER_ADDRESS, new bytes(0)), true);
+ }
+
+ function test_AcceptTermsOfService_SuccessIfAcceptingForContract() public {
+ FunctionsClientTestHelper s_functionsClientHelper = new FunctionsClientTestHelper(address(s_functionsRouter));
+
+ // Send as stranger
+ vm.stopPrank();
+ vm.startPrank(STRANGER_ADDRESS);
+
+ bytes32 message = s_termsOfServiceAllowList.getMessage(STRANGER_ADDRESS, address(s_functionsClientHelper));
+ bytes32 prefixedMessage = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", message));
+ (uint8 v, bytes32 r, bytes32 s) = vm.sign(TOS_SIGNER_PRIVATE_KEY, prefixedMessage);
+
+ // topic0 (function signature, always checked), NOT topic1 (false), NOT topic2 (false), NOT topic3 (false), and data (true).
+ bool checkTopic1 = false;
+ bool checkTopic2 = false;
+ bool checkTopic3 = false;
+ bool checkData = true;
+ vm.expectEmit(checkTopic1, checkTopic2, checkTopic3, checkData);
+ emit AddedAccess(address(s_functionsClientHelper));
+
+ s_functionsClientHelper.acceptTermsOfService(STRANGER_ADDRESS, address(s_functionsClientHelper), r, s, v);
+
+ assertEq(s_termsOfServiceAllowList.hasAccess(address(s_functionsClientHelper), new bytes(0)), true);
+ }
+}
+
+/// @notice #getAllAllowedSenders
+contract FunctionsTermsOfServiceAllowList_GetAllAllowedSenders is FunctionsOwnerAcceptTermsOfServiceSetup {
+ function test_GetAllAllowedSenders_Success() public {
+ // Send as stranger
+ vm.stopPrank();
+ vm.startPrank(STRANGER_ADDRESS);
+
+ address[] memory expectedSenders = new address[](1);
+ expectedSenders[0] = OWNER_ADDRESS;
+
+ assertEq(s_termsOfServiceAllowList.getAllAllowedSenders(), expectedSenders);
+ }
+}
+
+/// @notice #hasAccess
+contract FunctionsTermsOfServiceAllowList_HasAccess is FunctionsRoutesSetup {
+ function test_HasAccess_FalseWhenEnabled() public {
+ // Send as stranger
+ vm.stopPrank();
+ vm.startPrank(STRANGER_ADDRESS);
+
+ // Check access of account that is not on the allow list
+ assertEq(s_termsOfServiceAllowList.hasAccess(STRANGER_ADDRESS, new bytes(0)), false);
+ }
+
+ function test_HasAccess_TrueWhenDisabled() public {
+ // Disable allow list, which opens all access
+ s_termsOfServiceAllowList.updateConfig(
+ TermsOfServiceAllowList.Config({enabled: false, signerPublicKey: TOS_SIGNER})
+ );
+
+ // Send as stranger
+ vm.stopPrank();
+ vm.startPrank(STRANGER_ADDRESS);
+
+ // Check access of account that is not on the allow list
+ assertEq(s_termsOfServiceAllowList.hasAccess(STRANGER_ADDRESS, new bytes(0)), true);
+ }
+}
+
+/// @notice #isBlockedSender
+contract FunctionsTermsOfServiceAllowList_IsBlockedSender is FunctionsRoutesSetup {
+ function test_IsBlockedSender_SuccessFalse() public {
+ // Send as stranger
+ vm.stopPrank();
+ vm.startPrank(STRANGER_ADDRESS);
+
+ assertEq(s_termsOfServiceAllowList.isBlockedSender(STRANGER_ADDRESS), false);
+ }
+
+ function test_IsBlockedSender_SuccessTrue() public {
+ // Block sender
+ s_termsOfServiceAllowList.blockSender(STRANGER_ADDRESS);
+
+ // Send as stranger
+ vm.stopPrank();
+ vm.startPrank(STRANGER_ADDRESS);
+
+ assertEq(s_termsOfServiceAllowList.isBlockedSender(STRANGER_ADDRESS), true);
+ }
+}
+
+/// @notice #blockSender
+contract FunctionsTermsOfServiceAllowList_BlockSender is FunctionsRoutesSetup {
+ function test_BlockSender_RevertIfNotOwner() public {
+ // Send as stranger
+ vm.stopPrank();
+ vm.startPrank(STRANGER_ADDRESS);
+
+ vm.expectRevert("Only callable by owner");
+ s_termsOfServiceAllowList.blockSender(OWNER_ADDRESS);
+ }
+
+ event BlockedAccess(address user);
+
+ function test_BlockSender_Success() public {
+ // topic0 (function signature, always checked), NOT topic1 (false), NOT topic2 (false), NOT topic3 (false), and data (true).
+ bool checkTopic1 = false;
+ bool checkTopic2 = false;
+ bool checkTopic3 = false;
+ bool checkData = true;
+ vm.expectEmit(checkTopic1, checkTopic2, checkTopic3, checkData);
+ emit BlockedAccess(STRANGER_ADDRESS);
+
+ s_termsOfServiceAllowList.blockSender(STRANGER_ADDRESS);
+ assertEq(s_termsOfServiceAllowList.hasAccess(STRANGER_ADDRESS, new bytes(0)), false);
+ assertEq(s_termsOfServiceAllowList.isBlockedSender(STRANGER_ADDRESS), true);
+
+ // Account can no longer accept Terms of Service
+ bytes32 message = s_termsOfServiceAllowList.getMessage(STRANGER_ADDRESS, STRANGER_ADDRESS);
+ bytes32 prefixedMessage = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", message));
+ (uint8 v, bytes32 r, bytes32 s) = vm.sign(TOS_SIGNER_PRIVATE_KEY, prefixedMessage);
+ vm.expectRevert(TermsOfServiceAllowList.RecipientIsBlocked.selector);
+ s_termsOfServiceAllowList.acceptTermsOfService(STRANGER_ADDRESS, STRANGER_ADDRESS, r, s, v);
+ }
+}
+
+/// @notice #unblockSender
+contract FunctionsTermsOfServiceAllowList_UnblockSender is FunctionsRoutesSetup {
+ function setUp() public virtual override {
+ FunctionsRoutesSetup.setUp();
+
+ s_termsOfServiceAllowList.blockSender(STRANGER_ADDRESS);
+ }
+
+ function test_UnblockSender_RevertIfNotOwner() public {
+ // Send as stranger
+ vm.stopPrank();
+ vm.startPrank(STRANGER_ADDRESS);
+
+ vm.expectRevert("Only callable by owner");
+ s_termsOfServiceAllowList.unblockSender(STRANGER_ADDRESS);
+ }
+
+ event UnblockedAccess(address user);
+
+ function test_UnblockSender_Success() public {
+ // topic0 (function signature, always checked), NOT topic1 (false), NOT topic2 (false), NOT topic3 (false), and data (true).
+ bool checkTopic1 = false;
+ bool checkTopic2 = false;
+ bool checkTopic3 = false;
+ bool checkData = true;
+ vm.expectEmit(checkTopic1, checkTopic2, checkTopic3, checkData);
+ emit UnblockedAccess(STRANGER_ADDRESS);
+
+ s_termsOfServiceAllowList.unblockSender(STRANGER_ADDRESS);
+
+ // Send as stranger
+ vm.stopPrank();
+ vm.startPrank(STRANGER_ADDRESS);
+
+ // Account can now accept the Terms of Service
+ bytes32 message = s_termsOfServiceAllowList.getMessage(STRANGER_ADDRESS, STRANGER_ADDRESS);
+ bytes32 prefixedMessage = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", message));
+ (uint8 v, bytes32 r, bytes32 s) = vm.sign(TOS_SIGNER_PRIVATE_KEY, prefixedMessage);
+ s_termsOfServiceAllowList.acceptTermsOfService(STRANGER_ADDRESS, STRANGER_ADDRESS, r, s, v);
+ }
+}
diff --git a/contracts/src/v0.8/functions/1_0_0/.gitkeep b/contracts/src/v0.8/functions/tests/v1_0_0/OCR2.t.sol
similarity index 100%
rename from contracts/src/v0.8/functions/1_0_0/.gitkeep
rename to contracts/src/v0.8/functions/tests/v1_0_0/OCR2.t.sol
diff --git a/contracts/src/v0.8/functions/tests/v1_0_0/README.md b/contracts/src/v0.8/functions/tests/v1_0_0/README.md
new file mode 100644
index 00000000000..42aa6ed2b7b
--- /dev/null
+++ b/contracts/src/v0.8/functions/tests/v1_0_0/README.md
@@ -0,0 +1,22 @@
+## Usage
+
+First set the foundry profile to Functions:
+```
+export FOUNDRY_PROFILE=functions
+```
+
+To run all test files use:
+```
+forge test -vv
+```
+
+To run a specific file use:
+```
+forge test -vv --mp src/v0.8/functions/tests/v1_0_0/[File Name].t.sol
+```
+
+To see coverage:
+First ensure that the correct files are being evaluated. For example, if only v1 contracts are, then temporarily change the Functions profile in `./foundry.toml`.
+```
+forge coverage
+```
\ No newline at end of file
diff --git a/contracts/src/v0.8/functions/tests/v1_0_0/Setup.t.sol b/contracts/src/v0.8/functions/tests/v1_0_0/Setup.t.sol
new file mode 100644
index 00000000000..73644e38636
--- /dev/null
+++ b/contracts/src/v0.8/functions/tests/v1_0_0/Setup.t.sol
@@ -0,0 +1,561 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.19;
+
+import {BaseTest} from "./BaseTest.t.sol";
+import {FunctionsRouter} from "../../dev/v1_0_0/FunctionsRouter.sol";
+import {FunctionsCoordinatorTestHelper} from "./testhelpers/FunctionsCoordinatorTestHelper.sol";
+import {FunctionsBilling} from "../../dev/v1_0_0/FunctionsBilling.sol";
+import {FunctionsResponse} from "../../dev/v1_0_0/libraries/FunctionsResponse.sol";
+import {MockV3Aggregator} from "../../../tests/MockV3Aggregator.sol";
+import {TermsOfServiceAllowList} from "../../dev/v1_0_0/accessControl/TermsOfServiceAllowList.sol";
+import {FunctionsClientUpgradeHelper} from "./testhelpers/FunctionsClientUpgradeHelper.sol";
+import {MockLinkToken} from "../../../mocks/MockLinkToken.sol";
+
+import "forge-std/Vm.sol";
+
+/// @notice Set up to deploy the following contracts: FunctionsRouter, FunctionsCoordinator, LINK/ETH Feed, ToS Allow List, and LINK token
+contract FunctionsRouterSetup is BaseTest {
+ FunctionsRouter internal s_functionsRouter;
+ FunctionsCoordinatorTestHelper internal s_functionsCoordinator; // TODO: use actual FunctionsCoordinator instead of helper
+ MockV3Aggregator internal s_linkEthFeed;
+ TermsOfServiceAllowList internal s_termsOfServiceAllowList;
+ MockLinkToken internal s_linkToken;
+
+ uint16 internal s_maxConsumersPerSubscription = 3;
+ uint72 internal s_adminFee = 100;
+ uint72 internal s_donFee = 100;
+ bytes4 internal s_handleOracleFulfillmentSelector = 0x0ca76175;
+ uint16 s_subscriptionDepositMinimumRequests = 1;
+ uint72 s_subscriptionDepositJuels = 11 * JUELS_PER_LINK;
+
+ int256 internal LINK_ETH_RATE = 6000000000000000;
+
+ uint256 internal TOS_SIGNER_PRIVATE_KEY = 0x3;
+ address internal TOS_SIGNER = vm.addr(TOS_SIGNER_PRIVATE_KEY);
+
+ function setUp() public virtual override {
+ BaseTest.setUp();
+ s_linkToken = new MockLinkToken();
+ s_functionsRouter = new FunctionsRouter(address(s_linkToken), getRouterConfig());
+ s_linkEthFeed = new MockV3Aggregator(0, LINK_ETH_RATE);
+ s_functionsCoordinator = new FunctionsCoordinatorTestHelper(
+ address(s_functionsRouter),
+ getCoordinatorConfig(),
+ address(s_linkEthFeed)
+ );
+ s_termsOfServiceAllowList = new TermsOfServiceAllowList(getTermsOfServiceConfig());
+ }
+
+ function getRouterConfig() public view returns (FunctionsRouter.Config memory) {
+ uint32[] memory maxCallbackGasLimits = new uint32[](3);
+ maxCallbackGasLimits[0] = 300_000;
+ maxCallbackGasLimits[1] = 500_000;
+ maxCallbackGasLimits[2] = 1_000_000;
+
+ return
+ FunctionsRouter.Config({
+ maxConsumersPerSubscription: s_maxConsumersPerSubscription,
+ adminFee: s_adminFee,
+ handleOracleFulfillmentSelector: s_handleOracleFulfillmentSelector,
+ maxCallbackGasLimits: maxCallbackGasLimits,
+ gasForCallExactCheck: 5000,
+ subscriptionDepositMinimumRequests: s_subscriptionDepositMinimumRequests,
+ subscriptionDepositJuels: s_subscriptionDepositJuels
+ });
+ }
+
+ function getCoordinatorConfig() public view returns (FunctionsBilling.Config memory) {
+ return
+ FunctionsBilling.Config({
+ feedStalenessSeconds: 24 * 60 * 60, // 1 day
+ gasOverheadAfterCallback: 50_000, // TODO: update
+ gasOverheadBeforeCallback: 100_00, // TODO: update
+ requestTimeoutSeconds: 60 * 5, // 5 minutes
+ donFee: s_donFee,
+ maxSupportedRequestDataVersion: 1,
+ fulfillmentGasPriceOverEstimationBP: 5000,
+ fallbackNativePerUnitLink: 5000000000000000
+ });
+ }
+
+ function getTermsOfServiceConfig() public view returns (TermsOfServiceAllowList.Config memory) {
+ return TermsOfServiceAllowList.Config({enabled: true, signerPublicKey: TOS_SIGNER});
+ }
+}
+
+/// @notice Set up to set the OCR configuration of the Coordinator contract
+contract FunctionsDONSetup is FunctionsRouterSetup {
+ uint256 internal NOP_SIGNER_PRIVATE_KEY_1 = 0x100;
+ address internal NOP_SIGNER_ADDRESS_1 = vm.addr(NOP_SIGNER_PRIVATE_KEY_1);
+ uint256 internal NOP_SIGNER_PRIVATE_KEY_2 = 0x101;
+ address internal NOP_SIGNER_ADDRESS_2 = vm.addr(NOP_SIGNER_PRIVATE_KEY_2);
+ uint256 internal NOP_SIGNER_PRIVATE_KEY_3 = 0x102;
+ address internal NOP_SIGNER_ADDRESS_3 = vm.addr(NOP_SIGNER_PRIVATE_KEY_3);
+ uint256 internal NOP_SIGNER_PRIVATE_KEY_4 = 0x103;
+ address internal NOP_SIGNER_ADDRESS_4 = vm.addr(NOP_SIGNER_PRIVATE_KEY_4);
+
+ uint256 internal NOP_TRANSMITTER_PRIVATE_KEY_1 = 0x104;
+ address internal NOP_TRANSMITTER_ADDRESS_1 = vm.addr(NOP_TRANSMITTER_PRIVATE_KEY_1);
+ uint256 internal NOP_TRANSMITTER_PRIVATE_KEY_2 = 0x105;
+ address internal NOP_TRANSMITTER_ADDRESS_2 = vm.addr(NOP_TRANSMITTER_PRIVATE_KEY_2);
+ uint256 internal NOP_TRANSMITTER_PRIVATE_KEY_3 = 0x106;
+ address internal NOP_TRANSMITTER_ADDRESS_3 = vm.addr(NOP_TRANSMITTER_PRIVATE_KEY_3);
+ uint256 internal NOP_TRANSMITTER_PRIVATE_KEY_4 = 0x107;
+ address internal NOP_TRANSMITTER_ADDRESS_4 = vm.addr(NOP_TRANSMITTER_PRIVATE_KEY_4);
+
+ address[] internal s_signers;
+ address[] internal s_transmitters;
+ uint8 s_f = 1;
+ bytes internal s_onchainConfig = new bytes(0);
+ uint64 internal s_offchainConfigVersion = 1;
+ bytes internal s_offchainConfig = new bytes(0);
+
+ function setUp() public virtual override {
+ FunctionsRouterSetup.setUp();
+
+ s_signers = new address[](4);
+ s_signers[0] = NOP_SIGNER_ADDRESS_1;
+ s_signers[1] = NOP_SIGNER_ADDRESS_2;
+ s_signers[2] = NOP_SIGNER_ADDRESS_3;
+ s_signers[3] = NOP_SIGNER_ADDRESS_4;
+
+ s_transmitters = new address[](4);
+ s_transmitters[0] = NOP_TRANSMITTER_ADDRESS_1;
+ s_transmitters[1] = NOP_TRANSMITTER_ADDRESS_2;
+ s_transmitters[2] = NOP_TRANSMITTER_ADDRESS_3;
+ s_transmitters[3] = NOP_TRANSMITTER_ADDRESS_4;
+
+ // set OCR config
+ s_functionsCoordinator.setConfig(
+ s_signers,
+ s_transmitters,
+ s_f,
+ s_onchainConfig,
+ s_offchainConfigVersion,
+ s_offchainConfig
+ );
+ }
+}
+
+/// @notice Set up to add the Coordinator and ToS Allow Contract as routes on the Router contract
+contract FunctionsRoutesSetup is FunctionsDONSetup {
+ bytes32 s_donId = bytes32("1");
+
+ function setUp() public virtual override {
+ FunctionsDONSetup.setUp();
+
+ bytes32 allowListId = s_functionsRouter.getAllowListId();
+ bytes32[] memory proposedContractSetIds = new bytes32[](2);
+ proposedContractSetIds[0] = s_donId;
+ proposedContractSetIds[1] = allowListId;
+ address[] memory proposedContractSetAddresses = new address[](2);
+ proposedContractSetAddresses[0] = address(s_functionsCoordinator);
+ proposedContractSetAddresses[1] = address(s_termsOfServiceAllowList);
+
+ s_functionsRouter.proposeContractsUpdate(proposedContractSetIds, proposedContractSetAddresses);
+ s_functionsRouter.updateContracts();
+ }
+}
+
+/// @notice Set up for the OWNER_ADDRESS to accept the Terms of Service
+contract FunctionsOwnerAcceptTermsOfServiceSetup is FunctionsRoutesSetup {
+ function setUp() public virtual override {
+ FunctionsRoutesSetup.setUp();
+
+ bytes32 message = s_termsOfServiceAllowList.getMessage(OWNER_ADDRESS, OWNER_ADDRESS);
+ bytes32 prefixedMessage = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", message));
+ (uint8 v, bytes32 r, bytes32 s) = vm.sign(TOS_SIGNER_PRIVATE_KEY, prefixedMessage);
+ s_termsOfServiceAllowList.acceptTermsOfService(OWNER_ADDRESS, OWNER_ADDRESS, r, s, v);
+ }
+}
+
+/// @notice Set up to deploy a consumer contract
+contract FunctionsClientSetup is FunctionsOwnerAcceptTermsOfServiceSetup {
+ FunctionsClientUpgradeHelper internal s_functionsClient;
+
+ function setUp() public virtual override {
+ FunctionsOwnerAcceptTermsOfServiceSetup.setUp();
+
+ s_functionsClient = new FunctionsClientUpgradeHelper(address(s_functionsRouter));
+ }
+}
+
+/// @notice Set up to create a subscription, add the consumer contract as a consumer of the subscription, and fund the subscription with 's_subscriptionInitialFunding'
+contract FunctionsSubscriptionSetup is FunctionsClientSetup {
+ uint64 s_subscriptionId;
+ uint96 s_subscriptionInitialFunding = 10 * JUELS_PER_LINK; // 10 LINK
+
+ function setUp() public virtual override {
+ FunctionsClientSetup.setUp();
+
+ // Create subscription
+ s_subscriptionId = s_functionsRouter.createSubscription();
+ s_functionsRouter.addConsumer(s_subscriptionId, address(s_functionsClient));
+
+ // Fund subscription
+ s_linkToken.transferAndCall(address(s_functionsRouter), s_subscriptionInitialFunding, abi.encode(s_subscriptionId));
+ }
+}
+
+/// @notice Set up to initate a minimal request and store it in s_requests[1]
+contract FunctionsClientRequestSetup is FunctionsSubscriptionSetup {
+ struct RequestData {
+ string sourceCode;
+ bytes secrets;
+ string[] args;
+ bytes[] bytesArgs;
+ uint32 callbackGasLimit;
+ }
+ struct Request {
+ RequestData requestData;
+ bytes32 requestId;
+ FunctionsResponse.Commitment commitment;
+ }
+
+ mapping(uint256 => Request) s_requests;
+
+ uint96 s_fulfillmentRouterOwnerBalance = 0;
+ uint96 s_fulfillmentCoordinatorBalance = 0;
+
+ function setUp() public virtual override {
+ FunctionsSubscriptionSetup.setUp();
+
+ // Send request #1
+ string memory sourceCode = "return 'hello world';";
+ bytes memory secrets = new bytes(0);
+ string[] memory args = new string[](0);
+ bytes[] memory bytesArgs = new bytes[](0);
+ uint32 callbackGasLimit = 5500;
+ _sendAndStoreRequest(1, sourceCode, secrets, args, bytesArgs, callbackGasLimit);
+ }
+
+ function _getExpectedCost(uint256 gasUsed) internal view returns (uint96 totalCostJuels) {
+ uint96 juelsPerGas = uint96((1e18 * TX_GASPRICE_START) / uint256(LINK_ETH_RATE));
+ uint96 gasOverheadJuels = juelsPerGas *
+ (getCoordinatorConfig().gasOverheadBeforeCallback + getCoordinatorConfig().gasOverheadAfterCallback);
+ uint96 callbackGasCostJuels = uint96(juelsPerGas * gasUsed);
+ return gasOverheadJuels + s_donFee + s_adminFee + callbackGasCostJuels;
+ }
+
+ /// @notice Send a request and store information about it in s_requests
+ /// @param requestNumberKey - the key that the request will be stored in `s_requests` in
+ /// @param sourceCode - Raw source code for Request.codeLocation of Location.Inline, URL for Request.codeLocation of Location.Remote, or slot decimal number for Request.codeLocation of Location.DONHosted
+ /// @param secrets - Encrypted URLs for Request.secretsLocation of Location.Remote (use addSecretsReference()), or CBOR encoded slotid+version for Request.secretsLocation of Location.DONHosted (use addDONHostedSecrets())
+ /// @param args - String arguments that will be passed into the source code
+ /// @param bytesArgs - Bytes arguments that will be passed into the source code
+ /// @param callbackGasLimit - Gas limit for the fulfillment callback
+ function _sendAndStoreRequest(
+ uint256 requestNumberKey,
+ string memory sourceCode,
+ bytes memory secrets,
+ string[] memory args,
+ bytes[] memory bytesArgs,
+ uint32 callbackGasLimit
+ ) internal {
+ if (s_requests[requestNumberKey].requestId != bytes32(0)) {
+ revert("Request already written");
+ }
+
+ vm.recordLogs();
+
+ bytes32 requestId = s_functionsClient.sendRequest(
+ s_donId,
+ sourceCode,
+ secrets,
+ args,
+ bytesArgs,
+ s_subscriptionId,
+ callbackGasLimit
+ );
+
+ // Get commitment data from OracleRequest event log
+ Vm.Log[] memory entries = vm.getRecordedLogs();
+ (, , , , , , , FunctionsResponse.Commitment memory commitment) = abi.decode(
+ entries[0].data,
+ (address, uint64, address, bytes, uint16, bytes32, uint64, FunctionsResponse.Commitment)
+ );
+ s_requests[requestNumberKey] = Request({
+ requestData: RequestData({
+ sourceCode: sourceCode,
+ secrets: secrets,
+ args: args,
+ bytesArgs: bytesArgs,
+ callbackGasLimit: callbackGasLimit
+ }),
+ requestId: requestId,
+ commitment: commitment
+ });
+ }
+
+ /// @notice Send a request and store information about it in s_requests
+ /// @param requestNumberKeys - One or more requestNumberKeys that were used to store the request in `s_requests` of the requests, that will be added to the report
+ /// @param results - The result that will be sent to the consumer contract's callback. For each index, e.g. result[index] or errors[index], only one of should be filled.
+ /// @param errors - The error that will be sent to the consumer contract's callback. For each index, e.g. result[index] or errors[index], only one of should be filled.
+ /// @return report - Report bytes data
+ /// @return reportContext - Report context bytes32 data
+ function _buildReport(
+ uint256[] memory requestNumberKeys,
+ string[] memory results,
+ bytes[] memory errors
+ ) internal view returns (bytes memory report, bytes32[3] memory reportContext) {
+ // Build report
+ bytes32[] memory _requestIds = new bytes32[](requestNumberKeys.length);
+ bytes[] memory _results = new bytes[](requestNumberKeys.length);
+ bytes[] memory _errors = new bytes[](requestNumberKeys.length);
+ bytes[] memory _onchainMetadata = new bytes[](requestNumberKeys.length);
+ bytes[] memory _offchainMetadata = new bytes[](requestNumberKeys.length);
+ for (uint256 i = 0; i < requestNumberKeys.length; ++i) {
+ if (keccak256(bytes(results[i])) != keccak256(new bytes(0)) && keccak256(errors[i]) != keccak256(new bytes(0))) {
+ revert("Report can only contain a result OR an error, one must remain empty.");
+ }
+ _requestIds[i] = s_requests[requestNumberKeys[i]].requestId;
+ _results[i] = bytes(results[i]);
+ _errors[i] = errors[i];
+ _onchainMetadata[i] = abi.encode(s_requests[requestNumberKeys[i]].commitment);
+ _offchainMetadata[i] = new bytes(0); // No off-chain metadata
+ }
+ report = abi.encode(_requestIds, _results, _errors, _onchainMetadata, _offchainMetadata);
+
+ // Build report context
+ uint256 h = uint256(
+ keccak256(
+ abi.encode(
+ block.chainid,
+ address(s_functionsCoordinator),
+ 1,
+ s_signers,
+ s_transmitters,
+ s_f,
+ s_onchainConfig,
+ s_offchainConfigVersion,
+ s_offchainConfig
+ )
+ )
+ );
+ uint256 prefixMask = type(uint256).max << (256 - 16); // 0xFFFF00..00
+ uint256 prefix = 0x0001 << (256 - 16); // 0x000100..00
+ bytes32 configDigest = bytes32((prefix & prefixMask) | (h & ~prefixMask));
+ reportContext = [configDigest, configDigest, configDigest];
+
+ return (report, reportContext);
+ }
+
+ /// @notice Gather signatures on report data
+ /// @param report - Report bytes generated from `_buildReport`
+ /// @param reportContext - Report context bytes32 generated from `_buildReport`
+ /// @param signerPrivateKeys - One or more addresses that will sign the report data
+ /// @return rawRs - Signature rs
+ /// @return rawSs - Signature ss
+ /// @return rawVs - Signature vs
+ function _signReport(
+ bytes memory report,
+ bytes32[3] memory reportContext,
+ uint256[] memory signerPrivateKeys
+ ) internal pure returns (bytes32[] memory rawRs, bytes32[] memory rawSs, bytes32 rawVs) {
+ bytes32[] memory rs = new bytes32[](signerPrivateKeys.length);
+ bytes32[] memory ss = new bytes32[](signerPrivateKeys.length);
+ bytes memory vs = new bytes(signerPrivateKeys.length);
+
+ bytes32 reportDigest = keccak256(abi.encodePacked(keccak256(report), reportContext));
+
+ for (uint256 i = 0; i < signerPrivateKeys.length; i++) {
+ (uint8 v, bytes32 r, bytes32 s) = vm.sign(signerPrivateKeys[i], reportDigest);
+ rs[i] = r;
+ ss[i] = s;
+ vs[i] = bytes1(v - 27);
+ }
+
+ return (rs, ss, bytes32(vs));
+ }
+
+ /// @notice Provide a response from the DON to fulfill one or more requests and store the updated balances of the DON & Admin
+ /// @param requestNumberKeys - One or more requestNumberKeys that were used to store the request in `s_requests` of the requests, that will be added to the report
+ /// @param results - The result that will be sent to the consumer contract's callback. For each index, e.g. result[index] or errors[index], only one of should be filled.
+ /// @param errors - The error that will be sent to the consumer contract's callback. For each index, e.g. result[index] or errors[index], only one of should be filled.
+ /// @param transmitter - The address that will send the `.report` transaction
+ /// @param expectedToSucceed - Boolean representing if the report transmission is expected to produce a RequestProcessed event for every fulfillment. If not, we ignore retrieving the event log.
+ /// @param requestProcessedIndex - On a successful fulfillment the Router will emit a RequestProcessed event. To grab that event we must know the order at which this event was thrown in the report transmission lifecycle. This can change depending on the test setup (e.g. the Client contract gives an extra event during its callback)
+ /// @param transmitterGasToUse - Override the default amount of gas that the transmitter sends the `.report` transaction with
+ function _reportAndStore(
+ uint256[] memory requestNumberKeys,
+ string[] memory results,
+ bytes[] memory errors,
+ address transmitter,
+ bool expectedToSucceed,
+ uint8 requestProcessedIndex,
+ uint256 transmitterGasToUse
+ ) internal {
+ {
+ if (requestNumberKeys.length != results.length || requestNumberKeys.length != errors.length) {
+ revert("_reportAndStore arguments length mismatch");
+ }
+ }
+
+ (bytes memory report, bytes32[3] memory reportContext) = _buildReport(requestNumberKeys, results, errors);
+
+ // Sign the report
+ // Need at least 3 signers to fulfill minimum number of: (configInfo.n + configInfo.f) / 2 + 1
+ uint256[] memory signerPrivateKeys = new uint256[](3);
+ signerPrivateKeys[0] = NOP_SIGNER_PRIVATE_KEY_1;
+ signerPrivateKeys[1] = NOP_SIGNER_PRIVATE_KEY_2;
+ signerPrivateKeys[2] = NOP_SIGNER_PRIVATE_KEY_3;
+ (bytes32[] memory rawRs, bytes32[] memory rawSs, bytes32 rawVs) = _signReport(
+ report,
+ reportContext,
+ signerPrivateKeys
+ );
+
+ // Send as transmitter
+ vm.stopPrank();
+ vm.startPrank(transmitter);
+
+ // Send report
+ vm.recordLogs();
+ if (transmitterGasToUse > 0) {
+ s_functionsCoordinator.transmit{gas: transmitterGasToUse}(reportContext, report, rawRs, rawSs, rawVs);
+ } else {
+ s_functionsCoordinator.transmit(reportContext, report, rawRs, rawSs, rawVs);
+ }
+
+ if (expectedToSucceed) {
+ // Get actual cost from RequestProcessed event log
+ (uint96 totalCostJuels, , , , , ) = abi.decode(
+ vm.getRecordedLogs()[requestProcessedIndex].data,
+ (uint96, address, FunctionsResponse.FulfillResult, bytes, bytes, bytes)
+ );
+ // Store profit amounts
+ s_fulfillmentRouterOwnerBalance += s_adminFee;
+ // totalCostJuels = costWithoutCallbackJuels + adminFee + callbackGasCostJuels
+ s_fulfillmentCoordinatorBalance += totalCostJuels - s_adminFee;
+ }
+
+ // Return prank to Owner
+ vm.stopPrank();
+ vm.startPrank(OWNER_ADDRESS);
+ }
+
+ /// @notice Provide a response from the DON to fulfill one or more requests and store the updated balances of the DON & Admin
+ /// @param requestNumberKeys - One or more requestNumberKeys that were used to store the request in `s_requests` of the requests, that will be added to the report
+ /// @param results - The result that will be sent to the consumer contract's callback. For each index, e.g. result[index] or errors[index], only one of should be filled.
+ /// @param errors - The error that will be sent to the consumer contract's callback. For each index, e.g. result[index] or errors[index], only one of should be filled.
+ /// @param transmitter - The address that will send the `.report` transaction
+ /// @param expectedToSucceed - Boolean representing if the report transmission is expected to produce a RequestProcessed event for every fulfillment. If not, we ignore retrieving the event log.
+ /// @param requestProcessedIndex - On a successful fulfillment the Router will emit a RequestProcessed event. To grab that event we must know the order at which this event was thrown in the report transmission lifecycle. This can change depending on the test setup (e.g. the Client contract gives an extra event during its callback)
+ /// @dev @param transmitterGasToUse is overloaded to give transmitterGasToUse as 0] - Sends the `.report` transaction with the default amount of gas
+ function _reportAndStore(
+ uint256[] memory requestNumberKeys,
+ string[] memory results,
+ bytes[] memory errors,
+ address transmitter,
+ bool expectedToSucceed,
+ uint8 requestProcessedIndex
+ ) internal {
+ _reportAndStore(requestNumberKeys, results, errors, transmitter, expectedToSucceed, requestProcessedIndex, 0);
+ }
+
+ /// @notice Provide a response from the DON to fulfill one or more requests and store the updated balances of the DON & Admin
+ /// @param requestNumberKeys - One or more requestNumberKeys that were used to store the request in `s_requests` of the requests, that will be added to the report
+ /// @param results - The result that will be sent to the consumer contract's callback. For each index, e.g. result[index] or errors[index], only one of should be filled.
+ /// @param errors - The error that will be sent to the consumer contract's callback. For each index, e.g. result[index] or errors[index], only one of should be filled.
+ /// @param transmitter - The address that will send the `.report` transaction
+ /// @param expectedToSucceed - Boolean representing if the report transmission is expected to produce a RequestProcessed event for every fulfillment. If not, we ignore retrieving the event log.
+ /// @dev @param requestProcessedIndex is overloaded to give requestProcessedIndex as 3 (happy path value)] - On a successful fulfillment the Router will emit a RequestProcessed event. To grab that event we must know the order at which this event was thrown in the report transmission lifecycle. This can change depending on the test setup (e.g. the Client contract gives an extra event during its callback)
+ /// @dev @param transmitterGasToUse is overloaded to give transmitterGasToUse as 0] - Sends the `.report` transaction with the default amount of gas
+ function _reportAndStore(
+ uint256[] memory requestNumberKeys,
+ string[] memory results,
+ bytes[] memory errors,
+ address transmitter,
+ bool expectedToSucceed
+ ) internal {
+ _reportAndStore(requestNumberKeys, results, errors, transmitter, expectedToSucceed, 3);
+ }
+
+ /// @notice Provide a response from the DON to fulfill one or more requests and store the updated balances of the DON & Admin
+ /// @param requestNumberKeys - One or more requestNumberKeys that were used to store the request in `s_requests` of the requests, that will be added to the report
+ /// @param results - The result that will be sent to the consumer contract's callback. For each index, e.g. result[index] or errors[index], only one of should be filled.
+ /// @param errors - The error that will be sent to the consumer contract's callback. For each index, e.g. result[index] or errors[index], only one of should be filled.
+ /// @param transmitter - The address that will send the `.report` transaction
+ /// @dev @param expectedToSucceed is overloaded to give the value as true - The report transmission is expected to produce a RequestProcessed event for every fulfillment
+ /// @dev @param requestProcessedIndex is overloaded to give requestProcessedIndex as 3 (happy path value)] - On a successful fulfillment the Router will emit a RequestProcessed event. To grab that event we must know the order at which this event was thrown in the report transmission lifecycle. This can change depending on the test setup (e.g. the Client contract gives an extra event during its callback)
+ /// @dev @param transmitterGasToUse is overloaded to give transmitterGasToUse as 0] - Sends the `.report` transaction with the default amount of gas
+ function _reportAndStore(
+ uint256[] memory requestNumberKeys,
+ string[] memory results,
+ bytes[] memory errors,
+ address transmitter
+ ) internal {
+ _reportAndStore(requestNumberKeys, results, errors, transmitter, true);
+ }
+
+ /// @notice Provide a response from the DON to fulfill one or more requests and store the updated balances of the DON & Admin
+ /// @param requestNumberKeys - One or more requestNumberKeys that were used to store the request in `s_requests` of the requests, that will be added to the report
+ /// @param results - The result that will be sent to the consumer contract's callback. For each index, e.g. result[index] or errors[index], only one of should be filled.
+ /// @param errors - The error that will be sent to the consumer contract's callback. For each index, e.g. result[index] or errors[index], only one of should be filled.
+ /// @dev @param transmitter is overloaded to give the value of transmitter #1 - The address that will send the `.report` transaction
+ /// @dev @param expectedToSucceed is overloaded to give the value as true - The report transmission is expected to produce a RequestProcessed event for every fulfillment
+ /// @dev @param requestProcessedIndex is overloaded to give requestProcessedIndex as 3 (happy path value)] - On a successful fulfillment the Router will emit a RequestProcessed event. To grab that event we must know the order at which this event was thrown in the report transmission lifecycle. This can change depending on the test setup (e.g. the Client contract gives an extra event during its callback)
+ /// @dev @param transmitterGasToUse is overloaded to give transmitterGasToUse as 0] - Sends the `.report` transaction with the default amount of gas
+ function _reportAndStore(
+ uint256[] memory requestNumberKeys,
+ string[] memory results,
+ bytes[] memory errors
+ ) internal {
+ _reportAndStore(requestNumberKeys, results, errors, NOP_TRANSMITTER_ADDRESS_1);
+ }
+}
+
+/// @notice Set up to have transmitter #1 send a report that fulfills request #1
+contract FunctionsFulfillmentSetup is FunctionsClientRequestSetup {
+ function setUp() public virtual override {
+ FunctionsClientRequestSetup.setUp();
+
+ // Fulfill request 1
+ uint256[] memory requestNumberKeys = new uint256[](1);
+ requestNumberKeys[0] = 1;
+ string[] memory results = new string[](1);
+ results[0] = "hello world!";
+ bytes[] memory errors = new bytes[](1);
+ errors[0] = new bytes(0);
+
+ _reportAndStore(requestNumberKeys, results, errors, NOP_TRANSMITTER_ADDRESS_1, true);
+ }
+}
+
+/// @notice Set up to send and fulfill two more requests, s_request[2] reported by transmitter #2 and s_request[3] reported by transmitter #3
+contract FunctionsMultipleFulfillmentsSetup is FunctionsFulfillmentSetup {
+ function setUp() public virtual override {
+ FunctionsFulfillmentSetup.setUp();
+
+ // Make 2 additional requests (1 already complete)
+
+ // *** Request #2 ***
+ // Send
+ string memory sourceCode = "return 'hello world';";
+ bytes memory secrets = new bytes(0);
+ string[] memory args = new string[](0);
+ bytes[] memory bytesArgs = new bytes[](0);
+ uint32 callbackGasLimit = 5500;
+ _sendAndStoreRequest(2, sourceCode, secrets, args, bytesArgs, callbackGasLimit);
+ // Fulfill as transmitter #2
+ uint256[] memory requestNumberKeys1 = new uint256[](1);
+ requestNumberKeys1[0] = 2;
+ string[] memory results1 = new string[](1);
+ results1[0] = "hello world!";
+ bytes[] memory errors1 = new bytes[](1);
+ errors1[0] = new bytes(0);
+ _reportAndStore(requestNumberKeys1, results1, errors1, NOP_TRANSMITTER_ADDRESS_2, true);
+
+ // *** Request #3 ***
+ // Send
+ _sendAndStoreRequest(3, sourceCode, secrets, args, bytesArgs, callbackGasLimit);
+ // Fulfill as transmitter #3
+ uint256[] memory requestNumberKeys2 = new uint256[](1);
+ requestNumberKeys2[0] = 3;
+ string[] memory results2 = new string[](1);
+ results2[0] = "hello world!";
+ bytes[] memory errors2 = new bytes[](1);
+ errors2[0] = new bytes(0);
+ _reportAndStore(requestNumberKeys2, results2, errors2, NOP_TRANSMITTER_ADDRESS_3, true);
+ }
+}
diff --git a/contracts/src/v0.8/functions/tests/1_0_0/testhelpers/FunctionsClientTestHelper.sol b/contracts/src/v0.8/functions/tests/v1_0_0/testhelpers/FunctionsClientTestHelper.sol
similarity index 90%
rename from contracts/src/v0.8/functions/tests/1_0_0/testhelpers/FunctionsClientTestHelper.sol
rename to contracts/src/v0.8/functions/tests/v1_0_0/testhelpers/FunctionsClientTestHelper.sol
index 92255e0b572..987bf3e48ab 100644
--- a/contracts/src/v0.8/functions/tests/1_0_0/testhelpers/FunctionsClientTestHelper.sol
+++ b/contracts/src/v0.8/functions/tests/v1_0_0/testhelpers/FunctionsClientTestHelper.sol
@@ -1,11 +1,11 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.6;
-import {ITermsOfServiceAllowList} from "../../../dev/1_0_0/accessControl/interfaces/ITermsOfServiceAllowList.sol";
-import {IFunctionsSubscriptions} from "../../../dev/1_0_0/interfaces/IFunctionsSubscriptions.sol";
+import {ITermsOfServiceAllowList} from "../../../dev/v1_0_0/accessControl/interfaces/ITermsOfServiceAllowList.sol";
+import {IFunctionsSubscriptions} from "../../../dev/v1_0_0/interfaces/IFunctionsSubscriptions.sol";
-import {FunctionsRequest} from "../../../dev/1_0_0/libraries/FunctionsRequest.sol";
-import {FunctionsClient} from "../../../dev/1_0_0/FunctionsClient.sol";
+import {FunctionsRequest} from "../../../dev/v1_0_0/libraries/FunctionsRequest.sol";
+import {FunctionsClient} from "../../../dev/v1_0_0/FunctionsClient.sol";
contract FunctionsClientTestHelper is FunctionsClient {
using FunctionsRequest for FunctionsRequest.Request;
diff --git a/contracts/src/v0.8/functions/tests/v1_0_0/testhelpers/FunctionsClientUpgradeHelper.sol b/contracts/src/v0.8/functions/tests/v1_0_0/testhelpers/FunctionsClientUpgradeHelper.sol
new file mode 100644
index 00000000000..e04ead8ad83
--- /dev/null
+++ b/contracts/src/v0.8/functions/tests/v1_0_0/testhelpers/FunctionsClientUpgradeHelper.sol
@@ -0,0 +1,148 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.19;
+
+import {FunctionsRequest} from "../../../dev/v1_0_0/libraries/FunctionsRequest.sol";
+import {FunctionsClient} from "../../../dev/v1_0_0/FunctionsClient.sol";
+import {ConfirmedOwner} from "../../../../shared/access/ConfirmedOwner.sol";
+
+contract FunctionsClientUpgradeHelper is FunctionsClient, ConfirmedOwner {
+ using FunctionsRequest for FunctionsRequest.Request;
+
+ constructor(address router) FunctionsClient(router) ConfirmedOwner(msg.sender) {}
+
+ event ResponseReceived(bytes32 indexed requestId, bytes result, bytes err);
+
+ /**
+ * @notice Send a simple request
+ *
+ * @param donId DON ID
+ * @param source JavaScript source code
+ * @param secrets Encrypted secrets payload
+ * @param args List of arguments accessible from within the source code
+ * @param subscriptionId Funtions billing subscription ID
+ * @param callbackGasLimit Maximum amount of gas used to call the client contract's `handleOracleFulfillment` function
+ * @return Functions request ID
+ */
+ function sendRequest(
+ bytes32 donId,
+ string calldata source,
+ bytes calldata secrets,
+ string[] calldata args,
+ bytes[] memory bytesArgs,
+ uint64 subscriptionId,
+ uint32 callbackGasLimit
+ ) public onlyOwner returns (bytes32) {
+ FunctionsRequest.Request memory req;
+ req.initializeRequestForInlineJavaScript(source);
+ if (secrets.length > 0) req.addSecretsReference(secrets);
+ if (args.length > 0) req.setArgs(args);
+ if (bytesArgs.length > 0) req.setBytesArgs(bytesArgs);
+
+ return _sendRequest(FunctionsRequest.encodeCBOR(req), subscriptionId, callbackGasLimit, donId);
+ }
+
+ /**
+ * @notice Same as sendRequest but for DONHosted secrets
+ */
+ function sendRequestWithDONHostedSecrets(
+ bytes32 donId,
+ string calldata source,
+ uint8 slotId,
+ uint64 slotVersion,
+ string[] calldata args,
+ uint64 subscriptionId,
+ uint32 callbackGasLimit
+ ) public onlyOwner returns (bytes32) {
+ FunctionsRequest.Request memory req;
+ req.initializeRequestForInlineJavaScript(source);
+ req.addDONHostedSecrets(slotId, slotVersion);
+
+ if (args.length > 0) req.setArgs(args);
+
+ return _sendRequest(FunctionsRequest.encodeCBOR(req), subscriptionId, callbackGasLimit, donId);
+ }
+
+ // @notice Sends a Chainlink Functions request
+ // @param data The CBOR encoded bytes data for a Functions request
+ // @param subscriptionId The subscription ID that will be charged to service the request
+ // @param callbackGasLimit the amount of gas that will be available for the fulfillment callback
+ // @return requestId The generated request ID for this request
+ function _sendRequestToProposed(
+ bytes memory data,
+ uint64 subscriptionId,
+ uint32 callbackGasLimit,
+ bytes32 donId
+ ) internal returns (bytes32) {
+ bytes32 requestId = i_router.sendRequestToProposed(
+ subscriptionId,
+ data,
+ FunctionsRequest.REQUEST_DATA_VERSION,
+ callbackGasLimit,
+ donId
+ );
+ emit RequestSent(requestId);
+ return requestId;
+ }
+
+ /**
+ * @notice Send a simple request to the proposed contract
+ *
+ * @param donId DON ID
+ * @param source JavaScript source code
+ * @param secrets Encrypted secrets payload
+ * @param args List of arguments accessible from within the source code
+ * @param subscriptionId Funtions billing subscription ID
+ * @param callbackGasLimit Maximum amount of gas used to call the client contract's `handleOracleFulfillment` function
+ * @return Functions request ID
+ */
+ function sendRequestToProposed(
+ bytes32 donId,
+ string calldata source,
+ bytes calldata secrets,
+ string[] calldata args,
+ bytes[] memory bytesArgs,
+ uint64 subscriptionId,
+ uint32 callbackGasLimit
+ ) public onlyOwner returns (bytes32) {
+ FunctionsRequest.Request memory req;
+ req.initializeRequestForInlineJavaScript(source);
+ if (secrets.length > 0) req.addSecretsReference(secrets);
+ if (args.length > 0) req.setArgs(args);
+ if (bytesArgs.length > 0) req.setBytesArgs(bytesArgs);
+
+ return _sendRequestToProposed(FunctionsRequest.encodeCBOR(req), subscriptionId, callbackGasLimit, donId);
+ }
+
+ /**
+ * @notice Same as sendRequestToProposed but for DONHosted secrets
+ */
+ function sendRequestToProposedWithDONHostedSecrets(
+ bytes32 donId,
+ string calldata source,
+ uint8 slotId,
+ uint64 slotVersion,
+ string[] calldata args,
+ uint64 subscriptionId,
+ uint32 callbackGasLimit
+ ) public onlyOwner returns (bytes32) {
+ FunctionsRequest.Request memory req;
+ req.initializeRequestForInlineJavaScript(source);
+ req.addDONHostedSecrets(slotId, slotVersion);
+
+ if (args.length > 0) req.setArgs(args);
+
+ return _sendRequestToProposed(FunctionsRequest.encodeCBOR(req), subscriptionId, callbackGasLimit, donId);
+ }
+
+ /**
+ * @notice Callback that is invoked once the DON has resolved the request or hit an error
+ *
+ * @param requestId The request ID, returned by sendRequest()
+ * @param response Aggregated response from the user code
+ * @param err Aggregated error from the user code or from the execution pipeline
+ * Either response or error parameter will be set, but never both
+ */
+ function fulfillRequest(bytes32 requestId, bytes memory response, bytes memory err) internal override {
+ emit ResponseReceived(requestId, response, err);
+ }
+}
diff --git a/contracts/src/v0.8/functions/tests/1_0_0/testhelpers/FunctionsClientWithEmptyCallback.sol b/contracts/src/v0.8/functions/tests/v1_0_0/testhelpers/FunctionsClientWithEmptyCallback.sol
similarity index 87%
rename from contracts/src/v0.8/functions/tests/1_0_0/testhelpers/FunctionsClientWithEmptyCallback.sol
rename to contracts/src/v0.8/functions/tests/v1_0_0/testhelpers/FunctionsClientWithEmptyCallback.sol
index 4878290b6eb..5feede895f0 100644
--- a/contracts/src/v0.8/functions/tests/1_0_0/testhelpers/FunctionsClientWithEmptyCallback.sol
+++ b/contracts/src/v0.8/functions/tests/v1_0_0/testhelpers/FunctionsClientWithEmptyCallback.sol
@@ -1,8 +1,8 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.6;
-import {FunctionsRequest} from "../../../dev/1_0_0/libraries/FunctionsRequest.sol";
-import {FunctionsClient} from "../../../dev/1_0_0/FunctionsClient.sol";
+import {FunctionsRequest} from "../../../dev/v1_0_0/libraries/FunctionsRequest.sol";
+import {FunctionsClient} from "../../../dev/v1_0_0/FunctionsClient.sol";
contract FunctionsClientWithEmptyCallback is FunctionsClient {
using FunctionsRequest for FunctionsRequest.Request;
diff --git a/contracts/src/v0.8/functions/tests/1_0_0/testhelpers/FunctionsCoordinatorTestHelper.sol b/contracts/src/v0.8/functions/tests/v1_0_0/testhelpers/FunctionsCoordinatorTestHelper.sol
similarity index 69%
rename from contracts/src/v0.8/functions/tests/1_0_0/testhelpers/FunctionsCoordinatorTestHelper.sol
rename to contracts/src/v0.8/functions/tests/v1_0_0/testhelpers/FunctionsCoordinatorTestHelper.sol
index 0bf7adb7a25..bf55258fbdb 100644
--- a/contracts/src/v0.8/functions/tests/1_0_0/testhelpers/FunctionsCoordinatorTestHelper.sol
+++ b/contracts/src/v0.8/functions/tests/v1_0_0/testhelpers/FunctionsCoordinatorTestHelper.sol
@@ -1,8 +1,8 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.6;
-import {FunctionsCoordinator} from "../../../dev/1_0_0/FunctionsCoordinator.sol";
-import {FunctionsBilling} from "../../../dev/1_0_0/FunctionsBilling.sol";
+import {FunctionsCoordinator} from "../../../dev/v1_0_0/FunctionsCoordinator.sol";
+import {FunctionsBilling} from "../../../dev/v1_0_0/FunctionsBilling.sol";
contract FunctionsCoordinatorTestHelper is FunctionsCoordinator {
constructor(
@@ -23,4 +23,8 @@ contract FunctionsCoordinatorTestHelper is FunctionsCoordinator {
signers[1] = secondSigner;
_report(gasleft(), msg.sender, 2, signers, report);
}
+
+ function callReportWithSigners(bytes calldata report, address[MAX_NUM_ORACLES] memory signers) external {
+ _report(gasleft(), msg.sender, 2, signers, report);
+ }
}
diff --git a/contracts/src/v0.8/functions/tests/v1_0_0/testhelpers/FunctionsLoadTestClient.sol b/contracts/src/v0.8/functions/tests/v1_0_0/testhelpers/FunctionsLoadTestClient.sol
new file mode 100644
index 00000000000..c31962ba1f4
--- /dev/null
+++ b/contracts/src/v0.8/functions/tests/v1_0_0/testhelpers/FunctionsLoadTestClient.sol
@@ -0,0 +1,152 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.19;
+
+import {FunctionsClient} from "../../../dev/v1_0_0/FunctionsClient.sol";
+import {ConfirmedOwner} from "../../../../shared/access/ConfirmedOwner.sol";
+import {FunctionsRequest} from "../../../dev/v1_0_0/libraries/FunctionsRequest.sol";
+
+/**
+ * @title Chainlink Functions load test client implementation
+ */
+contract FunctionsLoadTestClient is FunctionsClient, ConfirmedOwner {
+ using FunctionsRequest for FunctionsRequest.Request;
+
+ uint32 public constant MAX_CALLBACK_GAS = 250_000;
+
+ bytes32 public lastRequestID;
+ bytes public lastResponse;
+ bytes public lastError;
+ uint32 public totalRequests;
+ uint32 public totalEmptyResponses;
+ uint32 public totalSucceededResponses;
+ uint32 public totalFailedResponses;
+
+ constructor(address router) FunctionsClient(router) ConfirmedOwner(msg.sender) {}
+
+ /**
+ * @notice Send a simple request
+ * @param times Number of times to send the request
+ * @param source JavaScript source code
+ * @param encryptedSecretsReferences Encrypted secrets payload
+ * @param args List of arguments accessible from within the source code
+ * @param subscriptionId Billing ID
+ * @param donId DON ID
+ */
+ function sendRequest(
+ uint32 times,
+ string calldata source,
+ bytes calldata encryptedSecretsReferences,
+ string[] calldata args,
+ uint64 subscriptionId,
+ bytes32 donId
+ ) external onlyOwner {
+ FunctionsRequest.Request memory req;
+ req.initializeRequestForInlineJavaScript(source);
+ if (encryptedSecretsReferences.length > 0) req.addSecretsReference(encryptedSecretsReferences);
+ if (args.length > 0) req.setArgs(args);
+ uint i = 0;
+ for (i = 0; i < times; i++) {
+ lastRequestID = _sendRequest(req.encodeCBOR(), subscriptionId, MAX_CALLBACK_GAS, donId);
+ totalRequests += 1;
+ }
+ }
+
+ /**
+ * @notice Same as sendRequest but for DONHosted secrets
+ * @param times Number of times to send the request
+ * @param source JavaScript source code
+ * @param slotId DON hosted secrets slot ID
+ * @param slotVersion DON hosted secrets slot version
+ * @param args List of arguments accessible from within the source code
+ * @param subscriptionId Billing ID
+ * @param donId DON ID
+ */
+ function sendRequestWithDONHostedSecrets(
+ uint32 times,
+ string calldata source,
+ uint8 slotId,
+ uint64 slotVersion,
+ string[] calldata args,
+ uint64 subscriptionId,
+ bytes32 donId
+ ) public onlyOwner {
+ FunctionsRequest.Request memory req;
+ req.initializeRequestForInlineJavaScript(source);
+ req.addDONHostedSecrets(slotId, slotVersion);
+ if (args.length > 0) req.setArgs(args);
+ uint i = 0;
+ for (i = 0; i < times; i++) {
+ lastRequestID = _sendRequest(req.encodeCBOR(), subscriptionId, MAX_CALLBACK_GAS, donId);
+ totalRequests += 1;
+ }
+ }
+
+ /**
+ * @notice Sends a Chainlink Functions request that has already been CBOR encoded
+ * @param times Number of times to send the request
+ * @param cborEncodedRequest The CBOR encoded bytes data for a Functions request
+ * @param subscriptionId The subscription ID that will be charged to service the request
+ * @param donId DON ID
+ */
+ function sendEncodedRequest(
+ uint32 times,
+ bytes memory cborEncodedRequest,
+ uint64 subscriptionId,
+ bytes32 donId
+ ) public onlyOwner {
+ uint i = 0;
+ for (i = 0; i < times; i++) {
+ lastRequestID = _sendRequest(cborEncodedRequest, subscriptionId, MAX_CALLBACK_GAS, donId);
+ totalRequests += 1;
+ }
+ }
+
+ function resetStats() external onlyOwner {
+ lastRequestID = "";
+ lastResponse = "";
+ lastError = "";
+ totalRequests = 0;
+ totalSucceededResponses = 0;
+ totalFailedResponses = 0;
+ totalEmptyResponses = 0;
+ }
+
+ function getStats()
+ public
+ view
+ onlyOwner
+ returns (bytes32, bytes memory, bytes memory, uint32, uint32, uint32, uint32)
+ {
+ return (
+ lastRequestID,
+ lastResponse,
+ lastError,
+ totalRequests,
+ totalSucceededResponses,
+ totalFailedResponses,
+ totalEmptyResponses
+ );
+ }
+
+ /**
+ * @notice Store latest result/error
+ * @param requestId The request ID, returned by sendRequest()
+ * @param response Aggregated response from the user code
+ * @param err Aggregated error from the user code or from the execution pipeline
+ * Either response or error parameter will be set, but never both
+ */
+ function fulfillRequest(bytes32 requestId, bytes memory response, bytes memory err) internal override {
+ lastRequestID = requestId;
+ lastResponse = response;
+ lastError = err;
+ if (response.length == 0) {
+ totalEmptyResponses += 1;
+ }
+ if (err.length != 0) {
+ totalFailedResponses += 1;
+ }
+ if (response.length != 0 && err.length == 0) {
+ totalSucceededResponses += 1;
+ }
+ }
+}
diff --git a/contracts/src/v0.8/functions/tests/1_0_0/testhelpers/FunctionsTestHelper.sol b/contracts/src/v0.8/functions/tests/v1_0_0/testhelpers/FunctionsTestHelper.sol
similarity index 82%
rename from contracts/src/v0.8/functions/tests/1_0_0/testhelpers/FunctionsTestHelper.sol
rename to contracts/src/v0.8/functions/tests/v1_0_0/testhelpers/FunctionsTestHelper.sol
index 57ae6e0bbad..9ab5386dda7 100644
--- a/contracts/src/v0.8/functions/tests/1_0_0/testhelpers/FunctionsTestHelper.sol
+++ b/contracts/src/v0.8/functions/tests/v1_0_0/testhelpers/FunctionsTestHelper.sol
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.6;
-import {FunctionsRequest} from "../../../dev/1_0_0/libraries/FunctionsRequest.sol";
+import {FunctionsRequest} from "../../../dev/v1_0_0/libraries/FunctionsRequest.sol";
contract FunctionsTestHelper {
using FunctionsRequest for FunctionsRequest.Request;
@@ -41,12 +41,6 @@ contract FunctionsTestHelper {
storeRequest(r);
}
- function addSignature(bytes memory signature) public {
- FunctionsRequest.Request memory r = s_req;
- r.requestSignature = signature;
- storeRequest(r);
- }
-
function storeRequest(FunctionsRequest.Request memory r) private {
s_req.codeLocation = r.codeLocation;
s_req.language = r.language;
@@ -54,6 +48,5 @@ contract FunctionsTestHelper {
s_req.args = r.args;
s_req.secretsLocation = r.secretsLocation;
s_req.encryptedSecretsReference = r.encryptedSecretsReference;
- s_req.requestSignature = r.requestSignature;
}
}
diff --git a/contracts/src/v0.8/functions/v1_0_0/.gitkeep b/contracts/src/v0.8/functions/v1_0_0/.gitkeep
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/contracts/src/v0.8/dev/CrossDomainDelegateForwarder.sol b/contracts/src/v0.8/l2ep/dev/CrossDomainDelegateForwarder.sol
similarity index 100%
rename from contracts/src/v0.8/dev/CrossDomainDelegateForwarder.sol
rename to contracts/src/v0.8/l2ep/dev/CrossDomainDelegateForwarder.sol
diff --git a/contracts/src/v0.8/dev/CrossDomainForwarder.sol b/contracts/src/v0.8/l2ep/dev/CrossDomainForwarder.sol
similarity index 100%
rename from contracts/src/v0.8/dev/CrossDomainForwarder.sol
rename to contracts/src/v0.8/l2ep/dev/CrossDomainForwarder.sol
diff --git a/contracts/src/v0.8/dev/CrossDomainOwnable.sol b/contracts/src/v0.8/l2ep/dev/CrossDomainOwnable.sol
similarity index 97%
rename from contracts/src/v0.8/dev/CrossDomainOwnable.sol
rename to contracts/src/v0.8/l2ep/dev/CrossDomainOwnable.sol
index 7a055ddad9e..966a66372fe 100644
--- a/contracts/src/v0.8/dev/CrossDomainOwnable.sol
+++ b/contracts/src/v0.8/l2ep/dev/CrossDomainOwnable.sol
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
-import "../shared/access/ConfirmedOwner.sol";
+import "../../shared/access/ConfirmedOwner.sol";
import "./interfaces/CrossDomainOwnableInterface.sol";
/**
diff --git a/contracts/src/v0.8/dev/ArbitrumCrossDomainForwarder.sol b/contracts/src/v0.8/l2ep/dev/arbitrum/ArbitrumCrossDomainForwarder.sol
similarity index 89%
rename from contracts/src/v0.8/dev/ArbitrumCrossDomainForwarder.sol
rename to contracts/src/v0.8/l2ep/dev/arbitrum/ArbitrumCrossDomainForwarder.sol
index cc04e0e4a00..4f4a197d809 100644
--- a/contracts/src/v0.8/dev/ArbitrumCrossDomainForwarder.sol
+++ b/contracts/src/v0.8/l2ep/dev/arbitrum/ArbitrumCrossDomainForwarder.sol
@@ -1,10 +1,10 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
-import "../interfaces/TypeAndVersionInterface.sol";
-import "./../vendor/arb-bridge-eth/v0.8.0-custom/contracts/libraries/AddressAliasHelper.sol";
-import "../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/Address.sol";
-import "./CrossDomainForwarder.sol";
+import "../../../interfaces/TypeAndVersionInterface.sol";
+import "../../../vendor/arb-bridge-eth/v0.8.0-custom/contracts/libraries/AddressAliasHelper.sol";
+import "../../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/Address.sol";
+import "../CrossDomainForwarder.sol";
/**
* @title ArbitrumCrossDomainForwarder - L1 xDomain account representation
diff --git a/contracts/src/v0.8/dev/ArbitrumCrossDomainGovernor.sol b/contracts/src/v0.8/l2ep/dev/arbitrum/ArbitrumCrossDomainGovernor.sol
similarity index 90%
rename from contracts/src/v0.8/dev/ArbitrumCrossDomainGovernor.sol
rename to contracts/src/v0.8/l2ep/dev/arbitrum/ArbitrumCrossDomainGovernor.sol
index 8e93bd2935d..8035d07ad2f 100644
--- a/contracts/src/v0.8/dev/ArbitrumCrossDomainGovernor.sol
+++ b/contracts/src/v0.8/l2ep/dev/arbitrum/ArbitrumCrossDomainGovernor.sol
@@ -1,9 +1,9 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
-import "./interfaces/DelegateForwarderInterface.sol";
-import "./../vendor/arb-bridge-eth/v0.8.0-custom/contracts/libraries/AddressAliasHelper.sol";
-import "../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/Address.sol";
+import "../interfaces/DelegateForwarderInterface.sol";
+import "../../../vendor/arb-bridge-eth/v0.8.0-custom/contracts/libraries/AddressAliasHelper.sol";
+import "../../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/Address.sol";
import "./ArbitrumCrossDomainForwarder.sol";
/**
diff --git a/contracts/src/v0.8/dev/ArbitrumSequencerUptimeFeed.sol b/contracts/src/v0.8/l2ep/dev/arbitrum/ArbitrumSequencerUptimeFeed.sol
similarity index 91%
rename from contracts/src/v0.8/dev/ArbitrumSequencerUptimeFeed.sol
rename to contracts/src/v0.8/l2ep/dev/arbitrum/ArbitrumSequencerUptimeFeed.sol
index 0191bbd88a3..3c09fb9acad 100644
--- a/contracts/src/v0.8/dev/ArbitrumSequencerUptimeFeed.sol
+++ b/contracts/src/v0.8/l2ep/dev/arbitrum/ArbitrumSequencerUptimeFeed.sol
@@ -1,16 +1,16 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
-import {AddressAliasHelper} from "./../vendor/arb-bridge-eth/v0.8.0-custom/contracts/libraries/AddressAliasHelper.sol";
-import {ForwarderInterface} from "./interfaces/ForwarderInterface.sol";
-import {AggregatorInterface} from "../interfaces/AggregatorInterface.sol";
-import {AggregatorV3Interface} from "../interfaces/AggregatorV3Interface.sol";
-import {AggregatorV2V3Interface} from "../interfaces/AggregatorV2V3Interface.sol";
-import {TypeAndVersionInterface} from "../interfaces/TypeAndVersionInterface.sol";
-import {FlagsInterface} from "./interfaces/FlagsInterface.sol";
-import {ArbitrumSequencerUptimeFeedInterface} from "./interfaces/ArbitrumSequencerUptimeFeedInterface.sol";
-import {SimpleReadAccessController} from "../SimpleReadAccessController.sol";
-import {ConfirmedOwner} from "../shared/access/ConfirmedOwner.sol";
+import {AddressAliasHelper} from "../../../vendor/arb-bridge-eth/v0.8.0-custom/contracts/libraries/AddressAliasHelper.sol";
+import {ForwarderInterface} from "./../interfaces/ForwarderInterface.sol";
+import {AggregatorInterface} from "../../../interfaces/AggregatorInterface.sol";
+import {AggregatorV3Interface} from "../../../interfaces/AggregatorV3Interface.sol";
+import {AggregatorV2V3Interface} from "../../../interfaces/AggregatorV2V3Interface.sol";
+import {TypeAndVersionInterface} from "../../../interfaces/TypeAndVersionInterface.sol";
+import {FlagsInterface} from "./../../../dev/interfaces/FlagsInterface.sol";
+import {ArbitrumSequencerUptimeFeedInterface} from "../interfaces/ArbitrumSequencerUptimeFeedInterface.sol";
+import {SimpleReadAccessController} from "../../../shared/access/SimpleReadAccessController.sol";
+import {ConfirmedOwner} from "../../../shared/access/ConfirmedOwner.sol";
/**
* @title ArbitrumSequencerUptimeFeed - L2 sequencer uptime status aggregator
diff --git a/contracts/src/v0.8/dev/ArbitrumValidator.sol b/contracts/src/v0.8/l2ep/dev/arbitrum/ArbitrumValidator.sol
similarity index 95%
rename from contracts/src/v0.8/dev/ArbitrumValidator.sol
rename to contracts/src/v0.8/l2ep/dev/arbitrum/ArbitrumValidator.sol
index 4e8d9a8537e..c882a09254a 100644
--- a/contracts/src/v0.8/dev/ArbitrumValidator.sol
+++ b/contracts/src/v0.8/l2ep/dev/arbitrum/ArbitrumValidator.sol
@@ -1,19 +1,19 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
-import "../interfaces/AggregatorValidatorInterface.sol";
-import "../interfaces/TypeAndVersionInterface.sol";
-import "../interfaces/AccessControllerInterface.sol";
-import "../interfaces/AggregatorV3Interface.sol";
-import "../SimpleWriteAccessController.sol";
+import "../../../interfaces/AggregatorValidatorInterface.sol";
+import "../../../interfaces/TypeAndVersionInterface.sol";
+import "../../../shared/interfaces/AccessControllerInterface.sol";
+import "../../../interfaces/AggregatorV3Interface.sol";
+import "../../../shared/access/SimpleWriteAccessController.sol";
/* ./dev dependencies - to be moved from ./dev after audit */
-import "./interfaces/ArbitrumSequencerUptimeFeedInterface.sol";
-import "./interfaces/FlagsInterface.sol";
-import "./interfaces/IArbitrumDelayedInbox.sol";
-import "./../vendor/arb-bridge-eth/v0.8.0-custom/contracts/libraries/AddressAliasHelper.sol";
-import "../vendor/@arbitrum/nitro-contracts/src/precompiles/ArbSys.sol";
-import "../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/Address.sol";
+import "../interfaces/ArbitrumSequencerUptimeFeedInterface.sol";
+import "../../../dev/interfaces/FlagsInterface.sol";
+import "../interfaces/IArbitrumDelayedInbox.sol";
+import "../../../vendor/arb-bridge-eth/v0.8.0-custom/contracts/libraries/AddressAliasHelper.sol";
+import "../../../vendor/@arbitrum/nitro-contracts/src/precompiles/ArbSys.sol";
+import "../../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/Address.sol";
/**
* @title ArbitrumValidator - makes xDomain L2 Flags contract call (using L2 xDomain Forwarder contract)
diff --git a/contracts/src/v0.8/dev/interfaces/ArbitrumSequencerUptimeFeedInterface.sol b/contracts/src/v0.8/l2ep/dev/interfaces/ArbitrumSequencerUptimeFeedInterface.sol
similarity index 100%
rename from contracts/src/v0.8/dev/interfaces/ArbitrumSequencerUptimeFeedInterface.sol
rename to contracts/src/v0.8/l2ep/dev/interfaces/ArbitrumSequencerUptimeFeedInterface.sol
diff --git a/contracts/src/v0.8/dev/interfaces/CrossDomainOwnableInterface.sol b/contracts/src/v0.8/l2ep/dev/interfaces/CrossDomainOwnableInterface.sol
similarity index 100%
rename from contracts/src/v0.8/dev/interfaces/CrossDomainOwnableInterface.sol
rename to contracts/src/v0.8/l2ep/dev/interfaces/CrossDomainOwnableInterface.sol
diff --git a/contracts/src/v0.8/dev/interfaces/DelegateForwarderInterface.sol b/contracts/src/v0.8/l2ep/dev/interfaces/DelegateForwarderInterface.sol
similarity index 100%
rename from contracts/src/v0.8/dev/interfaces/DelegateForwarderInterface.sol
rename to contracts/src/v0.8/l2ep/dev/interfaces/DelegateForwarderInterface.sol
diff --git a/contracts/src/v0.8/dev/interfaces/ForwarderInterface.sol b/contracts/src/v0.8/l2ep/dev/interfaces/ForwarderInterface.sol
similarity index 100%
rename from contracts/src/v0.8/dev/interfaces/ForwarderInterface.sol
rename to contracts/src/v0.8/l2ep/dev/interfaces/ForwarderInterface.sol
diff --git a/contracts/src/v0.8/dev/interfaces/IArbitrumDelayedInbox.sol b/contracts/src/v0.8/l2ep/dev/interfaces/IArbitrumDelayedInbox.sol
similarity index 85%
rename from contracts/src/v0.8/dev/interfaces/IArbitrumDelayedInbox.sol
rename to contracts/src/v0.8/l2ep/dev/interfaces/IArbitrumDelayedInbox.sol
index d209551b0c9..65e437189a7 100644
--- a/contracts/src/v0.8/dev/interfaces/IArbitrumDelayedInbox.sol
+++ b/contracts/src/v0.8/l2ep/dev/interfaces/IArbitrumDelayedInbox.sol
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
-import "../../vendor/arb-bridge-eth/v0.8.0-custom/contracts/bridge/interfaces/IInbox.sol";
+import "../../../vendor/arb-bridge-eth/v0.8.0-custom/contracts/bridge/interfaces/IInbox.sol";
/**
* @notice This interface extends Arbitrum's IInbox interface to include
diff --git a/contracts/src/v0.8/dev/interfaces/OptimismSequencerUptimeFeedInterface.sol b/contracts/src/v0.8/l2ep/dev/interfaces/OptimismSequencerUptimeFeedInterface.sol
similarity index 100%
rename from contracts/src/v0.8/dev/interfaces/OptimismSequencerUptimeFeedInterface.sol
rename to contracts/src/v0.8/l2ep/dev/interfaces/OptimismSequencerUptimeFeedInterface.sol
diff --git a/contracts/src/v0.8/dev/OptimismCrossDomainForwarder.sol b/contracts/src/v0.8/l2ep/dev/optimism/OptimismCrossDomainForwarder.sol
similarity index 90%
rename from contracts/src/v0.8/dev/OptimismCrossDomainForwarder.sol
rename to contracts/src/v0.8/l2ep/dev/optimism/OptimismCrossDomainForwarder.sol
index 9da3db692b9..1d7c211bbac 100644
--- a/contracts/src/v0.8/dev/OptimismCrossDomainForwarder.sol
+++ b/contracts/src/v0.8/l2ep/dev/optimism/OptimismCrossDomainForwarder.sol
@@ -1,12 +1,12 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
-import "../interfaces/TypeAndVersionInterface.sol";
+import "../../../interfaces/TypeAndVersionInterface.sol";
/* ./dev dependencies - to be moved from ./dev after audit */
-import "./CrossDomainForwarder.sol";
-import "../vendor/@eth-optimism/contracts/0.4.7/contracts/optimistic-ethereum/iOVM/bridge/messaging/iOVM_CrossDomainMessenger.sol";
-import "../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/Address.sol";
+import "../CrossDomainForwarder.sol";
+import "../../../vendor/@eth-optimism/contracts/v0.4.7/contracts/optimistic-ethereum/iOVM/bridge/messaging/iOVM_CrossDomainMessenger.sol";
+import "../../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/Address.sol";
/**
* @title OptimismCrossDomainForwarder - L1 xDomain account representation
diff --git a/contracts/src/v0.8/dev/OptimismCrossDomainGovernor.sol b/contracts/src/v0.8/l2ep/dev/optimism/OptimismCrossDomainGovernor.sol
similarity index 91%
rename from contracts/src/v0.8/dev/OptimismCrossDomainGovernor.sol
rename to contracts/src/v0.8/l2ep/dev/optimism/OptimismCrossDomainGovernor.sol
index 4c878b36068..bd1b0b9e885 100644
--- a/contracts/src/v0.8/dev/OptimismCrossDomainGovernor.sol
+++ b/contracts/src/v0.8/l2ep/dev/optimism/OptimismCrossDomainGovernor.sol
@@ -1,9 +1,9 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
-import "./interfaces/DelegateForwarderInterface.sol";
-import "../vendor/@eth-optimism/contracts/0.4.7/contracts/optimistic-ethereum/iOVM/bridge/messaging/iOVM_CrossDomainMessenger.sol";
-import "../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/Address.sol";
+import "../interfaces/DelegateForwarderInterface.sol";
+import "../../../vendor/@eth-optimism/contracts/v0.4.7/contracts/optimistic-ethereum/iOVM/bridge/messaging/iOVM_CrossDomainMessenger.sol";
+import "../../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/Address.sol";
import "./OptimismCrossDomainForwarder.sol";
/**
diff --git a/contracts/src/v0.8/dev/OptimismSequencerUptimeFeed.sol b/contracts/src/v0.8/l2ep/dev/optimism/OptimismSequencerUptimeFeed.sol
similarity index 93%
rename from contracts/src/v0.8/dev/OptimismSequencerUptimeFeed.sol
rename to contracts/src/v0.8/l2ep/dev/optimism/OptimismSequencerUptimeFeed.sol
index 86215f87237..a4ef57505b5 100644
--- a/contracts/src/v0.8/dev/OptimismSequencerUptimeFeed.sol
+++ b/contracts/src/v0.8/l2ep/dev/optimism/OptimismSequencerUptimeFeed.sol
@@ -1,13 +1,13 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
-import {AggregatorInterface} from "../interfaces/AggregatorInterface.sol";
-import {AggregatorV3Interface} from "../interfaces/AggregatorV3Interface.sol";
-import {AggregatorV2V3Interface} from "../interfaces/AggregatorV2V3Interface.sol";
-import {TypeAndVersionInterface} from "../interfaces/TypeAndVersionInterface.sol";
-import {OptimismSequencerUptimeFeedInterface} from "./interfaces/OptimismSequencerUptimeFeedInterface.sol";
-import {SimpleReadAccessController} from "../SimpleReadAccessController.sol";
-import {ConfirmedOwner} from "../shared/access/ConfirmedOwner.sol";
+import {AggregatorInterface} from "../../../interfaces/AggregatorInterface.sol";
+import {AggregatorV3Interface} from "../../../interfaces/AggregatorV3Interface.sol";
+import {AggregatorV2V3Interface} from "../../../interfaces/AggregatorV2V3Interface.sol";
+import {TypeAndVersionInterface} from "../../../interfaces/TypeAndVersionInterface.sol";
+import {OptimismSequencerUptimeFeedInterface} from "./../interfaces/OptimismSequencerUptimeFeedInterface.sol";
+import {SimpleReadAccessController} from "../../../shared/access/SimpleReadAccessController.sol";
+import {ConfirmedOwner} from "../../../shared/access/ConfirmedOwner.sol";
import {IL2CrossDomainMessenger} from "@eth-optimism/contracts/L2/messaging/IL2CrossDomainMessenger.sol";
/**
diff --git a/contracts/src/v0.8/dev/OptimismValidator.sol b/contracts/src/v0.8/l2ep/dev/optimism/OptimismValidator.sol
similarity index 88%
rename from contracts/src/v0.8/dev/OptimismValidator.sol
rename to contracts/src/v0.8/l2ep/dev/optimism/OptimismValidator.sol
index f08f2e323de..c25b481166f 100644
--- a/contracts/src/v0.8/dev/OptimismValidator.sol
+++ b/contracts/src/v0.8/l2ep/dev/optimism/OptimismValidator.sol
@@ -1,15 +1,15 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
-import "../interfaces/AggregatorValidatorInterface.sol";
-import "../interfaces/TypeAndVersionInterface.sol";
-import "../interfaces/AccessControllerInterface.sol";
-import "../interfaces/AggregatorV3Interface.sol";
-import "../SimpleWriteAccessController.sol";
+import "../../../interfaces/AggregatorValidatorInterface.sol";
+import "../../../interfaces/TypeAndVersionInterface.sol";
+import "../../../shared/interfaces/AccessControllerInterface.sol";
+import "../../../interfaces/AggregatorV3Interface.sol";
+import "../../../shared/access/SimpleWriteAccessController.sol";
-import "./interfaces/OptimismSequencerUptimeFeedInterface.sol";
+import "./../interfaces/OptimismSequencerUptimeFeedInterface.sol";
import "@eth-optimism/contracts/L1/messaging/IL1CrossDomainMessenger.sol";
-import "../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/Address.sol";
+import "../../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/Address.sol";
/**
* @title OptimismValidator - makes cross chain call to update the Sequencer Uptime Feed on L2
diff --git a/contracts/src/v0.8/libraries/Common.sol b/contracts/src/v0.8/libraries/Common.sol
index 2df1e5c94e6..5bb8275c72e 100644
--- a/contracts/src/v0.8/libraries/Common.sol
+++ b/contracts/src/v0.8/libraries/Common.sol
@@ -16,7 +16,7 @@ library Common {
// @notice Struct to hold the address and its associated weight
struct AddressAndWeight {
address addr;
- uint256 weight;
+ uint64 weight;
}
/**
diff --git a/contracts/src/v0.8/llo-feeds/FeeManager.sol b/contracts/src/v0.8/llo-feeds/FeeManager.sol
new file mode 100644
index 00000000000..0cc8273442d
--- /dev/null
+++ b/contracts/src/v0.8/llo-feeds/FeeManager.sol
@@ -0,0 +1,507 @@
+// SPDX-License-Identifier: MIT
+pragma solidity 0.8.16;
+
+import {ConfirmedOwner} from "../shared/access/ConfirmedOwner.sol";
+import {IFeeManager} from "./interfaces/IFeeManager.sol";
+import {TypeAndVersionInterface} from "../interfaces/TypeAndVersionInterface.sol";
+import {IERC165} from "../vendor/openzeppelin-solidity/v4.8.0/contracts/interfaces/IERC165.sol";
+import {Common} from "../libraries/Common.sol";
+import {IRewardManager} from "./interfaces/IRewardManager.sol";
+import {IWERC20} from "../shared/interfaces/IWERC20.sol";
+import {IERC20} from "../vendor/openzeppelin-solidity/v4.8.0/contracts/interfaces/IERC20.sol";
+import {Math} from "../vendor/openzeppelin-solidity/v4.8.0/contracts/utils/math/Math.sol";
+import {SafeERC20} from "../vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/utils/SafeERC20.sol";
+import {IVerifierFeeManager} from "./interfaces/IVerifierFeeManager.sol";
+
+/**
+ * @title FeeManager
+ * @author Michael Fletcher
+ * @author Austin Born
+ * @notice This contract is used for the handling of fees required for users verifying reports.
+ */
+contract FeeManager is IFeeManager, ConfirmedOwner, TypeAndVersionInterface {
+ using SafeERC20 for IERC20;
+
+ /// @notice list of subscribers and their discounts subscriberDiscounts[subscriber][feedId][token]
+ mapping(address => mapping(bytes32 => mapping(address => uint256))) public s_subscriberDiscounts;
+
+ /// @notice keep track of any subsidised link that is owed to the reward manager.
+ mapping(bytes32 => uint256) public s_linkDeficit;
+
+ /// @notice the total discount that can be applied to a fee, 1e18 = 100% discount
+ uint64 private constant PERCENTAGE_SCALAR = 1e18;
+
+ /// @notice the LINK token address
+ address public immutable i_linkAddress;
+
+ /// @notice the native token address
+ address public immutable i_nativeAddress;
+
+ /// @notice the proxy address
+ address public immutable i_proxyAddress;
+
+ /// @notice the reward manager address
+ IRewardManager public immutable i_rewardManager;
+
+ // @notice the mask to apply to get the report version
+ bytes32 private constant REPORT_VERSION_MASK = 0xffff000000000000000000000000000000000000000000000000000000000000;
+
+ // @notice the different report versions
+ bytes32 private constant REPORT_V1 = 0x0001000000000000000000000000000000000000000000000000000000000000;
+
+ /// @notice the surcharge fee to be paid if paying in native
+ uint256 public s_nativeSurcharge;
+
+ /// @notice the error thrown if the discount or surcharge is invalid
+ error InvalidSurcharge();
+
+ /// @notice the error thrown if the discount is invalid
+ error InvalidDiscount();
+
+ /// @notice the error thrown if the address is invalid
+ error InvalidAddress();
+
+ /// @notice thrown if msg.value is supplied with a bad quote
+ error InvalidDeposit();
+
+ /// @notice thrown if a report has expired
+ error ExpiredReport();
+
+ /// @notice thrown if a report has no quote
+ error InvalidQuote();
+
+ // @notice thrown when the caller is not authorized
+ error Unauthorized();
+
+ // @notice thrown when trying to clear a zero deficit
+ error ZeroDeficit();
+
+ /// @notice thrown when trying to pay an address that cannot except funds
+ error InvalidReceivingAddress();
+
+ /// @notice Emitted whenever a subscriber's discount is updated
+ /// @param subscriber address of the subscriber to update discounts for
+ /// @param feedId Feed ID for the discount
+ /// @param token Token address for the discount
+ /// @param discount Discount to apply, in relation to the PERCENTAGE_SCALAR
+ event SubscriberDiscountUpdated(address indexed subscriber, bytes32 indexed feedId, address token, uint64 discount);
+
+ /// @notice Emitted when updating the native surcharge
+ /// @param newSurcharge Surcharge amount to apply relative to PERCENTAGE_SCALAR
+ event NativeSurchargeUpdated(uint64 newSurcharge);
+
+ /// @notice Emits when this contract does not have enough LINK to send to the reward manager when paying in native
+ /// @param rewards Config digest and link fees which could not be subsidised
+ event InsufficientLink(IRewardManager.FeePayment[] rewards);
+
+ /// @notice Emitted when funds are withdrawn
+ /// @param adminAddress Address of the admin
+ /// @param recipient Address of the recipient
+ /// @param assetAddress Address of the asset withdrawn
+ /// @param quantity Amount of the asset withdrawn
+ event Withdraw(address adminAddress, address recipient, address assetAddress, uint192 quantity);
+
+ /// @notice Emits when a deficit has been cleared for a particular config digest
+ /// @param configDigest Config digest of the deficit cleared
+ /// @param linkQuantity Amount of LINK required to pay the deficit
+ event LinkDeficitCleared(bytes32 indexed configDigest, uint256 linkQuantity);
+
+ /// @notice Emits when a fee has been processed
+ /// @param configDigest Config digest of the fee processed
+ /// @param subscriber Address of the subscriber who paid the fee
+ /// @param fee Fee paid
+ /// @param reward Reward paid
+ /// @param appliedDiscount Discount applied to the fee
+ event DiscountApplied(
+ bytes32 indexed configDigest,
+ address indexed subscriber,
+ Common.Asset fee,
+ Common.Asset reward,
+ uint256 appliedDiscount
+ );
+
+ /**
+ * @notice Construct the FeeManager contract
+ * @param _linkAddress The address of the LINK token
+ * @param _nativeAddress The address of the wrapped ERC-20 version of the native token (represents fee in native or wrapped)
+ * @param _proxyAddress The address of the proxy contract
+ * @param _rewardManagerAddress The address of the reward manager contract
+ */
+ constructor(
+ address _linkAddress,
+ address _nativeAddress,
+ address _proxyAddress,
+ address _rewardManagerAddress
+ ) ConfirmedOwner(msg.sender) {
+ if (
+ _linkAddress == address(0) ||
+ _nativeAddress == address(0) ||
+ _proxyAddress == address(0) ||
+ _rewardManagerAddress == address(0)
+ ) revert InvalidAddress();
+
+ i_linkAddress = _linkAddress;
+ i_nativeAddress = _nativeAddress;
+ i_proxyAddress = _proxyAddress;
+ i_rewardManager = IRewardManager(_rewardManagerAddress);
+
+ IERC20(i_linkAddress).approve(address(i_rewardManager), type(uint256).max);
+ }
+
+ modifier onlyOwnerOrProxy() {
+ if (msg.sender != i_proxyAddress && msg.sender != owner()) revert Unauthorized();
+ _;
+ }
+
+ modifier onlyProxy() {
+ if (msg.sender != i_proxyAddress) revert Unauthorized();
+ _;
+ }
+
+ /// @inheritdoc TypeAndVersionInterface
+ function typeAndVersion() external pure override returns (string memory) {
+ return "FeeManager 2.0.0";
+ }
+
+ /// @inheritdoc IERC165
+ function supportsInterface(bytes4 interfaceId) external pure override returns (bool) {
+ return interfaceId == this.processFee.selector || interfaceId == this.processFeeBulk.selector;
+ }
+
+ /// @inheritdoc IVerifierFeeManager
+ function processFee(
+ bytes calldata payload,
+ bytes calldata parameterPayload,
+ address subscriber
+ ) external payable override onlyProxy {
+ (Common.Asset memory fee, Common.Asset memory reward, uint256 appliedDiscount) = _processFee(
+ payload,
+ parameterPayload,
+ subscriber
+ );
+
+ if (fee.amount == 0) {
+ _tryReturnChange(subscriber, msg.value);
+ return;
+ }
+
+ IFeeManager.FeeAndReward[] memory feeAndReward = new IFeeManager.FeeAndReward[](1);
+ feeAndReward[0] = IFeeManager.FeeAndReward(bytes32(payload), fee, reward, appliedDiscount);
+
+ if (fee.assetAddress == i_linkAddress) {
+ _handleFeesAndRewards(subscriber, feeAndReward, 1, 0);
+ } else {
+ _handleFeesAndRewards(subscriber, feeAndReward, 0, 1);
+ }
+ }
+
+ /// @inheritdoc IVerifierFeeManager
+ function processFeeBulk(
+ bytes[] calldata payloads,
+ bytes calldata parameterPayload,
+ address subscriber
+ ) external payable override onlyProxy {
+ FeeAndReward[] memory feesAndRewards = new IFeeManager.FeeAndReward[](payloads.length);
+
+ //keep track of the number of fees to prevent over initialising the FeePayment array within _convertToLinkAndNativeFees
+ uint256 numberOfLinkFees;
+ uint256 numberOfNativeFees;
+
+ uint256 feesAndRewardsIndex;
+ for (uint256 i; i < payloads.length; ++i) {
+ (Common.Asset memory fee, Common.Asset memory reward, uint256 appliedDiscount) = _processFee(
+ payloads[i],
+ parameterPayload,
+ subscriber
+ );
+
+ if (fee.amount != 0) {
+ feesAndRewards[feesAndRewardsIndex++] = IFeeManager.FeeAndReward(
+ bytes32(payloads[i]),
+ fee,
+ reward,
+ appliedDiscount
+ );
+
+ unchecked {
+ //keep track of some tallys to make downstream calculations more efficient
+ if (fee.assetAddress == i_linkAddress) {
+ ++numberOfLinkFees;
+ } else {
+ ++numberOfNativeFees;
+ }
+ }
+ }
+ }
+
+ if (numberOfLinkFees != 0 || numberOfNativeFees != 0) {
+ _handleFeesAndRewards(subscriber, feesAndRewards, numberOfLinkFees, numberOfNativeFees);
+ } else {
+ _tryReturnChange(subscriber, msg.value);
+ }
+ }
+
+ /// @inheritdoc IFeeManager
+ function getFeeAndReward(
+ address subscriber,
+ bytes memory report,
+ address quoteAddress
+ ) public view returns (Common.Asset memory, Common.Asset memory, uint256) {
+ Common.Asset memory fee;
+ Common.Asset memory reward;
+
+ //get the feedId from the report
+ bytes32 feedId = bytes32(report);
+
+ //the report needs to be a support version
+ bytes32 reportVersion = _getReportVersion(feedId);
+
+ //version 1 of the reports don't require quotes, so the fee will be 0
+ if (reportVersion == REPORT_V1) {
+ fee.assetAddress = i_nativeAddress;
+ reward.assetAddress = i_linkAddress;
+ return (fee, reward, 0);
+ }
+
+ //verify the quote payload is a supported token
+ if (quoteAddress != i_nativeAddress && quoteAddress != i_linkAddress) {
+ revert InvalidQuote();
+ }
+
+ //decode the report depending on the version
+ uint256 linkQuantity;
+ uint256 nativeQuantity;
+ uint256 expiresAt;
+ (, , , nativeQuantity, linkQuantity, expiresAt) = abi.decode(
+ report,
+ (bytes32, uint32, uint32, uint192, uint192, uint32)
+ );
+
+ //read the timestamp bytes from the report data and verify it has not expired
+ if (expiresAt < block.timestamp) {
+ revert ExpiredReport();
+ }
+
+ //get the discount being applied
+ uint256 discount = s_subscriberDiscounts[subscriber][feedId][quoteAddress];
+
+ //the reward is always set in LINK
+ reward.assetAddress = i_linkAddress;
+ reward.amount = Math.ceilDiv(linkQuantity * (PERCENTAGE_SCALAR - discount), PERCENTAGE_SCALAR);
+
+ //calculate either the LINK fee or native fee if it's within the report
+ if (quoteAddress == i_linkAddress) {
+ fee.assetAddress = i_linkAddress;
+ fee.amount = reward.amount;
+ } else {
+ uint256 surchargedFee = Math.ceilDiv(nativeQuantity * (PERCENTAGE_SCALAR + s_nativeSurcharge), PERCENTAGE_SCALAR);
+
+ fee.assetAddress = i_nativeAddress;
+ fee.amount = Math.ceilDiv(surchargedFee * (PERCENTAGE_SCALAR - discount), PERCENTAGE_SCALAR);
+ }
+
+ //return the fee
+ return (fee, reward, discount);
+ }
+
+ /// @inheritdoc IVerifierFeeManager
+ function setFeeRecipients(
+ bytes32 configDigest,
+ Common.AddressAndWeight[] calldata rewardRecipientAndWeights
+ ) external onlyOwnerOrProxy {
+ i_rewardManager.setRewardRecipients(configDigest, rewardRecipientAndWeights);
+ }
+
+ /// @inheritdoc IFeeManager
+ function setNativeSurcharge(uint64 surcharge) external onlyOwner {
+ if (surcharge > PERCENTAGE_SCALAR) revert InvalidSurcharge();
+
+ s_nativeSurcharge = surcharge;
+
+ emit NativeSurchargeUpdated(surcharge);
+ }
+
+ /// @inheritdoc IFeeManager
+ function updateSubscriberDiscount(
+ address subscriber,
+ bytes32 feedId,
+ address token,
+ uint64 discount
+ ) external onlyOwner {
+ //make sure the discount is not greater than the total discount that can be applied
+ if (discount > PERCENTAGE_SCALAR) revert InvalidDiscount();
+ //make sure the token is either LINK or native
+ if (token != i_linkAddress && token != i_nativeAddress) revert InvalidAddress();
+
+ s_subscriberDiscounts[subscriber][feedId][token] = discount;
+
+ emit SubscriberDiscountUpdated(subscriber, feedId, token, discount);
+ }
+
+ /// @inheritdoc IFeeManager
+ function withdraw(address assetAddress, address recipient, uint192 quantity) external onlyOwner {
+ //address 0 is used to withdraw native in the context of withdrawing
+ if (assetAddress == address(0)) {
+ (bool success, ) = payable(recipient).call{value: quantity}("");
+
+ if (!success) revert InvalidReceivingAddress();
+ return;
+ }
+
+ //withdraw the requested asset
+ IERC20(assetAddress).safeTransfer(recipient, quantity);
+
+ //emit event when funds are withdrawn
+ emit Withdraw(msg.sender, recipient, assetAddress, uint192(quantity));
+ }
+
+ /// @inheritdoc IFeeManager
+ function linkAvailableForPayment() external view returns (uint256) {
+ //return the amount of LINK this contact has available to pay rewards
+ return IERC20(i_linkAddress).balanceOf(address(this));
+ }
+
+ /**
+ * @notice Gets the current version of the report that is encoded as the last two bytes of the feed
+ * @param feedId feed id to get the report version for
+ */
+ function _getReportVersion(bytes32 feedId) internal pure returns (bytes32) {
+ return REPORT_VERSION_MASK & feedId;
+ }
+
+ function _processFee(
+ bytes calldata payload,
+ bytes calldata parameterPayload,
+ address subscriber
+ ) internal view returns (Common.Asset memory, Common.Asset memory, uint256) {
+ if (subscriber == address(this)) revert InvalidAddress();
+
+ //decode the report from the payload
+ (, bytes memory report) = abi.decode(payload, (bytes32[3], bytes));
+
+ //get the feedId from the report
+ bytes32 feedId = bytes32(report);
+
+ //v1 doesn't need a quote payload, so skip the decoding
+ address quote;
+ if (_getReportVersion(feedId) != REPORT_V1) {
+ //decode the quote from the bytes
+ (quote) = abi.decode(parameterPayload, (address));
+ }
+
+ //decode the fee, it will always be native or LINK
+ return getFeeAndReward(subscriber, report, quote);
+ }
+
+ function _handleFeesAndRewards(
+ address subscriber,
+ FeeAndReward[] memory feesAndRewards,
+ uint256 numberOfLinkFees,
+ uint256 numberOfNativeFees
+ ) internal {
+ IRewardManager.FeePayment[] memory linkRewards = new IRewardManager.FeePayment[](numberOfLinkFees);
+ IRewardManager.FeePayment[] memory nativeFeeLinkRewards = new IRewardManager.FeePayment[](numberOfNativeFees);
+
+ uint256 totalNativeFee;
+ uint256 totalNativeFeeLinkValue;
+
+ uint256 linkRewardsIndex;
+ uint256 nativeFeeLinkRewardsIndex;
+
+ uint256 totalNumberOfFees = numberOfLinkFees + numberOfNativeFees;
+ for (uint256 i; i < totalNumberOfFees; ++i) {
+ if (feesAndRewards[i].fee.assetAddress == i_linkAddress) {
+ linkRewards[linkRewardsIndex++] = IRewardManager.FeePayment(
+ feesAndRewards[i].configDigest,
+ uint192(feesAndRewards[i].reward.amount)
+ );
+ } else {
+ nativeFeeLinkRewards[nativeFeeLinkRewardsIndex++] = IRewardManager.FeePayment(
+ feesAndRewards[i].configDigest,
+ uint192(feesAndRewards[i].reward.amount)
+ );
+ totalNativeFee += feesAndRewards[i].fee.amount;
+ totalNativeFeeLinkValue += feesAndRewards[i].reward.amount;
+ }
+
+ if (feesAndRewards[i].appliedDiscount != 0) {
+ emit DiscountApplied(
+ feesAndRewards[i].configDigest,
+ subscriber,
+ feesAndRewards[i].fee,
+ feesAndRewards[i].reward,
+ feesAndRewards[i].appliedDiscount
+ );
+ }
+ }
+
+ //keep track of change in case of any over payment
+ uint256 change;
+
+ if (msg.value != 0) {
+ //there must be enough to cover the fee
+ if (totalNativeFee > msg.value) revert InvalidDeposit();
+
+ //wrap the amount required to pay the fee & approve as the subscriber paid in wrapped native
+ IWERC20(i_nativeAddress).deposit{value: totalNativeFee}();
+
+ unchecked {
+ //msg.value is always >= to fee.amount
+ change = msg.value - totalNativeFee;
+ }
+ } else {
+ if (totalNativeFee != 0) {
+ //subscriber has paid in wrapped native, so transfer the native to this contract
+ IERC20(i_nativeAddress).safeTransferFrom(subscriber, address(this), totalNativeFee);
+ }
+ }
+
+ if (linkRewards.length != 0) {
+ i_rewardManager.onFeePaid(linkRewards, subscriber);
+ }
+
+ if (nativeFeeLinkRewards.length != 0) {
+ //distribute subsidised fees paid in Native
+ if (totalNativeFeeLinkValue > IERC20(i_linkAddress).balanceOf(address(this))) {
+ // If not enough LINK on this contract to forward for rewards, tally the deficit to be paid by out-of-band LINK
+ for (uint256 i; i < nativeFeeLinkRewards.length; ++i) {
+ unchecked {
+ //we have previously tallied the fees, any overflows would have already reverted
+ s_linkDeficit[nativeFeeLinkRewards[i].poolId] += nativeFeeLinkRewards[i].amount;
+ }
+ }
+
+ emit InsufficientLink(nativeFeeLinkRewards);
+ } else {
+ //distribute the fees
+ i_rewardManager.onFeePaid(nativeFeeLinkRewards, address(this));
+ }
+ }
+
+ // a refund may be needed if the payee has paid in excess of the fee
+ _tryReturnChange(subscriber, change);
+ }
+
+ function _tryReturnChange(address subscriber, uint256 quantity) internal {
+ if (quantity != 0) {
+ payable(subscriber).transfer(quantity);
+ }
+ }
+
+ /// @inheritdoc IFeeManager
+ function payLinkDeficit(bytes32 configDigest) external onlyOwner {
+ uint256 deficit = s_linkDeficit[configDigest];
+
+ if (deficit == 0) revert ZeroDeficit();
+
+ delete s_linkDeficit[configDigest];
+
+ IRewardManager.FeePayment[] memory deficitFeePayment = new IRewardManager.FeePayment[](1);
+
+ deficitFeePayment[0] = IRewardManager.FeePayment(configDigest, uint192(deficit));
+
+ i_rewardManager.onFeePaid(deficitFeePayment, address(this));
+
+ emit LinkDeficitCleared(configDigest, deficit);
+ }
+}
diff --git a/contracts/src/v0.8/llo-feeds/dev/RewardManager.sol b/contracts/src/v0.8/llo-feeds/RewardManager.sol
similarity index 76%
rename from contracts/src/v0.8/llo-feeds/dev/RewardManager.sol
rename to contracts/src/v0.8/llo-feeds/RewardManager.sol
index fbe072cacab..f4bd835c256 100644
--- a/contracts/src/v0.8/llo-feeds/dev/RewardManager.sol
+++ b/contracts/src/v0.8/llo-feeds/RewardManager.sol
@@ -1,16 +1,16 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.16;
-import {ConfirmedOwner} from "../../shared/access/ConfirmedOwner.sol";
+import {ConfirmedOwner} from "../shared/access/ConfirmedOwner.sol";
import {IRewardManager} from "./interfaces/IRewardManager.sol";
-import {IERC20} from "../../vendor/openzeppelin-solidity/v4.8.0/contracts/interfaces/IERC20.sol";
-import {TypeAndVersionInterface} from "../../interfaces/TypeAndVersionInterface.sol";
-import {IERC165} from "../../vendor/openzeppelin-solidity/v4.8.0/contracts/interfaces/IERC165.sol";
-import {Common} from "../../libraries/Common.sol";
-import {SafeERC20} from "../../vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/utils/SafeERC20.sol";
+import {IERC20} from "../vendor/openzeppelin-solidity/v4.8.0/contracts/interfaces/IERC20.sol";
+import {TypeAndVersionInterface} from "../interfaces/TypeAndVersionInterface.sol";
+import {IERC165} from "../vendor/openzeppelin-solidity/v4.8.0/contracts/interfaces/IERC165.sol";
+import {Common} from "../libraries/Common.sol";
+import {SafeERC20} from "../vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/utils/SafeERC20.sol";
/**
- * @title FeeManager
+ * @title RewardManager
* @author Michael Fletcher
* @author Austin Born
* @notice This contract will be used to reward any configured recipients within a pool. Recipients will receive a share of their pool relative to their configured weight.
@@ -22,22 +22,22 @@ contract RewardManager is IRewardManager, ConfirmedOwner, TypeAndVersionInterfac
mapping(bytes32 => uint256) public s_totalRewardRecipientFees;
// @dev The mapping of fee balances for each pot last time the recipient claimed: s_totalRewardRecipientFeesLastClaimedAmounts[poolId][recipient]
- mapping(bytes32 => mapping(address => uint256)) private s_totalRewardRecipientFeesLastClaimedAmounts;
+ mapping(bytes32 => mapping(address => uint256)) public s_totalRewardRecipientFeesLastClaimedAmounts;
// @dev The mapping of RewardRecipient weights for a particular poolId: s_rewardRecipientWeights[poolId][rewardRecipient].
mapping(bytes32 => mapping(address => uint256)) public s_rewardRecipientWeights;
// @dev Keep track of the reward recipient weights that have been set to prevent duplicates
- mapping(bytes32 => bool) private s_rewardRecipientWeightsSet;
+ mapping(bytes32 => bool) public s_rewardRecipientWeightsSet;
// @dev Store a list of pool ids that have been registered, to make off chain lookups easier
bytes32[] public s_registeredPoolIds;
// @dev The address for the LINK contract
- address private immutable i_linkAddress;
+ address public immutable i_linkAddress;
// The total weight of all RewardRecipients. 1e18 = 100% of the pool fees
- uint256 private constant PERCENTAGE_SCALAR = 1e18;
+ uint64 private constant PERCENTAGE_SCALAR = 1e18;
// The fee manager address
address public s_feeManagerAddress;
@@ -54,11 +54,14 @@ contract RewardManager is IRewardManager, ConfirmedOwner, TypeAndVersionInterfac
// @notice Thrown when the calling contract is not within the authorized contracts
error Unauthorized();
+ // @notice Thrown when getAvailableRewardPoolIds parameters are incorrectly set
+ error InvalidPoolLength();
+
// Events emitted upon state change
event RewardRecipientsUpdated(bytes32 indexed poolId, Common.AddressAndWeight[] newRewardRecipients);
- event RewardsClaimed(bytes32 indexed poolId, address indexed recipient, uint256 quantity);
+ event RewardsClaimed(bytes32 indexed poolId, address indexed recipient, uint192 quantity);
event FeeManagerUpdated(address newFeeManagerAddress);
- event FeePaid(bytes32 poolId, address payee, uint256 quantity);
+ event FeePaid(FeePayment[] payments, address payer);
/**
* @notice Constructor
@@ -73,7 +76,7 @@ contract RewardManager is IRewardManager, ConfirmedOwner, TypeAndVersionInterfac
// @inheritdoc TypeAndVersionInterface
function typeAndVersion() external pure override returns (string memory) {
- return "RewardManager 0.0.1";
+ return "RewardManager 1.1.0";
}
// @inheritdoc IERC165
@@ -91,18 +94,30 @@ contract RewardManager is IRewardManager, ConfirmedOwner, TypeAndVersionInterfac
_;
}
+ modifier onlyFeeManager() {
+ if (msg.sender != s_feeManagerAddress) revert Unauthorized();
+ _;
+ }
+
/// @inheritdoc IRewardManager
- function onFeePaid(bytes32 poolId, address payee, uint256 amount) external override onlyOwnerOrFeeManager {
- //update the total fees collected for this pot
- unchecked {
- //the total amount for any ERC20 asset cannot exceed 2^256 - 1
- s_totalRewardRecipientFees[poolId] += amount;
+ function onFeePaid(FeePayment[] calldata payments, address payer) external override onlyFeeManager {
+ uint256 totalFeeAmount;
+ for (uint256 i; i < payments.length; ++i) {
+ unchecked {
+ //the total amount for any ERC-20 asset cannot exceed 2^256 - 1
+ //see https://github.com/OpenZeppelin/openzeppelin-contracts/blob/36bf1e46fa811f0f07d38eb9cfbc69a955f300ce/contracts/token/ERC20/ERC20.sol#L266
+ //for example implementation.
+ s_totalRewardRecipientFees[payments[i].poolId] += payments[i].amount;
+
+ //tally the total payable fees
+ totalFeeAmount += payments[i].amount;
+ }
}
- //transfer the fee to this contract
- IERC20(i_linkAddress).safeTransferFrom(payee, address(this), amount);
+ //transfer the fees to this contract
+ IERC20(i_linkAddress).safeTransferFrom(payer, address(this), totalFeeAmount);
- emit FeePaid(poolId, payee, amount);
+ emit FeePaid(payments, payer);
}
/// @inheritdoc IRewardManager
@@ -124,6 +139,9 @@ contract RewardManager is IRewardManager, ConfirmedOwner, TypeAndVersionInterfac
uint256 totalFeesInPot = s_totalRewardRecipientFees[poolId];
unchecked {
+ //avoid unnecessary storage reads if there's no fees in the pot
+ if (totalFeesInPot == 0) continue;
+
//get the claimable amount for this recipient, this calculation will never exceed the amount in the pot
uint256 claimableAmount = totalFeesInPot - s_totalRewardRecipientFeesLastClaimedAmounts[poolId][recipient];
@@ -140,7 +158,7 @@ contract RewardManager is IRewardManager, ConfirmedOwner, TypeAndVersionInterfac
s_totalRewardRecipientFeesLastClaimedAmounts[poolId][recipient] = totalFeesInPot;
//emit event if the recipient has rewards to claim
- emit RewardsClaimed(poolIds[i], recipient, recipientShare);
+ emit RewardsClaimed(poolIds[i], recipient, uint192(recipientShare));
}
}
@@ -194,8 +212,6 @@ contract RewardManager is IRewardManager, ConfirmedOwner, TypeAndVersionInterfac
//ensure the reward recipient address is not zero
if (recipientAddress == address(0)) revert InvalidAddress();
- //ensure the weight is not zero
- if (recipientWeight == 0) revert InvalidWeights();
//save/overwrite the weight for the reward recipient
s_rewardRecipientWeights[poolId][recipientAddress] = recipientWeight;
@@ -221,23 +237,18 @@ contract RewardManager is IRewardManager, ConfirmedOwner, TypeAndVersionInterfac
//loop all the reward recipients and claim their rewards before updating their weights
uint256 existingTotalWeight;
- for (uint256 i; i < newRewardRecipients.length; ) {
+ for (uint256 i; i < newRewardRecipients.length; ++i) {
//get the address
address recipientAddress = newRewardRecipients[i].addr;
//get the existing weight
uint256 existingWeight = s_rewardRecipientWeights[poolId][recipientAddress];
- //if the existing weight is 0, the recipient isn't part of this configuration
- if (existingWeight == 0) revert InvalidAddress();
-
//if a recipient is updated, the rewards must be claimed first as they can't claim previous fees at the new weight
_claimRewards(newRewardRecipients[i].addr, poolIds);
unchecked {
//keep tally of the weights so that the expected collective weight is known
existingTotalWeight += existingWeight;
- //there will never be enough reward recipients for i to overflow
- ++i;
}
}
@@ -255,13 +266,8 @@ contract RewardManager is IRewardManager, ConfirmedOwner, TypeAndVersionInterfac
poolIdsArray[0] = poolId;
//loop each recipient and claim the rewards for each of the pools and assets
- for (uint256 i; i < recipients.length; ) {
+ for (uint256 i; i < recipients.length; ++i) {
_claimRewards(recipients[i], poolIdsArray);
-
- unchecked {
- //there will never be enough recipients for i to overflow
- ++i;
- }
}
}
@@ -275,35 +281,40 @@ contract RewardManager is IRewardManager, ConfirmedOwner, TypeAndVersionInterfac
}
/// @inheritdoc IRewardManager
- function getAvailableRewardPoolIds(address recipient) external view returns (bytes32[] memory) {
+ function getAvailableRewardPoolIds(
+ address recipient,
+ uint256 startIndex,
+ uint256 endIndex
+ ) external view returns (bytes32[] memory) {
//get the length of the pool ids which we will loop through and potentially return
uint256 registeredPoolIdsLength = s_registeredPoolIds.length;
+ uint256 lastIndex = endIndex > registeredPoolIdsLength ? registeredPoolIdsLength : endIndex;
+
+ if (startIndex > lastIndex) revert InvalidPoolLength();
+
//create a new array with the maximum amount of potential pool ids
- bytes32[] memory claimablePoolIds = new bytes32[](registeredPoolIdsLength);
+ bytes32[] memory claimablePoolIds = new bytes32[](lastIndex - startIndex);
//we want the pools which a recipient has funds for to be sequential, so we need to keep track of the index
uint256 poolIdArrayIndex;
//loop all the pool ids, and check if the recipient has a registered weight and a claimable amount
- for (uint256 i; i < registeredPoolIdsLength; ) {
+ for (uint256 i = startIndex; i < lastIndex; ++i) {
//get the poolId
bytes32 poolId = s_registeredPoolIds[i];
+
//if the recipient has a weight, they are a recipient of this poolId
if (s_rewardRecipientWeights[poolId][recipient] != 0) {
+ //get the total in this pool
+ uint256 totalPoolAmount = s_totalRewardRecipientFees[poolId];
//if the recipient has any LINK, then add the poolId to the array
- if (s_totalRewardRecipientFees[poolId] != 0) {
- claimablePoolIds[poolIdArrayIndex] = poolId;
- unchecked {
- //there will never be enough pool ids for i to overflow
- ++poolIdArrayIndex;
+ unchecked {
+ //s_totalRewardRecipientFeesLastClaimedAmounts can never exceed total pool amount, and the number of pools can't exceed the max array length
+ if (totalPoolAmount - s_totalRewardRecipientFeesLastClaimedAmounts[poolId][recipient] != 0) {
+ claimablePoolIds[poolIdArrayIndex++] = poolId;
}
}
}
-
- unchecked {
- //there will never be enough poolIds for i to overflow
- ++i;
- }
}
return claimablePoolIds;
diff --git a/contracts/src/v0.8/llo-feeds/Verifier.sol b/contracts/src/v0.8/llo-feeds/Verifier.sol
index 0bc2dee18c8..dbd5fc73abc 100644
--- a/contracts/src/v0.8/llo-feeds/Verifier.sol
+++ b/contracts/src/v0.8/llo-feeds/Verifier.sol
@@ -195,11 +195,14 @@ contract Verifier is IVerifier, ConfirmedOwner, TypeAndVersionInterface {
/// @inheritdoc TypeAndVersionInterface
function typeAndVersion() external pure override returns (string memory) {
- return "Verifier 1.1.0";
+ return "Verifier 1.2.0";
}
/// @inheritdoc IVerifier
- function verify(bytes calldata signedReport, address sender) external override returns (bytes memory response) {
+ function verify(
+ bytes calldata signedReport,
+ address sender
+ ) external override returns (bytes memory verifierResponse) {
if (msg.sender != i_verifierProxyAddr) revert AccessForbidden();
(
bytes32[3] memory reportContext,
@@ -320,6 +323,7 @@ contract Verifier is IVerifier, ConfirmedOwner, TypeAndVersionInterface {
feedId,
block.chainid,
address(this),
+ 0, // 0 defaults to feedConfig.configCount + 1
signers,
offchainTransmitters,
f,
@@ -335,6 +339,7 @@ contract Verifier is IVerifier, ConfirmedOwner, TypeAndVersionInterface {
bytes32 feedId,
uint256 sourceChainId,
address sourceAddress,
+ uint32 newConfigCount,
address[] memory signers,
bytes32[] memory offchainTransmitters,
uint8 f,
@@ -347,6 +352,7 @@ contract Verifier is IVerifier, ConfirmedOwner, TypeAndVersionInterface {
feedId,
sourceChainId,
sourceAddress,
+ newConfigCount,
signers,
offchainTransmitters,
f,
@@ -361,6 +367,7 @@ contract Verifier is IVerifier, ConfirmedOwner, TypeAndVersionInterface {
/// @param feedId Feed ID to set config for
/// @param sourceChainId Chain ID of source config
/// @param sourceAddress Address of source config Verifier
+ /// @param newConfigCount Optional param to force the new config count
/// @param signers addresses with which oracles sign the reports
/// @param offchainTransmitters CSA key for the ith Oracle
/// @param f number of faulty oracles the system can tolerate
@@ -372,6 +379,7 @@ contract Verifier is IVerifier, ConfirmedOwner, TypeAndVersionInterface {
bytes32 feedId,
uint256 sourceChainId,
address sourceAddress,
+ uint32 newConfigCount,
address[] memory signers,
bytes32[] memory offchainTransmitters,
uint8 f,
@@ -383,7 +391,8 @@ contract Verifier is IVerifier, ConfirmedOwner, TypeAndVersionInterface {
VerifierState storage feedVerifierState = s_feedVerifierStates[feedId];
// Increment the number of times a config has been set first
- feedVerifierState.configCount++;
+ if (newConfigCount > 0) feedVerifierState.configCount = newConfigCount;
+ else feedVerifierState.configCount++;
bytes32 configDigest = _configDigestFromConfigData(
feedId,
diff --git a/contracts/src/v0.8/llo-feeds/VerifierProxy.sol b/contracts/src/v0.8/llo-feeds/VerifierProxy.sol
index 41907432a31..989c5c6b81a 100644
--- a/contracts/src/v0.8/llo-feeds/VerifierProxy.sol
+++ b/contracts/src/v0.8/llo-feeds/VerifierProxy.sol
@@ -5,7 +5,7 @@ import {ConfirmedOwner} from "../shared/access/ConfirmedOwner.sol";
import {IVerifierProxy} from "./interfaces/IVerifierProxy.sol";
import {IVerifier} from "./interfaces/IVerifier.sol";
import {TypeAndVersionInterface} from "../interfaces/TypeAndVersionInterface.sol";
-import {AccessControllerInterface} from "../interfaces/AccessControllerInterface.sol";
+import {AccessControllerInterface} from "../shared/interfaces/AccessControllerInterface.sol";
import {IERC165} from "../vendor/openzeppelin-solidity/v4.8.0/contracts/interfaces/IERC165.sol";
import {IVerifierFeeManager} from "./interfaces/IVerifierFeeManager.sol";
import {Common} from "../libraries/Common.sol";
@@ -65,6 +65,10 @@ contract VerifierProxy is IVerifierProxy, ConfirmedOwner, TypeAndVersionInterfac
/// not conform to the verifier interface
error VerifierInvalid();
+ /// @notice This error is thrown when the fee manager at an address does
+ /// not conform to the fee manager interface
+ error FeeManagerInvalid();
+
/// @notice This error is thrown whenever a verifier is not found
/// @param configDigest The digest for which a verifier is not found
error VerifierNotFound(bytes32 configDigest);
@@ -113,25 +117,51 @@ contract VerifierProxy is IVerifierProxy, ConfirmedOwner, TypeAndVersionInterfac
/// @inheritdoc TypeAndVersionInterface
function typeAndVersion() external pure override returns (string memory) {
- return "VerifierProxy 1.1.0";
+ return "VerifierProxy 2.0.0";
}
/// @inheritdoc IVerifierProxy
function verify(
- bytes calldata payload
- ) external payable override checkAccess returns (bytes memory verifierResponse) {
- // First 32 bytes of the signed report is the config digest
- bytes32 configDigest = bytes32(payload);
- address verifierAddress = s_verifiersByConfig[configDigest];
- if (verifierAddress == address(0)) revert VerifierNotFound(configDigest);
+ bytes calldata payload,
+ bytes calldata parameterPayload
+ ) external payable checkAccess returns (bytes memory) {
+ IVerifierFeeManager feeManager = s_feeManager;
+
+ // Bill the verifier
+ if (address(feeManager) != address(0)) {
+ feeManager.processFee{value: msg.value}(payload, parameterPayload, msg.sender);
+ }
+
+ return _verify(payload);
+ }
+ /// @inheritdoc IVerifierProxy
+ function verifyBulk(
+ bytes[] calldata payloads,
+ bytes calldata parameterPayload
+ ) external payable checkAccess returns (bytes[] memory verifiedReports) {
IVerifierFeeManager feeManager = s_feeManager;
// Bill the verifier
if (address(feeManager) != address(0)) {
- feeManager.processFee{value: msg.value}(payload, msg.sender);
+ feeManager.processFeeBulk{value: msg.value}(payloads, parameterPayload, msg.sender);
+ }
+
+ //verify the reports
+ verifiedReports = new bytes[](payloads.length);
+ for (uint256 i; i < payloads.length; ++i) {
+ verifiedReports[i] = _verify(payloads[i]);
}
+ return verifiedReports;
+ }
+
+ function _verify(bytes calldata payload) internal returns (bytes memory verifiedReport) {
+ // First 32 bytes of the signed report is the config digest
+ bytes32 configDigest = bytes32(payload);
+ address verifierAddress = s_verifiersByConfig[configDigest];
+ if (verifierAddress == address(0)) revert VerifierNotFound(configDigest);
+
return IVerifier(verifierAddress).verify(payload, msg.sender);
}
@@ -172,7 +202,7 @@ contract VerifierProxy is IVerifierProxy, ConfirmedOwner, TypeAndVersionInterfac
}
/// @inheritdoc IVerifierProxy
- function getVerifier(bytes32 configDigest) external view override returns (address verifierAddress) {
+ function getVerifier(bytes32 configDigest) external view override returns (address) {
return s_verifiersByConfig[configDigest];
}
@@ -187,6 +217,11 @@ contract VerifierProxy is IVerifierProxy, ConfirmedOwner, TypeAndVersionInterfac
function setFeeManager(IVerifierFeeManager feeManager) external onlyOwner {
if (address(feeManager) == address(0)) revert ZeroAddress();
+ if (
+ !IERC165(feeManager).supportsInterface(IVerifierFeeManager.processFee.selector) ||
+ !IERC165(feeManager).supportsInterface(IVerifierFeeManager.processFeeBulk.selector)
+ ) revert FeeManagerInvalid();
+
address oldFeeManager = address(s_feeManager);
s_feeManager = IVerifierFeeManager(feeManager);
emit FeeManagerSet(oldFeeManager, address(feeManager));
diff --git a/contracts/src/v0.8/llo-feeds/dev/FeeManager.sol b/contracts/src/v0.8/llo-feeds/dev/FeeManager.sol
deleted file mode 100644
index 2d3376cd67a..00000000000
--- a/contracts/src/v0.8/llo-feeds/dev/FeeManager.sol
+++ /dev/null
@@ -1,368 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity 0.8.16;
-
-import {ConfirmedOwner} from "../../shared/access/ConfirmedOwner.sol";
-import {IFeeManager} from "./interfaces/IFeeManager.sol";
-import {TypeAndVersionInterface} from "../../interfaces/TypeAndVersionInterface.sol";
-import {IERC165} from "../../vendor/openzeppelin-solidity/v4.8.0/contracts/interfaces/IERC165.sol";
-import {Common} from "../../libraries/Common.sol";
-import {IRewardManager} from "./interfaces/IRewardManager.sol";
-import {IWERC20} from "../../shared/interfaces/IWERC20.sol";
-import {IERC20} from "../../vendor/openzeppelin-solidity/v4.8.0/contracts/interfaces/IERC20.sol";
-import {Math} from "../../vendor/openzeppelin-solidity/v4.8.0/contracts/utils/math/Math.sol";
-import {SafeERC20} from "../../vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/utils/SafeERC20.sol";
-
-/**
- * @title FeeManager
- * @author Michael Fletcher
- * @author Austin Born
- * @notice This contract is used for the handling of fees required for users verifying reports.
- */
-contract FeeManager is IFeeManager, ConfirmedOwner, TypeAndVersionInterface {
- using SafeERC20 for IERC20;
-
- /// @notice list of subscribers and their discounts subscriberDiscounts[subscriber][feedId][token]
- mapping(address => mapping(bytes32 => mapping(address => uint256))) public s_subscriberDiscounts;
-
- /// @notice keep track of any subsidised link that is owed to the reward manager.
- mapping(bytes32 => uint256) public s_linkDeficit;
-
- /// @notice the total discount that can be applied to a fee, 1e18 = 100% discount
- uint256 private constant PERCENTAGE_SCALAR = 1e18;
-
- /// @notice the LINK token address
- address private immutable i_linkAddress;
-
- /// @notice the native token address
- address private immutable i_nativeAddress;
-
- /// @notice the proxy address
- address private immutable i_proxyAddress;
-
- /// @notice the reward manager address
- IRewardManager private immutable i_rewardManager;
-
- // @notice the mask to apply to get the report version
- bytes32 private constant REPORT_VERSION_MASK = 0xffff000000000000000000000000000000000000000000000000000000000000;
-
- // @notice the different report versions
- bytes32 private constant REPORT_V1 = 0x0001000000000000000000000000000000000000000000000000000000000000;
-
- /// @notice the surcharge fee to be paid if paying in native
- uint256 public s_nativeSurcharge;
-
- /// @notice the error thrown if the discount or surcharge is invalid
- error InvalidSurcharge();
-
- /// @notice the error thrown if the token is invalid
- error InvalidToken();
-
- /// @notice the error thrown if the discount is invalid
- error InvalidDiscount();
-
- /// @notice the error thrown if the address is invalid
- error InvalidAddress();
-
- /// @notice thrown if msg.value is supplied with a bad quote
- error InvalidDeposit();
-
- /// @notice thrown if a report has expired
- error ExpiredReport();
-
- /// @notice thrown if a report has no quote
- error InvalidQuote();
-
- // @notice thrown when the caller is not authorized
- error Unauthorized();
-
- // @notice thrown when trying to clear a zero deficit
- error ZeroDeficit();
-
- /// @notice Emitted whenever a subscriber's discount is updated
- /// @param subscriber address of the subscriber to update discounts for
- /// @param feedId Feed ID for the discount
- /// @param token Token address for the discount
- /// @param discount Discount to apply, in relation to the PERCENTAGE_SCALAR
- event SubscriberDiscountUpdated(address indexed subscriber, bytes32 indexed feedId, address token, uint256 discount);
-
- /// @notice Emitted when updating the native surcharge
- /// @param newSurcharge Surcharge amount to apply relative to PERCENTAGE_SCALAR
- event NativeSurchargeUpdated(uint256 newSurcharge);
-
- /// @notice Emits when this contract does not have enough LINK to send to the reward manager when paying in native
- /// @param configDigest Config digest of the report
- /// @param linkQuantity Amount of LINK required to pay the reward
- /// @param nativeQuantity Amount of native required to pay the reward
- event InsufficientLink(bytes32 indexed configDigest, uint256 linkQuantity, uint256 nativeQuantity);
-
- /// @notice Emitted when funds are withdrawn
- /// @param assetAddress Address of the asset withdrawn
- /// @param quantity Amount of the asset withdrawn
- event Withdraw(address adminAddress, address assetAddress, uint256 quantity);
-
- /// @notice Emits when a deficit has been cleared for a particular config digest
- /// @param configDigest Config digest of the deficit cleared
- /// @param linkQuantity Amount of LINK required to pay the deficit
- event LinkDeficitCleared(bytes32 indexed configDigest, uint256 linkQuantity);
-
- /**
- * @notice Construct the FeeManager contract
- * @param _linkAddress The address of the LINK token
- * @param _nativeAddress The address of the wrapped ERC-20 version of the native token (represents fee in native or wrapped)
- * @param _proxyAddress The address of the proxy contract
- * @param _rewardManagerAddress The address of the reward manager contract
- */
- constructor(
- address _linkAddress,
- address _nativeAddress,
- address _proxyAddress,
- address _rewardManagerAddress
- ) ConfirmedOwner(msg.sender) {
- if (
- _linkAddress == address(0) ||
- _nativeAddress == address(0) ||
- _proxyAddress == address(0) ||
- _rewardManagerAddress == address(0)
- ) revert InvalidAddress();
-
- i_linkAddress = _linkAddress;
- i_nativeAddress = _nativeAddress;
- i_proxyAddress = _proxyAddress;
- i_rewardManager = IRewardManager(_rewardManagerAddress);
-
- IERC20(i_linkAddress).approve(address(i_rewardManager), type(uint256).max);
- }
-
- modifier onlyOwnerOrProxy() {
- if (msg.sender != owner() && msg.sender != i_proxyAddress) revert Unauthorized();
- _;
- }
-
- /// @inheritdoc TypeAndVersionInterface
- function typeAndVersion() external pure override returns (string memory) {
- return "FeeManager 0.0.1";
- }
-
- /// @inheritdoc IERC165
- function supportsInterface(bytes4 interfaceId) external pure override returns (bool) {
- return interfaceId == this.processFee.selector;
- }
-
- /// @inheritdoc IFeeManager
- function processFee(bytes calldata payload, address subscriber) external payable onlyOwnerOrProxy {
- if (subscriber == address(this)) revert InvalidAddress();
-
- //decode the report from the payload
- (, bytes memory report) = abi.decode(payload, (bytes32[3], bytes));
-
- //get the feedId from the report
- bytes32 feedId = bytes32(report);
-
- //v2 doesn't need a quote payload, so skip the decoding if the report is a v1 report
- Quote memory quote;
- if (_getReportVersion(feedId) != REPORT_V1) {
- //all reports greater than v1 should have a quote payload
- (, , , , , bytes memory quoteBytes) = abi.decode(
- payload,
- (bytes32[3], bytes, bytes32[], bytes32[], bytes32, bytes)
- );
-
- //decode the quote from the bytes
- (quote) = abi.decode(quoteBytes, (Quote));
- }
-
- //decode the fee, it will always be native or LINK
- (Common.Asset memory fee, Common.Asset memory reward) = getFeeAndReward(msg.sender, report, quote);
-
- //keep track of change in case of any over payment
- uint256 change;
-
- //wrap the amount required to pay the fee
- if (msg.value != 0) {
- //quote must be in native with enough to cover the fee
- if (fee.assetAddress != i_nativeAddress) revert InvalidDeposit();
- if (fee.amount > msg.value) revert InvalidDeposit();
-
- //wrap the amount required to pay the fee & approve
- IWERC20(i_nativeAddress).deposit{value: fee.amount}();
-
- unchecked {
- //msg.value is always >= to fee.amount
- change = msg.value - fee.amount;
- }
- }
-
- //get the config digest which is the first 32 bytes of the payload
- bytes32 configDigest = bytes32(payload);
-
- //some users might not be billed
- if (fee.amount != 0) {
- //if the fee is in LINK, transfer directly from the subscriber to the reward manager
- if (fee.assetAddress == i_linkAddress) {
- //distributes the fee
- i_rewardManager.onFeePaid(configDigest, subscriber, reward.amount);
- } else {
- //if the fee is in native wrapped, transfer to this contract in exchange for the equivalent amount of LINK excluding the surcharge
- if (msg.value == 0) {
- IERC20(fee.assetAddress).safeTransferFrom(subscriber, address(this), fee.amount);
- }
-
- //check that the contract has enough LINK before paying the fee
- if (reward.amount > IERC20(i_linkAddress).balanceOf(address(this))) {
- // If not enough LINK on this contract to forward for rewards, tally the deficit to be paid by out-of-band LINK
- s_linkDeficit[configDigest] += reward.amount;
- emit InsufficientLink(configDigest, reward.amount, fee.amount);
- } else {
- //bill the payee and distribute the fee using the config digest as the key
- i_rewardManager.onFeePaid(configDigest, address(this), reward.amount);
- }
- }
- }
-
- // a refund may be needed if the payee has paid in excess of the fee
- if (change != 0) {
- payable(subscriber).transfer(change);
- }
- }
-
- /// @inheritdoc IFeeManager
- function getFeeAndReward(
- address subscriber,
- bytes memory report,
- Quote memory quote
- ) public view returns (Common.Asset memory, Common.Asset memory) {
- Common.Asset memory fee;
- Common.Asset memory reward;
-
- //get the feedId from the report
- bytes32 feedId = bytes32(report);
-
- //the report needs to be a support version
- bytes32 reportVersion = _getReportVersion(feedId);
-
- //version 1 of the reports don't require quotes, so the fee will be 0
- if (reportVersion == REPORT_V1) {
- fee.assetAddress = i_nativeAddress;
- reward.assetAddress = i_linkAddress;
- return (fee, reward);
- }
-
- //verify the quote payload is a supported token
- if (quote.quoteAddress != i_nativeAddress && quote.quoteAddress != i_linkAddress) {
- revert InvalidQuote();
- }
-
- //decode the report depending on the version
- uint256 linkQuantity;
- uint256 nativeQuantity;
- uint256 expiresAt;
- (, , , , linkQuantity, nativeQuantity, expiresAt) = abi.decode(
- report,
- (bytes32, uint32, uint32, int192, uint192, uint192, uint32)
- );
-
- //read the timestamp bytes from the report data and verify it has not expired
- if (expiresAt < block.timestamp) {
- revert ExpiredReport();
- }
-
- //the reward is always set in LINK
- reward.assetAddress = i_linkAddress;
- reward.amount = linkQuantity;
-
- //calculate either the LINK fee or native fee if it's within the report
- if (quote.quoteAddress == i_linkAddress) {
- fee.assetAddress = reward.assetAddress;
- fee.amount = reward.amount;
- } else {
- fee.assetAddress = i_nativeAddress;
- fee.amount = Math.ceilDiv(nativeQuantity * (PERCENTAGE_SCALAR + s_nativeSurcharge), PERCENTAGE_SCALAR);
- }
-
- //get the discount being applied
- uint256 discount = s_subscriberDiscounts[subscriber][feedId][quote.quoteAddress];
-
- //apply the discount to the fee, rounding up
- fee.amount = fee.amount - ((fee.amount * discount) / PERCENTAGE_SCALAR);
-
- //apply the discount to the reward, rounding down
- reward.amount = reward.amount - Math.ceilDiv(reward.amount * discount, PERCENTAGE_SCALAR);
-
- //return the fee
- return (fee, reward);
- }
-
- /// @inheritdoc IFeeManager
- function setFeeRecipients(
- bytes32 configDigest,
- Common.AddressAndWeight[] calldata rewardRecipientAndWeights
- ) external onlyOwnerOrProxy {
- i_rewardManager.setRewardRecipients(configDigest, rewardRecipientAndWeights);
- }
-
- /// @inheritdoc IFeeManager
- function setNativeSurcharge(uint256 surcharge) external onlyOwner {
- if (surcharge > PERCENTAGE_SCALAR) revert InvalidSurcharge();
-
- s_nativeSurcharge = surcharge;
-
- emit NativeSurchargeUpdated(surcharge);
- }
-
- /// @inheritdoc IFeeManager
- function updateSubscriberDiscount(
- address subscriber,
- bytes32 feedId,
- address token,
- uint256 discount
- ) external onlyOwner {
- //make sure the discount is not greater than the total discount that can be applied
- if (discount > PERCENTAGE_SCALAR) revert InvalidDiscount();
- //make sure the token is either LINK or native
- if (token != i_linkAddress && token != i_nativeAddress) revert InvalidAddress();
-
- s_subscriberDiscounts[subscriber][feedId][token] = discount;
-
- emit SubscriberDiscountUpdated(subscriber, feedId, token, discount);
- }
-
- /// @inheritdoc IFeeManager
- function withdraw(address assetAddress, uint256 quantity) external onlyOwner {
- //address 0 is used to withdraw native in the context of withdrawing
- if (assetAddress == address(0)) {
- payable(owner()).transfer(quantity);
- return;
- }
-
- //withdraw the requested asset
- IERC20(assetAddress).safeTransfer(owner(), quantity);
-
- //emit event when funds are withdrawn
- emit Withdraw(msg.sender, assetAddress, quantity);
- }
-
- /// @inheritdoc IFeeManager
- function linkAvailableForPayment() external view returns (uint256) {
- //return the amount of LINK this contact has available to pay rewards
- return IERC20(i_linkAddress).balanceOf(address(this));
- }
-
- /**
- * @notice Gets the current version of the report that is encoded as the last two bytes of the feed
- * @param feedId feed id to get the report version for
- */
- function _getReportVersion(bytes32 feedId) internal pure returns (bytes32) {
- return REPORT_VERSION_MASK & feedId;
- }
-
- /// @inheritdoc IFeeManager
- function payLinkDeficit(bytes32 configDigest) external onlyOwner {
- uint256 deficit = s_linkDeficit[configDigest];
- if (deficit == 0) revert ZeroDeficit();
-
- delete s_linkDeficit[configDigest];
- i_rewardManager.onFeePaid(configDigest, address(this), deficit);
-
- emit LinkDeficitCleared(configDigest, deficit);
- }
-}
diff --git a/contracts/src/v0.8/llo-feeds/dev/interfaces/IFeeManager.sol b/contracts/src/v0.8/llo-feeds/dev/interfaces/IFeeManager.sol
deleted file mode 100644
index e045b961c3e..00000000000
--- a/contracts/src/v0.8/llo-feeds/dev/interfaces/IFeeManager.sol
+++ /dev/null
@@ -1,76 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity 0.8.16;
-
-import {IERC165} from "../../../vendor/openzeppelin-solidity/v4.8.0/contracts/interfaces/IERC165.sol";
-import {Common} from "../../../libraries/Common.sol";
-import {IVerifierFeeManager} from "../../interfaces/IVerifierFeeManager.sol";
-
-interface IFeeManager is IERC165, IVerifierFeeManager {
- struct Quote {
- address quoteAddress;
- }
-
- /**
- * @notice Processes the fee for a report, billing the subscriber and paying the reward manager
- * @param payload report and quote data to process the fee for
- * @param subscriber address of the user to process fee for
- */
- function processFee(bytes calldata payload, address subscriber) external payable;
-
- /**
- * @notice Calculate the applied fee and the reward from a report. If the sender is a subscriber, they will receive a discount.
- * @param subscriber address trying to verify
- * @param report report to calculate the fee for
- * @param quote any metadata required to fetch the fee
- * @return (fee, reward) fee and the reward data
- */
- function getFeeAndReward(
- address subscriber,
- bytes memory report,
- Quote memory quote
- ) external returns (Common.Asset memory, Common.Asset memory);
-
- /**
- * @notice Sets the fee recipients within the reward manager
- * @param configDigest digest of the configuration
- * @param rewardRecipientAndWeights the address and weights of all the recipients to receive rewards
- */
- function setFeeRecipients(
- bytes32 configDigest,
- Common.AddressAndWeight[] calldata rewardRecipientAndWeights
- ) external;
-
- /**
- * @notice Sets the native surcharge
- * @param surcharge surcharge to be paid if paying in native
- */
- function setNativeSurcharge(uint256 surcharge) external;
-
- /**
- * @notice Adds a subscriber to the fee manager
- * @param subscriber address of the subscriber
- * @param feedId feed id to apply the discount to
- * @param token token to apply the discount to
- * @param discount discount to be applied to the fee
- */
- function updateSubscriberDiscount(address subscriber, bytes32 feedId, address token, uint256 discount) external;
-
- /**
- * @notice Withdraws any native rewards to the owner address
- * @param quantity quantity of native tokens to withdraw, address(0) is native
- * @param quantity quantity to withdraw
- */
- function withdraw(address assetAddress, uint256 quantity) external;
-
- /**
- * @notice Returns the link balance of the fee manager
- * @return link balance of the fee manager
- */
- function linkAvailableForPayment() external returns (uint256);
-
- /**
- * @notice Admin function to pay the LINK deficit for a given config digest
- * @param configDigest the config digest to pay the deficit for
- */
- function payLinkDeficit(bytes32 configDigest) external;
-}
diff --git a/contracts/src/v0.8/llo-feeds/interfaces/IFeeManager.sol b/contracts/src/v0.8/llo-feeds/interfaces/IFeeManager.sol
new file mode 100644
index 00000000000..ed7213870e2
--- /dev/null
+++ b/contracts/src/v0.8/llo-feeds/interfaces/IFeeManager.sol
@@ -0,0 +1,78 @@
+// SPDX-License-Identifier: MIT
+pragma solidity 0.8.16;
+
+import {IERC165} from "../../vendor/openzeppelin-solidity/v4.8.0/contracts/interfaces/IERC165.sol";
+import {Common} from "../../libraries/Common.sol";
+import {IVerifierFeeManager} from "./IVerifierFeeManager.sol";
+
+interface IFeeManager is IERC165, IVerifierFeeManager {
+ /**
+ * @notice Calculate the applied fee and the reward from a report. If the sender is a subscriber, they will receive a discount.
+ * @param subscriber address trying to verify
+ * @param report report to calculate the fee for
+ * @param quoteAddress address of the quote payment token
+ * @return (fee, reward, totalDiscount) fee and the reward data with the discount applied
+ */
+ function getFeeAndReward(
+ address subscriber,
+ bytes memory report,
+ address quoteAddress
+ ) external returns (Common.Asset memory, Common.Asset memory, uint256);
+
+ /**
+ * @notice Sets the native surcharge
+ * @param surcharge surcharge to be paid if paying in native
+ */
+ function setNativeSurcharge(uint64 surcharge) external;
+
+ /**
+ * @notice Adds a subscriber to the fee manager
+ * @param subscriber address of the subscriber
+ * @param feedId feed id to apply the discount to
+ * @param token token to apply the discount to
+ * @param discount discount to be applied to the fee
+ */
+ function updateSubscriberDiscount(address subscriber, bytes32 feedId, address token, uint64 discount) external;
+
+ /**
+ * @notice Withdraws any native or LINK rewards to the owner address
+ * @param assetAddress address of the asset to withdraw
+ * @param recipientAddress address to withdraw to
+ * @param quantity quantity to withdraw
+ */
+ function withdraw(address assetAddress, address recipientAddress, uint192 quantity) external;
+
+ /**
+ * @notice Returns the link balance of the fee manager
+ * @return link balance of the fee manager
+ */
+ function linkAvailableForPayment() external returns (uint256);
+
+ /**
+ * @notice Admin function to pay the LINK deficit for a given config digest
+ * @param configDigest the config digest to pay the deficit for
+ */
+ function payLinkDeficit(bytes32 configDigest) external;
+
+ /**
+ * @notice The structure to hold a fee and reward to verify a report
+ * @param digest the digest linked to the fee and reward
+ * @param fee the fee paid to verify the report
+ * @param reward the reward paid upon verification
+ & @param appliedDiscount the discount applied to the reward
+ */
+ struct FeeAndReward {
+ bytes32 configDigest;
+ Common.Asset fee;
+ Common.Asset reward;
+ uint256 appliedDiscount;
+ }
+
+ /**
+ * @notice The structure to hold quote metadata
+ * @param quoteAddress the address of the quote
+ */
+ struct Quote {
+ address quoteAddress;
+ }
+}
diff --git a/contracts/src/v0.8/llo-feeds/dev/interfaces/IRewardManager.sol b/contracts/src/v0.8/llo-feeds/interfaces/IRewardManager.sol
similarity index 69%
rename from contracts/src/v0.8/llo-feeds/dev/interfaces/IRewardManager.sol
rename to contracts/src/v0.8/llo-feeds/interfaces/IRewardManager.sol
index b560b8efb61..68cecc4f97a 100644
--- a/contracts/src/v0.8/llo-feeds/dev/interfaces/IRewardManager.sol
+++ b/contracts/src/v0.8/llo-feeds/interfaces/IRewardManager.sol
@@ -1,17 +1,16 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.16;
-import {IERC165} from "../../../vendor/openzeppelin-solidity/v4.8.0/contracts/interfaces/IERC165.sol";
-import {Common} from "../../../libraries/Common.sol";
+import {IERC165} from "../../vendor/openzeppelin-solidity/v4.8.0/contracts/interfaces/IERC165.sol";
+import {Common} from "../../libraries/Common.sol";
interface IRewardManager is IERC165 {
/**
* @notice Record the fee received for a particular pool
- * @param poolId poolId of the report being verified
- * @param payee the user the funds should be deposited from
- * @param amount the amount to be paid into the pool
+ * @param payments array of structs containing pool id and amount
+ * @param payee the user the funds should be retrieved from
*/
- function onFeePaid(bytes32 poolId, address payee, uint256 amount) external;
+ function onFeePaid(FeePayment[] calldata payments, address payee) external;
/**
* @notice Claims the rewards in a specific pool
@@ -49,6 +48,22 @@ interface IRewardManager is IERC165 {
/**
* @notice Gets a list of pool ids which have reward for a specific recipient.
* @param recipient address of the recipient to get pool ids for
+ * @param startIndex the index to start from
+ * @param endIndex the index to stop at
*/
- function getAvailableRewardPoolIds(address recipient) external view returns (bytes32[] memory);
+ function getAvailableRewardPoolIds(
+ address recipient,
+ uint256 startIndex,
+ uint256 endIndex
+ ) external view returns (bytes32[] memory);
+
+ /**
+ * @notice The structure to hold a fee payment notice
+ * @param poolId the poolId receiving the payment
+ * @param amount the amount being paid
+ */
+ struct FeePayment {
+ bytes32 poolId;
+ uint192 amount;
+ }
}
diff --git a/contracts/src/v0.8/llo-feeds/interfaces/IVerifier.sol b/contracts/src/v0.8/llo-feeds/interfaces/IVerifier.sol
index 181bf9ad716..7617d9a5c35 100644
--- a/contracts/src/v0.8/llo-feeds/interfaces/IVerifier.sol
+++ b/contracts/src/v0.8/llo-feeds/interfaces/IVerifier.sol
@@ -14,9 +14,9 @@ interface IVerifier is IERC165 {
* @dev Verification is typically only done through the proxy contract so
* we can't just use msg.sender to log the requester as the msg.sender
* contract will always be the proxy.
- * @return response The encoded verified response.
+ * @return verifierResponse The encoded verified response.
*/
- function verify(bytes calldata signedReport, address sender) external returns (bytes memory response);
+ function verify(bytes calldata signedReport, address sender) external returns (bytes memory verifierResponse);
/**
* @notice sets offchain reporting protocol configuration incl. participating oracles
@@ -45,6 +45,7 @@ interface IVerifier is IERC165 {
* @param feedId Feed ID to set config for
* @param sourceChainId Chain ID of source config
* @param sourceAddress Address of source config Verifier
+ * @param newConfigCount Param to force the new config count
* @param signers addresses with which oracles sign the reports
* @param offchainTransmitters CSA key for the ith Oracle
* @param f number of faulty oracles the system can tolerate
@@ -57,6 +58,7 @@ interface IVerifier is IERC165 {
bytes32 feedId,
uint256 sourceChainId,
address sourceAddress,
+ uint32 newConfigCount,
address[] memory signers,
bytes32[] memory offchainTransmitters,
uint8 f,
diff --git a/contracts/src/v0.8/llo-feeds/interfaces/IVerifierFeeManager.sol b/contracts/src/v0.8/llo-feeds/interfaces/IVerifierFeeManager.sol
index 345122eb50b..8e490d39d1e 100644
--- a/contracts/src/v0.8/llo-feeds/interfaces/IVerifierFeeManager.sol
+++ b/contracts/src/v0.8/llo-feeds/interfaces/IVerifierFeeManager.sol
@@ -7,10 +7,23 @@ import {Common} from "../../libraries/Common.sol";
interface IVerifierFeeManager is IERC165 {
/**
* @notice Handles fees for a report from the subscriber and manages rewards
- * @param payload report and quote to process the fee for
+ * @param payload report to process the fee for
+ * @param parameterPayload fee payload
* @param subscriber address of the fee will be applied
*/
- function processFee(bytes calldata payload, address subscriber) external payable;
+ function processFee(bytes calldata payload, bytes calldata parameterPayload, address subscriber) external payable;
+
+ /**
+ * @notice Processes the fees for each report in the payload, billing the subscriber and paying the reward manager
+ * @param payloads reports to process
+ * @param parameterPayload fee payload
+ * @param subscriber address of the user to process fee for
+ */
+ function processFeeBulk(
+ bytes[] calldata payloads,
+ bytes calldata parameterPayload,
+ address subscriber
+ ) external payable;
/**
* @notice Sets the fee recipients according to the fee manager
diff --git a/contracts/src/v0.8/llo-feeds/interfaces/IVerifierProxy.sol b/contracts/src/v0.8/llo-feeds/interfaces/IVerifierProxy.sol
index d128b5090fa..c2665261e9a 100644
--- a/contracts/src/v0.8/llo-feeds/interfaces/IVerifierProxy.sol
+++ b/contracts/src/v0.8/llo-feeds/interfaces/IVerifierProxy.sol
@@ -2,7 +2,7 @@
pragma solidity 0.8.16;
import {Common} from "../../libraries/Common.sol";
-import {AccessControllerInterface} from "../../interfaces/AccessControllerInterface.sol";
+import {AccessControllerInterface} from "../../shared/interfaces/AccessControllerInterface.sol";
import {IVerifierFeeManager} from "./IVerifierFeeManager.sol";
interface IVerifierProxy {
@@ -10,10 +10,27 @@ interface IVerifierProxy {
* @notice Verifies that the data encoded has been signed
* correctly by routing to the correct verifier, and bills the user if applicable.
* @param payload The encoded data to be verified, including the signed
- * report and any metadata for billing.
- * @return verifiedReport The encoded report from the verifier.
+ * report.
+ * @param parameterPayload fee metadata for billing
+ * @return verifierResponse The encoded report from the verifier.
*/
- function verify(bytes calldata payload) external payable returns (bytes memory verifiedReport);
+ function verify(
+ bytes calldata payload,
+ bytes calldata parameterPayload
+ ) external payable returns (bytes memory verifierResponse);
+
+ /**
+ * @notice Bulk verifies that the data encoded has been signed
+ * correctly by routing to the correct verifier, and bills the user if applicable.
+ * @param payloads The encoded payloads to be verified, including the signed
+ * report.
+ * @param parameterPayload fee metadata for billing
+ * @return verifiedReports The encoded reports from the verifier.
+ */
+ function verifyBulk(
+ bytes[] calldata payloads,
+ bytes calldata parameterPayload
+ ) external payable returns (bytes[] memory verifiedReports);
/**
* @notice Sets the verifier address initially, allowing `setVerifier` to be set by this Verifier in the future
diff --git a/contracts/src/v0.8/llo-feeds/test/fee-manager/BaseFeeManager.t.sol b/contracts/src/v0.8/llo-feeds/test/fee-manager/BaseFeeManager.t.sol
index b17679d1490..ef46ad37853 100644
--- a/contracts/src/v0.8/llo-feeds/test/fee-manager/BaseFeeManager.t.sol
+++ b/contracts/src/v0.8/llo-feeds/test/fee-manager/BaseFeeManager.t.sol
@@ -2,12 +2,14 @@
pragma solidity 0.8.16;
import {Test} from "forge-std/Test.sol";
-import {FeeManager} from "../../dev/FeeManager.sol";
-import {IFeeManager} from "../../dev/interfaces/IFeeManager.sol";
-import {RewardManager} from "../../dev/RewardManager.sol";
+import {FeeManager} from "../../FeeManager.sol";
+import {IFeeManager} from "../../interfaces/IFeeManager.sol";
+import {RewardManager} from "../../RewardManager.sol";
import {Common} from "../../../libraries/Common.sol";
import {ERC20Mock} from "../../../vendor/openzeppelin-solidity/v4.8.0/contracts/mocks/ERC20Mock.sol";
import {WERC20Mock} from "../../../shared/mocks/WERC20Mock.sol";
+import {IRewardManager} from "../../interfaces/IRewardManager.sol";
+import {FeeManagerProxy} from "../mocks/FeeManagerProxy.sol";
/**
* @title BaseFeeManagerTest
@@ -19,6 +21,7 @@ contract BaseFeeManagerTest is Test {
//contracts
FeeManager internal feeManager;
RewardManager internal rewardManager;
+ FeeManagerProxy internal feeManagerProxy;
ERC20Mock internal link;
WERC20Mock internal native;
@@ -52,7 +55,7 @@ contract BaseFeeManagerTest is Test {
uint256 internal constant DEFAULT_REPORT_NATIVE_FEE = 1e12;
//rewards
- uint256 internal constant FEE_SCALAR = 1e18;
+ uint64 internal constant FEE_SCALAR = 1e18;
address internal constant NATIVE_WITHDRAW_ADDRESS = address(0);
@@ -69,11 +72,18 @@ contract BaseFeeManagerTest is Test {
bytes4 internal immutable ZERO_DEFICIT = FeeManager.ZeroDeficit.selector;
//events emitted
- event SubscriberDiscountUpdated(address indexed subscriber, bytes32 indexed feedId, address token, uint256 discount);
- event NativeSurchargeUpdated(uint256 newSurcharge);
- event InsufficientLink(bytes32 indexed configDigest, uint256 linkQuantity, uint256 nativeQuantity);
- event Withdraw(address adminAddress, address assetAddress, uint256 quantity);
+ event SubscriberDiscountUpdated(address indexed subscriber, bytes32 indexed feedId, address token, uint64 discount);
+ event NativeSurchargeUpdated(uint64 newSurcharge);
+ event InsufficientLink(IRewardManager.FeePayment[] feesAndRewards);
+ event Withdraw(address adminAddress, address recipient, address assetAddress, uint192 quantity);
event LinkDeficitCleared(bytes32 indexed configDigest, uint256 linkQuantity);
+ event DiscountApplied(
+ bytes32 indexed configDigest,
+ address indexed subscriber,
+ Common.Asset fee,
+ Common.Asset reward,
+ uint256 appliedDiscountQuantity
+ );
function setUp() public virtual {
//change to admin user
@@ -87,8 +97,12 @@ contract BaseFeeManagerTest is Test {
link = new ERC20Mock("LINK", "LINK", ADMIN, 0);
native = new WERC20Mock();
- rewardManager = new RewardManager(getLinkAddress());
- feeManager = new FeeManager(getLinkAddress(), getNativeAddress(), PROXY, address(rewardManager));
+ feeManagerProxy = new FeeManagerProxy();
+ rewardManager = new RewardManager(address(link));
+ feeManager = new FeeManager(address(link), address(native), address(feeManagerProxy), address(rewardManager));
+
+ //link the feeManager to the proxy
+ feeManagerProxy.setFeeManager(feeManager);
//link the feeManager to the reward manager
rewardManager.setFeeManager(address(feeManager));
@@ -121,7 +135,7 @@ contract BaseFeeManagerTest is Test {
changePrank(sender);
//set the discount
- feeManager.updateSubscriberDiscount(subscriber, feedId, token, discount);
+ feeManager.updateSubscriberDiscount(subscriber, feedId, token, uint64(discount));
//change back to the original address
changePrank(originalAddr);
@@ -133,77 +147,67 @@ contract BaseFeeManagerTest is Test {
changePrank(sender);
//set the surcharge
- feeManager.setNativeSurcharge(surcharge);
+ feeManager.setNativeSurcharge(uint64(surcharge));
//change back to the original address
changePrank(originalAddr);
}
// solium-disable-next-line no-unused-vars
- function getFee(
- bytes memory report,
- IFeeManager.Quote memory quote,
- address subscriber
- ) public view returns (Common.Asset memory) {
+ function getFee(bytes memory report, address quote, address subscriber) public view returns (Common.Asset memory) {
//get the fee
- (Common.Asset memory fee, ) = feeManager.getFeeAndReward(subscriber, report, quote);
+ (Common.Asset memory fee, , ) = feeManager.getFeeAndReward(subscriber, report, quote);
return fee;
}
- function getReward(
- bytes memory report,
- IFeeManager.Quote memory quote,
- address subscriber
- ) public view returns (Common.Asset memory) {
+ function getReward(bytes memory report, address quote, address subscriber) public view returns (Common.Asset memory) {
//get the reward
- (, Common.Asset memory reward) = feeManager.getFeeAndReward(subscriber, report, quote);
+ (, Common.Asset memory reward, ) = feeManager.getFeeAndReward(subscriber, report, quote);
return reward;
}
- function getV0Report(bytes32 feedId) public pure returns (bytes memory) {
+ function getAppliedDiscount(bytes memory report, address quote, address subscriber) public view returns (uint256) {
+ //get the reward
+ (, , uint256 appliedDiscount) = feeManager.getFeeAndReward(subscriber, report, quote);
+
+ return appliedDiscount;
+ }
+
+ function getV1Report(bytes32 feedId) public pure returns (bytes memory) {
return abi.encode(feedId, uint32(0), int192(0), int192(0), int192(0), uint64(0), bytes32(0), uint64(0), uint64(0));
}
- function getV1Report(bytes32 feedId) public view returns (bytes memory) {
+ function getV2Report(bytes32 feedId) public view returns (bytes memory) {
return
abi.encode(
feedId,
uint32(0),
uint32(0),
- int192(0),
- uint192(DEFAULT_REPORT_LINK_FEE),
uint192(DEFAULT_REPORT_NATIVE_FEE),
- uint32(block.timestamp)
+ uint192(DEFAULT_REPORT_LINK_FEE),
+ uint32(block.timestamp),
+ int192(0)
);
}
- function getV1ReportWithExpiryAndFee(
- bytes32 feedId,
- uint256 expiry,
- uint256 linkFee,
- uint256 nativeFee
- ) public pure returns (bytes memory) {
- return abi.encode(feedId, uint32(0), uint32(0), int192(0), uint192(linkFee), uint192(nativeFee), uint32(expiry));
- }
-
- function getV2Report(bytes32 feedId) public view returns (bytes memory) {
+ function getV3Report(bytes32 feedId) public view returns (bytes memory) {
return
abi.encode(
feedId,
uint32(0),
uint32(0),
- int192(0),
- uint192(DEFAULT_REPORT_LINK_FEE),
uint192(DEFAULT_REPORT_NATIVE_FEE),
+ uint192(DEFAULT_REPORT_LINK_FEE),
uint32(block.timestamp),
int192(0),
+ int192(0),
int192(0)
);
}
- function getV2ReportWithCustomExpiryAndFee(
+ function getV3ReportWithCustomExpiryAndFee(
bytes32 feedId,
uint256 expiry,
uint256 linkFee,
@@ -214,30 +218,30 @@ contract BaseFeeManagerTest is Test {
feedId,
uint32(0),
uint32(0),
- int192(0),
- uint192(linkFee),
uint192(nativeFee),
+ uint192(linkFee),
uint32(expiry),
int192(0),
+ int192(0),
int192(0)
);
}
- function getLinkQuote() public view returns (IFeeManager.Quote memory) {
- return IFeeManager.Quote(getLinkAddress());
+ function getLinkQuote() public view returns (address) {
+ return address(link);
}
- function getNativeQuote() public view returns (IFeeManager.Quote memory) {
- return IFeeManager.Quote(getNativeAddress());
+ function getNativeQuote() public view returns (address) {
+ return address(native);
}
- function withdraw(address assetAddress, uint256 amount, address sender) public {
+ function withdraw(address assetAddress, address recipient, uint256 amount, address sender) public {
//record the current address and switch to the recipient
address originalAddr = msg.sender;
changePrank(sender);
//set the surcharge
- feeManager.withdraw(assetAddress, amount);
+ feeManager.withdraw(assetAddress, recipient, uint192(amount));
//change back to the original address
changePrank(originalAddr);
@@ -283,32 +287,55 @@ contract BaseFeeManagerTest is Test {
vm.deal(recipient, quantity);
}
- function processFee(bytes memory payload, address subscriber, uint256 wrappedNativeValue, address sender) public {
+ function ProcessFeeAsUser(
+ bytes memory payload,
+ address subscriber,
+ address tokenAddress,
+ uint256 wrappedNativeValue,
+ address sender
+ ) public {
//record the current address and switch to the recipient
address originalAddr = msg.sender;
changePrank(sender);
//process the fee
- feeManager.processFee{value: wrappedNativeValue}(payload, subscriber);
+ feeManager.processFee{value: wrappedNativeValue}(payload, abi.encode(tokenAddress), subscriber);
+
+ //change ProcessFeeAsUserback to the original address
+ changePrank(originalAddr);
+ }
+
+ function processFee(bytes memory payload, address subscriber, address feeAddress, uint256 wrappedNativeValue) public {
+ //record the current address and switch to the recipient
+ address originalAddr = msg.sender;
+ changePrank(subscriber);
+
+ //process the fee
+ feeManagerProxy.processFee{value: wrappedNativeValue}(payload, abi.encode(feeAddress));
//change back to the original address
changePrank(originalAddr);
}
- function getPayload(bytes memory reportPayload, bytes memory quotePayload) public pure returns (bytes memory) {
- return
- abi.encode(
- [DEFAULT_CONFIG_DIGEST, 0, 0],
- reportPayload,
- new bytes32[](1),
- new bytes32[](1),
- bytes32(""),
- quotePayload
- );
+ function processFee(
+ bytes[] memory payloads,
+ address subscriber,
+ address feeAddress,
+ uint256 wrappedNativeValue
+ ) public {
+ //record the current address and switch to the recipient
+ address originalAddr = msg.sender;
+ changePrank(subscriber);
+
+ //process the fee
+ feeManagerProxy.processFeeBulk{value: wrappedNativeValue}(payloads, abi.encode(feeAddress));
+
+ //change back to the original address
+ changePrank(originalAddr);
}
- function getQuotePayload(address quoteAddress) public pure returns (bytes memory) {
- return abi.encode(quoteAddress);
+ function getPayload(bytes memory reportPayload) public pure returns (bytes memory) {
+ return abi.encode([DEFAULT_CONFIG_DIGEST, 0, 0], reportPayload, new bytes32[](1), new bytes32[](1), bytes32(""));
}
function approveLink(address spender, uint256 quantity, address sender) public {
@@ -335,14 +362,6 @@ contract BaseFeeManagerTest is Test {
changePrank(originalAddr);
}
- function getLinkAddress() public view returns (address) {
- return address(link);
- }
-
- function getNativeAddress() public view returns (address) {
- return address(native);
- }
-
function payLinkDeficit(bytes32 configDigest, address sender) public {
//record the current address and switch to the recipient
address originalAddr = msg.sender;
diff --git a/contracts/src/v0.8/llo-feeds/test/fee-manager/FeeManager.general.t.sol b/contracts/src/v0.8/llo-feeds/test/fee-manager/FeeManager.general.t.sol
index 0c8c9dd9ee4..105c140b73a 100644
--- a/contracts/src/v0.8/llo-feeds/test/fee-manager/FeeManager.general.t.sol
+++ b/contracts/src/v0.8/llo-feeds/test/fee-manager/FeeManager.general.t.sol
@@ -2,7 +2,7 @@
pragma solidity 0.8.16;
import {Test} from "forge-std/Test.sol";
-import {FeeManager} from "../../dev/FeeManager.sol";
+import {FeeManager} from "../../FeeManager.sol";
import {Common} from "../../../libraries/Common.sol";
import "./BaseFeeManager.t.sol";
@@ -28,7 +28,7 @@ contract FeeManagerProcessFeeTest is BaseFeeManagerTest {
uint256 withdrawAmount = contractBalance / 2;
//withdraw some balance
- withdraw(getLinkAddress(), withdrawAmount, ADMIN);
+ withdraw(address(link), ADMIN, withdrawAmount, ADMIN);
//check the balance has been reduced
uint256 newContractBalance = getLinkBalance(address(feeManager));
@@ -54,7 +54,7 @@ contract FeeManagerProcessFeeTest is BaseFeeManagerTest {
uint256 withdrawAmount = contractBalance / 2;
//withdraw some balance
- withdraw(NATIVE_WITHDRAW_ADDRESS, withdrawAmount, ADMIN);
+ withdraw(NATIVE_WITHDRAW_ADDRESS, ADMIN, withdrawAmount, ADMIN);
//check the balance has been reduced
uint256 newContractBalance = getNativeUnwrappedBalance(address(feeManager));
@@ -76,12 +76,12 @@ contract FeeManagerProcessFeeTest is BaseFeeManagerTest {
vm.expectRevert(ONLY_CALLABLE_BY_OWNER_ERROR);
//withdraw some balance
- withdraw(getLinkAddress(), DEFAULT_LINK_MINT_QUANTITY, USER);
+ withdraw(address(link), ADMIN, DEFAULT_LINK_MINT_QUANTITY, USER);
}
function test_eventIsEmittedAfterSurchargeIsSet() public {
//native surcharge
- uint256 nativeSurcharge = FEE_SCALAR / 5;
+ uint64 nativeSurcharge = FEE_SCALAR / 5;
//expect an emit
vm.expectEmit();
@@ -95,16 +95,16 @@ contract FeeManagerProcessFeeTest is BaseFeeManagerTest {
function test_subscriberDiscountEventIsEmittedOnUpdate() public {
//native surcharge
- uint256 discount = FEE_SCALAR / 3;
+ uint64 discount = FEE_SCALAR / 3;
//an event should be emitted
vm.expectEmit();
//emit the event that is expected to be emitted
- emit SubscriberDiscountUpdated(USER, DEFAULT_FEED_1_V3, getNativeAddress(), discount);
+ emit SubscriberDiscountUpdated(USER, DEFAULT_FEED_1_V3, address(native), discount);
//set the surcharge
- setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, getNativeAddress(), discount, ADMIN);
+ setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(native), discount, ADMIN);
}
function test_eventIsEmittedUponWithdraw() public {
@@ -112,16 +112,16 @@ contract FeeManagerProcessFeeTest is BaseFeeManagerTest {
mintLink(address(feeManager), DEFAULT_LINK_MINT_QUANTITY);
//the amount to withdraw
- uint256 withdrawAmount = 1;
+ uint192 withdrawAmount = 1;
//expect an emit
vm.expectEmit();
//the event to be emitted
- emit Withdraw(ADMIN, getLinkAddress(), withdrawAmount);
+ emit Withdraw(ADMIN, ADMIN, address(link), withdrawAmount);
//withdraw some balance
- withdraw(getLinkAddress(), withdrawAmount, ADMIN);
+ withdraw(address(link), ADMIN, withdrawAmount, ADMIN);
}
function test_linkAvailableForPaymentReturnsLinkBalance() public {
@@ -137,16 +137,20 @@ contract FeeManagerProcessFeeTest is BaseFeeManagerTest {
function test_payLinkDeficit() public {
//get the default payload
- bytes memory payload = getPayload(getV2Report(DEFAULT_FEED_1_V3), getQuotePayload(getNativeAddress()));
+ bytes memory payload = getPayload(getV2Report(DEFAULT_FEED_1_V3));
approveNative(address(feeManager), DEFAULT_REPORT_NATIVE_FEE, USER);
//not enough funds in the reward pool should trigger an insufficient link event
vm.expectEmit();
- emit InsufficientLink(DEFAULT_CONFIG_DIGEST, DEFAULT_REPORT_LINK_FEE, DEFAULT_REPORT_NATIVE_FEE);
+
+ IRewardManager.FeePayment[] memory contractFees = new IRewardManager.FeePayment[](1);
+ contractFees[0] = IRewardManager.FeePayment(DEFAULT_CONFIG_DIGEST, uint192(DEFAULT_REPORT_LINK_FEE));
+
+ emit InsufficientLink(contractFees);
//process the fee
- processFee(payload, USER, 0, ADMIN);
+ processFee(payload, USER, address(native), 0);
//double check the rewardManager balance is 0
assertEq(getLinkBalance(address(rewardManager)), 0);
@@ -166,16 +170,21 @@ contract FeeManagerProcessFeeTest is BaseFeeManagerTest {
function test_payLinkDeficitTwice() public {
//get the default payload
- bytes memory payload = getPayload(getV2Report(DEFAULT_FEED_1_V3), getQuotePayload(getNativeAddress()));
+ bytes memory payload = getPayload(getV2Report(DEFAULT_FEED_1_V3));
approveNative(address(feeManager), DEFAULT_REPORT_NATIVE_FEE, USER);
//not enough funds in the reward pool should trigger an insufficient link event
vm.expectEmit();
- emit InsufficientLink(DEFAULT_CONFIG_DIGEST, DEFAULT_REPORT_LINK_FEE, DEFAULT_REPORT_NATIVE_FEE);
+
+ IRewardManager.FeePayment[] memory contractFees = new IRewardManager.FeePayment[](1);
+ contractFees[0] = IRewardManager.FeePayment(DEFAULT_CONFIG_DIGEST, uint192(DEFAULT_REPORT_LINK_FEE));
+
+ //emit the event that is expected to be emitted
+ emit InsufficientLink(contractFees);
//process the fee
- processFee(payload, USER, 0, ADMIN);
+ processFee(payload, USER, address(native), 0);
//double check the rewardManager balance is 0
assertEq(getLinkBalance(address(rewardManager)), 0);
@@ -200,14 +209,14 @@ contract FeeManagerProcessFeeTest is BaseFeeManagerTest {
function test_payLinkDeficitPaysAllFeesProcessed() public {
//get the default payload
- bytes memory payload = getPayload(getV2Report(DEFAULT_FEED_1_V3), getQuotePayload(getNativeAddress()));
+ bytes memory payload = getPayload(getV2Report(DEFAULT_FEED_1_V3));
//approve the native to be transferred from the user
approveNative(address(feeManager), DEFAULT_REPORT_NATIVE_FEE * 2, USER);
//processing the fee will transfer the native from the user to the feeManager
- processFee(payload, USER, 0, ADMIN);
- processFee(payload, USER, 0, ADMIN);
+ processFee(payload, USER, address(native), 0);
+ processFee(payload, USER, address(native), 0);
//check the deficit has been increased twice
assertEq(getLinkDeficit(DEFAULT_CONFIG_DIGEST), DEFAULT_REPORT_LINK_FEE * 2);
diff --git a/contracts/src/v0.8/llo-feeds/test/fee-manager/FeeManager.getFeeAndReward.t.sol b/contracts/src/v0.8/llo-feeds/test/fee-manager/FeeManager.getFeeAndReward.t.sol
index 0baf8dee084..dcabe6e5f9d 100644
--- a/contracts/src/v0.8/llo-feeds/test/fee-manager/FeeManager.getFeeAndReward.t.sol
+++ b/contracts/src/v0.8/llo-feeds/test/fee-manager/FeeManager.getFeeAndReward.t.sol
@@ -2,8 +2,8 @@
pragma solidity 0.8.16;
import {Test} from "forge-std/Test.sol";
-import {FeeManager} from "../../dev/FeeManager.sol";
-import {IFeeManager} from "../../dev/interfaces/IFeeManager.sol";
+import {FeeManager} from "../../FeeManager.sol";
+import {IFeeManager} from "../../interfaces/IFeeManager.sol";
import {Common} from "../../../libraries/Common.sol";
import "./BaseFeeManager.t.sol";
@@ -15,7 +15,7 @@ import "./BaseFeeManager.t.sol";
contract FeeManagerProcessFeeTest is BaseFeeManagerTest {
function test_baseFeeIsAppliedForNative() public {
//get the fee required by the feeManager
- Common.Asset memory fee = getFee(getV2Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER);
+ Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER);
//fee should be the default
assertEq(fee.amount, DEFAULT_REPORT_NATIVE_FEE);
@@ -23,7 +23,7 @@ contract FeeManagerProcessFeeTest is BaseFeeManagerTest {
function test_baseFeeIsAppliedForLink() public {
//get the fee required by the feeManager
- Common.Asset memory fee = getFee(getV2Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER);
+ Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER);
//fee should be the default
assertEq(fee.amount, DEFAULT_REPORT_LINK_FEE);
@@ -31,10 +31,10 @@ contract FeeManagerProcessFeeTest is BaseFeeManagerTest {
function test_discountAIsNotAppliedWhenSetForOtherUsers() public {
//set the subscriber discount for another user
- setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, getLinkAddress(), FEE_SCALAR / 2, ADMIN);
+ setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(link), FEE_SCALAR / 2, ADMIN);
//get the fee required by the feeManager
- Common.Asset memory fee = getFee(getV2Report(DEFAULT_FEED_1_V3), getNativeQuote(), INVALID_ADDRESS);
+ Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), INVALID_ADDRESS);
//fee should be the default
assertEq(fee.amount, DEFAULT_REPORT_NATIVE_FEE);
@@ -50,10 +50,10 @@ contract FeeManagerProcessFeeTest is BaseFeeManagerTest {
function test_discountIsAppliedForLink() public {
//set the subscriber discount to 50%
- setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, getLinkAddress(), FEE_SCALAR / 2, ADMIN);
+ setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(link), FEE_SCALAR / 2, ADMIN);
//get the fee required by the feeManager
- Common.Asset memory fee = getFee(getV2Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER);
+ Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER);
//fee should be half the default
assertEq(fee.amount, DEFAULT_REPORT_LINK_FEE / 2);
@@ -61,10 +61,10 @@ contract FeeManagerProcessFeeTest is BaseFeeManagerTest {
function test_DiscountIsAppliedForNative() public {
//set the subscriber discount to 50%
- setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, getNativeAddress(), FEE_SCALAR / 2, ADMIN);
+ setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(native), FEE_SCALAR / 2, ADMIN);
//get the fee required by the feeManager
- Common.Asset memory fee = getFee(getV2Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER);
+ Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER);
//fee should be half the default
assertEq(fee.amount, DEFAULT_REPORT_NATIVE_FEE / 2);
@@ -72,19 +72,19 @@ contract FeeManagerProcessFeeTest is BaseFeeManagerTest {
function test_discountIsNoLongerAppliedAfterRemoving() public {
//set the subscriber discount to 50%
- setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, getLinkAddress(), FEE_SCALAR / 2, ADMIN);
+ setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(link), FEE_SCALAR / 2, ADMIN);
//get the fee required by the feeManager
- Common.Asset memory fee = getFee(getV2Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER);
+ Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER);
//fee should be half the default
assertEq(fee.amount, DEFAULT_REPORT_LINK_FEE / 2);
//remove the discount
- setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, getLinkAddress(), 0, ADMIN);
+ setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(link), 0, ADMIN);
//get the fee required by the feeManager
- fee = getFee(getV2Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER);
+ fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER);
//fee should be the default
assertEq(fee.amount, DEFAULT_REPORT_LINK_FEE);
@@ -98,7 +98,7 @@ contract FeeManagerProcessFeeTest is BaseFeeManagerTest {
setNativeSurcharge(nativeSurcharge, ADMIN);
//get the fee required by the feeManager
- Common.Asset memory fee = getFee(getV2Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER);
+ Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER);
//calculate the expected surcharge
uint256 expectedSurcharge = ((DEFAULT_REPORT_NATIVE_FEE * nativeSurcharge) / FEE_SCALAR);
@@ -115,7 +115,7 @@ contract FeeManagerProcessFeeTest is BaseFeeManagerTest {
setNativeSurcharge(nativeSurcharge, ADMIN);
//get the fee required by the feeManager
- Common.Asset memory fee = getFee(getV2Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER);
+ Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER);
//fee should be the default
assertEq(fee.amount, DEFAULT_REPORT_LINK_FEE);
@@ -129,7 +129,7 @@ contract FeeManagerProcessFeeTest is BaseFeeManagerTest {
setNativeSurcharge(nativeSurcharge, ADMIN);
//get the fee required by the feeManager
- Common.Asset memory fee = getFee(getV2Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER);
+ Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER);
//calculate the expected surcharge
uint256 expectedSurcharge = ((DEFAULT_REPORT_NATIVE_FEE * nativeSurcharge) / FEE_SCALAR);
@@ -141,7 +141,7 @@ contract FeeManagerProcessFeeTest is BaseFeeManagerTest {
setNativeSurcharge(0, ADMIN);
//get the fee required by the feeManager
- fee = getFee(getV2Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER);
+ fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER);
//fee should be the default
assertEq(fee.amount, DEFAULT_REPORT_NATIVE_FEE);
@@ -155,7 +155,7 @@ contract FeeManagerProcessFeeTest is BaseFeeManagerTest {
setNativeSurcharge(nativeSurcharge, ADMIN);
//get the fee required by the feeManager
- Common.Asset memory fee = getFee(getV2Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER);
+ Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER);
//calculate the expected surcharge
uint256 expectedSurcharge = ((DEFAULT_REPORT_NATIVE_FEE * nativeSurcharge) / FEE_SCALAR);
@@ -167,7 +167,7 @@ contract FeeManagerProcessFeeTest is BaseFeeManagerTest {
setNativeSurcharge(nativeSurcharge, ADMIN);
//get the fee required by the feeManager
- fee = getFee(getV2Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER);
+ fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER);
//calculate the expected surcharge
expectedSurcharge = ((DEFAULT_REPORT_NATIVE_FEE * nativeSurcharge) / FEE_SCALAR);
@@ -181,13 +181,13 @@ contract FeeManagerProcessFeeTest is BaseFeeManagerTest {
uint256 nativeSurcharge = FEE_SCALAR / 5;
//set the subscriber discount to 50%
- setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, getNativeAddress(), FEE_SCALAR / 2, ADMIN);
+ setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(native), FEE_SCALAR / 2, ADMIN);
//set the surcharge
setNativeSurcharge(nativeSurcharge, ADMIN);
//get the fee required by the feeManager
- Common.Asset memory fee = getFee(getV2Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER);
+ Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER);
//calculate the expected surcharge quantity
uint256 expectedSurcharge = ((DEFAULT_REPORT_NATIVE_FEE * nativeSurcharge) / FEE_SCALAR);
@@ -204,7 +204,7 @@ contract FeeManagerProcessFeeTest is BaseFeeManagerTest {
vm.expectRevert(INVALID_QUOTE_ERROR);
//get the fee required by the feeManager
- getFee(getV2Report(DEFAULT_FEED_1_V3), IFeeManager.Quote(address(0)), USER);
+ getFee(getV3Report(DEFAULT_FEED_1_V3), address(0), USER);
}
function test_nativeSurcharge100Percent() public {
@@ -212,7 +212,7 @@ contract FeeManagerProcessFeeTest is BaseFeeManagerTest {
setNativeSurcharge(FEE_SCALAR, ADMIN);
//get the fee required by the feeManager
- Common.Asset memory fee = getFee(getV2Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER);
+ Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER);
//fee should be twice the base fee
assertEq(fee.amount, DEFAULT_REPORT_NATIVE_FEE * 2);
@@ -223,7 +223,7 @@ contract FeeManagerProcessFeeTest is BaseFeeManagerTest {
setNativeSurcharge(0, ADMIN);
//get the fee required by the feeManager
- Common.Asset memory fee = getFee(getV2Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER);
+ Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER);
//fee should base fee
assertEq(fee.amount, DEFAULT_REPORT_NATIVE_FEE);
@@ -239,13 +239,13 @@ contract FeeManagerProcessFeeTest is BaseFeeManagerTest {
function test_discountIsAppliedWith100PercentSurcharge() public {
//set the subscriber discount to 50%
- setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, getNativeAddress(), FEE_SCALAR / 2, ADMIN);
+ setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(native), FEE_SCALAR / 2, ADMIN);
//set the surcharge
setNativeSurcharge(FEE_SCALAR, ADMIN);
//get the fee required by the feeManager
- Common.Asset memory fee = getFee(getV2Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER);
+ Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER);
//calculate the expected discount quantity
uint256 expectedDiscount = DEFAULT_REPORT_NATIVE_FEE;
@@ -256,10 +256,10 @@ contract FeeManagerProcessFeeTest is BaseFeeManagerTest {
function test_feeIsZeroWith100PercentDiscount() public {
//set the subscriber discount to 100%
- setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, getNativeAddress(), FEE_SCALAR, ADMIN);
+ setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(native), FEE_SCALAR, ADMIN);
//get the fee required by the feeManager
- Common.Asset memory fee = getFee(getV2Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER);
+ Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER);
//fee should be zero
assertEq(fee.amount, 0);
@@ -267,10 +267,10 @@ contract FeeManagerProcessFeeTest is BaseFeeManagerTest {
function test_feeIsUpdatedAfterDiscountIsRemoved() public {
//set the subscriber discount to 50%
- setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, getNativeAddress(), FEE_SCALAR / 2, ADMIN);
+ setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(native), FEE_SCALAR / 2, ADMIN);
//get the fee required by the feeManager
- Common.Asset memory fee = getFee(getV2Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER);
+ Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER);
//calculate the expected discount quantity
uint256 expectedDiscount = DEFAULT_REPORT_NATIVE_FEE / 2;
@@ -279,10 +279,10 @@ contract FeeManagerProcessFeeTest is BaseFeeManagerTest {
assertEq(fee.amount, DEFAULT_REPORT_NATIVE_FEE - expectedDiscount);
//remove the discount
- setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, getNativeAddress(), 0, ADMIN);
+ setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(native), 0, ADMIN);
//get the fee required by the feeManager
- fee = getFee(getV2Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER);
+ fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER);
//fee should be the base fee
assertEq(fee.amount, DEFAULT_REPORT_NATIVE_FEE);
@@ -290,10 +290,10 @@ contract FeeManagerProcessFeeTest is BaseFeeManagerTest {
function test_feeIsUpdatedAfterNewDiscountIsApplied() public {
//set the subscriber discount to 50%
- setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, getNativeAddress(), FEE_SCALAR / 2, ADMIN);
+ setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(native), FEE_SCALAR / 2, ADMIN);
//get the fee required by the feeManager
- Common.Asset memory fee = getFee(getV2Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER);
+ Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER);
//calculate the expected discount quantity
uint256 expectedDiscount = DEFAULT_REPORT_NATIVE_FEE / 2;
@@ -302,10 +302,10 @@ contract FeeManagerProcessFeeTest is BaseFeeManagerTest {
assertEq(fee.amount, DEFAULT_REPORT_NATIVE_FEE - expectedDiscount);
//change the discount to 25%
- setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, getNativeAddress(), FEE_SCALAR / 4, ADMIN);
+ setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(native), FEE_SCALAR / 4, ADMIN);
//get the fee required by the feeManager
- fee = getFee(getV2Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER);
+ fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER);
//expected discount is now 25%
expectedDiscount = DEFAULT_REPORT_NATIVE_FEE / 4;
@@ -319,7 +319,7 @@ contract FeeManagerProcessFeeTest is BaseFeeManagerTest {
vm.expectRevert(INVALID_DISCOUNT_ERROR);
//set the subscriber discount to over 100%
- setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, getNativeAddress(), FEE_SCALAR + 1, ADMIN);
+ setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(native), FEE_SCALAR + 1, ADMIN);
}
function test_surchargeIsNotAppliedWith100PercentDiscount() public {
@@ -327,13 +327,13 @@ contract FeeManagerProcessFeeTest is BaseFeeManagerTest {
uint256 nativeSurcharge = FEE_SCALAR / 5;
//set the subscriber discount to 100%
- setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, getNativeAddress(), FEE_SCALAR, ADMIN);
+ setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(native), FEE_SCALAR, ADMIN);
//set the surcharge
setNativeSurcharge(nativeSurcharge, ADMIN);
//get the fee required by the feeManager
- Common.Asset memory fee = getFee(getV2Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER);
+ Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER);
//fee should be zero
assertEq(fee.amount, 0);
@@ -344,7 +344,7 @@ contract FeeManagerProcessFeeTest is BaseFeeManagerTest {
vm.expectRevert(ONLY_CALLABLE_BY_OWNER_ERROR);
//set the subscriber discount to 50%
- setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, getNativeAddress(), FEE_SCALAR, USER);
+ setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(native), FEE_SCALAR, USER);
}
function test_surchargeFeeRoundsUpWhenUneven() public {
@@ -355,7 +355,7 @@ contract FeeManagerProcessFeeTest is BaseFeeManagerTest {
setNativeSurcharge(nativeSurcharge, ADMIN);
//get the fee required by the feeManager
- Common.Asset memory fee = getFee(getV2Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER);
+ Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER);
//calculate the expected surcharge quantity
uint256 expectedSurcharge = (DEFAULT_REPORT_NATIVE_FEE * nativeSurcharge) / FEE_SCALAR;
@@ -369,10 +369,10 @@ contract FeeManagerProcessFeeTest is BaseFeeManagerTest {
uint256 discount = FEE_SCALAR / 3;
//set the subscriber discount to 33.333%
- setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, getNativeAddress(), discount, ADMIN);
+ setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(native), discount, ADMIN);
//get the fee required by the feeManager
- Common.Asset memory fee = getFee(getV2Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER);
+ Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER);
//calculate the expected quantity
uint256 expectedDiscount = ((DEFAULT_REPORT_NATIVE_FEE * discount) / FEE_SCALAR);
@@ -383,7 +383,7 @@ contract FeeManagerProcessFeeTest is BaseFeeManagerTest {
function test_reportWithNoExpiryOrFeeReturnsZero() public {
//get the fee required by the feeManager
- Common.Asset memory fee = getFee(getV0Report(DEFAULT_FEED_1_V1), getNativeQuote(), USER);
+ Common.Asset memory fee = getFee(getV1Report(DEFAULT_FEED_1_V1), getNativeQuote(), USER);
//fee should be zero
assertEq(fee.amount, 0);
@@ -391,12 +391,12 @@ contract FeeManagerProcessFeeTest is BaseFeeManagerTest {
function test_correctDiscountIsAppliedWhenBothTokensAreDiscounted() public {
//set the subscriber and native discounts
- setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, getLinkAddress(), FEE_SCALAR / 4, ADMIN);
- setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, getNativeAddress(), FEE_SCALAR / 2, ADMIN);
+ setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(link), FEE_SCALAR / 4, ADMIN);
+ setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(native), FEE_SCALAR / 2, ADMIN);
//get the fee required by the feeManager for both tokens
- Common.Asset memory linkFee = getFee(getV2Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER);
- Common.Asset memory nativeFee = getFee(getV2Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER);
+ Common.Asset memory linkFee = getFee(getV3Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER);
+ Common.Asset memory nativeFee = getFee(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER);
//calculate the expected discount quantity for each token
uint256 expectedDiscountLink = (DEFAULT_REPORT_LINK_FEE * FEE_SCALAR) / 4 / FEE_SCALAR;
@@ -409,10 +409,10 @@ contract FeeManagerProcessFeeTest is BaseFeeManagerTest {
function test_discountIsNotAppliedToOtherFeeds() public {
//set the subscriber discount to 50%
- setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, getNativeAddress(), FEE_SCALAR / 2, ADMIN);
+ setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(native), FEE_SCALAR / 2, ADMIN);
//get the fee required by the feeManager
- Common.Asset memory fee = getFee(getV2Report(DEFAULT_FEED_2_V3), getNativeQuote(), USER);
+ Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_2_V3), getNativeQuote(), USER);
//fee should be the base fee
assertEq(fee.amount, DEFAULT_REPORT_NATIVE_FEE);
@@ -420,11 +420,11 @@ contract FeeManagerProcessFeeTest is BaseFeeManagerTest {
function test_noFeeIsAppliedWhenReportHasZeroFee() public {
//set the subscriber discount to 50%
- setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, getNativeAddress(), FEE_SCALAR / 2, ADMIN);
+ setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(native), FEE_SCALAR / 2, ADMIN);
//get the fee required by the feeManager
Common.Asset memory fee = getFee(
- getV2ReportWithCustomExpiryAndFee(DEFAULT_FEED_1_V3, uint32(block.timestamp), 0, 0),
+ getV3ReportWithCustomExpiryAndFee(DEFAULT_FEED_1_V3, uint32(block.timestamp), 0, 0),
getNativeQuote(),
USER
);
@@ -435,14 +435,14 @@ contract FeeManagerProcessFeeTest is BaseFeeManagerTest {
function test_noFeeIsAppliedWhenReportHasZeroFeeAndDiscountAndSurchargeIsSet() public {
//set the subscriber discount to 50%
- setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, getNativeAddress(), FEE_SCALAR / 2, ADMIN);
+ setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(native), FEE_SCALAR / 2, ADMIN);
//set the surcharge
setNativeSurcharge(FEE_SCALAR / 2, ADMIN);
//get the fee required by the feeManager
Common.Asset memory fee = getFee(
- getV2ReportWithCustomExpiryAndFee(DEFAULT_FEED_1_V3, uint32(block.timestamp), 0, 0),
+ getV3ReportWithCustomExpiryAndFee(DEFAULT_FEED_1_V3, uint32(block.timestamp), 0, 0),
getNativeQuote(),
USER
);
@@ -453,7 +453,7 @@ contract FeeManagerProcessFeeTest is BaseFeeManagerTest {
function test_nativeSurchargeEventIsEmittedOnUpdate() public {
//native surcharge
- uint256 nativeSurcharge = FEE_SCALAR / 3;
+ uint64 nativeSurcharge = FEE_SCALAR / 3;
//an event should be emitted
vm.expectEmit();
@@ -467,29 +467,29 @@ contract FeeManagerProcessFeeTest is BaseFeeManagerTest {
function test_getBaseRewardWithLinkQuote() public {
//get the fee required by the feeManager
- Common.Asset memory fee = getReward(getV2Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER);
+ Common.Asset memory reward = getReward(getV3Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER);
//the reward should equal the base fee
- assertEq(fee.amount, DEFAULT_REPORT_LINK_FEE);
+ assertEq(reward.amount, DEFAULT_REPORT_LINK_FEE);
}
function test_getRewardWithLinkQuoteAndLinkDiscount() public {
//set the link discount
- setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, getLinkAddress(), FEE_SCALAR / 2, ADMIN);
+ setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(link), FEE_SCALAR / 2, ADMIN);
//get the fee required by the feeManager
- Common.Asset memory fee = getReward(getV2Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER);
+ Common.Asset memory reward = getReward(getV3Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER);
//the reward should equal the discounted base fee
- assertEq(fee.amount, DEFAULT_REPORT_LINK_FEE / 2);
+ assertEq(reward.amount, DEFAULT_REPORT_LINK_FEE / 2);
}
function test_getRewardWithNativeQuote() public {
//get the fee required by the feeManager
- Common.Asset memory fee = getReward(getV2Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER);
+ Common.Asset memory reward = getReward(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER);
//the reward should equal the base fee in link
- assertEq(fee.amount, DEFAULT_REPORT_LINK_FEE);
+ assertEq(reward.amount, DEFAULT_REPORT_LINK_FEE);
}
function test_getRewardWithNativeQuoteAndSurcharge() public {
@@ -497,43 +497,47 @@ contract FeeManagerProcessFeeTest is BaseFeeManagerTest {
setNativeSurcharge(FEE_SCALAR / 2, ADMIN);
//get the fee required by the feeManager
- Common.Asset memory fee = getReward(getV2Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER);
+ Common.Asset memory reward = getReward(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER);
//the reward should equal the base fee in link regardless of the surcharge
- assertEq(fee.amount, DEFAULT_REPORT_LINK_FEE);
+ assertEq(reward.amount, DEFAULT_REPORT_LINK_FEE);
}
function test_getRewardWithLinkDiscount() public {
//set the link discount
- setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, getLinkAddress(), FEE_SCALAR / 2, ADMIN);
+ setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(link), FEE_SCALAR / 2, ADMIN);
//get the fee required by the feeManager
- Common.Asset memory fee = getReward(getV2Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER);
+ Common.Asset memory reward = getReward(getV3Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER);
//the reward should equal the discounted base fee
- assertEq(fee.amount, DEFAULT_REPORT_LINK_FEE / 2);
+ assertEq(reward.amount, DEFAULT_REPORT_LINK_FEE / 2);
}
function test_getLinkFeeIsRoundedUp() public {
//set the link discount
- setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, getLinkAddress(), FEE_SCALAR / 3, ADMIN);
+ setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(link), FEE_SCALAR / 3, ADMIN);
//get the fee required by the feeManager
- Common.Asset memory fee = getFee(getV2Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER);
+ Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER);
//the reward should equal .66% + 1 of the base fee due to a 33% discount rounded up
assertEq(fee.amount, (DEFAULT_REPORT_LINK_FEE * 2) / 3 + 1);
}
- function test_getLinkRewardIsRoundedDown() public {
+ function test_getLinkRewardIsSameAsFee() public {
//set the link discount
- setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, getLinkAddress(), FEE_SCALAR / 3, ADMIN);
+ setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(link), FEE_SCALAR / 3, ADMIN);
//get the fee required by the feeManager
- Common.Asset memory fee = getReward(getV2Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER);
+ Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER);
+ Common.Asset memory reward = getReward(getV3Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER);
+
+ //check the reward is in link
+ assertEq(fee.assetAddress, address(link));
//the reward should equal .66% of the base fee due to a 33% discount rounded down
- assertEq(fee.amount, (DEFAULT_REPORT_LINK_FEE * 2) / 3);
+ assertEq(reward.amount, fee.amount);
}
function test_getLinkRewardWithNativeQuoteAndSurchargeWithLinkDiscount() public {
@@ -541,13 +545,13 @@ contract FeeManagerProcessFeeTest is BaseFeeManagerTest {
setNativeSurcharge(FEE_SCALAR / 2, ADMIN);
//set the link discount
- setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, getLinkAddress(), FEE_SCALAR / 3, ADMIN);
+ setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(link), FEE_SCALAR / 3, ADMIN);
//get the fee required by the feeManager
- Common.Asset memory fee = getReward(getV2Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER);
+ Common.Asset memory reward = getReward(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER);
//the reward should equal the base fee in link regardless of the surcharge
- assertEq(fee.amount, DEFAULT_REPORT_LINK_FEE);
+ assertEq(reward.amount, DEFAULT_REPORT_LINK_FEE);
}
function test_testRevertIfReportHasExpired() public {
@@ -556,7 +560,7 @@ contract FeeManagerProcessFeeTest is BaseFeeManagerTest {
//get the fee required by the feeManager
getFee(
- getV2ReportWithCustomExpiryAndFee(
+ getV3ReportWithCustomExpiryAndFee(
DEFAULT_FEED_1_V3,
block.timestamp - 1,
DEFAULT_REPORT_LINK_FEE,
@@ -566,4 +570,40 @@ contract FeeManagerProcessFeeTest is BaseFeeManagerTest {
USER
);
}
+
+ function test_discountIsReturnedForLink() public {
+ //set the subscriber discount to 50%
+ setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(link), FEE_SCALAR / 2, ADMIN);
+
+ //get the fee applied
+ uint256 discount = getAppliedDiscount(getV3Report(DEFAULT_FEED_1_V3), getLinkQuote(), USER);
+
+ //fee should be half the default
+ assertEq(discount, FEE_SCALAR / 2);
+ }
+
+ function test_DiscountIsReturnedForNative() public {
+ //set the subscriber discount to 50%
+ setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(native), FEE_SCALAR / 2, ADMIN);
+
+ //get the discount applied
+ uint256 discount = getAppliedDiscount(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER);
+
+ //fee should be half the default
+ assertEq(discount, FEE_SCALAR / 2);
+ }
+
+ function test_DiscountIsReturnedForNativeWithSurcharge() public {
+ //set the subscriber discount to 50%
+ setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(native), FEE_SCALAR / 2, ADMIN);
+
+ //set the surcharge
+ setNativeSurcharge(FEE_SCALAR / 5, ADMIN);
+
+ //get the discount applied
+ uint256 discount = getAppliedDiscount(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER);
+
+ //fee should be half the default
+ assertEq(discount, FEE_SCALAR / 2);
+ }
}
diff --git a/contracts/src/v0.8/llo-feeds/test/fee-manager/FeeManager.processFee.t.sol b/contracts/src/v0.8/llo-feeds/test/fee-manager/FeeManager.processFee.t.sol
index 4ba54bb5fdb..91fb42a500f 100644
--- a/contracts/src/v0.8/llo-feeds/test/fee-manager/FeeManager.processFee.t.sol
+++ b/contracts/src/v0.8/llo-feeds/test/fee-manager/FeeManager.processFee.t.sol
@@ -2,9 +2,10 @@
pragma solidity 0.8.16;
import {Test} from "forge-std/Test.sol";
-import {FeeManager} from "../../dev/FeeManager.sol";
+import {FeeManager} from "../../FeeManager.sol";
import {Common} from "../../../libraries/Common.sol";
import "./BaseFeeManager.t.sol";
+import {IRewardManager} from "../../interfaces/IRewardManager.sol";
/**
* @title BaseFeeManagerTest
@@ -18,24 +19,24 @@ contract FeeManagerProcessFeeTest is BaseFeeManagerTest {
function test_nonAdminProxyUserCannotProcessFee() public {
//get the default payload
- bytes memory payload = getPayload(getV2Report(DEFAULT_FEED_1_V3), getQuotePayload(getLinkAddress()));
+ bytes memory payload = getPayload(getV3Report(DEFAULT_FEED_1_V3));
//should revert as the user is not the owner
vm.expectRevert(UNAUTHORIZED_ERROR);
//process the fee
- processFee(payload, USER, 0, USER);
+ ProcessFeeAsUser(payload, USER, address(link), 0, USER);
}
function test_processFeeAsProxy() public {
//get the default payload
- bytes memory payload = getPayload(getV2Report(DEFAULT_FEED_1_V3), getQuotePayload(getLinkAddress()));
+ bytes memory payload = getPayload(getV3Report(DEFAULT_FEED_1_V3));
//approve the link to be transferred from the from the subscriber to the rewardManager
approveLink(address(rewardManager), DEFAULT_REPORT_LINK_FEE, USER);
//processing the fee will transfer the link from the user to the rewardManager
- processFee(payload, USER, 0, PROXY);
+ processFee(payload, USER, address(link), 0);
//check the link has been transferred
assertEq(getLinkBalance(address(rewardManager)), DEFAULT_REPORT_LINK_FEE);
@@ -46,42 +47,42 @@ contract FeeManagerProcessFeeTest is BaseFeeManagerTest {
function test_processFeeIfSubscriberIsSelf() public {
//get the default payload
- bytes memory payload = getPayload(getV2Report(DEFAULT_FEED_1_V3), getQuotePayload(getLinkAddress()));
+ bytes memory payload = getPayload(getV3Report(DEFAULT_FEED_1_V3));
- //expect a revert due to funds being unapproved
+ //expect a revert due to the feeManager being the subscriber
vm.expectRevert(INVALID_ADDRESS_ERROR);
- //process the fee will attempt to transfer link from the contract to the rewardManager, which won't be approved
- processFee(payload, address(feeManager), 0, ADMIN);
+ //process the fee will fail due to assertion
+ processFee(payload, address(feeManager), address(native), 0);
}
function test_processFeeWithWithEmptyQuotePayload() public {
//get the default payload
- bytes memory payload = getPayload(getV2Report(DEFAULT_FEED_1_V3), bytes(""));
+ bytes memory payload = getPayload(getV3Report(DEFAULT_FEED_1_V3));
//expect a revert as the quote is invalid
vm.expectRevert();
//processing the fee will transfer the link by default
- processFee(payload, USER, 0, ADMIN);
+ processFee(payload, USER, address(0), 0);
}
function test_processFeeWithWithZeroQuotePayload() public {
//get the default payload
- bytes memory payload = getPayload(getV2Report(DEFAULT_FEED_1_V3), getQuotePayload(INVALID_ADDRESS));
+ bytes memory payload = getPayload(getV3Report(DEFAULT_FEED_1_V3));
//expect a revert as the quote is invalid
vm.expectRevert(INVALID_QUOTE_ERROR);
//processing the fee will transfer the link by default
- processFee(payload, USER, 0, ADMIN);
+ processFee(payload, USER, INVALID_ADDRESS, 0);
}
function test_processFeeWithWithCorruptQuotePayload() public {
//get the default payload
bytes memory payload = abi.encode(
[DEFAULT_CONFIG_DIGEST, 0, 0],
- getV2Report(DEFAULT_FEED_1_V3),
+ getV3Report(DEFAULT_FEED_1_V3),
new bytes32[](1),
new bytes32[](1),
bytes32("")
@@ -91,23 +92,23 @@ contract FeeManagerProcessFeeTest is BaseFeeManagerTest {
vm.expectRevert();
//processing the fee will not withdraw anything as there is no fee to collect
- processFee(payload, USER, 0, ADMIN);
+ processFee(payload, USER, address(link), 0);
}
function test_processFeeDefaultReportsStillVerifiesWithEmptyQuote() public {
//get the default payload
- bytes memory payload = getPayload(getV0Report(DEFAULT_FEED_1_V1), bytes(""));
+ bytes memory payload = getPayload(getV1Report(DEFAULT_FEED_1_V1));
//processing the fee will transfer the link from the user to the rewardManager
- processFee(payload, USER, 0, PROXY);
+ processFee(payload, USER, address(0), 0);
}
function test_processFeeWithDefaultReportPayloadAndQuoteStillVerifies() public {
//get the default payload
- bytes memory payload = getPayload(getV0Report(DEFAULT_FEED_1_V1), getQuotePayload(getLinkAddress()));
+ bytes memory payload = getPayload(getV1Report(DEFAULT_FEED_1_V1));
//processing the fee will not withdraw anything as there is no fee to collect
- processFee(payload, USER, 0, ADMIN);
+ processFee(payload, USER, address(link), 0);
}
function test_processFeeNative() public {
@@ -115,13 +116,13 @@ contract FeeManagerProcessFeeTest is BaseFeeManagerTest {
mintLink(address(feeManager), DEFAULT_REPORT_LINK_FEE);
//get the default payload
- bytes memory payload = getPayload(getV2Report(DEFAULT_FEED_1_V3), getQuotePayload(getNativeAddress()));
+ bytes memory payload = getPayload(getV3Report(DEFAULT_FEED_1_V3));
//approve the native to be transferred from the user
approveNative(address(feeManager), DEFAULT_REPORT_NATIVE_FEE, USER);
//processing the fee will transfer the native from the user to the feeManager
- processFee(payload, USER, 0, ADMIN);
+ processFee(payload, USER, address(native), 0);
//check the native has been transferred
assertEq(getNativeBalance(address(feeManager)), DEFAULT_REPORT_NATIVE_FEE);
@@ -141,7 +142,7 @@ contract FeeManagerProcessFeeTest is BaseFeeManagerTest {
mintLink(address(feeManager), DEFAULT_REPORT_LINK_FEE / 2);
//get the default payload
- bytes memory payload = getPayload(getV2Report(DEFAULT_FEED_1_V3), getQuotePayload(getNativeAddress()));
+ bytes memory payload = getPayload(getV3Report(DEFAULT_FEED_1_V3));
//approve the native to be transferred from the user
approveNative(address(feeManager), DEFAULT_REPORT_NATIVE_FEE, USER);
@@ -149,11 +150,14 @@ contract FeeManagerProcessFeeTest is BaseFeeManagerTest {
//expect an emit as there's not enough link
vm.expectEmit();
+ IRewardManager.FeePayment[] memory contractFees = new IRewardManager.FeePayment[](1);
+ contractFees[0] = IRewardManager.FeePayment(DEFAULT_CONFIG_DIGEST, uint192(DEFAULT_REPORT_LINK_FEE));
+
//emit the event that is expected to be emitted
- emit InsufficientLink(DEFAULT_CONFIG_DIGEST, DEFAULT_REPORT_LINK_FEE, DEFAULT_REPORT_NATIVE_FEE);
+ emit InsufficientLink(contractFees);
//processing the fee will transfer the native from the user to the feeManager
- processFee(payload, USER, 0, ADMIN);
+ processFee(payload, USER, address(native), 0);
//check the native has been transferred
assertEq(getNativeBalance(address(feeManager)), DEFAULT_REPORT_NATIVE_FEE);
@@ -171,10 +175,10 @@ contract FeeManagerProcessFeeTest is BaseFeeManagerTest {
mintLink(address(feeManager), DEFAULT_REPORT_LINK_FEE);
//get the default payload
- bytes memory payload = getPayload(getV2Report(DEFAULT_FEED_1_V3), getQuotePayload(getNativeAddress()));
+ bytes memory payload = getPayload(getV3Report(DEFAULT_FEED_1_V3));
//only the proxy or admin can call processFee, they will pass in the native value on the users behalf
- processFee(payload, USER, DEFAULT_REPORT_NATIVE_FEE, PROXY);
+ processFee(payload, USER, address(native), DEFAULT_REPORT_NATIVE_FEE);
//check the native has been transferred and converted to wrapped native
assertEq(getNativeBalance(address(feeManager)), DEFAULT_REPORT_NATIVE_FEE);
@@ -187,7 +191,7 @@ contract FeeManagerProcessFeeTest is BaseFeeManagerTest {
assertEq(getLinkBalance(address(feeManager)), 0);
//check the subscriber has had the native deducted
- assertEq(getNativeUnwrappedBalance(PROXY), DEFAULT_NATIVE_MINT_QUANTITY - DEFAULT_REPORT_NATIVE_FEE);
+ assertEq(getNativeUnwrappedBalance(USER), DEFAULT_NATIVE_MINT_QUANTITY - DEFAULT_REPORT_NATIVE_FEE);
}
function test_processFeeWithUnwrappedNativeShortFunds() public {
@@ -195,13 +199,13 @@ contract FeeManagerProcessFeeTest is BaseFeeManagerTest {
mintLink(address(feeManager), DEFAULT_REPORT_LINK_FEE);
//get the default payload
- bytes memory payload = getPayload(getV2Report(DEFAULT_FEED_1_V3), getQuotePayload(getNativeAddress()));
+ bytes memory payload = getPayload(getV3Report(DEFAULT_FEED_1_V3));
//expect a revert as not enough funds
vm.expectRevert(INVALID_DEPOSIT_ERROR);
//only the proxy or admin can call processFee, they will pass in the native value on the users behalf
- processFee(payload, USER, DEFAULT_REPORT_NATIVE_FEE - 1, PROXY);
+ processFee(payload, USER, address(native), DEFAULT_REPORT_NATIVE_FEE - 1);
}
function test_processFeeWithUnwrappedNativeLinkAddress() public {
@@ -209,13 +213,37 @@ contract FeeManagerProcessFeeTest is BaseFeeManagerTest {
mintLink(address(feeManager), DEFAULT_REPORT_LINK_FEE);
//get the default payload
- bytes memory payload = getPayload(getV2Report(DEFAULT_FEED_1_V3), getQuotePayload(getLinkAddress()));
+ bytes memory payload = getPayload(getV3Report(DEFAULT_FEED_1_V3));
//expect a revert as not enough funds
- vm.expectRevert(INVALID_DEPOSIT_ERROR);
+ vm.expectRevert(INSUFFICIENT_ALLOWANCE_ERROR);
- //only the proxy or admin can call processFee, they will pass in the native value on the users behalf
- processFee(payload, USER, DEFAULT_REPORT_NATIVE_FEE - 1, PROXY);
+ //the change will be returned and the user will attempted to be billed in LINK
+ processFee(payload, USER, address(link), DEFAULT_REPORT_NATIVE_FEE - 1);
+ }
+
+ function test_processFeeWithUnwrappedNativeLinkAddressExcessiveFee() public {
+ //approve the link to be transferred from the from the subscriber to the rewardManager
+ approveLink(address(rewardManager), DEFAULT_REPORT_LINK_FEE, PROXY);
+
+ //get the default payload
+ bytes memory payload = getPayload(getV3Report(DEFAULT_FEED_1_V3));
+
+ //call processFee from the proxy to test whether the funds are returned to the subscriber. In reality, the funds would be returned to the caller of the proxy.
+ processFee(payload, PROXY, address(link), DEFAULT_REPORT_NATIVE_FEE);
+
+ //check the native unwrapped is no longer in the account
+ assertEq(getNativeBalance(address(feeManager)), 0);
+ assertEq(getNativeUnwrappedBalance(address(feeManager)), 0);
+
+ //check the link has been transferred to the rewardManager
+ assertEq(getLinkBalance(address(rewardManager)), DEFAULT_REPORT_LINK_FEE);
+
+ //check the feeManager has had the link deducted, the remaining balance should be 0
+ assertEq(getLinkBalance(address(feeManager)), 0);
+
+ //native should not be deducted
+ assertEq(getNativeUnwrappedBalance(PROXY), DEFAULT_NATIVE_MINT_QUANTITY);
}
function test_processFeeWithUnwrappedNativeWithExcessiveFee() public {
@@ -223,10 +251,10 @@ contract FeeManagerProcessFeeTest is BaseFeeManagerTest {
mintLink(address(feeManager), DEFAULT_REPORT_LINK_FEE);
//get the default payload
- bytes memory payload = getPayload(getV2Report(DEFAULT_FEED_1_V3), getQuotePayload(getNativeAddress()));
+ bytes memory payload = getPayload(getV3Report(DEFAULT_FEED_1_V3));
//call processFee from the proxy to test whether the funds are returned to the subscriber. In reality, the funds would be returned to the caller of the proxy.
- processFee(payload, PROXY, DEFAULT_REPORT_NATIVE_FEE * 2, PROXY);
+ processFee(payload, PROXY, address(native), DEFAULT_REPORT_NATIVE_FEE * 2);
//check the native has been transferred and converted to wrapped native
assertEq(getNativeBalance(address(feeManager)), DEFAULT_REPORT_NATIVE_FEE);
@@ -244,13 +272,13 @@ contract FeeManagerProcessFeeTest is BaseFeeManagerTest {
function test_processFeeUsesCorrectDigest() public {
//get the default payload
- bytes memory payload = getPayload(getV2Report(DEFAULT_FEED_1_V3), getQuotePayload(getLinkAddress()));
+ bytes memory payload = getPayload(getV3Report(DEFAULT_FEED_1_V3));
//approve the link to be transferred from the from the subscriber to the rewardManager
approveLink(address(rewardManager), DEFAULT_REPORT_LINK_FEE, USER);
//processing the fee will transfer the link from the user to the rewardManager
- processFee(payload, USER, 0, PROXY);
+ processFee(payload, USER, address(link), 0);
//check the link has been transferred
assertEq(getLinkBalance(address(rewardManager)), DEFAULT_REPORT_LINK_FEE);
@@ -266,25 +294,25 @@ contract FeeManagerProcessFeeTest is BaseFeeManagerTest {
//replicate a default payload
bytes memory payload = abi.encode(
[DEFAULT_CONFIG_DIGEST, 0, 0],
- getV1Report(DEFAULT_FEED_1_V1),
+ getV2Report(DEFAULT_FEED_1_V1),
new bytes32[](1),
new bytes32[](1),
bytes32("")
);
//processing the fee will transfer the link from the user to the rewardManager
- processFee(payload, USER, 0, PROXY);
+ processFee(payload, USER, address(0), 0);
}
function test_V2PayloadVerifies() public {
//get the default payload
- bytes memory payload = getPayload(getV1Report(DEFAULT_FEED_1_V2), getQuotePayload(getLinkAddress()));
+ bytes memory payload = getPayload(getV2Report(DEFAULT_FEED_1_V2));
//approve the link to be transferred from the from the subscriber to the rewardManager
approveLink(address(rewardManager), DEFAULT_REPORT_LINK_FEE, USER);
//processing the fee will transfer the link from the user to the rewardManager
- processFee(payload, USER, 0, ADMIN);
+ processFee(payload, USER, address(link), 0);
//check the link has been transferred
assertEq(getLinkBalance(address(rewardManager)), DEFAULT_REPORT_LINK_FEE);
@@ -295,36 +323,172 @@ contract FeeManagerProcessFeeTest is BaseFeeManagerTest {
function test_V2PayloadWithoutQuoteFails() public {
//get the default payload
- bytes memory payload = getPayload(getV1Report(DEFAULT_FEED_1_V2), bytes(""));
+ bytes memory payload = getPayload(getV2Report(DEFAULT_FEED_1_V2));
//expect a revert as the quote is invalid
vm.expectRevert();
//processing the fee will transfer the link from the user to the rewardManager
- processFee(payload, USER, 0, ADMIN);
+ processFee(payload, USER, address(0), 0);
}
function test_V2PayloadWithoutZeroFee() public {
//get the default payload
- bytes memory payload = getPayload(getV1Report(DEFAULT_FEED_1_V2), getQuotePayload(getLinkAddress()));
+ bytes memory payload = getPayload(getV2Report(DEFAULT_FEED_1_V2));
//expect a revert as the quote is invalid
vm.expectRevert();
//processing the fee will transfer the link from the user to the rewardManager
- processFee(payload, USER, 0, ADMIN);
+ processFee(payload, USER, address(link), 0);
}
function test_processFeeWithInvalidReportVersionFailsToDecode() public {
bytes memory data = abi.encode(0x0000100000000000000000000000000000000000000000000000000000000000);
//get the default payload
- bytes memory payload = getPayload(data, getQuotePayload(getLinkAddress()));
+ bytes memory payload = getPayload(data);
//serialization will fail as there is no report to decode
vm.expectRevert();
//processing the fee will not withdraw anything as there is no fee to collect
- processFee(payload, USER, 0, ADMIN);
+ processFee(payload, USER, address(link), 0);
+ }
+
+ function test_processFeeWithZeroNativeNonZeroLinkWithNativeQuote() public {
+ //get the default payload
+ bytes memory payload = getPayload(
+ getV3ReportWithCustomExpiryAndFee(DEFAULT_FEED_1_V3, block.timestamp, DEFAULT_REPORT_LINK_FEE, 0)
+ );
+
+ //call processFee should not revert as the fee is 0
+ processFee(payload, PROXY, address(native), 0);
+ }
+
+ function test_processFeeWithZeroNativeNonZeroLinkWithLinkQuote() public {
+ //get the default payload
+ bytes memory payload = getPayload(
+ getV3ReportWithCustomExpiryAndFee(DEFAULT_FEED_1_V3, block.timestamp, DEFAULT_REPORT_LINK_FEE, 0)
+ );
+
+ //approve the link to be transferred from the from the subscriber to the rewardManager
+ approveLink(address(rewardManager), DEFAULT_REPORT_LINK_FEE, USER);
+
+ //processing the fee will transfer the link to the rewardManager from the user
+ processFee(payload, USER, address(link), 0);
+
+ //check the link has been transferred
+ assertEq(getLinkBalance(address(rewardManager)), DEFAULT_REPORT_LINK_FEE);
+
+ //check the user has had the link fee deducted
+ assertEq(getLinkBalance(USER), DEFAULT_LINK_MINT_QUANTITY - DEFAULT_REPORT_LINK_FEE);
+ }
+
+ function test_processFeeWithZeroLinkNonZeroNativeWithNativeQuote() public {
+ //simulate a deposit of link for the conversion pool
+ mintLink(address(feeManager), DEFAULT_REPORT_LINK_FEE);
+
+ //get the default payload
+ bytes memory payload = getPayload(
+ getV3ReportWithCustomExpiryAndFee(DEFAULT_FEED_1_V3, block.timestamp, 0, DEFAULT_REPORT_NATIVE_FEE)
+ );
+
+ //approve the native to be transferred from the user
+ approveNative(address(feeManager), DEFAULT_REPORT_NATIVE_FEE, USER);
+
+ //processing the fee will transfer the native from the user to the feeManager
+ processFee(payload, USER, address(native), 0);
+
+ //check the native has been transferred
+ assertEq(getNativeBalance(address(feeManager)), DEFAULT_REPORT_NATIVE_FEE);
+
+ //check no link has been transferred to the rewardManager
+ assertEq(getLinkBalance(address(rewardManager)), 0);
+
+ //check the feeManager has had no link deducted
+ assertEq(getLinkBalance(address(feeManager)), DEFAULT_REPORT_LINK_FEE);
+
+ //check the subscriber has had the native deducted
+ assertEq(getNativeBalance(USER), DEFAULT_NATIVE_MINT_QUANTITY - DEFAULT_REPORT_NATIVE_FEE);
+ }
+
+ function test_processFeeWithZeroLinkNonZeroNativeWithLinkQuote() public {
+ //get the default payload
+ bytes memory payload = getPayload(
+ getV3ReportWithCustomExpiryAndFee(DEFAULT_FEED_1_V3, block.timestamp, 0, DEFAULT_REPORT_NATIVE_FEE)
+ );
+
+ //call processFee should not revert as the fee is 0
+ processFee(payload, USER, address(link), 0);
+ }
+
+ function test_processFeeWithZeroNativeNonZeroLinkReturnsChange() public {
+ //get the default payload
+ bytes memory payload = getPayload(
+ getV3ReportWithCustomExpiryAndFee(DEFAULT_FEED_1_V3, block.timestamp, 0, DEFAULT_REPORT_NATIVE_FEE)
+ );
+
+ //call processFee should not revert as the fee is 0
+ processFee(payload, USER, address(link), DEFAULT_REPORT_NATIVE_FEE);
+
+ //check the change has been returned
+ assertEq(USER.balance, DEFAULT_NATIVE_MINT_QUANTITY);
+ }
+
+ function test_V1PayloadVerifiesAndReturnsChange() public {
+ //emulate a V1 payload with no quote
+ bytes memory payload = getPayload(getV1Report(DEFAULT_FEED_1_V1));
+
+ processFee(payload, USER, address(0), DEFAULT_REPORT_NATIVE_FEE);
+
+ //Fee manager should not contain any native
+ assertEq(address(feeManager).balance, 0);
+ assertEq(getNativeBalance(address(feeManager)), 0);
+
+ //check the unused native passed in is returned
+ assertEq(USER.balance, DEFAULT_NATIVE_MINT_QUANTITY);
+ }
+
+ function test_processFeeWithDiscountEmitsEvent() public {
+ //simulate a deposit of link for the conversion pool
+ mintLink(address(feeManager), DEFAULT_REPORT_LINK_FEE);
+
+ //set the subscriber discount to 50%
+ setSubscriberDiscount(USER, DEFAULT_FEED_1_V3, address(native), FEE_SCALAR / 2, ADMIN);
+
+ //approve the native to be transferred from the user
+ approveNative(address(feeManager), DEFAULT_REPORT_NATIVE_FEE / 2, USER);
+
+ //get the default payload
+ bytes memory payload = getPayload(getV3Report(DEFAULT_FEED_1_V3));
+
+ Common.Asset memory fee = getFee(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER);
+ Common.Asset memory reward = getReward(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER);
+ uint256 appliedDiscount = getAppliedDiscount(getV3Report(DEFAULT_FEED_1_V3), getNativeQuote(), USER);
+
+ vm.expectEmit();
+
+ emit DiscountApplied(DEFAULT_CONFIG_DIGEST, USER, fee, reward, appliedDiscount);
+
+ //call processFee should not revert as the fee is 0
+ processFee(payload, USER, address(native), 0);
+ }
+
+ function test_processFeeWithNoDiscountDoesNotEmitEvent() public {
+ //simulate a deposit of link for the conversion pool
+ mintLink(address(feeManager), DEFAULT_REPORT_LINK_FEE);
+
+ //approve the native to be transferred from the user
+ approveNative(address(feeManager), DEFAULT_REPORT_NATIVE_FEE, USER);
+
+ //get the default payload
+ bytes memory payload = getPayload(getV3Report(DEFAULT_FEED_1_V3));
+
+ //call processFee should not revert as the fee is 0
+ processFee(payload, USER, address(native), 0);
+
+ //no logs should have been emitted
+ assertEq(vm.getRecordedLogs().length, 0);
}
}
diff --git a/contracts/src/v0.8/llo-feeds/test/fee-manager/FeeManager.processFeeBulk.t.sol b/contracts/src/v0.8/llo-feeds/test/fee-manager/FeeManager.processFeeBulk.t.sol
new file mode 100644
index 00000000000..25fb804630d
--- /dev/null
+++ b/contracts/src/v0.8/llo-feeds/test/fee-manager/FeeManager.processFeeBulk.t.sol
@@ -0,0 +1,196 @@
+// SPDX-License-Identifier: UNLICENSED
+pragma solidity 0.8.16;
+
+import {Test} from "forge-std/Test.sol";
+import {FeeManager} from "../../FeeManager.sol";
+import {Common} from "../../../libraries/Common.sol";
+import "./BaseFeeManager.t.sol";
+import {IRewardManager} from "../../interfaces/IRewardManager.sol";
+
+/**
+ * @title BaseFeeManagerTest
+ * @author Michael Fletcher
+ * @notice This contract will test the functionality of the feeManager processFee
+ */
+contract FeeManagerProcessFeeTest is BaseFeeManagerTest {
+ uint256 internal constant NUMBER_OF_REPORTS = 5;
+
+ function setUp() public override {
+ super.setUp();
+ }
+
+ function test_processMultipleLinkReports() public {
+ bytes memory payload = getPayload(getV3Report(DEFAULT_FEED_1_V3));
+
+ bytes[] memory payloads = new bytes[](NUMBER_OF_REPORTS);
+ for (uint256 i = 0; i < NUMBER_OF_REPORTS; ++i) {
+ payloads[i] = payload;
+ }
+
+ approveLink(address(rewardManager), DEFAULT_REPORT_LINK_FEE * NUMBER_OF_REPORTS, USER);
+
+ processFee(payloads, USER, address(link), DEFAULT_NATIVE_MINT_QUANTITY);
+
+ assertEq(getLinkBalance(address(rewardManager)), DEFAULT_REPORT_LINK_FEE * NUMBER_OF_REPORTS);
+ assertEq(getLinkBalance(address(feeManager)), 0);
+ assertEq(getLinkBalance(USER), DEFAULT_LINK_MINT_QUANTITY - DEFAULT_REPORT_LINK_FEE * NUMBER_OF_REPORTS);
+
+ //the subscriber (user) should receive funds back and not the proxy, although when live the proxy will forward the funds sent and not cover it seen here
+ assertEq(USER.balance, DEFAULT_NATIVE_MINT_QUANTITY);
+ assertEq(PROXY.balance, DEFAULT_NATIVE_MINT_QUANTITY);
+ }
+
+ function test_processMultipleWrappedNativeReports() public {
+ mintLink(address(feeManager), DEFAULT_REPORT_LINK_FEE * NUMBER_OF_REPORTS + 1);
+
+ bytes memory payload = getPayload(getV3Report(DEFAULT_FEED_1_V3));
+
+ bytes[] memory payloads = new bytes[](NUMBER_OF_REPORTS);
+ for (uint256 i; i < NUMBER_OF_REPORTS; ++i) {
+ payloads[i] = payload;
+ }
+
+ approveNative(address(feeManager), DEFAULT_REPORT_NATIVE_FEE * NUMBER_OF_REPORTS, USER);
+
+ processFee(payloads, USER, address(native), 0);
+
+ assertEq(getNativeBalance(address(feeManager)), DEFAULT_REPORT_NATIVE_FEE * NUMBER_OF_REPORTS);
+ assertEq(getLinkBalance(address(rewardManager)), DEFAULT_REPORT_LINK_FEE * NUMBER_OF_REPORTS);
+ assertEq(getLinkBalance(address(feeManager)), 1);
+ assertEq(getNativeBalance(USER), DEFAULT_NATIVE_MINT_QUANTITY - DEFAULT_REPORT_NATIVE_FEE * NUMBER_OF_REPORTS);
+ }
+
+ function test_processMultipleUnwrappedNativeReports() public {
+ mintLink(address(feeManager), DEFAULT_REPORT_LINK_FEE * NUMBER_OF_REPORTS + 1);
+
+ bytes memory payload = getPayload(getV3Report(DEFAULT_FEED_1_V3));
+
+ bytes[] memory payloads = new bytes[](NUMBER_OF_REPORTS);
+ for (uint256 i; i < NUMBER_OF_REPORTS; ++i) {
+ payloads[i] = payload;
+ }
+
+ processFee(payloads, USER, address(native), DEFAULT_REPORT_NATIVE_FEE * NUMBER_OF_REPORTS * 2);
+
+ assertEq(getNativeBalance(address(feeManager)), DEFAULT_REPORT_NATIVE_FEE * NUMBER_OF_REPORTS);
+ assertEq(getLinkBalance(address(rewardManager)), DEFAULT_REPORT_LINK_FEE * NUMBER_OF_REPORTS);
+ assertEq(getLinkBalance(address(feeManager)), 1);
+
+ assertEq(PROXY.balance, DEFAULT_NATIVE_MINT_QUANTITY);
+ assertEq(USER.balance, DEFAULT_NATIVE_MINT_QUANTITY - DEFAULT_REPORT_NATIVE_FEE * NUMBER_OF_REPORTS);
+ }
+
+ function test_processV1V2V3Reports() public {
+ mintLink(address(feeManager), 1);
+
+ bytes memory payloadV1 = abi.encode(
+ [DEFAULT_CONFIG_DIGEST, 0, 0],
+ getV1Report(DEFAULT_FEED_1_V1),
+ new bytes32[](1),
+ new bytes32[](1),
+ bytes32("")
+ );
+
+ bytes memory linkPayloadV2 = getPayload(getV2Report(DEFAULT_FEED_1_V2));
+ bytes memory linkPayloadV3 = getPayload(getV3Report(DEFAULT_FEED_1_V3));
+
+ bytes[] memory payloads = new bytes[](5);
+ payloads[0] = payloadV1;
+ payloads[1] = linkPayloadV2;
+ payloads[2] = linkPayloadV2;
+ payloads[3] = linkPayloadV3;
+ payloads[4] = linkPayloadV3;
+
+ approveLink(address(rewardManager), DEFAULT_REPORT_LINK_FEE * 4, USER);
+
+ processFee(payloads, USER, address(link), 0);
+
+ assertEq(getNativeBalance(address(feeManager)), 0);
+ assertEq(getLinkBalance(address(rewardManager)), DEFAULT_REPORT_LINK_FEE * 4);
+ assertEq(getLinkBalance(address(feeManager)), 1);
+
+ assertEq(getLinkBalance(USER), DEFAULT_LINK_MINT_QUANTITY - DEFAULT_REPORT_LINK_FEE * 4);
+ assertEq(getNativeBalance(USER), DEFAULT_NATIVE_MINT_QUANTITY - 0);
+ }
+
+ function test_processV1V2V3ReportsWithUnwrapped() public {
+ mintLink(address(feeManager), DEFAULT_REPORT_LINK_FEE * 4 + 1);
+
+ bytes memory payloadV1 = abi.encode(
+ [DEFAULT_CONFIG_DIGEST, 0, 0],
+ getV1Report(DEFAULT_FEED_1_V1),
+ new bytes32[](1),
+ new bytes32[](1),
+ bytes32("")
+ );
+
+ bytes memory nativePayloadV2 = getPayload(getV2Report(DEFAULT_FEED_1_V2));
+ bytes memory nativePayloadV3 = getPayload(getV3Report(DEFAULT_FEED_1_V3));
+
+ bytes[] memory payloads = new bytes[](5);
+ payloads[0] = payloadV1;
+ payloads[1] = nativePayloadV2;
+ payloads[2] = nativePayloadV2;
+ payloads[3] = nativePayloadV3;
+ payloads[4] = nativePayloadV3;
+
+ processFee(payloads, USER, address(native), DEFAULT_REPORT_NATIVE_FEE * 4);
+
+ assertEq(getNativeBalance(address(feeManager)), DEFAULT_REPORT_NATIVE_FEE * 4);
+ assertEq(getLinkBalance(address(rewardManager)), DEFAULT_REPORT_LINK_FEE * 4);
+ assertEq(getLinkBalance(address(feeManager)), 1);
+
+ assertEq(USER.balance, DEFAULT_NATIVE_MINT_QUANTITY - DEFAULT_REPORT_NATIVE_FEE * 4);
+ assertEq(PROXY.balance, DEFAULT_NATIVE_MINT_QUANTITY);
+ }
+
+ function test_processMultipleV1Reports() public {
+ bytes memory payload = abi.encode(
+ [DEFAULT_CONFIG_DIGEST, 0, 0],
+ getV1Report(DEFAULT_FEED_1_V1),
+ new bytes32[](1),
+ new bytes32[](1),
+ bytes32("")
+ );
+
+ bytes[] memory payloads = new bytes[](NUMBER_OF_REPORTS);
+ for (uint256 i = 0; i < NUMBER_OF_REPORTS; ++i) {
+ payloads[i] = payload;
+ }
+
+ processFee(payloads, USER, address(native), DEFAULT_REPORT_NATIVE_FEE * 5);
+
+ assertEq(USER.balance, DEFAULT_NATIVE_MINT_QUANTITY);
+ assertEq(PROXY.balance, DEFAULT_NATIVE_MINT_QUANTITY);
+ }
+
+ function test_eventIsEmittedIfNotEnoughLink() public {
+ bytes memory nativePayload = getPayload(getV3Report(DEFAULT_FEED_1_V3));
+
+ bytes[] memory payloads = new bytes[](5);
+ payloads[0] = nativePayload;
+ payloads[1] = nativePayload;
+ payloads[2] = nativePayload;
+ payloads[3] = nativePayload;
+ payloads[4] = nativePayload;
+
+ approveNative(address(feeManager), DEFAULT_REPORT_NATIVE_FEE * 5, USER);
+
+ IRewardManager.FeePayment[] memory payments = new IRewardManager.FeePayment[](5);
+ payments[0] = IRewardManager.FeePayment(DEFAULT_CONFIG_DIGEST, uint192(DEFAULT_REPORT_LINK_FEE));
+ payments[1] = IRewardManager.FeePayment(DEFAULT_CONFIG_DIGEST, uint192(DEFAULT_REPORT_LINK_FEE));
+ payments[2] = IRewardManager.FeePayment(DEFAULT_CONFIG_DIGEST, uint192(DEFAULT_REPORT_LINK_FEE));
+ payments[3] = IRewardManager.FeePayment(DEFAULT_CONFIG_DIGEST, uint192(DEFAULT_REPORT_LINK_FEE));
+ payments[4] = IRewardManager.FeePayment(DEFAULT_CONFIG_DIGEST, uint192(DEFAULT_REPORT_LINK_FEE));
+
+ vm.expectEmit();
+
+ emit InsufficientLink(payments);
+
+ processFee(payloads, USER, address(native), 0);
+
+ assertEq(getNativeBalance(address(feeManager)), DEFAULT_REPORT_NATIVE_FEE * 5);
+ assertEq(getNativeBalance(USER), DEFAULT_NATIVE_MINT_QUANTITY - DEFAULT_REPORT_NATIVE_FEE * 5);
+ assertEq(getLinkBalance(USER), DEFAULT_LINK_MINT_QUANTITY);
+ }
+}
diff --git a/contracts/src/v0.8/llo-feeds/test/gas/Gas_VerifierTest.t.sol b/contracts/src/v0.8/llo-feeds/test/gas/Gas_VerifierTest.t.sol
index e3764fce0a6..5e601034bb8 100644
--- a/contracts/src/v0.8/llo-feeds/test/gas/Gas_VerifierTest.t.sol
+++ b/contracts/src/v0.8/llo-feeds/test/gas/Gas_VerifierTest.t.sol
@@ -3,8 +3,9 @@ pragma solidity 0.8.16;
import {BaseTest, BaseTestWithConfiguredVerifierAndFeeManager} from "../verifier/BaseVerifierTest.t.sol";
import {Verifier} from "../../Verifier.sol";
-import {SimpleWriteAccessController} from "../../../SimpleWriteAccessController.sol";
+import {SimpleWriteAccessController} from "../../../shared/access/SimpleWriteAccessController.sol";
import {Common} from "../../../libraries/Common.sol";
+import {IRewardManager} from "../../interfaces/IRewardManager.sol";
contract Verifier_setConfig is BaseTest {
address[] internal s_signerAddrs;
@@ -58,32 +59,102 @@ contract Verifier_verifyWithFee is BaseTestWithConfiguredVerifierAndFeeManager {
_approveLink(address(rewardManager), DEFAULT_REPORT_LINK_FEE, USER);
_approveNative(address(feeManager), DEFAULT_REPORT_NATIVE_FEE, USER);
+ IRewardManager.FeePayment[] memory payments = new IRewardManager.FeePayment[](1);
+ payments[0] = IRewardManager.FeePayment(latestConfigDigest, uint192(DEFAULT_REPORT_LINK_FEE));
+
changePrank(address(feeManager));
- rewardManager.onFeePaid(latestConfigDigest, address(this), DEFAULT_REPORT_LINK_FEE);
+ rewardManager.onFeePaid(payments, address(this));
changePrank(USER);
}
function testVerifyProxyWithLinkFeeSuccess_gas() public {
- bytes memory signedLinkPayload = _generateEncodedBlobWithQuote(
- _generateV2Report(),
- _generateReportContext(FEED_ID_V3),
- _getSigners(FAULT_TOLERANCE + 1),
- _generateQuote(address(link))
+ bytes memory signedLinkPayload = _generateV3EncodedBlob(
+ _generateV3Report(),
+ _generateReportContext(v3ConfigDigest),
+ _getSigners(FAULT_TOLERANCE + 1)
);
- s_verifierProxy.verify(signedLinkPayload);
+ s_verifierProxy.verify(signedLinkPayload, abi.encode(link));
}
function testVerifyProxyWithNativeFeeSuccess_gas() public {
- bytes memory signedNativePayload = _generateEncodedBlobWithQuote(
- _generateV2Report(),
- _generateReportContext(FEED_ID_V3),
- _getSigners(FAULT_TOLERANCE + 1),
- _generateQuote(address(native))
+ bytes memory signedNativePayload = _generateV3EncodedBlob(
+ _generateV3Report(),
+ _generateReportContext(v3ConfigDigest),
+ _getSigners(FAULT_TOLERANCE + 1)
+ );
+
+ s_verifierProxy.verify(signedNativePayload, abi.encode(native));
+ }
+}
+
+contract Verifier_bulkVerifyWithFee is BaseTestWithConfiguredVerifierAndFeeManager {
+ uint256 internal constant DEFAULT_LINK_MINT_QUANTITY = 100 ether;
+ uint256 internal constant DEFAULT_NATIVE_MINT_QUANTITY = 100 ether;
+ uint256 internal constant NUMBER_OF_REPORTS_TO_VERIFY = 5;
+
+ function setUp() public virtual override {
+ super.setUp();
+
+ //mint some link and eth to warm the storage
+ link.mint(address(rewardManager), DEFAULT_LINK_MINT_QUANTITY);
+ native.mint(address(feeManager), DEFAULT_NATIVE_MINT_QUANTITY);
+
+ //warm the rewardManager
+ link.mint(address(this), DEFAULT_NATIVE_MINT_QUANTITY);
+ _approveLink(address(rewardManager), DEFAULT_REPORT_LINK_FEE, address(this));
+ (, , bytes32 latestConfigDigest) = s_verifier.latestConfigDetails(FEED_ID);
+
+ //mint some tokens to the user
+ link.mint(USER, DEFAULT_LINK_MINT_QUANTITY);
+ native.mint(USER, DEFAULT_NATIVE_MINT_QUANTITY);
+ vm.deal(USER, DEFAULT_NATIVE_MINT_QUANTITY);
+
+ //mint some link tokens to the feeManager pool
+ link.mint(address(feeManager), DEFAULT_REPORT_LINK_FEE * NUMBER_OF_REPORTS_TO_VERIFY);
+
+ //approve funds prior to test
+ _approveLink(address(rewardManager), DEFAULT_REPORT_LINK_FEE * NUMBER_OF_REPORTS_TO_VERIFY, USER);
+ _approveNative(address(feeManager), DEFAULT_REPORT_NATIVE_FEE * NUMBER_OF_REPORTS_TO_VERIFY, USER);
+
+ IRewardManager.FeePayment[] memory payments = new IRewardManager.FeePayment[](1);
+ payments[0] = IRewardManager.FeePayment(latestConfigDigest, uint192(DEFAULT_REPORT_LINK_FEE));
+
+ changePrank(address(feeManager));
+ rewardManager.onFeePaid(payments, address(this));
+
+ changePrank(USER);
+ }
+
+ function testBulkVerifyProxyWithLinkFeeSuccess_gas() public {
+ bytes memory signedLinkPayload = _generateV3EncodedBlob(
+ _generateV3Report(),
+ _generateReportContext(v3ConfigDigest),
+ _getSigners(FAULT_TOLERANCE + 1)
+ );
+
+ bytes[] memory signedLinkPayloads = new bytes[](NUMBER_OF_REPORTS_TO_VERIFY);
+ for (uint256 i = 0; i < NUMBER_OF_REPORTS_TO_VERIFY; i++) {
+ signedLinkPayloads[i] = signedLinkPayload;
+ }
+
+ s_verifierProxy.verifyBulk(signedLinkPayloads, abi.encode(link));
+ }
+
+ function testBulkVerifyProxyWithNativeFeeSuccess_gas() public {
+ bytes memory signedNativePayload = _generateV3EncodedBlob(
+ _generateV3Report(),
+ _generateReportContext(v3ConfigDigest),
+ _getSigners(FAULT_TOLERANCE + 1)
);
- s_verifierProxy.verify(signedNativePayload);
+ bytes[] memory signedNativePayloads = new bytes[](NUMBER_OF_REPORTS_TO_VERIFY);
+ for (uint256 i = 0; i < NUMBER_OF_REPORTS_TO_VERIFY; i++) {
+ signedNativePayloads[i] = signedNativePayload;
+ }
+
+ s_verifierProxy.verifyBulk(signedNativePayloads, abi.encode(native));
}
}
@@ -93,7 +164,7 @@ contract Verifier_verify is BaseTestWithConfiguredVerifierAndFeeManager {
function setUp() public override {
BaseTestWithConfiguredVerifierAndFeeManager.setUp();
- BaseTest.V0Report memory s_testReportOne = _createV0Report(
+ BaseTest.V1Report memory s_testReportOne = _createV1Report(
FEED_ID,
OBSERVATIONS_TIMESTAMP,
MEDIAN,
@@ -108,7 +179,7 @@ contract Verifier_verify is BaseTestWithConfiguredVerifierAndFeeManager {
bytes32[3] memory reportContext;
reportContext[0] = s_configDigest;
reportContext[1] = bytes32(abi.encode(uint32(5), uint8(1)));
- s_signedReport = _generateEncodedBlob(s_testReportOne, reportContext, _getSigners(FAULT_TOLERANCE + 1));
+ s_signedReport = _generateV1EncodedBlob(s_testReportOne, reportContext, _getSigners(FAULT_TOLERANCE + 1));
}
function testVerifySuccess_gas() public {
@@ -118,7 +189,7 @@ contract Verifier_verify is BaseTestWithConfiguredVerifierAndFeeManager {
}
function testVerifyProxySuccess_gas() public {
- s_verifierProxy.verify(s_signedReport);
+ s_verifierProxy.verify(s_signedReport, abi.encode(native));
}
}
@@ -132,7 +203,7 @@ contract Verifier_accessControlledVerify is BaseTestWithConfiguredVerifierAndFee
function setUp() public override {
BaseTestWithConfiguredVerifierAndFeeManager.setUp();
- BaseTest.V0Report memory s_testReportOne = _createV0Report(
+ BaseTest.V1Report memory s_testReportOne = _createV1Report(
FEED_ID,
OBSERVATIONS_TIMESTAMP,
MEDIAN,
@@ -147,7 +218,7 @@ contract Verifier_accessControlledVerify is BaseTestWithConfiguredVerifierAndFee
bytes32[3] memory reportContext;
reportContext[0] = s_configDigest;
reportContext[1] = bytes32(abi.encode(uint32(5), uint8(1)));
- s_signedReport = _generateEncodedBlob(s_testReportOne, reportContext, _getSigners(FAULT_TOLERANCE + 1));
+ s_signedReport = _generateV1EncodedBlob(s_testReportOne, reportContext, _getSigners(FAULT_TOLERANCE + 1));
s_accessController = new SimpleWriteAccessController();
s_verifierProxy.setAccessController(s_accessController);
s_accessController.addAccess(CLIENT);
@@ -155,6 +226,6 @@ contract Verifier_accessControlledVerify is BaseTestWithConfiguredVerifierAndFee
function testVerifyWithAccessControl_gas() public {
changePrank(CLIENT);
- s_verifierProxy.verify(s_signedReport);
+ s_verifierProxy.verify(s_signedReport, abi.encode(native));
}
}
diff --git a/contracts/src/v0.8/llo-feeds/test/mocks/ErroredVerifier.sol b/contracts/src/v0.8/llo-feeds/test/mocks/ErroredVerifier.sol
index 23ef7c85802..a0a404d88d7 100644
--- a/contracts/src/v0.8/llo-feeds/test/mocks/ErroredVerifier.sol
+++ b/contracts/src/v0.8/llo-feeds/test/mocks/ErroredVerifier.sol
@@ -46,6 +46,7 @@ contract ErroredVerifier is IVerifier {
bytes32,
uint256,
address,
+ uint32,
address[] memory,
bytes32[] memory,
uint8,
diff --git a/contracts/src/v0.8/llo-feeds/test/mocks/FeeManagerProxy.sol b/contracts/src/v0.8/llo-feeds/test/mocks/FeeManagerProxy.sol
new file mode 100644
index 00000000000..e39f1a021f7
--- /dev/null
+++ b/contracts/src/v0.8/llo-feeds/test/mocks/FeeManagerProxy.sol
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: MIT
+pragma solidity 0.8.16;
+
+import "../../interfaces/IFeeManager.sol";
+
+contract FeeManagerProxy {
+ IFeeManager internal i_feeManager;
+
+ function processFee(bytes calldata payload, bytes calldata parameterPayload) public payable {
+ i_feeManager.processFee{value: msg.value}(payload, parameterPayload, msg.sender);
+ }
+
+ function processFeeBulk(bytes[] calldata payloads, bytes calldata parameterPayload) public payable {
+ i_feeManager.processFeeBulk{value: msg.value}(payloads, parameterPayload, msg.sender);
+ }
+
+ function setFeeManager(IFeeManager feeManager) public {
+ i_feeManager = feeManager;
+ }
+}
diff --git a/contracts/src/v0.8/llo-feeds/test/reward-manager/BaseRewardManager.t.sol b/contracts/src/v0.8/llo-feeds/test/reward-manager/BaseRewardManager.t.sol
index 7d7aa6aac38..4a701093168 100644
--- a/contracts/src/v0.8/llo-feeds/test/reward-manager/BaseRewardManager.t.sol
+++ b/contracts/src/v0.8/llo-feeds/test/reward-manager/BaseRewardManager.t.sol
@@ -3,8 +3,9 @@ pragma solidity 0.8.16;
import {Test} from "forge-std/Test.sol";
import {ERC20Mock} from "../../../vendor/openzeppelin-solidity/v4.8.0/contracts/mocks/ERC20Mock.sol";
-import {RewardManager} from "../../dev/RewardManager.sol";
+import {RewardManager} from "../../RewardManager.sol";
import {Common} from "../../../libraries/Common.sol";
+import {IRewardManager} from "../../interfaces/IRewardManager.sol";
/**
* @title BaseRewardManagerTest
@@ -55,10 +56,10 @@ contract BaseRewardManagerTest is Test {
uint256 internal constant DEFAULT_MINT_QUANTITY = 100 ether;
//reward scalar (this should match the const in the contract)
- uint256 internal constant POOL_SCALAR = 1e18;
- uint256 internal constant ONE_PERCENT = POOL_SCALAR / 100;
- uint256 internal constant FIFTY_PERCENT = POOL_SCALAR / 2;
- uint256 internal constant TEN_PERCENT = POOL_SCALAR / 10;
+ uint64 internal constant POOL_SCALAR = 1e18;
+ uint64 internal constant ONE_PERCENT = POOL_SCALAR / 100;
+ uint64 internal constant FIFTY_PERCENT = POOL_SCALAR / 2;
+ uint64 internal constant TEN_PERCENT = POOL_SCALAR / 10;
//the selector for each error
bytes4 internal immutable UNAUTHORIZED_ERROR_SELECTOR = RewardManager.Unauthorized.selector;
@@ -66,12 +67,13 @@ contract BaseRewardManagerTest is Test {
bytes4 internal immutable INVALID_WEIGHT_ERROR_SELECTOR = RewardManager.InvalidWeights.selector;
bytes4 internal immutable INVALID_POOL_ID_ERROR_SELECTOR = RewardManager.InvalidPoolId.selector;
bytes internal constant ONLY_CALLABLE_BY_OWNER_ERROR = "Only callable by owner";
+ bytes4 internal immutable INVALID_POOL_LENGTH_SELECTOR = RewardManager.InvalidPoolLength.selector;
// Events emitted within the reward manager
event RewardRecipientsUpdated(bytes32 indexed poolId, Common.AddressAndWeight[] newRewardRecipients);
- event RewardsClaimed(bytes32 indexed poolId, address indexed recipient, uint256 quantity);
+ event RewardsClaimed(bytes32 indexed poolId, address indexed recipient, uint192 quantity);
event FeeManagerUpdated(address newProxyAddress);
- event FeePaid(bytes32 poolId, address payee, uint256 quantity);
+ event FeePaid(IRewardManager.FeePayment[] payments, address payee);
function setUp() public virtual {
//change to admin user
@@ -164,15 +166,27 @@ contract BaseRewardManagerTest is Test {
}
function addFundsToPool(bytes32 poolId, Common.Asset memory amount, address sender) public {
+ IRewardManager.FeePayment[] memory payments = new IRewardManager.FeePayment[](1);
+ payments[0] = IRewardManager.FeePayment(poolId, uint192(amount.amount));
+
+ addFundsToPool(payments, sender);
+ }
+
+ function addFundsToPool(IRewardManager.FeePayment[] memory payments, address sender) public {
//record the current address and switch to the sender
address originalAddr = msg.sender;
changePrank(sender);
+ uint256 totalPayment;
+ for (uint256 i; i < payments.length; ++i) {
+ totalPayment += payments[i].amount;
+ }
+
//approve the amount being paid into the pool
- ERC20Mock(amount.assetAddress).approve(address(rewardManager), amount.amount);
+ ERC20Mock(address(asset)).approve(address(rewardManager), totalPayment);
//this represents the verifier adding some funds to the pool
- rewardManager.onFeePaid(poolId, sender, amount.amount);
+ rewardManager.onFeePaid(payments, sender);
//change back to the original address
changePrank(originalAddr);
diff --git a/contracts/src/v0.8/llo-feeds/test/reward-manager/RewardManager.claim.t.sol b/contracts/src/v0.8/llo-feeds/test/reward-manager/RewardManager.claim.t.sol
index 358ffeee40c..9a3749d1dde 100644
--- a/contracts/src/v0.8/llo-feeds/test/reward-manager/RewardManager.claim.t.sol
+++ b/contracts/src/v0.8/llo-feeds/test/reward-manager/RewardManager.claim.t.sol
@@ -40,7 +40,7 @@ contract RewardManagerClaimTest is BaseRewardManagerTest {
}
}
- function test_claimRewardsWithDuplicatPoolIdsDoesNotPayoutTwice() public {
+ function test_claimRewardsWithDuplicatePoolIdsDoesNotPayoutTwice() public {
//add funds to a different pool to ensure they're not claimed
addFundsToPool(SECONDARY_POOL_ID, getAsset(POOL_DEPOSIT_AMOUNT), FEE_MANAGER);
@@ -227,7 +227,7 @@ contract RewardManagerClaimTest is BaseRewardManagerTest {
vm.expectEmit();
//emit the event that is expected to be emitted
- emit RewardsClaimed(PRIMARY_POOL_ID, recipient.addr, POOL_DEPOSIT_AMOUNT / 4);
+ emit RewardsClaimed(PRIMARY_POOL_ID, recipient.addr, uint192(POOL_DEPOSIT_AMOUNT / 4));
//claim the individual rewards for each recipient
claimRewards(PRIMARY_POOL_ARRAY, recipient.addr);
@@ -550,7 +550,11 @@ contract RewardManagerRecipientClaimMultiplePoolsTest is BaseRewardManagerTest {
function test_getRewardsAvailableToRecipientInBothPools() public {
//get index 0 as this recipient is in both default pools
- bytes32[] memory poolIds = rewardManager.getAvailableRewardPoolIds(getPrimaryRecipients()[0].addr);
+ bytes32[] memory poolIds = rewardManager.getAvailableRewardPoolIds(
+ getPrimaryRecipients()[0].addr,
+ 0,
+ type(uint256).max
+ );
//check the recipient is in both pools
assertEq(poolIds[0], PRIMARY_POOL_ID);
@@ -559,7 +563,11 @@ contract RewardManagerRecipientClaimMultiplePoolsTest is BaseRewardManagerTest {
function test_getRewardsAvailableToRecipientInSinglePool() public {
//get index 0 as this recipient is in both default pools
- bytes32[] memory poolIds = rewardManager.getAvailableRewardPoolIds(getPrimaryRecipients()[1].addr);
+ bytes32[] memory poolIds = rewardManager.getAvailableRewardPoolIds(
+ getPrimaryRecipients()[1].addr,
+ 0,
+ type(uint256).max
+ );
//check the recipient is in both pools
assertEq(poolIds[0], PRIMARY_POOL_ID);
@@ -568,12 +576,54 @@ contract RewardManagerRecipientClaimMultiplePoolsTest is BaseRewardManagerTest {
function test_getRewardsAvailableToRecipientInNoPools() public {
//get index 0 as this recipient is in both default pools
- bytes32[] memory poolIds = rewardManager.getAvailableRewardPoolIds(FEE_MANAGER);
+ bytes32[] memory poolIds = rewardManager.getAvailableRewardPoolIds(FEE_MANAGER, 0, type(uint256).max);
//check the recipient is in neither pool
assertEq(poolIds[0], ZERO_POOL_ID);
assertEq(poolIds[1], ZERO_POOL_ID);
}
+
+ function test_getRewardsAvailableToRecipientInBothPoolsWhereAlreadyClaimed() public {
+ //get index 0 as this recipient is in both default pools
+ bytes32[] memory poolIds = rewardManager.getAvailableRewardPoolIds(
+ getPrimaryRecipients()[0].addr,
+ 0,
+ type(uint256).max
+ );
+
+ //check the recipient is in both pools
+ assertEq(poolIds[0], PRIMARY_POOL_ID);
+ assertEq(poolIds[1], SECONDARY_POOL_ID);
+
+ //claim the rewards for each pool
+ claimRewards(PRIMARY_POOL_ARRAY, getPrimaryRecipients()[0].addr);
+ claimRewards(SECONDARY_POOL_ARRAY, getSecondaryRecipients()[0].addr);
+
+ //get the available pools again
+ poolIds = rewardManager.getAvailableRewardPoolIds(getPrimaryRecipients()[0].addr, 0, type(uint256).max);
+
+ //user should not be in any pool
+ assertEq(poolIds[0], ZERO_POOL_ID);
+ assertEq(poolIds[1], ZERO_POOL_ID);
+ }
+
+ function test_getAvailableRewardsCursorCannotBeGreaterThanTotalPools() public {
+ vm.expectRevert(INVALID_POOL_LENGTH_SELECTOR);
+
+ rewardManager.getAvailableRewardPoolIds(FEE_MANAGER, type(uint256).max, 0);
+ }
+
+ function test_getAvailableRewardsCursorAndTotalPoolsEqual() public {
+ bytes32[] memory poolIds = rewardManager.getAvailableRewardPoolIds(getPrimaryRecipients()[0].addr, 2, 2);
+
+ assertEq(poolIds.length, 0);
+ }
+
+ function test_getAvailableRewardsCursorSingleResult() public {
+ bytes32[] memory poolIds = rewardManager.getAvailableRewardPoolIds(getPrimaryRecipients()[0].addr, 0, 1);
+
+ assertEq(poolIds[0], PRIMARY_POOL_ID);
+ }
}
contract RewardManagerRecipientClaimDifferentWeightsTest is BaseRewardManagerTest {
@@ -636,7 +686,7 @@ contract RewardManagerRecipientClaimUnevenWeightTest is BaseRewardManagerTest {
//array of recipients
Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](2);
- uint256 oneThird = POOL_SCALAR / 3;
+ uint64 oneThird = POOL_SCALAR / 3;
//init each recipient with even weights.
recipients[0] = Common.AddressAndWeight(DEFAULT_RECIPIENT_1, oneThird);
diff --git a/contracts/src/v0.8/llo-feeds/test/reward-manager/RewardManager.general.t.sol b/contracts/src/v0.8/llo-feeds/test/reward-manager/RewardManager.general.t.sol
index e656ca1fcf4..befe6bfce93 100644
--- a/contracts/src/v0.8/llo-feeds/test/reward-manager/RewardManager.general.t.sol
+++ b/contracts/src/v0.8/llo-feeds/test/reward-manager/RewardManager.general.t.sol
@@ -3,8 +3,9 @@ pragma solidity 0.8.16;
import {BaseRewardManagerTest} from "./BaseRewardManager.t.sol";
import {Common} from "../../../libraries/Common.sol";
-import {RewardManager} from "../../dev/RewardManager.sol";
+import {RewardManager} from "../../RewardManager.sol";
import {ERC20Mock} from "../../../vendor/openzeppelin-solidity/v4.8.0/contracts/mocks/ERC20Mock.sol";
+import {IRewardManager} from "../../interfaces/IRewardManager.sol";
/**
* @title BaseRewardManagerTest
@@ -48,12 +49,15 @@ contract RewardManagerSetupTest is BaseRewardManagerTest {
//approve the amount being paid into the pool
ERC20Mock(getAsset(POOL_DEPOSIT_AMOUNT).assetAddress).approve(address(rewardManager), POOL_DEPOSIT_AMOUNT);
+ IRewardManager.FeePayment[] memory payments = new IRewardManager.FeePayment[](1);
+ payments[0] = IRewardManager.FeePayment(PRIMARY_POOL_ID, uint192(POOL_DEPOSIT_AMOUNT));
+
//event is emitted when funds are added
vm.expectEmit();
- emit FeePaid(PRIMARY_POOL_ID, FEE_MANAGER, POOL_DEPOSIT_AMOUNT);
+ emit FeePaid(payments, FEE_MANAGER);
//this represents the verifier adding some funds to the pool
- rewardManager.onFeePaid(PRIMARY_POOL_ID, FEE_MANAGER, POOL_DEPOSIT_AMOUNT);
+ rewardManager.onFeePaid(payments, FEE_MANAGER);
}
function test_setFeeManagerZeroAddress() public {
diff --git a/contracts/src/v0.8/llo-feeds/test/reward-manager/RewardManager.payRecipients.t.sol b/contracts/src/v0.8/llo-feeds/test/reward-manager/RewardManager.payRecipients.t.sol
index 8506210f2df..5dcf1eeae4f 100644
--- a/contracts/src/v0.8/llo-feeds/test/reward-manager/RewardManager.payRecipients.t.sol
+++ b/contracts/src/v0.8/llo-feeds/test/reward-manager/RewardManager.payRecipients.t.sol
@@ -3,6 +3,7 @@ pragma solidity 0.8.16;
import {BaseRewardManagerTest} from "./BaseRewardManager.t.sol";
import {Common} from "../../../libraries/Common.sol";
+import {IRewardManager} from "../../interfaces/IRewardManager.sol";
/**
* @title BaseRewardManagerTest
@@ -185,7 +186,10 @@ contract RewardManagerPayRecipientsTest is BaseRewardManagerTest {
//should revert if the caller isn't an admin or recipient within the pool
vm.expectRevert(UNAUTHORIZED_ERROR_SELECTOR);
+ IRewardManager.FeePayment[] memory payments = new IRewardManager.FeePayment[](1);
+ payments[0] = IRewardManager.FeePayment(PRIMARY_POOL_ID, uint192(POOL_DEPOSIT_AMOUNT));
+
//add funds to the pool
- rewardManager.onFeePaid(PRIMARY_POOL_ID, USER, POOL_DEPOSIT_AMOUNT);
+ rewardManager.onFeePaid(payments, USER);
}
}
diff --git a/contracts/src/v0.8/llo-feeds/test/reward-manager/RewardManager.setRecipients.t.sol b/contracts/src/v0.8/llo-feeds/test/reward-manager/RewardManager.setRecipients.t.sol
index 0c58a8562cf..58cce9a9154 100644
--- a/contracts/src/v0.8/llo-feeds/test/reward-manager/RewardManager.setRecipients.t.sol
+++ b/contracts/src/v0.8/llo-feeds/test/reward-manager/RewardManager.setRecipients.t.sol
@@ -3,7 +3,7 @@ pragma solidity 0.8.16;
import {BaseRewardManagerTest} from "./BaseRewardManager.t.sol";
import {Common} from "../../../libraries/Common.sol";
-import {RewardManager} from "../../dev/RewardManager.sol";
+import {RewardManager} from "../../RewardManager.sol";
/**
* @title BaseRewardManagerTest
@@ -32,24 +32,6 @@ contract RewardManagerSetRecipientsTest is BaseRewardManagerTest {
setRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN);
}
- function test_setRewardRecipientWithZeroWeight() public {
- //array of recipients
- Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](5);
-
- //init each recipient with even weights
- recipients[0] = Common.AddressAndWeight(DEFAULT_RECIPIENT_1, ONE_PERCENT * 25);
- recipients[1] = Common.AddressAndWeight(DEFAULT_RECIPIENT_2, ONE_PERCENT * 25);
- recipients[2] = Common.AddressAndWeight(DEFAULT_RECIPIENT_3, ONE_PERCENT * 25);
- recipients[3] = Common.AddressAndWeight(DEFAULT_RECIPIENT_4, ONE_PERCENT * 25);
- recipients[4] = Common.AddressAndWeight(DEFAULT_RECIPIENT_5, 0);
-
- //Zero weight should fail
- vm.expectRevert(INVALID_WEIGHT_ERROR_SELECTOR);
-
- //set the recipients
- setRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN);
- }
-
function test_setRewardRecipientWithZeroAddress() public {
//array of recipients
Common.AddressAndWeight[] memory recipients = getPrimaryRecipients();
diff --git a/contracts/src/v0.8/llo-feeds/test/reward-manager/RewardManager.updateRewardRecipients.t.sol b/contracts/src/v0.8/llo-feeds/test/reward-manager/RewardManager.updateRewardRecipients.t.sol
index de12f11bf92..e6f964f9f9f 100644
--- a/contracts/src/v0.8/llo-feeds/test/reward-manager/RewardManager.updateRewardRecipients.t.sol
+++ b/contracts/src/v0.8/llo-feeds/test/reward-manager/RewardManager.updateRewardRecipients.t.sol
@@ -3,7 +3,7 @@ pragma solidity 0.8.16;
import {BaseRewardManagerTest} from "./BaseRewardManager.t.sol";
import {Common} from "../../../libraries/Common.sol";
-import {RewardManager} from "../../dev/RewardManager.sol";
+import {RewardManager} from "../../RewardManager.sol";
/**
* @title BaseRewardManagerTest
@@ -106,146 +106,6 @@ contract RewardManagerUpdateRewardRecipientsTest is BaseRewardManagerTest {
updateRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN);
}
- function test_updateRecipientsToDifferentSet() public {
- //create a list of containing recipients from the primary configured set, and new recipients
- Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](getPrimaryRecipients().length + 4);
- for (uint256 i; i < getPrimaryRecipients().length; i++) {
- //copy the recipient and set the weight to 0 which implies the recipient is being replaced
- recipients[i] = Common.AddressAndWeight(getPrimaryRecipients()[i].addr, 0);
- }
-
- //add the new recipients individually
- recipients[4] = Common.AddressAndWeight(DEFAULT_RECIPIENT_5, ONE_PERCENT * 25);
- recipients[5] = Common.AddressAndWeight(DEFAULT_RECIPIENT_6, ONE_PERCENT * 25);
- recipients[6] = Common.AddressAndWeight(DEFAULT_RECIPIENT_7, ONE_PERCENT * 25);
- recipients[7] = Common.AddressAndWeight(DEFAULT_RECIPIENT_8, ONE_PERCENT * 25);
-
- //should revert as it's not possible to new recipients
- vm.expectRevert(INVALID_ADDRESS_ERROR_SELECTOR);
-
- //updating a recipient should force the funds to be paid out for the primary recipients
- updateRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN);
- }
-
- function test_updateRecipientsToDifferentPartialSet() public {
- //create a list of containing recipients from the primary configured set, and new recipients
- Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](getPrimaryRecipients().length + 2);
- for (uint256 i; i < getPrimaryRecipients().length; i++) {
- //copy the recipient and set the weight to 0 which implies the recipient is being replaced
- recipients[i] = Common.AddressAndWeight(getPrimaryRecipients()[i].addr, 0);
- }
-
- //add the new recipients individually
- recipients[4] = Common.AddressAndWeight(DEFAULT_RECIPIENT_5, FIFTY_PERCENT);
- recipients[5] = Common.AddressAndWeight(DEFAULT_RECIPIENT_6, FIFTY_PERCENT);
-
- //should revert as it's not possible to add new recipients
- vm.expectRevert(INVALID_ADDRESS_ERROR_SELECTOR);
-
- //updating a recipient should force the funds to be paid out for the primary recipients
- updateRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN);
- }
-
- function test_updateRecipientsToDifferentLargerSet() public {
- //create a list of containing recipients from the primary configured set, and new recipients
- Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](getPrimaryRecipients().length + 5);
- for (uint256 i; i < getPrimaryRecipients().length; i++) {
- //copy the recipient and set the weight to 0 which implies the recipient is being replaced
- recipients[i] = Common.AddressAndWeight(getPrimaryRecipients()[i].addr, 0);
- }
-
- //add the new recipients individually
- recipients[4] = Common.AddressAndWeight(DEFAULT_RECIPIENT_5, TEN_PERCENT * 2);
- recipients[5] = Common.AddressAndWeight(DEFAULT_RECIPIENT_6, TEN_PERCENT * 2);
- recipients[6] = Common.AddressAndWeight(DEFAULT_RECIPIENT_7, TEN_PERCENT * 2);
- recipients[7] = Common.AddressAndWeight(DEFAULT_RECIPIENT_8, TEN_PERCENT * 2);
- recipients[8] = Common.AddressAndWeight(DEFAULT_RECIPIENT_9, TEN_PERCENT * 2);
-
- //should revert as changing the recipient set is not allowed
- vm.expectRevert(INVALID_ADDRESS_ERROR_SELECTOR);
-
- //updating a recipient should force the funds to be paid out for the primary recipients
- updateRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN);
- }
-
- function test_updateRecipientsUpdateAndRemoveExistingForLargerSet() public {
- //create a list of containing recipients from the primary configured set, and new recipients
- Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](9);
-
- //update the existing recipients
- recipients[0] = Common.AddressAndWeight(getPrimaryRecipients()[0].addr, 0);
- recipients[1] = Common.AddressAndWeight(getPrimaryRecipients()[1].addr, 0);
- recipients[2] = Common.AddressAndWeight(getPrimaryRecipients()[2].addr, TEN_PERCENT * 3);
- recipients[3] = Common.AddressAndWeight(getPrimaryRecipients()[3].addr, TEN_PERCENT * 3);
-
- //add the new recipients individually
- recipients[4] = Common.AddressAndWeight(DEFAULT_RECIPIENT_5, TEN_PERCENT);
- recipients[5] = Common.AddressAndWeight(DEFAULT_RECIPIENT_6, TEN_PERCENT);
- recipients[6] = Common.AddressAndWeight(DEFAULT_RECIPIENT_7, TEN_PERCENT);
- recipients[7] = Common.AddressAndWeight(DEFAULT_RECIPIENT_8, TEN_PERCENT);
- recipients[8] = Common.AddressAndWeight(DEFAULT_RECIPIENT_9, TEN_PERCENT);
-
- //should revert as it's not possible to add new recipients
- vm.expectRevert(INVALID_ADDRESS_ERROR_SELECTOR);
-
- //updating a recipient should force the funds to be paid out for the primary recipients
- updateRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN);
- }
-
- function test_updateRecipientsUpdateAndRemoveExistingForSmallerSet() public {
- //create a list of containing recipients from the primary configured set, and new recipients
- Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](5);
-
- //update the existing recipients
- recipients[0] = Common.AddressAndWeight(getPrimaryRecipients()[0].addr, 0);
- recipients[1] = Common.AddressAndWeight(getPrimaryRecipients()[1].addr, 0);
- recipients[2] = Common.AddressAndWeight(getPrimaryRecipients()[2].addr, TEN_PERCENT * 3);
- recipients[3] = Common.AddressAndWeight(getPrimaryRecipients()[3].addr, TEN_PERCENT * 2);
-
- //add the new recipients individually
- recipients[4] = Common.AddressAndWeight(DEFAULT_RECIPIENT_5, TEN_PERCENT * 5);
-
- //should revert as it's not possible to add new recipients
- vm.expectRevert(INVALID_ADDRESS_ERROR_SELECTOR);
-
- //updating a recipient should force the funds to be paid out for the primary recipients
- updateRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN);
- }
-
- function test_updateRecipientsToDifferentSetWithInvalidWeights() public {
- //create a list of containing recipients from the primary configured set, and new recipients
- Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](getPrimaryRecipients().length + 2);
- for (uint256 i; i < getPrimaryRecipients().length; i++) {
- //copy the recipient and set the weight to 0 which implies the recipient is being replaced
- recipients[i] = Common.AddressAndWeight(getPrimaryRecipients()[i].addr, 0);
- }
-
- //add the new recipients individually
- recipients[4] = Common.AddressAndWeight(DEFAULT_RECIPIENT_5, TEN_PERCENT * 5);
- recipients[5] = Common.AddressAndWeight(DEFAULT_RECIPIENT_6, TEN_PERCENT);
-
- //should revert as the addresses are not in the configured set
- vm.expectRevert(INVALID_ADDRESS_ERROR_SELECTOR);
-
- //updating a recipient should force the funds to be paid out for the primary recipients
- updateRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN);
- }
-
- function test_updatePartialRecipientsToSubset() public {
- //create a list of containing recipients from the primary configured set, and new recipients
- Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](4);
- recipients[0] = Common.AddressAndWeight(DEFAULT_RECIPIENT_1, 0);
- recipients[1] = Common.AddressAndWeight(DEFAULT_RECIPIENT_2, 0);
- recipients[2] = Common.AddressAndWeight(DEFAULT_RECIPIENT_3, TEN_PERCENT * 5);
- recipients[3] = Common.AddressAndWeight(DEFAULT_RECIPIENT_4, TEN_PERCENT * 5);
-
- //should revert as changing the recipients is not allowed
- vm.expectRevert(INVALID_WEIGHT_ERROR_SELECTOR);
-
- //updating a recipient should force the funds to be paid out for the primary recipients
- updateRewardRecipients(PRIMARY_POOL_ID, recipients, ADMIN);
- }
-
function test_updatePartialRecipientsWithUnderWeightSet() public {
//create a list of containing recipients from the primary configured set, and new recipients
Common.AddressAndWeight[] memory recipients = new Common.AddressAndWeight[](4);
diff --git a/contracts/src/v0.8/llo-feeds/test/verifier/BaseVerifierTest.t.sol b/contracts/src/v0.8/llo-feeds/test/verifier/BaseVerifierTest.t.sol
index 38ceb3030ef..3faa65fb52b 100644
--- a/contracts/src/v0.8/llo-feeds/test/verifier/BaseVerifierTest.t.sol
+++ b/contracts/src/v0.8/llo-feeds/test/verifier/BaseVerifierTest.t.sol
@@ -8,13 +8,13 @@ import {IVerifier} from "../../interfaces/IVerifier.sol";
import {ErroredVerifier} from "../mocks/ErroredVerifier.sol";
import {Verifier} from "../../Verifier.sol";
import {Strings} from "@openzeppelin/contracts/utils/Strings.sol";
-import {AccessControllerInterface} from "../../../interfaces/AccessControllerInterface.sol";
-import {FeeManager} from "../../dev/FeeManager.sol";
+import {AccessControllerInterface} from "../../../shared/interfaces/AccessControllerInterface.sol";
+import {FeeManager} from "../../FeeManager.sol";
import {Common} from "../../../libraries/Common.sol";
import {ERC20Mock} from "../../../vendor/openzeppelin-solidity/v4.8.0/contracts/mocks/ERC20Mock.sol";
import {WERC20Mock} from "../../../shared/mocks/WERC20Mock.sol";
-import {FeeManager} from "../../dev/FeeManager.sol";
-import {RewardManager} from "../../dev/RewardManager.sol";
+import {FeeManager} from "../../FeeManager.sol";
+import {RewardManager} from "../../RewardManager.sol";
contract BaseTest is Test {
uint256 internal constant MAX_ORACLES = 31;
@@ -63,7 +63,7 @@ contract BaseTest is Test {
address signerAddress;
}
- struct V0Report {
+ struct V1Report {
// The feed ID the report has data for
bytes32 feedId;
// The time the median value was observed on
@@ -148,12 +148,27 @@ contract BaseTest is Test {
return (rs, ss, bytes32(vs));
}
- function _generateEncodedBlob(
- V0Report memory report,
+ function _encodeReport(V1Report memory report) internal pure returns (bytes memory) {
+ return
+ abi.encode(
+ report.feedId,
+ report.observationsTimestamp,
+ report.median,
+ report.bid,
+ report.ask,
+ report.blocknumberUpperBound,
+ report.upperBlockhash,
+ report.blocknumberLowerBound,
+ report.currentBlockTimestamp
+ );
+ }
+
+ function _generateV1EncodedBlob(
+ V1Report memory report,
bytes32[3] memory reportContext,
Signer[] memory signers
) internal pure returns (bytes memory) {
- bytes memory reportBytes = abi.encode(report);
+ bytes memory reportBytes = _encodeReport(report);
(bytes32[] memory rs, bytes32[] memory ss, bytes32 rawVs) = _generateSignerSignatures(
reportBytes,
reportContext,
@@ -173,7 +188,7 @@ contract BaseTest is Test {
bytes memory onchainConfig,
uint64 offchainConfigVersion,
bytes memory offchainConfig
- ) internal view returns (bytes32) {
+ ) internal pure returns (bytes32) {
uint256 h = uint256(
keccak256(
abi.encode(
@@ -195,7 +210,7 @@ contract BaseTest is Test {
return bytes32((prefix & prefixMask) | (h & ~prefixMask));
}
- function _createV0Report(
+ function _createV1Report(
bytes32 feedId,
uint32 observationsTimestamp,
int192 median,
@@ -205,9 +220,9 @@ contract BaseTest is Test {
bytes32 upperBlockhash,
uint64 blocknumberLowerBound,
uint32 currentBlockTimestamp
- ) internal pure returns (V0Report memory) {
+ ) internal pure returns (V1Report memory) {
return
- V0Report({
+ V1Report({
feedId: feedId,
observationsTimestamp: observationsTimestamp,
median: median,
@@ -243,21 +258,24 @@ contract BaseTestWithConfiguredVerifierAndFeeManager is BaseTest {
uint256 internal constant DEFAULT_REPORT_LINK_FEE = 1e10;
uint256 internal constant DEFAULT_REPORT_NATIVE_FEE = 1e12;
- struct V2Report {
+ bytes32 internal v1ConfigDigest;
+ bytes32 internal v3ConfigDigest;
+
+ struct V3Report {
// The feed ID the report has data for
bytes32 feedId;
// The time the median value was observed on
uint32 observationsTimestamp;
// The timestamp the report is valid from
uint32 validFromTimestamp;
- // The median value agreed in an OCR round
- int192 benchmarkPrice;
// The link fee
uint192 linkFee;
// The native fee
uint192 nativeFee;
// The expiry of the report
uint32 expiresAt;
+ // The median value agreed in an OCR round
+ int192 benchmarkPrice;
// The best bid value agreed in an OCR round
int192 bid;
// The best ask value agreed in an OCR round
@@ -279,6 +297,7 @@ contract BaseTestWithConfiguredVerifierAndFeeManager is BaseTest {
bytes(""),
new Common.AddressAndWeight[](0)
);
+ (, , v1ConfigDigest) = s_verifier.latestConfigDetails(FEED_ID);
s_verifier.setConfig(
FEED_ID_V3,
@@ -290,6 +309,7 @@ contract BaseTestWithConfiguredVerifierAndFeeManager is BaseTest {
bytes(""),
new Common.AddressAndWeight[](0)
);
+ (, , v3ConfigDigest) = s_verifier.latestConfigDetails(FEED_ID_V3);
link = new ERC20Mock("LINK", "LINK", ADMIN, 0);
native = new WERC20Mock();
@@ -301,26 +321,25 @@ contract BaseTestWithConfiguredVerifierAndFeeManager is BaseTest {
rewardManager.setFeeManager(address(feeManager));
}
- function _encodeReport(V2Report memory report) internal pure returns (bytes memory) {
+ function _encodeReport(V3Report memory report) internal pure returns (bytes memory) {
return
abi.encode(
report.feedId,
report.observationsTimestamp,
report.validFromTimestamp,
- report.benchmarkPrice,
- report.linkFee,
report.nativeFee,
+ report.linkFee,
report.expiresAt,
+ report.benchmarkPrice,
report.bid,
report.ask
);
}
- function _generateEncodedBlobWithQuote(
- V2Report memory report,
+ function _generateV3EncodedBlob(
+ V3Report memory report,
bytes32[3] memory reportContext,
- Signer[] memory signers,
- bytes memory quote
+ Signer[] memory signers
) internal pure returns (bytes memory) {
bytes memory reportBytes = _encodeReport(report);
(bytes32[] memory rs, bytes32[] memory ss, bytes32 rawVs) = _generateSignerSignatures(
@@ -328,33 +347,42 @@ contract BaseTestWithConfiguredVerifierAndFeeManager is BaseTest {
reportContext,
signers
);
-
- return abi.encode(reportContext, reportBytes, rs, ss, rawVs, quote);
+ return abi.encode(reportContext, reportBytes, rs, ss, rawVs);
}
- function _generateQuote(address billingAddress) internal pure returns (bytes memory) {
- return abi.encode(billingAddress);
+ function _generateV1Report() internal view returns (V1Report memory) {
+ return
+ _createV1Report(
+ FEED_ID,
+ OBSERVATIONS_TIMESTAMP,
+ MEDIAN,
+ BID,
+ ASK,
+ BLOCKNUMBER_UPPER_BOUND,
+ bytes32(blockhash(BLOCKNUMBER_UPPER_BOUND)),
+ BLOCKNUMBER_LOWER_BOUND,
+ uint32(block.timestamp)
+ );
}
- function _generateV2Report() internal view returns (V2Report memory) {
+ function _generateV3Report() internal view returns (V3Report memory) {
return
- V2Report({
+ V3Report({
feedId: FEED_ID_V3,
observationsTimestamp: OBSERVATIONS_TIMESTAMP,
validFromTimestamp: uint32(block.timestamp),
- benchmarkPrice: MEDIAN,
- linkFee: uint192(DEFAULT_REPORT_LINK_FEE),
nativeFee: uint192(DEFAULT_REPORT_NATIVE_FEE),
+ linkFee: uint192(DEFAULT_REPORT_LINK_FEE),
expiresAt: uint32(block.timestamp),
+ benchmarkPrice: MEDIAN,
bid: BID,
ask: ASK
});
}
- function _generateReportContext(bytes32 feedId) internal view returns (bytes32[3] memory) {
- (, , bytes32 latestConfigDigest) = s_verifier.latestConfigDetails(feedId);
+ function _generateReportContext(bytes32 configDigest) internal pure returns (bytes32[3] memory) {
bytes32[3] memory reportContext;
- reportContext[0] = latestConfigDigest;
+ reportContext[0] = configDigest;
reportContext[1] = bytes32(abi.encode(uint32(5), uint8(1)));
return reportContext;
}
@@ -375,11 +403,25 @@ contract BaseTestWithConfiguredVerifierAndFeeManager is BaseTest {
changePrank(originalAddr);
}
- function _verify(bytes memory payload, uint256 wrappedNativeValue, address sender) internal {
+ function _verify(bytes memory payload, address feeAddress, uint256 wrappedNativeValue, address sender) internal {
+ address originalAddr = msg.sender;
+ changePrank(sender);
+
+ s_verifierProxy.verify{value: wrappedNativeValue}(payload, abi.encode(feeAddress));
+
+ changePrank(originalAddr);
+ }
+
+ function _verifyBulk(
+ bytes[] memory payload,
+ address feeAddress,
+ uint256 wrappedNativeValue,
+ address sender
+ ) internal {
address originalAddr = msg.sender;
changePrank(sender);
- s_verifierProxy.verify{value: wrappedNativeValue}(payload);
+ s_verifierProxy.verifyBulk{value: wrappedNativeValue}(payload, abi.encode(feeAddress));
changePrank(originalAddr);
}
diff --git a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierActivateConfigTest.t.sol b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierActivateConfigTest.t.sol
index 501f23d10d3..641d2772595 100644
--- a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierActivateConfigTest.t.sol
+++ b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierActivateConfigTest.t.sol
@@ -29,13 +29,13 @@ contract VerifierActivateConfigWithDeactivatedConfigTest is BaseTestWithMultiple
event ConfigActivated(bytes32 configDigest);
- V0Report internal s_testReportOne;
+ V1Report internal s_testReportOne;
function setUp() public override {
BaseTestWithMultipleConfiguredDigests.setUp();
s_reportContext[0] = s_configDigestTwo;
s_reportContext[1] = bytes32(abi.encode(uint32(5), uint8(1)));
- s_testReportOne = _createV0Report(
+ s_testReportOne = _createV1Report(
FEED_ID,
uint32(block.timestamp),
MEDIAN,
@@ -54,7 +54,7 @@ contract VerifierActivateConfigWithDeactivatedConfigTest is BaseTestWithMultiple
s_verifier.activateConfig(FEED_ID, s_configDigestTwo);
changePrank(address(s_verifierProxy));
- bytes memory signedReport = _generateEncodedBlob(
+ bytes memory signedReport = _generateV1EncodedBlob(
s_testReportOne,
s_reportContext,
_getSigners(FAULT_TOLERANCE_TWO + 1)
diff --git a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierDeactivateFeedTest.t.sol b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierDeactivateFeedTest.t.sol
index e44a9a03f81..fc6814d3bfe 100644
--- a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierDeactivateFeedTest.t.sol
+++ b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierDeactivateFeedTest.t.sol
@@ -34,13 +34,13 @@ contract VerifierDeactivateFeedWithVerifyTest is BaseTestWithMultipleConfiguredD
event ConfigActivated(bytes32 configDigest);
- V0Report internal s_testReportOne;
+ V1Report internal s_testReportOne;
function setUp() public override {
BaseTestWithMultipleConfiguredDigests.setUp();
s_reportContext[0] = s_configDigestOne;
s_reportContext[1] = bytes32(abi.encode(uint32(5), uint8(1)));
- s_testReportOne = _createV0Report(
+ s_testReportOne = _createV1Report(
FEED_ID,
uint32(block.timestamp),
MEDIAN,
@@ -59,7 +59,7 @@ contract VerifierDeactivateFeedWithVerifyTest is BaseTestWithMultipleConfiguredD
s_verifier.activateFeed(FEED_ID);
changePrank(address(s_verifierProxy));
- bytes memory signedReport = _generateEncodedBlob(
+ bytes memory signedReport = _generateV1EncodedBlob(
s_testReportOne,
s_reportContext,
_getSigners(FAULT_TOLERANCE + 1)
@@ -72,7 +72,7 @@ contract VerifierDeactivateFeedWithVerifyTest is BaseTestWithMultipleConfiguredD
changePrank(address(s_verifierProxy));
s_reportContext[0] = s_configDigestTwo;
- bytes memory signedReport = _generateEncodedBlob(
+ bytes memory signedReport = _generateV1EncodedBlob(
s_testReportOne,
s_reportContext,
_getSigners(FAULT_TOLERANCE_TWO + 1)
@@ -83,7 +83,7 @@ contract VerifierDeactivateFeedWithVerifyTest is BaseTestWithMultipleConfiguredD
function test_currentReportFailsVerification() public {
changePrank(address(s_verifierProxy));
- bytes memory signedReport = _generateEncodedBlob(
+ bytes memory signedReport = _generateV1EncodedBlob(
s_testReportOne,
s_reportContext,
_getSigners(FAULT_TOLERANCE + 1)
@@ -97,7 +97,7 @@ contract VerifierDeactivateFeedWithVerifyTest is BaseTestWithMultipleConfiguredD
changePrank(address(s_verifierProxy));
s_reportContext[0] = s_configDigestTwo;
- bytes memory signedReport = _generateEncodedBlob(
+ bytes memory signedReport = _generateV1EncodedBlob(
s_testReportOne,
s_reportContext,
_getSigners(FAULT_TOLERANCE_TWO + 1)
diff --git a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxyConstructorTest.t.sol b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxyConstructorTest.t.sol
index b4d13423ecd..7de7dea03d1 100644
--- a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxyConstructorTest.t.sol
+++ b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxyConstructorTest.t.sol
@@ -4,7 +4,7 @@ pragma solidity 0.8.16;
import {BaseTest} from "./BaseVerifierTest.t.sol";
import {IVerifier} from "../../interfaces/IVerifier.sol";
import {VerifierProxy} from "../../VerifierProxy.sol";
-import {AccessControllerInterface} from "../../../interfaces/AccessControllerInterface.sol";
+import {AccessControllerInterface} from "../../../shared/interfaces/AccessControllerInterface.sol";
contract VerifierProxyConstructorTest is BaseTest {
function test_correctlySetsTheOwner() public {
@@ -20,6 +20,6 @@ contract VerifierProxyConstructorTest is BaseTest {
function test_correctlySetsVersion() public {
string memory version = s_verifierProxy.typeAndVersion();
- assertEq(version, "VerifierProxy 1.1.0");
+ assertEq(version, "VerifierProxy 2.0.0");
}
}
diff --git a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxyInitializeVerifierTest.t.sol b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxyInitializeVerifierTest.t.sol
index 92b98c6d9d2..66ddb4bf3c3 100644
--- a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxyInitializeVerifierTest.t.sol
+++ b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxyInitializeVerifierTest.t.sol
@@ -4,7 +4,7 @@ pragma solidity 0.8.16;
import {BaseTest} from "./BaseVerifierTest.t.sol";
import {IVerifier} from "../../interfaces/IVerifier.sol";
import {VerifierProxy} from "../../VerifierProxy.sol";
-import {AccessControllerInterface} from "../../../interfaces/AccessControllerInterface.sol";
+import {AccessControllerInterface} from "../../../shared/interfaces/AccessControllerInterface.sol";
contract VerifierProxyInitializeVerifierTest is BaseTest {
bytes32 latestDigest;
diff --git a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxySetAccessControllerTest.t.sol b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxySetAccessControllerTest.t.sol
index a93f30a743a..c9799e375c9 100644
--- a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxySetAccessControllerTest.t.sol
+++ b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxySetAccessControllerTest.t.sol
@@ -2,7 +2,7 @@
pragma solidity 0.8.16;
import {BaseTest} from "./BaseVerifierTest.t.sol";
-import {AccessControllerInterface} from "../../../interfaces/AccessControllerInterface.sol";
+import {AccessControllerInterface} from "../../../shared/interfaces/AccessControllerInterface.sol";
contract VerifierProxySetAccessControllerTest is BaseTest {
event AccessControllerSet(address oldAccessController, address newAccessController);
diff --git a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxySetVerifierTest.t.sol b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxySetVerifierTest.t.sol
index ee7b2c96b7b..9fa2f16d900 100644
--- a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxySetVerifierTest.t.sol
+++ b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxySetVerifierTest.t.sol
@@ -4,7 +4,7 @@ pragma solidity 0.8.16;
import {BaseTestWithConfiguredVerifierAndFeeManager} from "./BaseVerifierTest.t.sol";
import {IVerifier} from "../../interfaces/IVerifier.sol";
import {VerifierProxy} from "../../VerifierProxy.sol";
-import {AccessControllerInterface} from "../../../interfaces/AccessControllerInterface.sol";
+import {AccessControllerInterface} from "../../../shared/interfaces/AccessControllerInterface.sol";
import {IERC165} from "../../../vendor/openzeppelin-solidity/v4.8.0/contracts/interfaces/IERC165.sol";
import {Common} from "../../../libraries/Common.sol";
diff --git a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxyTest.t.sol b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxyTest.t.sol
index ffce4e6fa50..5aa3e791ed8 100644
--- a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxyTest.t.sol
+++ b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierProxyTest.t.sol
@@ -4,14 +4,24 @@ pragma solidity 0.8.16;
import {BaseTestWithConfiguredVerifierAndFeeManager} from "./BaseVerifierTest.t.sol";
import {IVerifier} from "../../interfaces/IVerifier.sol";
import {VerifierProxy} from "../../VerifierProxy.sol";
-import {AccessControllerInterface} from "../../../interfaces/AccessControllerInterface.sol";
+import {AccessControllerInterface} from "../../../shared/interfaces/AccessControllerInterface.sol";
import {IERC165} from "../../../vendor/openzeppelin-solidity/v4.8.0/contracts/interfaces/IERC165.sol";
import {Common} from "../../../libraries/Common.sol";
-import {FeeManager} from "../../dev/FeeManager.sol";
+import {FeeManager} from "../../FeeManager.sol";
contract VerifierProxyInitializeVerifierTest is BaseTestWithConfiguredVerifierAndFeeManager {
function test_setFeeManagerZeroAddress() public {
vm.expectRevert(abi.encodeWithSelector(VerifierProxy.ZeroAddress.selector));
s_verifierProxy.setFeeManager(FeeManager(address(0)));
}
+
+ function test_setFeeManagerWhichDoesntHonourInterface() public {
+ vm.expectRevert(abi.encodeWithSelector(VerifierProxy.FeeManagerInvalid.selector));
+ s_verifierProxy.setFeeManager(FeeManager(address(s_verifier)));
+ }
+
+ function test_setFeeManagerWhichDoesntHonourIERC165Interface() public {
+ vm.expectRevert();
+ s_verifierProxy.setFeeManager(FeeManager(address(1)));
+ }
}
diff --git a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierSetConfigFromSourceTest.t.sol b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierSetConfigFromSourceTest.t.sol
index 2ba25294168..57c98622f5b 100644
--- a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierSetConfigFromSourceTest.t.sol
+++ b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierSetConfigFromSourceTest.t.sol
@@ -20,6 +20,7 @@ contract VerifierSetConfigFromSourceTest is BaseTest {
FEED_ID,
12345,
address(12345),
+ 0,
_getSignerAddresses(signers),
s_offchaintransmitters,
FAULT_TOLERANCE,
@@ -39,6 +40,7 @@ contract VerifierSetConfigFromSourceMultipleDigestsTest is BaseTestWithMultipleC
FEED_ID,
12345,
address(12345),
+ 0,
_getSignerAddresses(newSigners),
s_offchaintransmitters,
4,
@@ -60,6 +62,7 @@ contract VerifierSetConfigFromSourceMultipleDigestsTest is BaseTestWithMultipleC
FEED_ID_2,
12345,
address(12345),
+ 0,
_getSignerAddresses(newSigners),
s_offchaintransmitters,
4,
@@ -77,6 +80,7 @@ contract VerifierSetConfigFromSourceMultipleDigestsTest is BaseTestWithMultipleC
FEED_ID_3,
12345,
address(12345),
+ 0,
_getSignerAddresses(newSigners),
s_offchaintransmitters,
4,
@@ -100,6 +104,7 @@ contract VerifierSetConfigFromSourceMultipleDigestsTest is BaseTestWithMultipleC
FEED_ID,
12345,
address(s_verifier),
+ 0,
_getSignerAddresses(newSigners),
s_offchaintransmitters,
4,
diff --git a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierTest.t.sol b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierTest.t.sol
index 424b1124b92..1b4340495fc 100644
--- a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierTest.t.sol
+++ b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierTest.t.sol
@@ -26,7 +26,7 @@ contract VerifierConstructorTest is BaseTest {
assertEq(configDigestTwo, EMPTY_BYTES);
string memory typeAndVersion = s_verifier.typeAndVersion();
- assertEq(typeAndVersion, "Verifier 1.1.0");
+ assertEq(typeAndVersion, "Verifier 1.2.0");
}
}
diff --git a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierTestBillingReport.t.sol b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierTestBillingReport.t.sol
index 086816a7c57..fffa291b0d8 100644
--- a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierTestBillingReport.t.sol
+++ b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierTestBillingReport.t.sol
@@ -17,65 +17,205 @@ contract VerifierTestWithConfiguredVerifierAndFeeManager is BaseTestWithConfigur
link.mint(USER, DEFAULT_LINK_MINT_QUANTITY);
native.mint(USER, DEFAULT_NATIVE_MINT_QUANTITY);
vm.deal(USER, DEFAULT_NATIVE_MINT_QUANTITY);
+
+ //mint some link tokens to the feeManager pool
+ link.mint(address(feeManager), DEFAULT_REPORT_LINK_FEE);
}
}
contract VerifierTestBillingReport is VerifierTestWithConfiguredVerifierAndFeeManager {
function test_verifyWithLink() public {
- bytes memory signedReport = _generateEncodedBlobWithQuote(
- _generateV2Report(),
- _generateReportContext(FEED_ID_V3),
- _getSigners(FAULT_TOLERANCE + 1),
- _generateQuote(address(link))
+ bytes memory signedReport = _generateV3EncodedBlob(
+ _generateV3Report(),
+ _generateReportContext(v3ConfigDigest),
+ _getSigners(FAULT_TOLERANCE + 1)
);
_approveLink(address(rewardManager), DEFAULT_REPORT_LINK_FEE, USER);
- _verify(signedReport, 0, USER);
+ _verify(signedReport, address(link), 0, USER);
assertEq(link.balanceOf(USER), DEFAULT_LINK_MINT_QUANTITY - DEFAULT_REPORT_LINK_FEE);
}
function test_verifyWithNative() public {
- bytes memory signedReport = _generateEncodedBlobWithQuote(
- _generateV2Report(),
- _generateReportContext(FEED_ID_V3),
- _getSigners(FAULT_TOLERANCE + 1),
- _generateQuote(address(native))
+ bytes memory signedReport = _generateV3EncodedBlob(
+ _generateV3Report(),
+ _generateReportContext(v3ConfigDigest),
+ _getSigners(FAULT_TOLERANCE + 1)
);
_approveNative(address(feeManager), DEFAULT_REPORT_NATIVE_FEE, USER);
- _verify(signedReport, 0, USER);
+ _verify(signedReport, address(native), 0, USER);
assertEq(native.balanceOf(USER), DEFAULT_NATIVE_MINT_QUANTITY - DEFAULT_REPORT_NATIVE_FEE);
+ assertEq(link.balanceOf(address(rewardManager)), DEFAULT_REPORT_LINK_FEE);
}
function test_verifyWithNativeUnwrapped() public {
- bytes memory signedReport = _generateEncodedBlobWithQuote(
- _generateV2Report(),
- _generateReportContext(FEED_ID_V3),
- _getSigners(FAULT_TOLERANCE + 1),
- _generateQuote(address(native))
+ bytes memory signedReport = _generateV3EncodedBlob(
+ _generateV3Report(),
+ _generateReportContext(v3ConfigDigest),
+ _getSigners(FAULT_TOLERANCE + 1)
);
- _verify(signedReport, DEFAULT_REPORT_NATIVE_FEE, USER);
+ _verify(signedReport, address(native), DEFAULT_REPORT_NATIVE_FEE, USER);
assertEq(USER.balance, DEFAULT_NATIVE_MINT_QUANTITY - DEFAULT_REPORT_NATIVE_FEE);
assertEq(address(feeManager).balance, 0);
}
function test_verifyWithNativeUnwrappedReturnsChange() public {
- bytes memory signedReport = _generateEncodedBlobWithQuote(
- _generateV2Report(),
- _generateReportContext(FEED_ID_V3),
- _getSigners(FAULT_TOLERANCE + 1),
- _generateQuote(address(native))
+ bytes memory signedReport = _generateV3EncodedBlob(
+ _generateV3Report(),
+ _generateReportContext(v3ConfigDigest),
+ _getSigners(FAULT_TOLERANCE + 1)
);
- _verify(signedReport, DEFAULT_REPORT_NATIVE_FEE * 2, USER);
+ _verify(signedReport, address(native), DEFAULT_REPORT_NATIVE_FEE * 2, USER);
assertEq(USER.balance, DEFAULT_NATIVE_MINT_QUANTITY - DEFAULT_REPORT_NATIVE_FEE);
assertEq(address(feeManager).balance, 0);
}
}
+
+contract VerifierBulkVerifyBillingReport is VerifierTestWithConfiguredVerifierAndFeeManager {
+ uint256 internal constant NUMBERS_OF_REPORTS = 5;
+
+ function test_verifyWithBulkLink() public {
+ bytes memory signedReport = _generateV3EncodedBlob(
+ _generateV3Report(),
+ _generateReportContext(v3ConfigDigest),
+ _getSigners(FAULT_TOLERANCE + 1)
+ );
+
+ bytes[] memory signedReports = new bytes[](NUMBERS_OF_REPORTS);
+ for (uint256 i = 0; i < NUMBERS_OF_REPORTS; i++) {
+ signedReports[i] = signedReport;
+ }
+
+ _approveLink(address(rewardManager), DEFAULT_REPORT_LINK_FEE * NUMBERS_OF_REPORTS, USER);
+
+ _verifyBulk(signedReports, address(link), 0, USER);
+
+ assertEq(link.balanceOf(USER), DEFAULT_LINK_MINT_QUANTITY - DEFAULT_REPORT_LINK_FEE * NUMBERS_OF_REPORTS);
+ assertEq(link.balanceOf(address(rewardManager)), DEFAULT_REPORT_LINK_FEE * NUMBERS_OF_REPORTS);
+ }
+
+ function test_verifyWithBulkNative() public {
+ bytes memory signedReport = _generateV3EncodedBlob(
+ _generateV3Report(),
+ _generateReportContext(v3ConfigDigest),
+ _getSigners(FAULT_TOLERANCE + 1)
+ );
+
+ bytes[] memory signedReports = new bytes[](NUMBERS_OF_REPORTS);
+ for (uint256 i = 0; i < NUMBERS_OF_REPORTS; i++) {
+ signedReports[i] = signedReport;
+ }
+
+ _approveNative(address(feeManager), DEFAULT_REPORT_NATIVE_FEE * NUMBERS_OF_REPORTS, USER);
+
+ _verifyBulk(signedReports, address(native), 0, USER);
+
+ assertEq(native.balanceOf(USER), DEFAULT_NATIVE_MINT_QUANTITY - DEFAULT_REPORT_NATIVE_FEE * NUMBERS_OF_REPORTS);
+ }
+
+ function test_verifyWithBulkNativeUnwrapped() public {
+ bytes memory signedReport = _generateV3EncodedBlob(
+ _generateV3Report(),
+ _generateReportContext(v3ConfigDigest),
+ _getSigners(FAULT_TOLERANCE + 1)
+ );
+
+ bytes[] memory signedReports = new bytes[](NUMBERS_OF_REPORTS);
+ for (uint256 i; i < NUMBERS_OF_REPORTS; i++) {
+ signedReports[i] = signedReport;
+ }
+
+ _verifyBulk(signedReports, address(native), DEFAULT_REPORT_NATIVE_FEE * NUMBERS_OF_REPORTS, USER);
+
+ assertEq(USER.balance, DEFAULT_NATIVE_MINT_QUANTITY - DEFAULT_REPORT_NATIVE_FEE * 5);
+ assertEq(address(feeManager).balance, 0);
+ }
+
+ function test_verifyWithBulkNativeUnwrappedReturnsChange() public {
+ bytes memory signedReport = _generateV3EncodedBlob(
+ _generateV3Report(),
+ _generateReportContext(v3ConfigDigest),
+ _getSigners(FAULT_TOLERANCE + 1)
+ );
+
+ bytes[] memory signedReports = new bytes[](NUMBERS_OF_REPORTS);
+ for (uint256 i = 0; i < NUMBERS_OF_REPORTS; i++) {
+ signedReports[i] = signedReport;
+ }
+
+ _verifyBulk(signedReports, address(native), DEFAULT_REPORT_NATIVE_FEE * (NUMBERS_OF_REPORTS * 2), USER);
+
+ assertEq(USER.balance, DEFAULT_NATIVE_MINT_QUANTITY - DEFAULT_REPORT_NATIVE_FEE * NUMBERS_OF_REPORTS);
+ assertEq(address(feeManager).balance, 0);
+ }
+
+ function test_verifyMultiVersions() public {
+ bytes memory signedReportV1 = _generateV1EncodedBlob(
+ _generateV1Report(),
+ _generateReportContext(v1ConfigDigest),
+ _getSigners(FAULT_TOLERANCE + 1)
+ );
+
+ bytes memory signedReportV3 = _generateV3EncodedBlob(
+ _generateV3Report(),
+ _generateReportContext(v3ConfigDigest),
+ _getSigners(FAULT_TOLERANCE + 1)
+ );
+
+ bytes[] memory signedReports = new bytes[](3);
+
+ signedReports[0] = signedReportV1;
+ signedReports[1] = signedReportV3;
+ signedReports[2] = signedReportV3;
+
+ _approveLink(address(rewardManager), 2 * DEFAULT_REPORT_LINK_FEE, USER);
+
+ _verifyBulk(signedReports, address(link), 0, USER);
+
+ assertEq(link.balanceOf(USER), DEFAULT_LINK_MINT_QUANTITY - 2 * DEFAULT_REPORT_LINK_FEE);
+ assertEq(native.balanceOf(USER), DEFAULT_NATIVE_MINT_QUANTITY);
+ assertEq(link.balanceOf(address(rewardManager)), DEFAULT_REPORT_LINK_FEE * 2);
+ }
+
+ function test_verifyMultiVersionsReturnsVerifiedReports() public {
+ bytes memory signedReportV1 = _generateV1EncodedBlob(
+ _generateV1Report(),
+ _generateReportContext(v1ConfigDigest),
+ _getSigners(FAULT_TOLERANCE + 1)
+ );
+
+ bytes memory signedReportV3 = _generateV3EncodedBlob(
+ _generateV3Report(),
+ _generateReportContext(v3ConfigDigest),
+ _getSigners(FAULT_TOLERANCE + 1)
+ );
+
+ bytes[] memory signedReports = new bytes[](3);
+
+ signedReports[0] = signedReportV1;
+ signedReports[1] = signedReportV3;
+ signedReports[2] = signedReportV3;
+
+ _approveLink(address(rewardManager), 2 * DEFAULT_REPORT_LINK_FEE, USER);
+
+ address originalAddr = msg.sender;
+ changePrank(USER);
+
+ bytes[] memory verifierReports = s_verifierProxy.verifyBulk{value: 0}(signedReports, abi.encode(link));
+
+ changePrank(originalAddr);
+
+ assertEq(verifierReports[0], _encodeReport(_generateV1Report()));
+ assertEq(verifierReports[1], _encodeReport(_generateV3Report()));
+ assertEq(verifierReports[2], _encodeReport(_generateV3Report()));
+ }
+}
diff --git a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierVerifyTest.t.sol b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierVerifyTest.t.sol
index 38bb86a663d..b4fcac75d3a 100644
--- a/contracts/src/v0.8/llo-feeds/test/verifier/VerifierVerifyTest.t.sol
+++ b/contracts/src/v0.8/llo-feeds/test/verifier/VerifierVerifyTest.t.sol
@@ -4,7 +4,7 @@ pragma solidity 0.8.16;
import {BaseTestWithConfiguredVerifierAndFeeManager} from "./BaseVerifierTest.t.sol";
import {Verifier} from "../../Verifier.sol";
import {VerifierProxy} from "../../VerifierProxy.sol";
-import {AccessControllerInterface} from "../../../interfaces/AccessControllerInterface.sol";
+import {AccessControllerInterface} from "../../../shared/interfaces/AccessControllerInterface.sol";
import {Common} from "../../../libraries/Common.sol";
contract VerifierVerifyTest is BaseTestWithConfiguredVerifierAndFeeManager {
@@ -12,14 +12,14 @@ contract VerifierVerifyTest is BaseTestWithConfiguredVerifierAndFeeManager {
event ReportVerified(bytes32 indexed feedId, address requester);
- V0Report internal s_testReportOne;
+ V1Report internal s_testReportOne;
function setUp() public virtual override {
BaseTestWithConfiguredVerifierAndFeeManager.setUp();
(, , bytes32 configDigest) = s_verifier.latestConfigDetails(FEED_ID);
s_reportContext[0] = configDigest;
s_reportContext[1] = bytes32(abi.encode(uint32(5), uint8(1)));
- s_testReportOne = _createV0Report(
+ s_testReportOne = _createV1Report(
FEED_ID,
OBSERVATIONS_TIMESTAMP,
MEDIAN,
@@ -32,7 +32,7 @@ contract VerifierVerifyTest is BaseTestWithConfiguredVerifierAndFeeManager {
);
}
- function assertReportsEqual(bytes memory response, V0Report memory testReport) public {
+ function assertReportsEqual(bytes memory response, V1Report memory testReport) public {
(
bytes32 feedId,
uint32 timestamp,
@@ -57,23 +57,23 @@ contract VerifierVerifyTest is BaseTestWithConfiguredVerifierAndFeeManager {
contract VerifierProxyVerifyTest is VerifierVerifyTest {
function test_revertsIfNoVerifierConfigured() public {
s_reportContext[0] = bytes32("corrupt-digest");
- bytes memory signedReport = _generateEncodedBlob(
+ bytes memory signedReport = _generateV1EncodedBlob(
s_testReportOne,
s_reportContext,
_getSigners(FAULT_TOLERANCE + 1)
);
vm.expectRevert(abi.encodeWithSelector(VerifierProxy.VerifierNotFound.selector, bytes32("corrupt-digest")));
- s_verifierProxy.verify(signedReport);
+ s_verifierProxy.verify(signedReport, bytes(""));
}
function test_proxiesToTheCorrectVerifier() public {
- bytes memory signedReport = _generateEncodedBlob(
+ bytes memory signedReport = _generateV1EncodedBlob(
s_testReportOne,
s_reportContext,
_getSigners(FAULT_TOLERANCE + 1)
);
- bytes memory response = s_verifierProxy.verify(signedReport);
+ bytes memory response = s_verifierProxy.verify(signedReport, abi.encode(native));
assertReportsEqual(response, s_testReportOne);
}
}
@@ -92,7 +92,7 @@ contract VerifierProxyAccessControlledVerificationTest is VerifierVerifyTest {
abi.encodeWithSelector(AccessControllerInterface.hasAccess.selector, USER),
abi.encode(false)
);
- bytes memory signedReport = _generateEncodedBlob(
+ bytes memory signedReport = _generateV1EncodedBlob(
s_testReportOne,
s_reportContext,
_getSigners(FAULT_TOLERANCE + 1)
@@ -100,7 +100,7 @@ contract VerifierProxyAccessControlledVerificationTest is VerifierVerifyTest {
vm.expectRevert(abi.encodeWithSelector(VerifierProxy.AccessForbidden.selector));
changePrank(USER);
- s_verifierProxy.verify(signedReport);
+ s_verifierProxy.verify(signedReport, abi.encode(native));
}
function test_proxiesToTheVerifierIfHasAccess() public {
@@ -110,21 +110,21 @@ contract VerifierProxyAccessControlledVerificationTest is VerifierVerifyTest {
abi.encode(true)
);
- bytes memory signedReport = _generateEncodedBlob(
+ bytes memory signedReport = _generateV1EncodedBlob(
s_testReportOne,
s_reportContext,
_getSigners(FAULT_TOLERANCE + 1)
);
changePrank(USER);
- bytes memory response = s_verifierProxy.verify(signedReport);
+ bytes memory response = s_verifierProxy.verify(signedReport, bytes(""));
assertReportsEqual(response, s_testReportOne);
}
}
contract VerifierVerifySingleConfigDigestTest is VerifierVerifyTest {
function test_revertsIfVerifiedByNonProxy() public {
- bytes memory signedReport = _generateEncodedBlob(
+ bytes memory signedReport = _generateV1EncodedBlob(
s_testReportOne,
s_reportContext,
_getSigners(FAULT_TOLERANCE + 1)
@@ -136,7 +136,7 @@ contract VerifierVerifySingleConfigDigestTest is VerifierVerifyTest {
function test_revertsIfVerifiedWithIncorrectAddresses() public {
Signer[] memory signers = _getSigners(FAULT_TOLERANCE + 1);
signers[10].mockPrivateKey = 1234;
- bytes memory signedReport = _generateEncodedBlob(s_testReportOne, s_reportContext, signers);
+ bytes memory signedReport = _generateV1EncodedBlob(s_testReportOne, s_reportContext, signers);
changePrank(address(s_verifierProxy));
vm.expectRevert(abi.encodeWithSelector(Verifier.BadVerification.selector));
s_verifier.verify(signedReport, msg.sender);
@@ -155,14 +155,18 @@ contract VerifierVerifySingleConfigDigestTest is VerifierVerifyTest {
function test_revertsIfConfigDigestNotSet() public {
bytes32[3] memory reportContext = s_reportContext;
reportContext[0] = bytes32("wrong-context-digest");
- bytes memory signedReport = _generateEncodedBlob(s_testReportOne, reportContext, _getSigners(FAULT_TOLERANCE + 1));
+ bytes memory signedReport = _generateV1EncodedBlob(
+ s_testReportOne,
+ reportContext,
+ _getSigners(FAULT_TOLERANCE + 1)
+ );
vm.expectRevert(abi.encodeWithSelector(Verifier.DigestInactive.selector, FEED_ID, reportContext[0]));
changePrank(address(s_verifierProxy));
s_verifier.verify(signedReport, msg.sender);
}
function test_revertsIfReportHasUnconfiguredFeedID() public {
- V0Report memory report = _createV0Report(
+ V1Report memory report = _createV1Report(
FEED_ID_2,
OBSERVATIONS_TIMESTAMP,
MEDIAN,
@@ -173,14 +177,14 @@ contract VerifierVerifySingleConfigDigestTest is VerifierVerifyTest {
BLOCKNUMBER_LOWER_BOUND,
uint32(block.timestamp)
);
- bytes memory signedReport = _generateEncodedBlob(report, s_reportContext, _getSigners(FAULT_TOLERANCE + 1));
+ bytes memory signedReport = _generateV1EncodedBlob(report, s_reportContext, _getSigners(FAULT_TOLERANCE + 1));
vm.expectRevert(abi.encodeWithSelector(Verifier.DigestInactive.selector, FEED_ID_2, s_reportContext[0]));
changePrank(address(s_verifierProxy));
s_verifier.verify(signedReport, msg.sender);
}
function test_revertsIfWrongNumberOfSigners() public {
- bytes memory signedReport = _generateEncodedBlob(s_testReportOne, s_reportContext, _getSigners(10));
+ bytes memory signedReport = _generateV1EncodedBlob(s_testReportOne, s_reportContext, _getSigners(10));
vm.expectRevert(abi.encodeWithSelector(Verifier.IncorrectSignatureCount.selector, 10, FAULT_TOLERANCE + 1));
changePrank(address(s_verifierProxy));
s_verifier.verify(signedReport, msg.sender);
@@ -190,14 +194,14 @@ contract VerifierVerifySingleConfigDigestTest is VerifierVerifyTest {
Signer[] memory signers = _getSigners(FAULT_TOLERANCE + 1);
// Duplicate signer at index 1
signers[0] = signers[1];
- bytes memory signedReport = _generateEncodedBlob(s_testReportOne, s_reportContext, signers);
+ bytes memory signedReport = _generateV1EncodedBlob(s_testReportOne, s_reportContext, signers);
vm.expectRevert(abi.encodeWithSelector(Verifier.BadVerification.selector));
changePrank(address(s_verifierProxy));
s_verifier.verify(signedReport, msg.sender);
}
function test_returnsThePriceAndBlockNumIfReportVerified() public {
- bytes memory signedReport = _generateEncodedBlob(
+ bytes memory signedReport = _generateV1EncodedBlob(
s_testReportOne,
s_reportContext,
_getSigners(FAULT_TOLERANCE + 1)
@@ -210,7 +214,7 @@ contract VerifierVerifySingleConfigDigestTest is VerifierVerifyTest {
function test_setsTheCorrectEpoch() public {
s_reportContext[1] = bytes32(uint256(5 << 8));
- bytes memory signedReport = _generateEncodedBlob(
+ bytes memory signedReport = _generateV1EncodedBlob(
s_testReportOne,
s_reportContext,
_getSigners(FAULT_TOLERANCE + 1)
@@ -223,7 +227,7 @@ contract VerifierVerifySingleConfigDigestTest is VerifierVerifyTest {
}
function test_emitsAnEventIfReportVerified() public {
- bytes memory signedReport = _generateEncodedBlob(
+ bytes memory signedReport = _generateV1EncodedBlob(
s_testReportOne,
s_reportContext,
_getSigners(FAULT_TOLERANCE + 1)
@@ -260,7 +264,7 @@ contract VerifierVerifyMultipleConfigDigestTest is VerifierVerifyTest {
function test_revertsIfVerifyingWithAnUnsetDigest() public {
s_verifier.deactivateConfig(FEED_ID, (s_oldConfigDigest));
- bytes memory signedReport = _generateEncodedBlob(
+ bytes memory signedReport = _generateV1EncodedBlob(
s_testReportOne,
s_reportContext,
_getSigners(FAULT_TOLERANCE + 1)
@@ -271,7 +275,7 @@ contract VerifierVerifyMultipleConfigDigestTest is VerifierVerifyTest {
}
function test_canVerifyOlderReportsWithOlderConfigs() public {
- bytes memory signedReport = _generateEncodedBlob(
+ bytes memory signedReport = _generateV1EncodedBlob(
s_testReportOne,
s_reportContext,
_getSigners(FAULT_TOLERANCE + 1)
@@ -283,7 +287,7 @@ contract VerifierVerifyMultipleConfigDigestTest is VerifierVerifyTest {
function test_canVerifyNewerReportsWithNewerConfigs() public {
s_reportContext[0] = s_newConfigDigest;
- bytes memory signedReport = _generateEncodedBlob(
+ bytes memory signedReport = _generateV1EncodedBlob(
s_testReportOne,
s_reportContext,
_getSigners(FAULT_TOLERANCE_TWO + 1)
@@ -296,7 +300,7 @@ contract VerifierVerifyMultipleConfigDigestTest is VerifierVerifyTest {
function test_revertsIfAReportIsVerifiedWithAnExistingButIncorrectDigest() public {
// Try sending the older digest signed with the new set of signers
s_reportContext[0] = s_oldConfigDigest;
- bytes memory signedReport = _generateEncodedBlob(
+ bytes memory signedReport = _generateV1EncodedBlob(
s_testReportOne,
s_reportContext,
_getSigners(FAULT_TOLERANCE_TWO + 1)
diff --git a/contracts/src/v0.8/mocks/VRFCoordinatorV2Mock.sol b/contracts/src/v0.8/mocks/VRFCoordinatorV2Mock.sol
index 8dfb0dca7c5..a263a3be500 100644
--- a/contracts/src/v0.8/mocks/VRFCoordinatorV2Mock.sol
+++ b/contracts/src/v0.8/mocks/VRFCoordinatorV2Mock.sol
@@ -5,8 +5,9 @@ pragma solidity ^0.8.4;
import "../shared/interfaces/LinkTokenInterface.sol";
import "../interfaces/VRFCoordinatorV2Interface.sol";
import "../vrf/VRFConsumerBaseV2.sol";
+import "../shared/access/ConfirmedOwner.sol";
-contract VRFCoordinatorV2Mock is VRFCoordinatorV2Interface {
+contract VRFCoordinatorV2Mock is VRFCoordinatorV2Interface, ConfirmedOwner {
uint96 public immutable BASE_FEE;
uint96 public immutable GAS_PRICE_LINK;
uint16 public immutable MAX_CONSUMERS = 100;
@@ -17,6 +18,7 @@ contract VRFCoordinatorV2Mock is VRFCoordinatorV2Interface {
error TooManyConsumers();
error InvalidConsumer();
error InvalidRandomWords();
+ error Reentrant();
event RandomWordsRequested(
bytes32 indexed keyHash,
@@ -34,7 +36,13 @@ contract VRFCoordinatorV2Mock is VRFCoordinatorV2Interface {
event SubscriptionCanceled(uint64 indexed subId, address to, uint256 amount);
event ConsumerAdded(uint64 indexed subId, address consumer);
event ConsumerRemoved(uint64 indexed subId, address consumer);
+ event ConfigSet();
+ struct Config {
+ // Reentrancy protection.
+ bool reentrancyLock;
+ }
+ Config private s_config;
uint64 s_currentSubId;
uint256 s_nextRequestId = 1;
uint256 s_nextPreSeed = 100;
@@ -52,9 +60,18 @@ contract VRFCoordinatorV2Mock is VRFCoordinatorV2Interface {
}
mapping(uint256 => Request) s_requests; /* requestId */ /* request */
- constructor(uint96 _baseFee, uint96 _gasPriceLink) {
+ constructor(uint96 _baseFee, uint96 _gasPriceLink) ConfirmedOwner(msg.sender) {
BASE_FEE = _baseFee;
GAS_PRICE_LINK = _gasPriceLink;
+ setConfig();
+ }
+
+ /**
+ * @notice Sets the configuration of the vrfv2 mock coordinator
+ */
+ function setConfig() public onlyOwner {
+ s_config = Config({reentrancyLock: false});
+ emit ConfigSet();
}
function consumerIsAdded(uint64 _subId, address _consumer) public view returns (bool) {
@@ -85,7 +102,7 @@ contract VRFCoordinatorV2Mock is VRFCoordinatorV2Interface {
* @param _requestId the request to fulfill
* @param _consumer the VRF randomness consumer to send the result to
*/
- function fulfillRandomWords(uint256 _requestId, address _consumer) external {
+ function fulfillRandomWords(uint256 _requestId, address _consumer) external nonReentrant {
fulfillRandomWordsWithOverride(_requestId, _consumer, new uint256[](0));
}
@@ -114,7 +131,9 @@ contract VRFCoordinatorV2Mock is VRFCoordinatorV2Interface {
VRFConsumerBaseV2 v;
bytes memory callReq = abi.encodeWithSelector(v.rawFulfillRandomWords.selector, _requestId, _words);
+ s_config.reentrancyLock = true;
(bool success, ) = _consumer.call{gas: req.callbackGasLimit}(callReq);
+ s_config.reentrancyLock = false;
uint96 payment = uint96(BASE_FEE + ((startGas - gasleft()) * GAS_PRICE_LINK));
if (s_subscriptions[req.subId].balance < payment) {
@@ -146,7 +165,7 @@ contract VRFCoordinatorV2Mock is VRFCoordinatorV2Interface {
uint16 _minimumRequestConfirmations,
uint32 _callbackGasLimit,
uint32 _numWords
- ) external override onlyValidConsumer(_subId, msg.sender) returns (uint256) {
+ ) external override nonReentrant onlyValidConsumer(_subId, msg.sender) returns (uint256) {
if (s_subscriptions[_subId].owner == address(0)) {
revert InvalidSubscription();
}
@@ -185,7 +204,7 @@ contract VRFCoordinatorV2Mock is VRFCoordinatorV2Interface {
return (s_subscriptions[_subId].balance, 0, s_subscriptions[_subId].owner, s_consumers[_subId]);
}
- function cancelSubscription(uint64 _subId, address _to) external override onlySubOwner(_subId) {
+ function cancelSubscription(uint64 _subId, address _to) external override onlySubOwner(_subId) nonReentrant {
emit SubscriptionCanceled(_subId, _to, s_subscriptions[_subId].balance);
delete (s_subscriptions[_subId]);
}
@@ -221,7 +240,7 @@ contract VRFCoordinatorV2Mock is VRFCoordinatorV2Interface {
function removeConsumer(
uint64 _subId,
address _consumer
- ) external override onlySubOwner(_subId) onlyValidConsumer(_subId, _consumer) {
+ ) external override onlySubOwner(_subId) onlyValidConsumer(_subId, _consumer) nonReentrant {
address[] storage consumers = s_consumers[_subId];
for (uint256 i = 0; i < consumers.length; i++) {
if (consumers[i] == _consumer) {
@@ -237,7 +256,7 @@ contract VRFCoordinatorV2Mock is VRFCoordinatorV2Interface {
function getConfig()
external
- view
+ pure
returns (
uint16 minimumRequestConfirmations,
uint32 maxGasLimit,
@@ -250,7 +269,7 @@ contract VRFCoordinatorV2Mock is VRFCoordinatorV2Interface {
function getFeeConfig()
external
- view
+ pure
returns (
uint32 fulfillmentFlatFeeLinkPPMTier1,
uint32 fulfillmentFlatFeeLinkPPMTier2,
@@ -276,19 +295,26 @@ contract VRFCoordinatorV2Mock is VRFCoordinatorV2Interface {
);
}
- function getFallbackWeiPerUnitLink() external view returns (int256) {
+ modifier nonReentrant() {
+ if (s_config.reentrancyLock) {
+ revert Reentrant();
+ }
+ _;
+ }
+
+ function getFallbackWeiPerUnitLink() external pure returns (int256) {
return 4000000000000000; // 0.004 Ether
}
- function requestSubscriptionOwnerTransfer(uint64 _subId, address _newOwner) external pure override {
+ function requestSubscriptionOwnerTransfer(uint64 /*_subId*/, address /*_newOwner*/) external pure override {
revert("not implemented");
}
- function acceptSubscriptionOwnerTransfer(uint64 _subId) external pure override {
+ function acceptSubscriptionOwnerTransfer(uint64 /*_subId*/) external pure override {
revert("not implemented");
}
- function pendingRequestExists(uint64 subId) public view override returns (bool) {
+ function pendingRequestExists(uint64 /*subId*/) public pure override returns (bool) {
revert("not implemented");
}
}
diff --git a/contracts/src/v0.8/SimpleReadAccessController.sol b/contracts/src/v0.8/shared/access/SimpleReadAccessController.sol
similarity index 100%
rename from contracts/src/v0.8/SimpleReadAccessController.sol
rename to contracts/src/v0.8/shared/access/SimpleReadAccessController.sol
diff --git a/contracts/src/v0.8/SimpleWriteAccessController.sol b/contracts/src/v0.8/shared/access/SimpleWriteAccessController.sol
similarity index 95%
rename from contracts/src/v0.8/SimpleWriteAccessController.sol
rename to contracts/src/v0.8/shared/access/SimpleWriteAccessController.sol
index 75459173989..c73dec470b2 100644
--- a/contracts/src/v0.8/SimpleWriteAccessController.sol
+++ b/contracts/src/v0.8/shared/access/SimpleWriteAccessController.sol
@@ -1,8 +1,8 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
-import "./shared/access/ConfirmedOwner.sol";
-import "./interfaces/AccessControllerInterface.sol";
+import "./ConfirmedOwner.sol";
+import "../interfaces/AccessControllerInterface.sol";
/**
* @title SimpleWriteAccessController
diff --git a/contracts/src/v0.8/interfaces/AccessControllerInterface.sol b/contracts/src/v0.8/shared/interfaces/AccessControllerInterface.sol
similarity index 100%
rename from contracts/src/v0.8/interfaces/AccessControllerInterface.sol
rename to contracts/src/v0.8/shared/interfaces/AccessControllerInterface.sol
diff --git a/contracts/src/v0.8/tests/MercuryUpkeep.sol b/contracts/src/v0.8/tests/MercuryUpkeep.sol
deleted file mode 100644
index cf3ca6be519..00000000000
--- a/contracts/src/v0.8/tests/MercuryUpkeep.sol
+++ /dev/null
@@ -1,119 +0,0 @@
-pragma solidity 0.8.16;
-
-import "../automation/interfaces/AutomationCompatibleInterface.sol";
-import "../dev/automation/2_1/interfaces/FeedLookupCompatibleInterface.sol";
-import {ArbSys} from "../vendor/@arbitrum/nitro-contracts/src/precompiles/ArbSys.sol";
-
-//interface IVerifierProxy {
-// /**
-// * @notice Verifies that the data encoded has been signed
-// * correctly by routing to the correct verifier.
-// * @param signedReport The encoded data to be verified.
-// * @return verifierResponse The encoded response from the verifier.
-// */
-// function verify(bytes memory signedReport) external returns (bytes memory verifierResponse);
-//}
-
-contract MercuryUpkeep is AutomationCompatibleInterface, FeedLookupCompatibleInterface {
- event MercuryPerformEvent(
- address indexed origin,
- address indexed sender,
- uint256 indexed blockNumber,
- bytes v0,
- bytes v1,
- bytes ed
- );
-
- ArbSys internal constant ARB_SYS = ArbSys(0x0000000000000000000000000000000000000064);
- // IVerifierProxy internal constant VERIFIER = IVerifierProxy(0xa4D813064dc6E2eFfaCe02a060324626d4C5667f);
-
- uint256 public testRange;
- uint256 public interval;
- uint256 public previousPerformBlock;
- uint256 public initialBlock;
- uint256 public counter;
- string[] public feeds;
- string public feedParamKey;
- string public timeParamKey;
- bool public immutable useL1BlockNumber;
- bool public shouldRevertCallback;
- bool public callbackReturnBool;
-
- constructor(uint256 _testRange, uint256 _interval, bool _useL1BlockNumber) {
- testRange = _testRange;
- interval = _interval;
- previousPerformBlock = 0;
- initialBlock = 0;
- counter = 0;
- feedParamKey = "feedIdHex"; // feedIDStr is deprecated
- feeds = [
- "0x4554482d5553442d415242495452554d2d544553544e45540000000000000000",
- "0x4254432d5553442d415242495452554d2d544553544e45540000000000000000"
- ];
- timeParamKey = "blockNumber"; // timestamp not supported yet
- useL1BlockNumber = _useL1BlockNumber;
- callbackReturnBool = true;
- }
-
- function setShouldRevertCallback(bool value) public {
- shouldRevertCallback = value;
- }
-
- function setCallbackReturnBool(bool value) public {
- callbackReturnBool = value;
- }
-
- function checkCallback(bytes[] memory values, bytes memory extraData) external view returns (bool, bytes memory) {
- require(!shouldRevertCallback, "shouldRevertCallback is true");
- // do sth about the chainlinkBlob data in values and extraData
- bytes memory performData = abi.encode(values, extraData);
- return (callbackReturnBool, performData);
- }
-
- function checkUpkeep(bytes calldata data) external view returns (bool, bytes memory) {
- if (!eligible()) {
- return (false, data);
- }
- uint256 blockNumber;
- if (useL1BlockNumber) {
- blockNumber = block.number;
- } else {
- blockNumber = ARB_SYS.arbBlockNumber();
- }
- // encode ARB_SYS as extraData to verify that it is provided to checkCallback correctly.
- // in reality, this can be any data or empty
- revert FeedLookup(feedParamKey, feeds, timeParamKey, blockNumber, abi.encodePacked(address(ARB_SYS)));
- }
-
- function performUpkeep(bytes calldata performData) external {
- uint256 blockNumber;
- if (useL1BlockNumber) {
- blockNumber = block.number;
- } else {
- blockNumber = ARB_SYS.arbBlockNumber();
- }
- if (initialBlock == 0) {
- initialBlock = blockNumber;
- }
- (bytes[] memory values, bytes memory extraData) = abi.decode(performData, (bytes[], bytes));
- previousPerformBlock = blockNumber;
- counter = counter + 1;
- // bytes memory v0 = VERIFIER.verify(values[0]);
- // bytes memory v1 = VERIFIER.verify(values[1]);
- emit MercuryPerformEvent(tx.origin, msg.sender, blockNumber, values[0], values[1], extraData);
- }
-
- function eligible() public view returns (bool) {
- if (initialBlock == 0) {
- return true;
- }
-
- uint256 blockNumber;
- if (useL1BlockNumber) {
- blockNumber = block.number;
- } else {
- blockNumber = ARB_SYS.arbBlockNumber();
- }
- return (blockNumber - initialBlock) < testRange && (blockNumber - previousPerformBlock) >= interval;
- }
-}
diff --git a/contracts/src/v0.8/tests/StreamsLookupUpkeep.sol b/contracts/src/v0.8/tests/StreamsLookupUpkeep.sol
new file mode 100644
index 00000000000..69729a189e2
--- /dev/null
+++ b/contracts/src/v0.8/tests/StreamsLookupUpkeep.sol
@@ -0,0 +1,151 @@
+pragma solidity 0.8.16;
+
+import "../automation/interfaces/AutomationCompatibleInterface.sol";
+import "../automation/interfaces/StreamsLookupCompatibleInterface.sol";
+import {ArbSys} from "../vendor/@arbitrum/nitro-contracts/src/precompiles/ArbSys.sol";
+
+interface IVerifierProxy {
+ /**
+ * @notice Verifies that the data encoded has been signed
+ * correctly by routing to the correct verifier.
+ * @param signedReport The encoded data to be verified.
+ * @return verifierResponse The encoded response from the verifier.
+ */
+ function verify(bytes memory signedReport) external returns (bytes memory verifierResponse);
+}
+
+contract StreamsLookupUpkeep is AutomationCompatibleInterface, StreamsLookupCompatibleInterface {
+ event MercuryPerformEvent(address indexed sender, uint256 indexed blockNumber, bytes v0, bytes verifiedV0, bytes ed);
+
+ ArbSys internal constant ARB_SYS = ArbSys(0x0000000000000000000000000000000000000064);
+ // keep these in sync with verifier proxy in RDD
+ IVerifierProxy internal constant PRODUCTION_TESTNET_VERIFIER_PROXY =
+ IVerifierProxy(0x09DFf56A4fF44e0f4436260A04F5CFa65636A481);
+ IVerifierProxy internal constant STAGING_TESTNET_VERIFIER_PROXY =
+ IVerifierProxy(0x60448B880c9f3B501af3f343DA9284148BD7D77C);
+
+ uint256 public testRange;
+ uint256 public interval;
+ uint256 public previousPerformBlock;
+ uint256 public initialBlock;
+ uint256 public counter;
+ string[] public feeds;
+ string public feedParamKey;
+ string public timeParamKey;
+ bool public immutable useArbBlock;
+ bool public staging;
+ bool public verify;
+ bool public shouldRevertCallback;
+ bool public callbackReturnBool;
+
+ constructor(uint256 _testRange, uint256 _interval, bool _useArbBlock, bool _staging, bool _verify) {
+ testRange = _testRange;
+ interval = _interval;
+ previousPerformBlock = 0;
+ initialBlock = 0;
+ counter = 0;
+ useArbBlock = _useArbBlock;
+ feedParamKey = "feedIDs"; // feedIDs for v0.3
+ timeParamKey = "timestamp"; // timestamp
+ // search feeds in notion: "Schema and Feed ID Registry"
+ feeds = [
+ //"0x4554482d5553442d415242495452554d2d544553544e45540000000000000000", // ETH / USD in production testnet v0.2
+ //"0x4254432d5553442d415242495452554d2d544553544e45540000000000000000" // BTC / USD in production testnet v0.2
+ "0x00028c915d6af0fd66bba2d0fc9405226bca8d6806333121a7d9832103d1563c" // ETH / USD in staging testnet v0.3
+ ];
+ staging = _staging;
+ verify = _verify;
+ callbackReturnBool = true;
+ }
+
+ function setParamKeys(string memory _feedParamKey, string memory _timeParamKey) external {
+ feedParamKey = _feedParamKey;
+ timeParamKey = _timeParamKey;
+ }
+
+ function setFeeds(string[] memory _feeds) external {
+ feeds = _feeds;
+ }
+
+ function setShouldRevertCallback(bool value) public {
+ shouldRevertCallback = value;
+ }
+
+ function setCallbackReturnBool(bool value) public {
+ callbackReturnBool = value;
+ }
+
+ function reset() public {
+ previousPerformBlock = 0;
+ initialBlock = 0;
+ counter = 0;
+ }
+
+ function checkCallback(bytes[] memory values, bytes memory extraData) external view returns (bool, bytes memory) {
+ require(!shouldRevertCallback, "shouldRevertCallback is true");
+ // do sth about the chainlinkBlob data in values and extraData
+ bytes memory performData = abi.encode(values, extraData);
+ return (callbackReturnBool, performData);
+ }
+
+ function checkUpkeep(bytes calldata data) external view returns (bool, bytes memory) {
+ if (!eligible()) {
+ return (false, data);
+ }
+ uint256 timeParam;
+ if (keccak256(abi.encodePacked(feedParamKey)) == keccak256(abi.encodePacked("feedIdHex"))) {
+ if (useArbBlock) {
+ timeParam = ARB_SYS.arbBlockNumber();
+ } else {
+ timeParam = block.number;
+ }
+ } else {
+ // assume this will be feedIDs for v0.3
+ timeParam = block.timestamp;
+ }
+
+ // encode ARB_SYS as extraData to verify that it is provided to checkCallback correctly.
+ // in reality, this can be any data or empty
+ revert StreamsLookup(feedParamKey, feeds, timeParamKey, timeParam, abi.encodePacked(address(ARB_SYS)));
+ }
+
+ function performUpkeep(bytes calldata performData) external {
+ uint256 blockNumber;
+ if (useArbBlock) {
+ blockNumber = ARB_SYS.arbBlockNumber();
+ } else {
+ blockNumber = block.number;
+ }
+ if (initialBlock == 0) {
+ initialBlock = blockNumber;
+ }
+ (bytes[] memory values, bytes memory extraData) = abi.decode(performData, (bytes[], bytes));
+ previousPerformBlock = blockNumber;
+ counter = counter + 1;
+
+ bytes memory v0 = "";
+ bytes memory v1 = "";
+ if (verify) {
+ if (staging) {
+ v0 = STAGING_TESTNET_VERIFIER_PROXY.verify(values[0]);
+ } else {
+ v0 = PRODUCTION_TESTNET_VERIFIER_PROXY.verify(values[0]);
+ }
+ }
+ emit MercuryPerformEvent(msg.sender, blockNumber, values[0], v0, extraData);
+ }
+
+ function eligible() public view returns (bool) {
+ if (initialBlock == 0) {
+ return true;
+ }
+
+ uint256 blockNumber;
+ if (useArbBlock) {
+ blockNumber = ARB_SYS.arbBlockNumber();
+ } else {
+ blockNumber = block.number;
+ }
+ return (blockNumber - initialBlock) < testRange && (blockNumber - previousPerformBlock) >= interval;
+ }
+}
diff --git a/contracts/src/v0.8/tests/VerifiableLoadBase.sol b/contracts/src/v0.8/tests/VerifiableLoadBase.sol
index 03f581dab1d..1b51ed303ae 100644
--- a/contracts/src/v0.8/tests/VerifiableLoadBase.sol
+++ b/contracts/src/v0.8/tests/VerifiableLoadBase.sol
@@ -2,23 +2,23 @@
pragma solidity ^0.8.16;
import "../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/structs/EnumerableSet.sol";
-import "../dev/automation/2_1/interfaces/IKeeperRegistryMaster.sol";
+import "../automation/interfaces/v2_1/IKeeperRegistryMaster.sol";
import {ArbSys} from "../vendor/@arbitrum/nitro-contracts/src/precompiles/ArbSys.sol";
-import "../dev/automation/2_1/AutomationRegistrar2_1.sol";
-import {LogTriggerConfig} from "../dev/automation/2_1/AutomationUtils2_1.sol";
+import "../automation/v2_1/AutomationRegistrar2_1.sol";
+import {LogTriggerConfig} from "../automation/v2_1/AutomationUtils2_1.sol";
abstract contract VerifiableLoadBase is ConfirmedOwner {
error IndexOutOfRange();
-
- event LogEmitted(uint256 indexed upkeepId, uint256 indexed blockNum, address addr);
- event UpkeepsRegistered(uint256[] upkeepIds);
+ event LogEmitted(uint256 indexed upkeepId, uint256 indexed blockNum, address indexed addr);
+ event LogEmittedAgain(uint256 indexed upkeepId, uint256 indexed blockNum, address indexed addr);
event UpkeepTopUp(uint256 upkeepId, uint96 amount, uint256 blockNum);
- event Received(address sender, uint256 value);
using EnumerableSet for EnumerableSet.UintSet;
ArbSys internal constant ARB_SYS = ArbSys(0x0000000000000000000000000000000000000064);
//bytes32 public constant emittedSig = 0x97009585a4d2440f981ab6f6eec514343e1e6b2aa9b991a26998e6806f41bf08; //keccak256(LogEmitted(uint256,uint256,address))
bytes32 public immutable emittedSig = LogEmitted.selector;
+ // bytes32 public constant emittedAgainSig = 0xc76416badc8398ce17c93eab7b4f60f263241694cf503e4df24f233a8cc1c50d; //keccak256(LogEmittedAgain(uint256,uint256,address))
+ bytes32 public immutable emittedAgainSig = LogEmittedAgain.selector;
mapping(uint256 => uint256) public lastTopUpBlocks;
mapping(uint256 => uint256) public intervals;
@@ -51,6 +51,14 @@ abstract contract VerifiableLoadBase is ConfirmedOwner {
// different sizes of buckets. it's better to redeploy this contract with new values.
uint16 public immutable BUCKET_SIZE = 100;
+ // search feeds in notion: "Schema and Feed ID Registry"
+ string[] public feedsHex = [
+ "0x4554482d5553442d415242495452554d2d544553544e45540000000000000000",
+ "0x4254432d5553442d415242495452554d2d544553544e45540000000000000000"
+ ];
+ string public feedParamKey = "feedIdHex"; // feedIDs for v0.3
+ string public timeParamKey = "blockNumber"; // timestamp for v0.3
+
/**
* @param _registrar a automation registrar 2.1 address
* @param _useArb if this contract will use arbitrum block number
@@ -63,8 +71,15 @@ abstract contract VerifiableLoadBase is ConfirmedOwner {
useArbitrumBlockNum = _useArb;
}
- receive() external payable {
- emit Received(msg.sender, msg.value);
+ receive() external payable {}
+
+ function setParamKeys(string memory _feedParamKey, string memory _timeParamKey) external {
+ feedParamKey = _feedParamKey;
+ timeParamKey = _timeParamKey;
+ }
+
+ function setFeeds(string[] memory _feeds) external {
+ feedsHex = _feeds;
}
/**
@@ -100,7 +115,10 @@ abstract contract VerifiableLoadBase is ConfirmedOwner {
* @param maxCount the max number of upkeep IDs requested
* @return an array of active upkeep IDs
*/
- function getActiveUpkeepIDs(uint256 startIndex, uint256 maxCount) external view returns (uint256[] memory) {
+ function getActiveUpkeepIDsDeployedByThisContract(
+ uint256 startIndex,
+ uint256 maxCount
+ ) external view returns (uint256[] memory) {
uint256 maxIdx = s_upkeepIDs.length();
if (startIndex >= maxIdx) revert IndexOutOfRange();
if (maxCount == 0) {
@@ -113,6 +131,19 @@ abstract contract VerifiableLoadBase is ConfirmedOwner {
return ids;
}
+ /**
+ * @notice gets an array of active upkeep IDs.
+ * @param startIndex the start index of upkeep IDs
+ * @param maxCount the max number of upkeep IDs requested
+ * @return an array of active upkeep IDs
+ */
+ function getAllActiveUpkeepIDsOnRegistry(
+ uint256 startIndex,
+ uint256 maxCount
+ ) external view returns (uint256[] memory) {
+ return registry.getActiveUpkeepIDs(startIndex, maxCount);
+ }
+
/**
* @notice register an upkeep via the registrar.
* @param params a registration params struct
@@ -125,18 +156,96 @@ abstract contract VerifiableLoadBase is ConfirmedOwner {
return upkeepId;
}
- function getLogTriggerConfig(uint256 upkeepId) external view returns (bytes memory logTrigger) {
+ /**
+ * @notice returns a log trigger config
+ */
+ function getLogTriggerConfig(
+ address addr,
+ uint8 selector,
+ bytes32 topic0,
+ bytes32 topic1,
+ bytes32 topic2,
+ bytes32 topic3
+ ) external view returns (bytes memory logTrigger) {
LogTriggerConfig memory cfg = LogTriggerConfig({
- contractAddress: address(this),
- filterSelector: 1, // only filter by topic1
- topic0: emittedSig,
- topic1: bytes32(abi.encode(upkeepId)),
- topic2: 0x000000000000000000000000000000000000000000000000000000000000000,
- topic3: 0x000000000000000000000000000000000000000000000000000000000000000
+ contractAddress: addr,
+ filterSelector: selector,
+ topic0: topic0,
+ topic1: topic1,
+ topic2: topic2,
+ topic3: topic3
});
return abi.encode(cfg);
}
+ // this function sets pipeline data and trigger config for log trigger upkeeps
+ function batchPreparingUpkeeps(
+ uint256[] calldata upkeepIds,
+ uint8 selector,
+ bytes32 topic0,
+ bytes32 topic1,
+ bytes32 topic2,
+ bytes32 topic3
+ ) external {
+ uint256 len = upkeepIds.length;
+ for (uint256 i = 0; i < len; i++) {
+ uint256 upkeepId = upkeepIds[i];
+
+ this.updateUpkeepPipelineData(upkeepId, abi.encode(upkeepId));
+
+ uint8 triggerType = registry.getTriggerType(upkeepId);
+ if (triggerType == 1) {
+ // currently no using a filter selector
+ bytes memory triggerCfg = this.getLogTriggerConfig(address(this), selector, topic0, topic2, topic2, topic3);
+ registry.setUpkeepTriggerConfig(upkeepId, triggerCfg);
+ }
+ }
+ }
+
+ // this function sets pipeline data and trigger config for log trigger upkeeps
+ function batchPreparingUpkeepsSimple(uint256[] calldata upkeepIds, uint8 log, uint8 selector) external {
+ uint256 len = upkeepIds.length;
+ for (uint256 i = 0; i < len; i++) {
+ uint256 upkeepId = upkeepIds[i];
+
+ this.updateUpkeepPipelineData(upkeepId, abi.encode(upkeepId));
+
+ uint8 triggerType = registry.getTriggerType(upkeepId);
+ if (triggerType == 1) {
+ // currently no using a filter selector
+ bytes32 sig = emittedSig;
+ if (log != 0) {
+ sig = emittedAgainSig;
+ }
+ bytes memory triggerCfg = this.getLogTriggerConfig(
+ address(this),
+ selector,
+ sig,
+ bytes32(abi.encode(upkeepId)),
+ bytes32(0),
+ bytes32(0)
+ );
+ registry.setUpkeepTriggerConfig(upkeepId, triggerCfg);
+ }
+ }
+ }
+
+ function updateLogTriggerConfig1(
+ uint256 upkeepId,
+ address addr,
+ uint8 selector,
+ bytes32 topic0,
+ bytes32 topic1,
+ bytes32 topic2,
+ bytes32 topic3
+ ) external {
+ registry.setUpkeepTriggerConfig(upkeepId, this.getLogTriggerConfig(addr, selector, topic0, topic1, topic2, topic3));
+ }
+
+ function updateLogTriggerConfig2(uint256 upkeepId, bytes calldata cfg) external {
+ registry.setUpkeepTriggerConfig(upkeepId, cfg);
+ }
+
/**
* @notice batch registering upkeeps.
* @param number the number of upkeeps to be registered
@@ -174,15 +283,10 @@ abstract contract VerifiableLoadBase is ConfirmedOwner {
uint256[] memory upkeepIds = new uint256[](number);
for (uint8 i = 0; i < number; i++) {
uint256 upkeepId = _registerUpkeep(params);
- if (triggerType == 1) {
- bytes memory triggerCfg = this.getLogTriggerConfig(upkeepId);
- registry.setUpkeepTriggerConfig(upkeepId, triggerCfg);
- }
upkeepIds[i] = upkeepId;
checkGasToBurns[upkeepId] = checkGasToBurn;
performGasToBurns[upkeepId] = performGasToBurn;
}
- emit UpkeepsRegistered(upkeepIds);
}
function topUpFund(uint256 upkeepId, uint256 blockNum) public {
@@ -197,6 +301,22 @@ abstract contract VerifiableLoadBase is ConfirmedOwner {
}
}
+ function getMinBalanceForUpkeep(uint256 upkeepId) external view returns (uint96) {
+ return registry.getMinBalanceForUpkeep(upkeepId);
+ }
+
+ function getForwarder(uint256 upkeepID) external view returns (address) {
+ return registry.getForwarder(upkeepID);
+ }
+
+ function getBalance(uint256 id) external view returns (uint96 balance) {
+ return registry.getBalance(id);
+ }
+
+ function getTriggerType(uint256 upkeepId) external view returns (uint8) {
+ return registry.getTriggerType(upkeepId);
+ }
+
function burnPerformGas(uint256 upkeepId, uint256 startGas, uint256 blockNum) public {
uint256 performGasToBurn = performGasToBurns[upkeepId];
while (startGas - gasleft() + 10000 < performGasToBurn) {
@@ -234,15 +354,6 @@ abstract contract VerifiableLoadBase is ConfirmedOwner {
}
}
- /**
- * @notice cancel an upkeep.
- * @param upkeepId the upkeep ID
- */
- function cancelUpkeep(uint256 upkeepId) external {
- registry.cancelUpkeep(upkeepId);
- s_upkeepIDs.remove(upkeepId);
- }
-
/**
* @notice batch canceling upkeeps.
* @param upkeepIds an array of upkeep IDs
@@ -250,7 +361,8 @@ abstract contract VerifiableLoadBase is ConfirmedOwner {
function batchCancelUpkeeps(uint256[] calldata upkeepIds) external {
uint256 len = upkeepIds.length;
for (uint8 i = 0; i < len; i++) {
- this.cancelUpkeep(upkeepIds[i]);
+ registry.cancelUpkeep(upkeepIds[i]);
+ s_upkeepIDs.remove(upkeepIds[i]);
}
}
@@ -261,29 +373,29 @@ abstract contract VerifiableLoadBase is ConfirmedOwner {
return (getBlockNumber() - previousPerformBlocks[upkeepId]) >= intervals[upkeepId];
}
- /**
- * @notice set a new add LINK amount.
- * @param amount the new value
- */
- function setAddLinkAmount(uint96 amount) external {
- addLinkAmount = amount;
- }
-
- function setUpkeepTopUpCheckInterval(uint256 newInterval) external {
- upkeepTopUpCheckInterval = newInterval;
- }
-
- function setMinBalanceThresholdMultiplier(uint8 newMinBalanceThresholdMultiplier) external {
- minBalanceThresholdMultiplier = newMinBalanceThresholdMultiplier;
- }
-
- function setPerformGasToBurn(uint256 upkeepId, uint256 value) public {
- performGasToBurns[upkeepId] = value;
- }
-
- function setCheckGasToBurn(uint256 upkeepId, uint256 value) public {
- checkGasToBurns[upkeepId] = value;
- }
+ // /**
+ // * @notice set a new add LINK amount.
+ // * @param amount the new value
+ // */
+ // function setAddLinkAmount(uint96 amount) external {
+ // addLinkAmount = amount;
+ // }
+ //
+ // function setUpkeepTopUpCheckInterval(uint256 newInterval) external {
+ // upkeepTopUpCheckInterval = newInterval;
+ // }
+ //
+ // function setMinBalanceThresholdMultiplier(uint8 newMinBalanceThresholdMultiplier) external {
+ // minBalanceThresholdMultiplier = newMinBalanceThresholdMultiplier;
+ // }
+
+ // function setPerformGasToBurn(uint256 upkeepId, uint256 value) public {
+ // performGasToBurns[upkeepId] = value;
+ // }
+ //
+ // function setCheckGasToBurn(uint256 upkeepId, uint256 value) public {
+ // checkGasToBurns[upkeepId] = value;
+ // }
function setPerformDataSize(uint256 upkeepId, uint256 value) public {
performDataSizes[upkeepId] = value;
@@ -334,22 +446,46 @@ abstract contract VerifiableLoadBase is ConfirmedOwner {
/**
* @notice finds all log trigger upkeeps and emits logs to serve as the initial trigger for upkeeps
*/
- function batchSendLogs() external {
- uint256[] memory upkeepIds = registry.getActiveUpkeepIDs(0, 0);
+ function batchSendLogs(uint8 log) external {
+ uint256[] memory upkeepIds = this.getActiveUpkeepIDsDeployedByThisContract(0, 0);
uint256 len = upkeepIds.length;
uint256 blockNum = getBlockNumber();
for (uint256 i = 0; i < len; i++) {
uint256 upkeepId = upkeepIds[i];
uint8 triggerType = registry.getTriggerType(upkeepId);
if (triggerType == 1) {
- emit LogEmitted(upkeepId, blockNum, address(this));
+ if (log == 0) {
+ emit LogEmitted(upkeepId, blockNum, address(this));
+ } else {
+ emit LogEmittedAgain(upkeepId, blockNum, address(this));
+ }
}
}
}
- function sendLog(uint256 upkeepId) external {
+ function getUpkeepInfo(uint256 upkeepId) public view returns (KeeperRegistryBase2_1.UpkeepInfo memory) {
+ return registry.getUpkeep(upkeepId);
+ }
+
+ function getUpkeepTriggerConfig(uint256 upkeepId) public view returns (bytes memory) {
+ return registry.getUpkeepTriggerConfig(upkeepId);
+ }
+
+ function getUpkeepPrivilegeConfig(uint256 upkeepId) public view returns (bytes memory) {
+ return registry.getUpkeepPrivilegeConfig(upkeepId);
+ }
+
+ function setUpkeepPrivilegeConfig(uint256 upkeepId, bytes memory cfg) external {
+ registry.setUpkeepPrivilegeConfig(upkeepId, cfg);
+ }
+
+ function sendLog(uint256 upkeepId, uint8 log) external {
uint256 blockNum = getBlockNumber();
- emit LogEmitted(upkeepId, blockNum, address(this));
+ if (log == 0) {
+ emit LogEmitted(upkeepId, blockNum, address(this));
+ } else {
+ emit LogEmittedAgain(upkeepId, blockNum, address(this));
+ }
}
function getDelaysLength(uint256 upkeepId) public view returns (uint256) {
diff --git a/contracts/src/v0.8/tests/VerifiableLoadLogTriggerUpkeep.sol b/contracts/src/v0.8/tests/VerifiableLoadLogTriggerUpkeep.sol
index a1842449110..45630fcadc6 100644
--- a/contracts/src/v0.8/tests/VerifiableLoadLogTriggerUpkeep.sol
+++ b/contracts/src/v0.8/tests/VerifiableLoadLogTriggerUpkeep.sol
@@ -2,79 +2,82 @@
pragma solidity 0.8.16;
import "./VerifiableLoadBase.sol";
-import "../dev/automation/2_1/interfaces/ILogAutomation.sol";
-import "../dev/automation/2_1/interfaces/FeedLookupCompatibleInterface.sol";
-
-contract VerifiableLoadLogTriggerUpkeep is VerifiableLoadBase, FeedLookupCompatibleInterface, ILogAutomation {
- string[] public feedsHex = [
- "0x4554482d5553442d415242495452554d2d544553544e45540000000000000000",
- "0x4254432d5553442d415242495452554d2d544553544e45540000000000000000"
- ];
- string public feedParamKey = "feedIdHex";
- string public timeParamKey = "blockNumber";
- bool public autoLog;
+import "../automation/interfaces/ILogAutomation.sol";
+import "../automation/interfaces/StreamsLookupCompatibleInterface.sol";
+
+contract VerifiableLoadLogTriggerUpkeep is VerifiableLoadBase, StreamsLookupCompatibleInterface, ILogAutomation {
bool public useMercury;
+ uint8 public logNum;
/**
* @param _registrar a automation registrar 2.1 address
* @param _useArb if this contract will use arbitrum block number
- * @param _autoLog if the upkeep will emit logs to trigger its next log trigger process
* @param _useMercury if the log trigger upkeeps will use mercury lookup
*/
constructor(
AutomationRegistrar2_1 _registrar,
bool _useArb,
- bool _autoLog,
bool _useMercury
) VerifiableLoadBase(_registrar, _useArb) {
- autoLog = _autoLog;
- useMercury = _useMercury;
- }
-
- function setAutoLog(bool _autoLog) external {
- autoLog = _autoLog;
- }
-
- function setUseMercury(bool _useMercury) external {
useMercury = _useMercury;
+ logNum = 0;
}
- function setFeedsHex(string[] memory newFeeds) external {
- feedsHex = newFeeds;
+ function setLog(uint8 _log) external {
+ logNum = _log;
}
function checkLog(Log calldata log, bytes memory checkData) external returns (bool, bytes memory) {
uint256 startGas = gasleft();
uint256 blockNum = getBlockNumber();
+ uint256 uid = abi.decode(checkData, (uint256));
+ bytes32 sig = emittedSig;
+ if (logNum != 0) {
+ sig = emittedAgainSig;
+ }
// filter by event signature
- if (log.topics[0] == emittedSig) {
+ if (log.topics[0] == sig) {
bytes memory t1 = abi.encodePacked(log.topics[1]); // bytes32 to bytes
uint256 upkeepId = abi.decode(t1, (uint256));
+ if (upkeepId != uid) {
+ revert("upkeep ids don't match");
+ }
bytes memory t2 = abi.encodePacked(log.topics[2]);
uint256 blockNum = abi.decode(t2, (uint256));
+ bytes memory t3 = abi.encodePacked(log.topics[3]);
+ address addr = abi.decode(t3, (address));
+
uint256 checkGasToBurn = checkGasToBurns[upkeepId];
while (startGas - gasleft() + 15000 < checkGasToBurn) {
dummyMap[blockhash(blockNum)] = false;
}
+ uint256 timeParam;
+ if (keccak256(abi.encodePacked(feedParamKey)) == keccak256(abi.encodePacked("feedIdHex"))) {
+ timeParam = blockNum;
+ } else {
+ // assume this will be feedIDs for v0.3
+ timeParam = block.timestamp;
+ }
+
if (useMercury) {
- revert FeedLookup(feedParamKey, feedsHex, timeParamKey, blockNum, abi.encode(upkeepId, blockNum));
+ revert StreamsLookup(feedParamKey, feedsHex, timeParamKey, timeParam, abi.encode(upkeepId, blockNum, addr));
}
// if we don't use mercury, create a perform data which resembles the output of checkCallback
- bytes[] memory values = new bytes[](1);
- bytes memory extraData = abi.encode(upkeepId, blockNum);
+ bytes[] memory values = new bytes[](feedsHex.length);
+ bytes memory extraData = abi.encode(upkeepId, blockNum, addr);
return (true, abi.encode(values, extraData));
}
- revert("could not find matching event sig");
+ revert("unexpected event sig");
}
function performUpkeep(bytes calldata performData) external {
uint256 startGas = gasleft();
(bytes[] memory values, bytes memory extraData) = abi.decode(performData, (bytes[], bytes));
- (uint256 upkeepId, uint256 logBlockNumber) = abi.decode(extraData, (uint256, uint256));
+ (uint256 upkeepId, uint256 logBlockNumber, address addr) = abi.decode(extraData, (uint256, uint256, address));
uint256 firstPerformBlock = firstPerformBlocks[upkeepId];
uint256 previousPerformBlock = previousPerformBlocks[upkeepId];
@@ -102,9 +105,7 @@ contract VerifiableLoadLogTriggerUpkeep is VerifiableLoadBase, FeedLookupCompati
// minBalanceThresholdMultiplier (20) * min balance. If not, add addLinkAmount (0.2) to the upkeep
// upkeepTopUpCheckInterval, minBalanceThresholdMultiplier, and addLinkAmount are configurable
topUpFund(upkeepId, currentBlockNum);
- if (autoLog) {
- emit LogEmitted(upkeepId, currentBlockNum, address(this));
- }
+ emit LogEmitted(upkeepId, currentBlockNum, address(this));
burnPerformGas(upkeepId, startGas, currentBlockNum);
}
diff --git a/contracts/src/v0.8/tests/VerifiableLoadMercuryUpkeep.sol b/contracts/src/v0.8/tests/VerifiableLoadStreamsLookupUpkeep.sol
similarity index 76%
rename from contracts/src/v0.8/tests/VerifiableLoadMercuryUpkeep.sol
rename to contracts/src/v0.8/tests/VerifiableLoadStreamsLookupUpkeep.sol
index 09e62f988a5..209c60ca974 100644
--- a/contracts/src/v0.8/tests/VerifiableLoadMercuryUpkeep.sol
+++ b/contracts/src/v0.8/tests/VerifiableLoadStreamsLookupUpkeep.sol
@@ -2,23 +2,11 @@
pragma solidity 0.8.16;
import "./VerifiableLoadBase.sol";
-import "../dev/automation/2_1/interfaces/FeedLookupCompatibleInterface.sol";
-
-contract VerifiableLoadMercuryUpkeep is VerifiableLoadBase, FeedLookupCompatibleInterface {
- string[] public feedsHex = [
- "0x4554482d5553442d415242495452554d2d544553544e45540000000000000000",
- "0x4254432d5553442d415242495452554d2d544553544e45540000000000000000",
- "0x555344432d5553442d415242495452554d2d544553544e455400000000000000"
- ];
- string public constant feedParamKey = "feedIdHex";
- string public constant timeParamKey = "blockNumber";
+import "../automation/interfaces/StreamsLookupCompatibleInterface.sol";
+contract VerifiableLoadStreamsLookupUpkeep is VerifiableLoadBase, StreamsLookupCompatibleInterface {
constructor(AutomationRegistrar2_1 _registrar, bool _useArb) VerifiableLoadBase(_registrar, _useArb) {}
- function setFeedsHex(string[] memory newFeeds) external {
- feedsHex = newFeeds;
- }
-
function checkCallback(
bytes[] memory values,
bytes memory extraData
@@ -46,7 +34,15 @@ contract VerifiableLoadMercuryUpkeep is VerifiableLoadBase, FeedLookupCompatible
return (false, pData);
}
- revert FeedLookup(feedParamKey, feedsHex, timeParamKey, blockNum, abi.encode(upkeepId));
+ uint256 timeParam;
+ if (keccak256(abi.encodePacked(feedParamKey)) == keccak256(abi.encodePacked("feedIdHex"))) {
+ timeParam = blockNum;
+ } else {
+ // assume this will be feedIDs for v0.3
+ timeParam = block.timestamp;
+ }
+
+ revert StreamsLookup(feedParamKey, feedsHex, timeParamKey, timeParam, abi.encode(upkeepId));
}
function performUpkeep(bytes calldata performData) external {
diff --git a/contracts/src/v0.8/vendor/@ensdomains/buffer/0.1.0/Buffer.sol b/contracts/src/v0.8/vendor/@ensdomains/buffer/v0.1.0/Buffer.sol
similarity index 100%
rename from contracts/src/v0.8/vendor/@ensdomains/buffer/0.1.0/Buffer.sol
rename to contracts/src/v0.8/vendor/@ensdomains/buffer/v0.1.0/Buffer.sol
diff --git a/contracts/src/v0.8/vendor/@eth-optimism/contracts/0.4.7/contracts/optimistic-ethereum/iOVM/bridge/messaging/iOVM_CrossDomainMessenger.sol b/contracts/src/v0.8/vendor/@eth-optimism/contracts/v0.4.7/contracts/optimistic-ethereum/iOVM/bridge/messaging/iOVM_CrossDomainMessenger.sol
similarity index 100%
rename from contracts/src/v0.8/vendor/@eth-optimism/contracts/0.4.7/contracts/optimistic-ethereum/iOVM/bridge/messaging/iOVM_CrossDomainMessenger.sol
rename to contracts/src/v0.8/vendor/@eth-optimism/contracts/v0.4.7/contracts/optimistic-ethereum/iOVM/bridge/messaging/iOVM_CrossDomainMessenger.sol
diff --git a/contracts/src/v0.8/vendor/@eth-optimism/contracts/0.8.6/contracts/L2/predeploys/OVM_GasPriceOracle.sol b/contracts/src/v0.8/vendor/@eth-optimism/contracts/v0.8.6/contracts/L2/predeploys/OVM_GasPriceOracle.sol
similarity index 100%
rename from contracts/src/v0.8/vendor/@eth-optimism/contracts/0.8.6/contracts/L2/predeploys/OVM_GasPriceOracle.sol
rename to contracts/src/v0.8/vendor/@eth-optimism/contracts/v0.8.6/contracts/L2/predeploys/OVM_GasPriceOracle.sol
diff --git a/contracts/src/v0.8/vendor/@eth-optimism/contracts/0.8.9/contracts/L2/predeploys/OVM_GasPriceOracle.sol b/contracts/src/v0.8/vendor/@eth-optimism/contracts/v0.8.9/contracts/L2/predeploys/OVM_GasPriceOracle.sol
similarity index 100%
rename from contracts/src/v0.8/vendor/@eth-optimism/contracts/0.8.9/contracts/L2/predeploys/OVM_GasPriceOracle.sol
rename to contracts/src/v0.8/vendor/@eth-optimism/contracts/v0.8.9/contracts/L2/predeploys/OVM_GasPriceOracle.sol
diff --git a/contracts/src/v0.8/vendor/solidity-cborutils/v2.0.0/CBOR.sol b/contracts/src/v0.8/vendor/solidity-cborutils/v2.0.0/CBOR.sol
index fbcedd53f1a..5c111370875 100644
--- a/contracts/src/v0.8/vendor/solidity-cborutils/v2.0.0/CBOR.sol
+++ b/contracts/src/v0.8/vendor/solidity-cborutils/v2.0.0/CBOR.sol
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
-import "../../@ensdomains/buffer/0.1.0/Buffer.sol";
+import "../../@ensdomains/buffer/v0.1.0/Buffer.sol";
/**
* @dev A library for populating CBOR encoded payload in Solidity.
diff --git a/contracts/test/cross-version/directory.test.ts b/contracts/test/cross-version/directory.test.ts
new file mode 100644
index 00000000000..fde5e59299d
--- /dev/null
+++ b/contracts/test/cross-version/directory.test.ts
@@ -0,0 +1,31 @@
+import fs from 'fs'
+import path from 'path'
+import { expect } from 'chai'
+
+// Directories that start with a number do not currently work with typechain (https://github.com/dethcrypto/TypeChain/issues/794)
+describe('Directory', () => {
+ it('Should not have a file or directory starting with a number in contracts/src', () => {
+ const srcPath = path.join(__dirname, '..', '..', 'src')
+
+ const noNumbersAsFirstChar = (dirPath: string): boolean => {
+ const entries = fs.readdirSync(dirPath, { withFileTypes: true })
+
+ for (const entry of entries) {
+ if (/^\d/.test(entry.name)) {
+ throw new Error(
+ `${path.join(dirPath, entry.name)} starts with a number`,
+ )
+ }
+
+ if (entry.isDirectory()) {
+ const newPath = path.join(dirPath, entry.name)
+ noNumbersAsFirstChar(newPath)
+ }
+ }
+
+ return true
+ }
+
+ expect(noNumbersAsFirstChar(srcPath)).to.be.true
+ })
+})
diff --git a/contracts/test/v0.7/Operator.test.ts b/contracts/test/v0.7/Operator.test.ts
index 251ee65a7ae..4af846576b3 100644
--- a/contracts/test/v0.7/Operator.test.ts
+++ b/contracts/test/v0.7/Operator.test.ts
@@ -1024,9 +1024,8 @@ describe('Operator', () => {
.deploy(link.address, operator.address, specId)
const paymentAmount = toWei('1')
await link.transfer(gasGuzzlingConsumer.address, paymentAmount)
- const tx = await gasGuzzlingConsumer.gassyRequestEthereumPrice(
- paymentAmount,
- )
+ const tx =
+ await gasGuzzlingConsumer.gassyRequestEthereumPrice(paymentAmount)
const receipt = await tx.wait()
request = decodeRunRequest(receipt.logs?.[3])
})
@@ -1480,9 +1479,8 @@ describe('Operator', () => {
.deploy(link.address, operator.address, specId)
const paymentAmount = toWei('1')
await link.transfer(gasGuzzlingConsumer.address, paymentAmount)
- const tx = await gasGuzzlingConsumer.gassyRequestEthereumPrice(
- paymentAmount,
- )
+ const tx =
+ await gasGuzzlingConsumer.gassyRequestEthereumPrice(paymentAmount)
const receipt = await tx.wait()
request = decodeRunRequest(receipt.logs?.[3])
})
@@ -2087,9 +2085,8 @@ describe('Operator', () => {
.deploy(link.address, operator.address, specId)
const paymentAmount = toWei('1')
await link.transfer(gasGuzzlingConsumer.address, paymentAmount)
- const tx = await gasGuzzlingConsumer.gassyMultiWordRequest(
- paymentAmount,
- )
+ const tx =
+ await gasGuzzlingConsumer.gassyMultiWordRequest(paymentAmount)
const receipt = await tx.wait()
request = decodeRunRequest(receipt.logs?.[3])
})
@@ -2604,9 +2601,8 @@ describe('Operator', () => {
.deploy(link.address, operator.address, specId)
const paymentAmount = toWei('1')
await link.transfer(gasGuzzlingConsumer.address, paymentAmount)
- const tx = await gasGuzzlingConsumer.gassyMultiWordRequest(
- paymentAmount,
- )
+ const tx =
+ await gasGuzzlingConsumer.gassyMultiWordRequest(paymentAmount)
const receipt = await tx.wait()
request = decodeRunRequest(receipt.logs?.[3])
})
diff --git a/contracts/test/v0.8/Flags.test.ts b/contracts/test/v0.8/Flags.test.ts
index 9533bf8eb28..eff0912c9e1 100644
--- a/contracts/test/v0.8/Flags.test.ts
+++ b/contracts/test/v0.8/Flags.test.ts
@@ -17,7 +17,7 @@ let consumer: Contract
before(async () => {
personas = (await getUsers()).personas
controllerFactory = await ethers.getContractFactory(
- 'src/v0.8/SimpleWriteAccessController.sol:SimpleWriteAccessController',
+ 'src/v0.8/shared/access/SimpleWriteAccessController.sol:SimpleWriteAccessController',
personas.Nelly,
)
consumerFactory = await ethers.getContractFactory(
diff --git a/contracts/test/v0.8/SimpleReadAccessController.test.ts b/contracts/test/v0.8/SimpleReadAccessController.test.ts
index 03bd944da2e..32e2e743de0 100644
--- a/contracts/test/v0.8/SimpleReadAccessController.test.ts
+++ b/contracts/test/v0.8/SimpleReadAccessController.test.ts
@@ -12,7 +12,7 @@ let controller: Contract
before(async () => {
personas = (await getUsers()).personas
controllerFactory = await ethers.getContractFactory(
- 'src/v0.8/SimpleReadAccessController.sol:SimpleReadAccessController',
+ 'src/v0.8/shared/access/SimpleReadAccessController.sol:SimpleReadAccessController',
personas.Carol,
)
})
diff --git a/contracts/test/v0.8/SimpleWriteAccessController.test.ts b/contracts/test/v0.8/SimpleWriteAccessController.test.ts
index 29b094ef4b0..f4d7f21966b 100644
--- a/contracts/test/v0.8/SimpleWriteAccessController.test.ts
+++ b/contracts/test/v0.8/SimpleWriteAccessController.test.ts
@@ -12,7 +12,7 @@ let controller: Contract
before(async () => {
personas = (await getUsers()).personas
controllerFactory = await ethers.getContractFactory(
- 'src/v0.8/SimpleWriteAccessController.sol:SimpleWriteAccessController',
+ 'src/v0.8/shared/access/SimpleWriteAccessController.sol:SimpleWriteAccessController',
personas.Carol,
)
})
diff --git a/contracts/test/v0.8/automation/AutomationRegistrar2_1.test.ts b/contracts/test/v0.8/automation/AutomationRegistrar2_1.test.ts
index 323050def56..b88911910c4 100644
--- a/contracts/test/v0.8/automation/AutomationRegistrar2_1.test.ts
+++ b/contracts/test/v0.8/automation/AutomationRegistrar2_1.test.ts
@@ -6,6 +6,7 @@ import { BigNumber, Signer } from 'ethers'
import { LinkToken__factory as LinkTokenFactory } from '../../../typechain/factories/LinkToken__factory'
import { MockV3Aggregator__factory as MockV3AggregatorFactory } from '../../../typechain/factories/MockV3Aggregator__factory'
import { UpkeepMock__factory as UpkeepMockFactory } from '../../../typechain/factories/UpkeepMock__factory'
+import { AutomationRegistrar2_1__factory as AutomationRegistrarFactory } from '../../../typechain/factories/AutomationRegistrar2_1__factory'
import { MockV3Aggregator } from '../../../typechain/MockV3Aggregator'
import { LinkToken } from '../../../typechain/LinkToken'
import { UpkeepMock } from '../../../typechain/UpkeepMock'
@@ -14,6 +15,26 @@ import { IKeeperRegistryMaster as IKeeperRegistry } from '../../../typechain/IKe
import { AutomationRegistrar2_1 as Registrar } from '../../../typechain/AutomationRegistrar2_1'
import { deployRegistry21 } from './helpers'
+//////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////
+
+/*********************************** REGISTRAR v2.1 IS FROZEN ************************************/
+
+// We are leaving the original tests enabled, however as 2.1 is still actively being deployed
+
+describe('AutomationRegistrar2_1 - Frozen [ @skip-coverage ]', () => {
+ it('has not changed', () => {
+ assert.equal(
+ ethers.utils.id(AutomationRegistrarFactory.bytecode),
+ '0x9633058bd81e8479f88baaee9bda533406295c80ccbc43d4509701001bbea6e3',
+ 'KeeperRegistry bytecode has changed',
+ )
+ })
+})
+
+//////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////
+
// copied from KeeperRegistryBase2_1.sol
enum Trigger {
CONDITION,
diff --git a/contracts/test/v0.8/automation/CanaryUpkeep1_2.test.ts b/contracts/test/v0.8/automation/CanaryUpkeep1_2.test.ts
deleted file mode 100644
index c94dffa6b84..00000000000
--- a/contracts/test/v0.8/automation/CanaryUpkeep1_2.test.ts
+++ /dev/null
@@ -1,225 +0,0 @@
-import { ethers } from 'hardhat'
-import { BigNumber, Signer } from 'ethers'
-import moment from 'moment'
-import { assert } from 'chai'
-import { CanaryUpkeep12 as CanaryUpkeep } from '../../../typechain/CanaryUpkeep12'
-import { CanaryUpkeep1_2__factory as CanaryUpkeepFactory } from '../../../typechain/factories/CanaryUpkeep1_2__factory'
-import { KeeperRegistry1_2 as KeeperRegistry } from '../../../typechain/KeeperRegistry1_2'
-import { KeeperRegistry1_2__factory as KeeperRegistryFactory } from '../../../typechain/factories/KeeperRegistry1_2__factory'
-import { fastForward, reset } from '../../test-helpers/helpers'
-import { getUsers, Personas } from '../../test-helpers/setup'
-import { evmRevert } from '../../test-helpers/matchers'
-
-let personas: Personas
-let canaryUpkeep: CanaryUpkeep
-let canaryUpkeepFactory: CanaryUpkeepFactory
-let owner: Signer
-let nelly: Signer
-let nancy: Signer
-let ned: Signer
-let keeperAddresses: string[]
-let keeperRegistry: KeeperRegistry
-let keeperRegistryFactory: KeeperRegistryFactory
-
-const defaultInterval = 300
-const paymentPremiumPPB = BigNumber.from(250000000)
-const flatFeeMicroLink = BigNumber.from(0)
-const blockCountPerTurn = BigNumber.from(3)
-const stalenessSeconds = BigNumber.from(43820)
-const gasCeilingMultiplier = BigNumber.from(1)
-const checkGasLimit = BigNumber.from(20000000)
-const fallbackGasPrice = BigNumber.from(200)
-const fallbackLinkPrice = BigNumber.from(200000000)
-const maxPerformGas = BigNumber.from(5000000)
-const minUpkeepSpend = BigNumber.from('1000000000000000000')
-const transcoder = ethers.constants.AddressZero
-const registrar = ethers.constants.AddressZero
-const config = {
- paymentPremiumPPB,
- flatFeeMicroLink,
- blockCountPerTurn,
- checkGasLimit,
- stalenessSeconds,
- gasCeilingMultiplier,
- minUpkeepSpend,
- maxPerformGas,
- fallbackGasPrice,
- fallbackLinkPrice,
- transcoder,
- registrar,
-}
-
-describe('CanaryUpkeep1_2', () => {
- before(async () => {
- personas = (await getUsers()).personas
- owner = personas.Default
- nelly = personas.Nelly
- nancy = personas.Nancy
- ned = personas.Ned
- keeperAddresses = [
- await nelly.getAddress(),
- await nancy.getAddress(),
- await ned.getAddress(),
- ]
- })
- beforeEach(async () => {
- // @ts-ignore bug in autogen file
- keeperRegistryFactory = await ethers.getContractFactory('KeeperRegistry1_2')
- keeperRegistry = await keeperRegistryFactory
- .connect(owner)
- .deploy(
- ethers.constants.AddressZero,
- ethers.constants.AddressZero,
- ethers.constants.AddressZero,
- config,
- )
- await keeperRegistry.deployed()
-
- // @ts-ignore bug in autogen file
- canaryUpkeepFactory = await ethers.getContractFactory('CanaryUpkeep1_2')
- canaryUpkeep = await canaryUpkeepFactory
- .connect(owner)
- .deploy(keeperRegistry.address, defaultInterval)
- await canaryUpkeep.deployed()
- })
-
- afterEach(async () => {
- await reset()
- })
-
- describe('setInterval()', () => {
- it('allows the owner setting interval', async () => {
- await canaryUpkeep.connect(owner).setInterval(400)
- const newInterval = await canaryUpkeep.getInterval()
- assert.equal(
- newInterval.toNumber(),
- 400,
- 'The interval is not updated correctly',
- )
- })
-
- it('does not allow someone who is not an owner setting interval', async () => {
- await evmRevert(
- canaryUpkeep.connect(ned).setInterval(400),
- 'Only callable by owner',
- )
- })
- })
-
- describe('checkUpkeep()', () => {
- it('returns true when sufficient time passes', async () => {
- await fastForward(moment.duration(6, 'minutes').asSeconds())
- await keeperRegistry.setKeepers(keeperAddresses, keeperAddresses)
- const [needsUpkeep] = await canaryUpkeep.checkUpkeep('0x')
- assert.isTrue(needsUpkeep)
- })
-
- it('returns false when insufficient time passes', async () => {
- await fastForward(moment.duration(2, 'minutes').asSeconds())
- await keeperRegistry.setKeepers(keeperAddresses, keeperAddresses)
- const [needsUpkeep] = await canaryUpkeep.checkUpkeep('0x')
- assert.isFalse(needsUpkeep)
- })
-
- it('returns false when keeper array is empty', async () => {
- await fastForward(moment.duration(6, 'minutes').asSeconds())
- const [needsUpkeep] = await canaryUpkeep.checkUpkeep('0x')
- assert.isTrue(needsUpkeep)
- })
- })
-
- describe('performUpkeep()', () => {
- it('enforces that transaction origin is the anticipated keeper', async () => {
- await keeperRegistry.setKeepers(keeperAddresses, keeperAddresses)
-
- const oldTimestamp = await canaryUpkeep.connect(nelly).getTimestamp()
- const oldKeeperIndex = await canaryUpkeep.connect(nelly).getKeeperIndex()
- await fastForward(moment.duration(6, 'minutes').asSeconds())
- await canaryUpkeep.connect(nelly).performUpkeep('0x')
- const newKeeperIndex = await canaryUpkeep.connect(nelly).getKeeperIndex()
- assert.equal(
- newKeeperIndex.toNumber() - oldKeeperIndex.toNumber(),
- 1,
- 'keeper index needs to increment by 1 after performUpkeep',
- )
-
- const newTimestamp = await canaryUpkeep.connect(nelly).getTimestamp()
- const interval = await canaryUpkeep.connect(nelly).getInterval()
- assert.isAtLeast(
- newTimestamp.toNumber() - oldTimestamp.toNumber(),
- interval.toNumber(),
- 'timestamp needs to be updated after performUpkeep',
- )
- })
-
- it('enforces that keeper index will reset to zero after visiting the last keeper', async () => {
- await keeperRegistry.setKeepers(keeperAddresses, keeperAddresses)
-
- await fastForward(moment.duration(6, 'minutes').asSeconds())
- await canaryUpkeep.connect(nelly).performUpkeep('0x')
-
- await fastForward(moment.duration(6, 'minutes').asSeconds())
- await canaryUpkeep.connect(nancy).performUpkeep('0x')
-
- await fastForward(moment.duration(6, 'minutes').asSeconds())
- await canaryUpkeep.connect(ned).performUpkeep('0x')
-
- const keeperIndex = await canaryUpkeep.connect(ned).getKeeperIndex()
- assert.equal(
- keeperIndex.toNumber(),
- 0,
- 'Keeper index is not updated properly',
- )
- })
-
- it('updates the keeper index after the keepers array is shortened', async () => {
- await keeperRegistry.setKeepers(keeperAddresses, keeperAddresses)
-
- await fastForward(moment.duration(6, 'minutes').asSeconds())
- await canaryUpkeep.connect(nelly).performUpkeep('0x')
-
- await fastForward(moment.duration(6, 'minutes').asSeconds())
- await canaryUpkeep.connect(nancy).performUpkeep('0x')
-
- let shortAddresses: string[] = [
- await nelly.getAddress(),
- await nancy.getAddress(),
- ]
- await keeperRegistry.setKeepers(shortAddresses, shortAddresses)
-
- await fastForward(moment.duration(6, 'minutes').asSeconds())
- await canaryUpkeep.connect(nelly).performUpkeep('0x')
- const keeperIndex = await canaryUpkeep.getKeeperIndex()
- assert.equal(
- keeperIndex.toNumber(),
- 1,
- 'Keeper index is not updated properly',
- )
- })
-
- it('reverts if the keeper array is empty', async () => {
- await evmRevert(
- canaryUpkeep.connect(nelly).performUpkeep('0x'),
- `NoKeeperNodes`,
- )
- })
-
- it('reverts if not enough time has passed', async () => {
- await keeperRegistry.setKeepers(keeperAddresses, keeperAddresses)
- await fastForward(moment.duration(3, 'minutes').asSeconds())
- await evmRevert(
- canaryUpkeep.connect(nelly).performUpkeep('0x'),
- `InsufficientInterval`,
- )
- })
-
- it('reverts if an incorrect keeper tries to perform upkeep', async () => {
- await keeperRegistry.setKeepers(keeperAddresses, keeperAddresses)
- await fastForward(moment.duration(6, 'minutes').asSeconds())
- await evmRevert(
- canaryUpkeep.connect(nancy).performUpkeep('0x'),
- 'transaction origin is not the anticipated keeper.',
- )
- })
- })
-})
diff --git a/contracts/test/v0.8/automation/CronUpkeep.test.ts b/contracts/test/v0.8/automation/CronUpkeep.test.ts
index 755b4494c81..f153345b570 100644
--- a/contracts/test/v0.8/automation/CronUpkeep.test.ts
+++ b/contracts/test/v0.8/automation/CronUpkeep.test.ts
@@ -321,12 +321,10 @@ describe('CronUpkeep', () => {
it('creates jobs with sequential IDs', async () => {
const cronString1 = '0 * * * *'
const cronString2 = '0 1,2,3 */4 5-6 1-2'
- const encodedSpec1 = await cronFactoryContract.encodeCronString(
- cronString1,
- )
- const encodedSpec2 = await cronFactoryContract.encodeCronString(
- cronString2,
- )
+ const encodedSpec1 =
+ await cronFactoryContract.encodeCronString(cronString1)
+ const encodedSpec2 =
+ await cronFactoryContract.encodeCronString(cronString2)
const nextTick1 = (
await cronTestHelper.calculateNextTick(cronString1)
).toNumber()
diff --git a/contracts/test/v0.8/automation/IKeeperRegistryMaster.test.ts b/contracts/test/v0.8/automation/IKeeperRegistryMaster.test.ts
index a3a18473eca..bd4b24e54c6 100644
--- a/contracts/test/v0.8/automation/IKeeperRegistryMaster.test.ts
+++ b/contracts/test/v0.8/automation/IKeeperRegistryMaster.test.ts
@@ -87,7 +87,7 @@ describe('IKeeperRegistryMaster', () => {
const checksum = ethers.utils.id(compositeABIs.join(''))
const knownChecksum = fs
.readFileSync(
- 'src/v0.8/dev/automation/2_1/interfaces/IKeeperRegistryMaster.sol',
+ 'src/v0.8/automation/interfaces/v2_1/IKeeperRegistryMaster.sol',
)
.toString()
.slice(17, 83) // checksum located at top of file
diff --git a/contracts/test/v0.8/automation/KeeperRegistry2_1.test.ts b/contracts/test/v0.8/automation/KeeperRegistry2_1.test.ts
index 8ddc2f450e6..1355e6509fb 100644
--- a/contracts/test/v0.8/automation/KeeperRegistry2_1.test.ts
+++ b/contracts/test/v0.8/automation/KeeperRegistry2_1.test.ts
@@ -14,7 +14,7 @@ import { evmRevert } from '../../test-helpers/matchers'
import { getUsers, Personas } from '../../test-helpers/setup'
import { randomAddress, toWei } from '../../test-helpers/helpers'
import { LinkToken__factory as LinkTokenFactory } from '../../../typechain/factories/LinkToken__factory'
-import { MercuryUpkeep__factory as MercuryUpkeepFactory } from '../../../typechain/factories/MercuryUpkeep__factory'
+import { StreamsLookupUpkeep__factory as StreamsLookupUpkeepFactory } from '../../../typechain/factories/StreamsLookupUpkeep__factory'
import { MockV3Aggregator__factory as MockV3AggregatorFactory } from '../../../typechain/factories/MockV3Aggregator__factory'
import { UpkeepMock__factory as UpkeepMockFactory } from '../../../typechain/factories/UpkeepMock__factory'
import { UpkeepAutoFunder__factory as UpkeepAutoFunderFactory } from '../../../typechain/factories/UpkeepAutoFunder__factory'
@@ -22,9 +22,13 @@ import { MockArbGasInfo__factory as MockArbGasInfoFactory } from '../../../typec
import { MockOVMGasPriceOracle__factory as MockOVMGasPriceOracleFactory } from '../../../typechain/factories/MockOVMGasPriceOracle__factory'
import { ILogAutomation__factory as ILogAutomationactory } from '../../../typechain/factories/ILogAutomation__factory'
import { IAutomationForwarder__factory as IAutomationForwarderFactory } from '../../../typechain/factories/IAutomationForwarder__factory'
+import { KeeperRegistry2_1__factory as KeeperRegistryFactory } from '../../../typechain/factories/KeeperRegistry2_1__factory'
+import { KeeperRegistryLogicA2_1__factory as KeeperRegistryLogicAFactory } from '../../../typechain/factories/KeeperRegistryLogicA2_1__factory'
+import { KeeperRegistryLogicB2_1__factory as KeeperRegistryLogicBFactory } from '../../../typechain/factories/KeeperRegistryLogicB2_1__factory'
+import { AutomationForwarderLogic__factory as AutomationForwarderLogicFactory } from '../../../typechain/factories/AutomationForwarderLogic__factory'
import { MockArbSys__factory as MockArbSysFactory } from '../../../typechain/factories/MockArbSys__factory'
import { AutomationUtils2_1 as AutomationUtils } from '../../../typechain/AutomationUtils2_1'
-import { MercuryUpkeep } from '../../../typechain/MercuryUpkeep'
+import { StreamsLookupUpkeep } from '../../../typechain/StreamsLookupUpkeep'
import { MockV3Aggregator } from '../../../typechain/MockV3Aggregator'
import { LinkToken } from '../../../typechain/LinkToken'
import { UpkeepMock } from '../../../typechain/UpkeepMock'
@@ -49,6 +53,41 @@ import { deployRegistry21 } from './helpers'
const describeMaybe = process.env.SKIP_SLOW ? describe.skip : describe
const itMaybe = process.env.SKIP_SLOW ? it.skip : it
+//////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////
+
+/*********************************** REGISTRY v2.1 IS FROZEN ************************************/
+
+// We are leaving the original tests enabled, however as 2.1 is still actively being deployed
+
+describe('KeeperRegistry2_1 - Frozen [ @skip-coverage ]', () => {
+ it('has not changed', () => {
+ assert.equal(
+ ethers.utils.id(KeeperRegistryFactory.bytecode),
+ '0xd8dfe20e746039e8420349326becc0a15dcd8fa3cd6aa0924d214328a7c45206',
+ 'KeeperRegistry bytecode has changed',
+ )
+ assert.equal(
+ ethers.utils.id(KeeperRegistryLogicAFactory.bytecode),
+ '0xe69d334fa75af0d6d8572996d815c93b8be1c8546670510b0d20ef349e57b2df',
+ 'KeeperRegistryLogicA bytecode has changed',
+ )
+ assert.equal(
+ ethers.utils.id(KeeperRegistryLogicBFactory.bytecode),
+ '0x891c26ba35b9b13afc9400fac5471d15842828ab717cbdc70ee263210c542563',
+ 'KeeperRegistryLogicB bytecode has changed',
+ )
+ assert.equal(
+ ethers.utils.id(AutomationForwarderLogicFactory.bytecode),
+ '0x195e2d7ecc26c75206820a5d3bd16e3a0214dc9764cc335f5d2c457cda90fe84',
+ 'AutomationForwarderLogic bytecode has changed',
+ )
+ })
+})
+
+//////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////
+
// copied from AutomationRegistryInterface2_1.sol
enum UpkeepFailureReason {
NONE,
@@ -142,7 +181,7 @@ let upkeepMockFactory: UpkeepMockFactory
let upkeepAutoFunderFactory: UpkeepAutoFunderFactory
let mockArbGasInfoFactory: MockArbGasInfoFactory
let mockOVMGasPriceOracleFactory: MockOVMGasPriceOracleFactory
-let mercuryUpkeepFactory: MercuryUpkeepFactory
+let streamsLookupUpkeepFactory: StreamsLookupUpkeepFactory
let personas: Personas
// contracts
@@ -160,7 +199,7 @@ let ltUpkeep: MockContract
let transcoder: UpkeepTranscoder
let mockArbGasInfo: MockArbGasInfo
let mockOVMGasPriceOracle: MockOVMGasPriceOracle
-let mercuryUpkeep: MercuryUpkeep
+let streamsLookupUpkeep: StreamsLookupUpkeep
let automationUtils: AutomationUtils
function now() {
@@ -411,7 +450,7 @@ describe('KeeperRegistry2_1', () => {
let upkeepId: BigNumber // conditional upkeep
let afUpkeepId: BigNumber // auto funding upkeep
let logUpkeepId: BigNumber // log trigger upkeepID
- let mercuryUpkeepId: BigNumber // mercury upkeep
+ let streamsLookupUpkeepId: BigNumber // streams lookup upkeep
const numUpkeeps = 4 // see above
let keeperAddresses: string[]
let payees: string[]
@@ -435,14 +474,15 @@ describe('KeeperRegistry2_1', () => {
'src/v0.8/tests/MockV3Aggregator.sol:MockV3Aggregator',
)) as unknown as MockV3AggregatorFactory
upkeepMockFactory = await ethers.getContractFactory('UpkeepMock')
- upkeepAutoFunderFactory = await ethers.getContractFactory(
- 'UpkeepAutoFunder',
- )
+ upkeepAutoFunderFactory =
+ await ethers.getContractFactory('UpkeepAutoFunder')
mockArbGasInfoFactory = await ethers.getContractFactory('MockArbGasInfo')
mockOVMGasPriceOracleFactory = await ethers.getContractFactory(
'MockOVMGasPriceOracle',
)
- mercuryUpkeepFactory = await ethers.getContractFactory('MercuryUpkeep')
+ streamsLookupUpkeepFactory = await ethers.getContractFactory(
+ 'StreamsLookupUpkeep',
+ )
owner = personas.Default
keeper1 = personas.Carol
@@ -664,17 +704,17 @@ describe('KeeperRegistry2_1', () => {
const verifyConsistentAccounting = async (
maxAllowedSpareChange: BigNumber,
) => {
- let expectedLinkBalance = (await registry.getState()).state
+ const expectedLinkBalance = (await registry.getState()).state
.expectedLinkBalance
- let linkTokenBalance = await linkToken.balanceOf(registry.address)
- let upkeepIdBalance = (await registry.getUpkeep(upkeepId)).balance
+ const linkTokenBalance = await linkToken.balanceOf(registry.address)
+ const upkeepIdBalance = (await registry.getUpkeep(upkeepId)).balance
let totalKeeperBalance = BigNumber.from(0)
for (let i = 0; i < keeperAddresses.length; i++) {
totalKeeperBalance = totalKeeperBalance.add(
(await registry.getTransmitterInfo(keeperAddresses[i])).balance,
)
}
- let ownerBalance = (await registry.getState()).state.ownerLinkBalance
+ const ownerBalance = (await registry.getState()).state.ownerLinkBalance
assert.isTrue(expectedLinkBalance.eq(linkTokenBalance))
assert.isTrue(
upkeepIdBalance
@@ -700,6 +740,7 @@ describe('KeeperRegistry2_1', () => {
performData?: string
checkBlockNum?: number
checkBlockHash?: string
+ logBlockHash?: BytesLike
txHash?: BytesLike
logIndex?: number
timestamp?: number
@@ -722,6 +763,7 @@ describe('KeeperRegistry2_1', () => {
checkBlockHash: latestBlock.hash,
logIndex: 0,
txHash: undefined, // assigned uniquely below
+ logBlockHash: undefined, // assigned uniquely below
timestamp: now(),
gasLimit: undefined,
gasPrice: undefined,
@@ -739,6 +781,7 @@ describe('KeeperRegistry2_1', () => {
break
case Trigger.LOG:
trigger = encodeLogTrigger({
+ logBlockHash: config.logBlockHash || ethers.utils.randomBytes(32),
txHash: config.txHash || ethers.utils.randomBytes(32),
logIndex: config.logIndex,
blockNum: config.checkBlockNum,
@@ -825,12 +868,14 @@ describe('KeeperRegistry2_1', () => {
mockOVMGasPriceOracle = await mockOVMGasPriceOracleFactory
.connect(owner)
.deploy()
- mercuryUpkeep = await mercuryUpkeepFactory
+ streamsLookupUpkeep = await streamsLookupUpkeepFactory
.connect(owner)
.deploy(
BigNumber.from('10000'),
BigNumber.from('100'),
- true /* set to true so it uses block.number */,
+ false /* useArbBlock */,
+ true /* staging */,
+ false /* verify mercury response */,
)
const arbOracleCode = await ethers.provider.send('eth_getCode', [
@@ -991,13 +1036,13 @@ describe('KeeperRegistry2_1', () => {
tx = await registry
.connect(owner)
['registerUpkeep(address,uint32,address,bytes,bytes)'](
- mercuryUpkeep.address,
+ streamsLookupUpkeep.address,
performGas,
await admin.getAddress(),
randomBytes,
'0x',
)
- mercuryUpkeepId = await getUpkeepID(tx)
+ streamsLookupUpkeepId = await getUpkeepID(tx)
}
const getMultipleUpkeepsDeployedAndFunded = async (
@@ -1005,9 +1050,9 @@ describe('KeeperRegistry2_1', () => {
numPassingLogUpkeeps: number,
numFailingUpkeeps: number,
) => {
- let passingConditionalUpkeepIds = []
- let passingLogUpkeepIds = []
- let failingUpkeepIds = []
+ const passingConditionalUpkeepIds = []
+ const passingLogUpkeepIds = []
+ const failingUpkeepIds = []
for (let i = 0; i < numPassingConditionalUpkeeps; i++) {
const mock = await upkeepMockFactory.deploy()
await mock.setCanPerform(true)
@@ -1195,18 +1240,19 @@ describe('KeeperRegistry2_1', () => {
})
it('handles duplicate log triggers', async () => {
+ const logBlockHash = ethers.utils.randomBytes(32)
const txHash = ethers.utils.randomBytes(32)
const logIndex = 0
const expectedDedupKey = ethers.utils.solidityKeccak256(
- ['uint256', 'bytes32', 'uint32'],
- [logUpkeepId, txHash, logIndex],
+ ['uint256', 'bytes32', 'bytes32', 'uint32'],
+ [logUpkeepId, logBlockHash, txHash, logIndex],
)
assert.isFalse(await registry.hasDedupKey(expectedDedupKey))
const tx = await getTransmitTx(
registry,
keeper1,
[logUpkeepId, logUpkeepId],
- { txHash, logIndex }, // will result in the same dedup key
+ { logBlockHash, txHash, logIndex }, // will result in the same dedup key
)
const receipt = await tx.wait()
const staleUpkeepReport = parseStaleUpkeepReportLogs(receipt)
@@ -2126,15 +2172,15 @@ describe('KeeperRegistry2_1', () => {
numFailingUpkeeps +
'] performs successful upkeeps and does not charge failing upkeeps',
async () => {
- let allUpkeeps = await getMultipleUpkeepsDeployedAndFunded(
+ const allUpkeeps = await getMultipleUpkeepsDeployedAndFunded(
numPassingConditionalUpkeeps,
numPassingLogUpkeeps,
numFailingUpkeeps,
)
- let passingConditionalUpkeepIds =
+ const passingConditionalUpkeepIds =
allUpkeeps.passingConditionalUpkeepIds
- let passingLogUpkeepIds = allUpkeeps.passingLogUpkeepIds
- let failingUpkeepIds = allUpkeeps.failingUpkeepIds
+ const passingLogUpkeepIds = allUpkeeps.passingLogUpkeepIds
+ const failingUpkeepIds = allUpkeeps.failingUpkeepIds
const keeperBefore = await registry.getTransmitterInfo(
await keeper1.getAddress(),
@@ -2353,15 +2399,15 @@ describe('KeeperRegistry2_1', () => {
numFailingUpkeeps +
'] splits gas overhead appropriately among performed upkeeps [ @skip-coverage ]',
async () => {
- let allUpkeeps = await getMultipleUpkeepsDeployedAndFunded(
+ const allUpkeeps = await getMultipleUpkeepsDeployedAndFunded(
numPassingConditionalUpkeeps,
numPassingLogUpkeeps,
numFailingUpkeeps,
)
- let passingConditionalUpkeepIds =
+ const passingConditionalUpkeepIds =
allUpkeeps.passingConditionalUpkeepIds
- let passingLogUpkeepIds = allUpkeeps.passingLogUpkeepIds
- let failingUpkeepIds = allUpkeeps.failingUpkeepIds
+ const passingLogUpkeepIds = allUpkeeps.passingLogUpkeepIds
+ const failingUpkeepIds = allUpkeeps.failingUpkeepIds
// Perform the upkeeps once to remove non-zero storage slots and have predictable gas measurement
let tx = await getTransmitTx(
@@ -3192,7 +3238,7 @@ describe('KeeperRegistry2_1', () => {
it('calls checkLog for log-trigger upkeeps', async () => {
const log: Log = {
index: 0,
- txIndex: 0,
+ timestamp: 0,
txHash: ethers.utils.randomBytes(32),
blockNumber: 100,
blockHash: ethers.utils.randomBytes(32),
@@ -3293,7 +3339,7 @@ describe('KeeperRegistry2_1', () => {
expect(upkeepIds).to.deep.equal([
afUpkeepId,
logUpkeepId,
- mercuryUpkeepId,
+ streamsLookupUpkeepId,
])
})
@@ -5435,12 +5481,12 @@ describe('KeeperRegistry2_1', () => {
describe('#checkCallback', () => {
it('returns false with appropriate failure reason when target callback reverts', async () => {
- await mercuryUpkeep.setShouldRevertCallback(true)
+ await streamsLookupUpkeep.setShouldRevertCallback(true)
const values: any[] = ['0x1234', '0xabcd']
const res = await registry
.connect(zeroAddress)
- .callStatic.checkCallback(mercuryUpkeepId, values, '0x')
+ .callStatic.checkCallback(streamsLookupUpkeepId, values, '0x')
assert.isFalse(res.upkeepNeeded)
assert.equal(res.performData, '0x')
@@ -5459,7 +5505,7 @@ describe('KeeperRegistry2_1', () => {
const values: any[] = [longBytes, longBytes]
const res = await registry
.connect(zeroAddress)
- .callStatic.checkCallback(mercuryUpkeepId, values, '0x')
+ .callStatic.checkCallback(streamsLookupUpkeepId, values, '0x')
assert.isFalse(res.upkeepNeeded)
assert.equal(res.performData, '0x')
@@ -5471,11 +5517,11 @@ describe('KeeperRegistry2_1', () => {
})
it('returns false with appropriate failure reason when target callback returns false', async () => {
- await mercuryUpkeep.setCallbackReturnBool(false)
+ await streamsLookupUpkeep.setCallbackReturnBool(false)
const values: any[] = ['0x1234', '0xabcd']
const res = await registry
.connect(zeroAddress)
- .callStatic.checkCallback(mercuryUpkeepId, values, '0x')
+ .callStatic.checkCallback(streamsLookupUpkeepId, values, '0x')
assert.isFalse(res.upkeepNeeded)
assert.equal(res.performData, '0x')
@@ -5491,7 +5537,7 @@ describe('KeeperRegistry2_1', () => {
const res = await registry
.connect(zeroAddress)
- .callStatic.checkCallback(mercuryUpkeepId, values, '0x')
+ .callStatic.checkCallback(streamsLookupUpkeepId, values, '0x')
const expectedPerformData = ethers.utils.defaultAbiCoder.encode(
['bytes[]', 'bytes'],
[values, '0x'],
@@ -5618,8 +5664,8 @@ describe('KeeperRegistry2_1', () => {
await getTransmitTx(registry, keeper1, [upkeepId])
const registryPremium = (await registry.getState()).state.totalPremium
- let k1 = await registry.getTransmitterInfo(await keeper1.getAddress())
- let k2 = await registry.getTransmitterInfo(await keeper2.getAddress())
+ const k1 = await registry.getTransmitterInfo(await keeper1.getAddress())
+ const k2 = await registry.getTransmitterInfo(await keeper2.getAddress())
// Withdrawing for first time, last collected = 0
assert.isTrue(k1.lastCollected.eq(BigNumber.from(0)))
diff --git a/contracts/test/v0.8/automation/UpkeepTranscoder.test.ts b/contracts/test/v0.8/automation/UpkeepTranscoder.test.ts
index cc908be1303..6ce7673a228 100644
--- a/contracts/test/v0.8/automation/UpkeepTranscoder.test.ts
+++ b/contracts/test/v0.8/automation/UpkeepTranscoder.test.ts
@@ -31,10 +31,7 @@ describe('UpkeepTranscoder', () => {
const encodedData = '0xc0ffee'
it('reverts if the from type is not an enum value', async () => {
- await evmRevert(
- transcoder.transcodeUpkeeps(3, 1, encodedData),
- 'function was called with incorrect parameters',
- )
+ await evmRevert(transcoder.transcodeUpkeeps(3, 1, encodedData))
})
it('reverts if the from type != to type', async () => {
diff --git a/contracts/test/v0.8/automation/UpkeepTranscoder3_0.test.ts b/contracts/test/v0.8/automation/UpkeepTranscoder3_0.test.ts
index 8bad7f63873..2f0f169ab1f 100644
--- a/contracts/test/v0.8/automation/UpkeepTranscoder3_0.test.ts
+++ b/contracts/test/v0.8/automation/UpkeepTranscoder3_0.test.ts
@@ -164,9 +164,8 @@ async function deployLegacyRegistry1_2(
) {
const mock = await upkeepMockFactory.deploy()
// @ts-ignore bug in autogen file
- const keeperRegistryFactory = await ethers.getContractFactory(
- 'KeeperRegistry1_2',
- )
+ const keeperRegistryFactory =
+ await ethers.getContractFactory('KeeperRegistry1_2')
transcoder = await upkeepTranscoderFactory.connect(owner).deploy()
const legacyRegistry = await keeperRegistryFactory
.connect(owner)
diff --git a/contracts/test/v0.8/automation/UpkeepTranscoder4_0.test.ts b/contracts/test/v0.8/automation/UpkeepTranscoder4_0.test.ts
index 7c7715fd599..970054893d2 100644
--- a/contracts/test/v0.8/automation/UpkeepTranscoder4_0.test.ts
+++ b/contracts/test/v0.8/automation/UpkeepTranscoder4_0.test.ts
@@ -10,6 +10,7 @@ import { getUsers, Personas } from '../../test-helpers/setup'
import { KeeperRegistryLogic2_0__factory as KeeperRegistryLogic20Factory } from '../../../typechain/factories/KeeperRegistryLogic2_0__factory'
import { KeeperRegistry1_3__factory as KeeperRegistry1_3Factory } from '../../../typechain/factories/KeeperRegistry1_3__factory'
import { KeeperRegistryLogic1_3__factory as KeeperRegistryLogicFactory } from '../../../typechain/factories/KeeperRegistryLogic1_3__factory'
+import { UpkeepTranscoder4_0__factory as UpkeepTranscoderFactory } from '../../../typechain/factories/UpkeepTranscoder4_0__factory'
import { toWei } from '../../test-helpers/helpers'
import { loadFixture } from '@nomicfoundation/hardhat-network-helpers'
import {
@@ -23,6 +24,26 @@ import {
} from '../../../typechain'
import { deployRegistry21 } from './helpers'
+//////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////
+
+/*********************************** TRANSCODER v4.0 IS FROZEN ************************************/
+
+// We are leaving the original tests enabled, however as automation v2.1 is still actively being deployed
+
+describe('UpkeepTranscoder v4.0 - Frozen [ @skip-coverage ]', () => {
+ it('has not changed', () => {
+ assert.equal(
+ ethers.utils.id(UpkeepTranscoderFactory.bytecode),
+ '0xf22c4701b0088e6e69c389a34a22041a69f00890a89246e3c2a6d38172222dae',
+ 'UpkeepTranscoder bytecode has changed',
+ )
+ })
+})
+
+//////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////
+
let transcoder: UpkeepTranscoder
let linkTokenFactory: LinkTokenFactory
let keeperRegistryFactory20: KeeperRegistry2_0Factory
@@ -119,9 +140,8 @@ const encodeUpkeepV12 = (ids: number[], upkeeps: any[], checkDatas: any[]) => {
}
async function deployRegistry1_2(): Promise<[BigNumber, KeeperRegistry1_2]> {
- const keeperRegistryFactory = await ethers.getContractFactory(
- 'KeeperRegistry1_2',
- )
+ const keeperRegistryFactory =
+ await ethers.getContractFactory('KeeperRegistry1_2')
const registry12 = await keeperRegistryFactory
.connect(owner)
.deploy(linkToken.address, linkEthFeed.address, gasPriceFeed.address, {
diff --git a/contracts/test/v0.8/dev/ArbitrumCrossDomainForwarder.test.ts b/contracts/test/v0.8/dev/ArbitrumCrossDomainForwarder.test.ts
index 63a22c6ba3c..6b6d8abad1b 100644
--- a/contracts/test/v0.8/dev/ArbitrumCrossDomainForwarder.test.ts
+++ b/contracts/test/v0.8/dev/ArbitrumCrossDomainForwarder.test.ts
@@ -28,7 +28,7 @@ before(async () => {
// Contract factories
forwarderFactory = await ethers.getContractFactory(
- 'src/v0.8/dev/ArbitrumCrossDomainForwarder.sol:ArbitrumCrossDomainForwarder',
+ 'src/v0.8/l2ep/dev/arbitrum/ArbitrumCrossDomainForwarder.sol:ArbitrumCrossDomainForwarder',
owner,
)
greeterFactory = await ethers.getContractFactory(
diff --git a/contracts/test/v0.8/dev/ArbitrumCrossDomainGovernor.test.ts b/contracts/test/v0.8/dev/ArbitrumCrossDomainGovernor.test.ts
index c7a8098800c..1275cc6f3fb 100644
--- a/contracts/test/v0.8/dev/ArbitrumCrossDomainGovernor.test.ts
+++ b/contracts/test/v0.8/dev/ArbitrumCrossDomainGovernor.test.ts
@@ -31,7 +31,7 @@ before(async () => {
// Contract factories
governorFactory = await ethers.getContractFactory(
- 'src/v0.8/dev/ArbitrumCrossDomainGovernor.sol:ArbitrumCrossDomainGovernor',
+ 'src/v0.8/l2ep/dev/arbitrum/ArbitrumCrossDomainGovernor.sol:ArbitrumCrossDomainGovernor',
owner,
)
greeterFactory = await ethers.getContractFactory(
diff --git a/contracts/test/v0.8/dev/ArbitrumSequencerUptimeFeed.test.ts b/contracts/test/v0.8/dev/ArbitrumSequencerUptimeFeed.test.ts
index c5bf9eacb56..ad1b549acca 100644
--- a/contracts/test/v0.8/dev/ArbitrumSequencerUptimeFeed.test.ts
+++ b/contracts/test/v0.8/dev/ArbitrumSequencerUptimeFeed.test.ts
@@ -38,7 +38,7 @@ describe('ArbitrumSequencerUptimeFeed', () => {
beforeEach(async () => {
const accessControllerFactory = await ethers.getContractFactory(
- 'src/v0.8/SimpleWriteAccessController.sol:SimpleWriteAccessController',
+ 'src/v0.8/shared/access/SimpleWriteAccessController.sol:SimpleWriteAccessController',
deployer,
)
accessController = await accessControllerFactory.deploy()
@@ -55,7 +55,7 @@ describe('ArbitrumSequencerUptimeFeed', () => {
const arbitrumSequencerStatusRecorderFactory =
await ethers.getContractFactory(
- 'src/v0.8/dev/ArbitrumSequencerUptimeFeed.sol:ArbitrumSequencerUptimeFeed',
+ 'src/v0.8/l2ep/dev/arbitrum/ArbitrumSequencerUptimeFeed.sol:ArbitrumSequencerUptimeFeed',
deployer,
)
arbitrumSequencerUptimeFeed =
diff --git a/contracts/test/v0.8/dev/ArbitrumValidator.test.ts b/contracts/test/v0.8/dev/ArbitrumValidator.test.ts
index e1d478d33d1..2f95a6f6fb0 100644
--- a/contracts/test/v0.8/dev/ArbitrumValidator.test.ts
+++ b/contracts/test/v0.8/dev/ArbitrumValidator.test.ts
@@ -8,9 +8,9 @@ import {
} from '@ethereum-waffle/mock-contract'
/// Pick ABIs from compilation
// @ts-ignore
-import { abi as arbitrumSequencerStatusRecorderAbi } from '../../../artifacts/src/v0.8/dev/ArbitrumSequencerUptimeFeed.sol/ArbitrumSequencerUptimeFeed.json'
+import { abi as arbitrumSequencerStatusRecorderAbi } from '../../../artifacts/src/v0.8/l2ep/dev/arbitrum/ArbitrumSequencerUptimeFeed.sol/ArbitrumSequencerUptimeFeed.json'
// @ts-ignore
-import { abi as arbitrumInboxAbi } from '../../../artifacts/src/v0.8/dev/vendor/arb-bridge-eth/v0.8.0-custom/contracts/bridge/interfaces/IInbox.sol/IInbox.json'
+import { abi as arbitrumInboxAbi } from '../../../artifacts/src/v0.8/vendor/arb-bridge-eth/v0.8.0-custom/contracts/bridge/interfaces/IInbox.sol/IInbox.json'
// @ts-ignore
import { abi as aggregatorAbi } from '../../../artifacts/src/v0.8/interfaces/AggregatorV2V3Interface.sol/AggregatorV2V3Interface.json'
@@ -50,14 +50,14 @@ describe('ArbitrumValidator', () => {
beforeEach(async () => {
const accessControllerFactory = await ethers.getContractFactory(
- 'src/v0.8/SimpleWriteAccessController.sol:SimpleWriteAccessController',
+ 'src/v0.8/shared/access/SimpleWriteAccessController.sol:SimpleWriteAccessController',
deployer,
)
accessController = await accessControllerFactory.deploy()
// Required for building the calldata
arbitrumSequencerStatusRecorderFactory = await ethers.getContractFactory(
- 'src/v0.8/dev/ArbitrumSequencerUptimeFeed.sol:ArbitrumSequencerUptimeFeed',
+ 'src/v0.8/l2ep/dev/arbitrum/ArbitrumSequencerUptimeFeed.sol:ArbitrumSequencerUptimeFeed',
deployer,
)
l1GasFeed = await deployMockContract(deployer as any, aggregatorAbi)
@@ -76,7 +76,7 @@ describe('ArbitrumValidator', () => {
// Contract under test
const arbitrumValidatorFactory = await ethers.getContractFactory(
- 'src/v0.8/dev/ArbitrumValidator.sol:ArbitrumValidator',
+ 'src/v0.8/l2ep/dev/arbitrum/ArbitrumValidator.sol:ArbitrumValidator',
deployer,
)
arbitrumValidator = await arbitrumValidatorFactory.deploy(
diff --git a/contracts/test/v0.8/dev/AuthorizedOriginReceiver.test.ts b/contracts/test/v0.8/dev/AuthorizedOriginReceiver.test.ts
index 007986810c9..dc6406422de 100644
--- a/contracts/test/v0.8/dev/AuthorizedOriginReceiver.test.ts
+++ b/contracts/test/v0.8/dev/AuthorizedOriginReceiver.test.ts
@@ -10,7 +10,7 @@ before(async () => {
roles = (await getUsers()).roles
authorizedOriginReceiverFactory = await ethers.getContractFactory(
- 'src/v0.8/functions/tests/0_0_0/testhelpers/AuthorizedOriginReceiverTestHelper.sol:AuthorizedOriginReceiverTestHelper',
+ 'src/v0.8/functions/tests/v0_0_0/testhelpers/AuthorizedOriginReceiverTestHelper.sol:AuthorizedOriginReceiverTestHelper',
roles.defaultAccount,
)
})
diff --git a/contracts/test/v0.8/dev/AuthorizedReceiver.test.ts b/contracts/test/v0.8/dev/AuthorizedReceiver.test.ts
index 578c7192007..ca9951e6889 100644
--- a/contracts/test/v0.8/dev/AuthorizedReceiver.test.ts
+++ b/contracts/test/v0.8/dev/AuthorizedReceiver.test.ts
@@ -10,7 +10,7 @@ before(async () => {
roles = (await getUsers()).roles
authorizedReceiverFactory = await ethers.getContractFactory(
- 'src/v0.8/functions/tests/0_0_0/testhelpers/AuthorizedReceiverTestHelper.sol:AuthorizedReceiverTestHelper',
+ 'src/v0.8/functions/tests/v0_0_0/testhelpers/AuthorizedReceiverTestHelper.sol:AuthorizedReceiverTestHelper',
roles.defaultAccount,
)
})
diff --git a/contracts/test/v0.8/dev/CrossDomainOwnable.test.ts b/contracts/test/v0.8/dev/CrossDomainOwnable.test.ts
index c46845f4f06..7d9d58cfbaa 100644
--- a/contracts/test/v0.8/dev/CrossDomainOwnable.test.ts
+++ b/contracts/test/v0.8/dev/CrossDomainOwnable.test.ts
@@ -17,7 +17,7 @@ before(async () => {
// Contract factories
ownableFactory = await ethers.getContractFactory(
- 'src/v0.8/dev/CrossDomainOwnable.sol:CrossDomainOwnable',
+ 'src/v0.8/l2ep/dev/CrossDomainOwnable.sol:CrossDomainOwnable',
owner,
)
})
diff --git a/contracts/test/v0.8/dev/OptimismCrossDomainForwarder.test.ts b/contracts/test/v0.8/dev/OptimismCrossDomainForwarder.test.ts
index 2668f4ea672..3b75b412bfd 100644
--- a/contracts/test/v0.8/dev/OptimismCrossDomainForwarder.test.ts
+++ b/contracts/test/v0.8/dev/OptimismCrossDomainForwarder.test.ts
@@ -26,7 +26,7 @@ before(async () => {
// Contract factories
forwarderFactory = await ethers.getContractFactory(
- 'src/v0.8/dev/OptimismCrossDomainForwarder.sol:OptimismCrossDomainForwarder',
+ 'src/v0.8/l2ep/dev/optimism/OptimismCrossDomainForwarder.sol:OptimismCrossDomainForwarder',
owner,
)
greeterFactory = await ethers.getContractFactory(
@@ -40,9 +40,8 @@ before(async () => {
describe('OptimismCrossDomainForwarder', () => {
beforeEach(async () => {
- crossDomainMessenger = await crossDomainMessengerFactory.deploy(
- l1OwnerAddress,
- )
+ crossDomainMessenger =
+ await crossDomainMessengerFactory.deploy(l1OwnerAddress)
forwarder = await forwarderFactory.deploy(
crossDomainMessenger.address,
l1OwnerAddress,
diff --git a/contracts/test/v0.8/dev/OptimismCrossDomainGovernor.test.ts b/contracts/test/v0.8/dev/OptimismCrossDomainGovernor.test.ts
index 53c3f4ef254..9ea425bb995 100644
--- a/contracts/test/v0.8/dev/OptimismCrossDomainGovernor.test.ts
+++ b/contracts/test/v0.8/dev/OptimismCrossDomainGovernor.test.ts
@@ -28,7 +28,7 @@ before(async () => {
// Contract factories
governorFactory = await ethers.getContractFactory(
- 'src/v0.8/dev/OptimismCrossDomainGovernor.sol:OptimismCrossDomainGovernor',
+ 'src/v0.8/l2ep/dev/optimism/OptimismCrossDomainGovernor.sol:OptimismCrossDomainGovernor',
owner,
)
greeterFactory = await ethers.getContractFactory(
@@ -46,9 +46,8 @@ before(async () => {
describe('OptimismCrossDomainGovernor', () => {
beforeEach(async () => {
- crossDomainMessenger = await crossDomainMessengerFactory.deploy(
- l1OwnerAddress,
- )
+ crossDomainMessenger =
+ await crossDomainMessengerFactory.deploy(l1OwnerAddress)
governor = await governorFactory.deploy(
crossDomainMessenger.address,
l1OwnerAddress,
diff --git a/contracts/test/v0.8/dev/OptimismSequencerUptimeFeed.test.ts b/contracts/test/v0.8/dev/OptimismSequencerUptimeFeed.test.ts
index 3be966d816a..2856568793a 100644
--- a/contracts/test/v0.8/dev/OptimismSequencerUptimeFeed.test.ts
+++ b/contracts/test/v0.8/dev/OptimismSequencerUptimeFeed.test.ts
@@ -43,7 +43,7 @@ describe('OptimismSequencerUptimeFeed', () => {
beforeEach(async () => {
const optimismSequencerStatusRecorderFactory =
await ethers.getContractFactory(
- 'src/v0.8/dev/OptimismSequencerUptimeFeed.sol:OptimismSequencerUptimeFeed',
+ 'src/v0.8/l2ep/dev/optimism/OptimismSequencerUptimeFeed.sol:OptimismSequencerUptimeFeed',
deployer,
)
optimismUptimeFeed = await optimismSequencerStatusRecorderFactory.deploy(
@@ -108,8 +108,7 @@ describe('OptimismSequencerUptimeFeed', () => {
.updateStatus(true, timestamp.add(200))
// Submit another status update with the same status
- const currentBlock = await ethers.provider.getBlockNumber()
- const latestBlock = await ethers.provider.getBlock(currentBlock)
+ const latestBlock = await ethers.provider.getBlock('latest')
await expect(tx)
.to.emit(optimismUptimeFeed, 'RoundUpdated')
diff --git a/contracts/test/v0.8/dev/OptimismValidator.test.ts b/contracts/test/v0.8/dev/OptimismValidator.test.ts
index 4ed901af825..120b1057d14 100644
--- a/contracts/test/v0.8/dev/OptimismValidator.test.ts
+++ b/contracts/test/v0.8/dev/OptimismValidator.test.ts
@@ -4,7 +4,7 @@ import { expect } from 'chai'
import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'
/// Pick ABIs from compilation
// @ts-ignore
-import { abi as optimismSequencerStatusRecorderAbi } from '../../../artifacts/src/v0.8/dev/OptimismSequencerUptimeFeed.sol/OptimismSequencerUptimeFeed.json'
+import { abi as optimismSequencerStatusRecorderAbi } from '../../../artifacts/src/v0.8/l2ep/dev/optimism/OptimismSequencerUptimeFeed.sol/OptimismSequencerUptimeFeed.json'
// @ts-ignore
import { abi as optimismL1CrossDomainMessengerAbi } from '@eth-optimism/contracts/artifacts/contracts/L1/messaging/L1CrossDomainMessenger.sol'
// @ts-ignore
@@ -30,7 +30,7 @@ describe('OptimismValidator', () => {
beforeEach(async () => {
// Required for building the calldata
optimismUptimeFeedFactory = await ethers.getContractFactory(
- 'src/v0.8/dev/OptimismSequencerUptimeFeed.sol:OptimismSequencerUptimeFeed',
+ 'src/v0.8/l2ep/dev/optimism/OptimismSequencerUptimeFeed.sol:OptimismSequencerUptimeFeed',
deployer,
)
@@ -44,7 +44,7 @@ describe('OptimismValidator', () => {
// Contract under test
const optimismValidatorFactory = await ethers.getContractFactory(
- 'src/v0.8/dev/OptimismValidator.sol:OptimismValidator',
+ 'src/v0.8/l2ep/dev/optimism/OptimismValidator.sol:OptimismValidator',
deployer,
)
@@ -75,8 +75,7 @@ describe('OptimismValidator', () => {
it('posts sequencer status when there is not status change', async () => {
await optimismValidator.addAccess(eoaValidator.address)
- const currentBlockNum = await ethers.provider.getBlockNumber()
- const currentBlock = await ethers.provider.getBlock(currentBlockNum)
+ const currentBlock = await ethers.provider.getBlock('latest')
const futureTimestamp = currentBlock.timestamp + 5000
await ethers.provider.send('evm_setNextBlockTimestamp', [futureTimestamp])
@@ -100,8 +99,7 @@ describe('OptimismValidator', () => {
it('post sequencer offline', async () => {
await optimismValidator.addAccess(eoaValidator.address)
- const currentBlockNum = await ethers.provider.getBlockNumber()
- const currentBlock = await ethers.provider.getBlock(currentBlockNum)
+ const currentBlock = await ethers.provider.getBlock('latest')
const futureTimestamp = currentBlock.timestamp + 10000
await ethers.provider.send('evm_setNextBlockTimestamp', [futureTimestamp])
diff --git a/contracts/test/v0.8/dev/VRFCoordinatorV2Mock.test.ts b/contracts/test/v0.8/dev/VRFCoordinatorV2Mock.test.ts
index b3446ddb154..b0a2a10b201 100644
--- a/contracts/test/v0.8/dev/VRFCoordinatorV2Mock.test.ts
+++ b/contracts/test/v0.8/dev/VRFCoordinatorV2Mock.test.ts
@@ -262,7 +262,7 @@ describe('VRFCoordinatorV2Mock', () => {
expect(receipt.events[0].args['success']).to.equal(true)
assert(
receipt.events[0].args['payment']
- .sub(BigNumber.from('100119017000000000'))
+ .sub(BigNumber.from('100119403000000000'))
.lt(BigNumber.from('10000000000')),
)
@@ -315,7 +315,7 @@ describe('VRFCoordinatorV2Mock', () => {
expect(receipt.events[0].args['success']).to.equal(true)
assert(
receipt.events[0].args['payment']
- .sub(BigNumber.from('100119017000000000'))
+ .sub(BigNumber.from('100120516000000000'))
.lt(BigNumber.from('10000000000')),
)
diff --git a/contracts/test/v0.8/foundry/transmission/EIP_712_1014_4337.t.sol b/contracts/test/v0.8/foundry/transmission/EIP_712_1014_4337.t.sol
index 3040fda97de..acdc6773642 100644
--- a/contracts/test/v0.8/foundry/transmission/EIP_712_1014_4337.t.sol
+++ b/contracts/test/v0.8/foundry/transmission/EIP_712_1014_4337.t.sol
@@ -1,15 +1,15 @@
pragma solidity ^0.8.15;
import "../BaseTest.t.sol";
-import "../../../../src/v0.8/dev/transmission/4337/SmartContractAccountFactory.sol";
+import "../../../../src/v0.8/dev/transmission/ERC-4337/SmartContractAccountFactory.sol";
import "../../../../src/v0.8/dev/transmission/testhelpers/SmartContractAccountHelper.sol";
-import "../../../../src/v0.8/dev/transmission/4337/SCA.sol";
+import "../../../../src/v0.8/dev/transmission/ERC-4337/SCA.sol";
import "../../../../src/v0.8/dev/transmission/testhelpers/Greeter.sol";
-import "../../../../src/v0.8/dev/transmission/4337/Paymaster.sol";
+import "../../../../src/v0.8/dev/transmission/ERC-4337/Paymaster.sol";
import "../../../../src/v0.8/vendor/entrypoint/interfaces/UserOperation.sol";
import "../../../../src/v0.8/vendor/entrypoint/core/EntryPoint.sol";
import "../../../../src/v0.8/vendor/entrypoint/interfaces/IEntryPoint.sol";
-import "../../../../src/v0.8/dev/transmission/4337/SCALibrary.sol";
+import "../../../../src/v0.8/dev/transmission/ERC-4337/SCALibrary.sol";
import "../../../../src/v0.8/mocks/MockLinkToken.sol";
import "../../../../src/v0.8/shared/interfaces/LinkTokenInterface.sol";
import "../../../../src/v0.8/mocks/VRFCoordinatorMock.sol";
diff --git a/contracts/test/v0.8/foundry/vrf/TrustedBlockhashStore.t.sol b/contracts/test/v0.8/foundry/vrf/TrustedBlockhashStore.t.sol
index d2f52552e43..47fff7ea900 100644
--- a/contracts/test/v0.8/foundry/vrf/TrustedBlockhashStore.t.sol
+++ b/contracts/test/v0.8/foundry/vrf/TrustedBlockhashStore.t.sol
@@ -48,6 +48,7 @@ contract TrustedBlockhashStoreTest is BaseTest {
assertEq(blockhash(unreachableBlock), 0);
// Store blockhash from whitelisted address;
+ uint256[] memory invalidBlockNums = new uint256[](0);
uint256[] memory blockNums = new uint256[](1);
blockNums[0] = unreachableBlock;
bytes32[] memory blockhashes = new bytes32[](1);
@@ -64,9 +65,25 @@ contract TrustedBlockhashStoreTest is BaseTest {
vm.expectRevert("Only callable by owner");
bhs.setWhitelist(new address[](0));
- // Should store unreachable blocks via whitelisted address.
+ // Should not store for a mismatched list of block numbers and hashes.
changePrank(LINK_WHALE);
+ vm.expectRevert(TrustedBlockhashStore.InvalidTrustedBlockhashes.selector);
+ bhs.storeTrusted(invalidBlockNums, blockhashes, recentBlockNumber, blockhash(recentBlockNumber));
+
+ // Should store unreachable blocks via whitelisted address.
bhs.storeTrusted(blockNums, blockhashes, recentBlockNumber, blockhash(recentBlockNumber));
assertEq(bhs.getBlockhash(unreachableBlock), unreachableBlockhash);
+
+ // Change whitelist. Assert that the old whitelisted address can no longer store,
+ // but the new one can.
+ address[] memory newWhitelist = new address[](1);
+ newWhitelist[0] = LINK_WHALE_2;
+ bhs.setWhitelist(newWhitelist);
+
+ vm.expectRevert(TrustedBlockhashStore.NotInWhitelist.selector);
+ bhs.storeTrusted(blockNums, blockhashes, recentBlockNumber, blockhash(recentBlockNumber));
+
+ changePrank(LINK_WHALE_2);
+ bhs.storeTrusted(blockNums, blockhashes, recentBlockNumber, blockhash(recentBlockNumber));
}
}
diff --git a/contracts/test/v0.8/foundry/vrf/VRFCoordinatorV2Mock.t.sol b/contracts/test/v0.8/foundry/vrf/VRFCoordinatorV2Mock.t.sol
new file mode 100644
index 00000000000..dd607f2ce7b
--- /dev/null
+++ b/contracts/test/v0.8/foundry/vrf/VRFCoordinatorV2Mock.t.sol
@@ -0,0 +1,381 @@
+pragma solidity 0.8.6;
+
+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 {VRFCoordinatorV2Mock} from "../../../../src/v0.8/mocks/VRFCoordinatorV2Mock.sol";
+import {VRFConsumerV2} from "../../../../src/v0.8/vrf/testhelpers/VRFConsumerV2.sol";
+
+contract VRFCoordinatorV2MockTest is BaseTest {
+ MockLinkToken internal s_linkToken;
+ MockV3Aggregator internal s_linkEthFeed;
+ VRFCoordinatorV2Mock internal s_vrfCoordinatorV2Mock;
+ VRFConsumerV2 internal s_vrfConsumerV2;
+ address internal s_subOwner = address(1234);
+ address internal s_randomOwner = address(4567);
+
+ // VRF KeyV2 generated from a node; not sensitive information.
+ // The secret key used to generate this key is: 10.
+ bytes internal constant UNCOMPRESSED_PUBLIC_KEY =
+ hex"a0434d9e47f3c86235477c7b1ae6ae5d3442d49b1943c2b752a68e2a47e247c7893aba425419bc27a3b6c7e693a24c696f794c2ed877a1593cbee53b037368d7";
+ bytes internal constant COMPRESSED_PUBLIC_KEY =
+ hex"a0434d9e47f3c86235477c7b1ae6ae5d3442d49b1943c2b752a68e2a47e247c701";
+ bytes32 internal constant KEY_HASH = hex"9f2353bde94264dbc3d554a94cceba2d7d2b4fdce4304d3e09a1fea9fbeb1528";
+
+ uint32 internal constant DEFAULT_CALLBACK_GAS_LIMIT = 500_000;
+ uint16 internal constant DEFAULT_REQUEST_CONFIRMATIONS = 3;
+ uint32 internal constant DEFAULT_NUM_WORDS = 1;
+
+ uint96 pointOneLink = 0.1 ether;
+ uint96 oneLink = 1 ether;
+
+ event SubscriptionCreated(uint64 indexed subId, address owner);
+ event SubscriptionFunded(uint64 indexed subId, uint256 oldBalance, uint256 newBalance);
+ event SubscriptionCanceled(uint64 indexed subId, address to, uint256 amount);
+ event ConsumerAdded(uint64 indexed subId, address consumer);
+ event ConsumerRemoved(uint64 indexed subId, address consumer);
+ event RandomWordsRequested(
+ bytes32 indexed keyHash,
+ uint256 requestId,
+ uint256 preSeed,
+ uint64 indexed subId,
+ uint16 minimumRequestConfirmations,
+ uint32 callbackGasLimit,
+ uint32 numWords,
+ address indexed sender
+ );
+ event RandomWordsFulfilled(uint256 indexed requestId, uint256 outputSeed, uint96 payment, bool success);
+
+ function setUp() public override {
+ BaseTest.setUp();
+
+ // Fund our users.
+ vm.roll(1);
+ vm.deal(OWNER, 10_000 ether);
+ vm.deal(s_subOwner, 20 ether);
+
+ // Deploy link token and link/eth feed.
+ s_linkToken = new MockLinkToken();
+ s_linkEthFeed = new MockV3Aggregator(18, 500000000000000000); // .5 ETH (good for testing)
+
+ // Deploy coordinator and consumer.
+ s_vrfCoordinatorV2Mock = new VRFCoordinatorV2Mock(
+ pointOneLink,
+ 1_000_000_000 // 0.000000001 LINK per gas
+ );
+ address coordinatorAddr = address(s_vrfCoordinatorV2Mock);
+ s_vrfConsumerV2 = new VRFConsumerV2(coordinatorAddr, address(s_linkToken));
+
+ s_vrfCoordinatorV2Mock.setConfig();
+ }
+
+ function testCreateSubscription() public {
+ vm.startPrank(s_subOwner);
+ vm.expectEmit(
+ true, // no first indexed topic
+ false, // no second indexed topic
+ false, // no third indexed topic
+ true // check data (target coordinator address)
+ );
+ emit SubscriptionCreated(1, s_subOwner);
+ uint64 subId = s_vrfCoordinatorV2Mock.createSubscription();
+ assertEq(subId, 1);
+
+ (uint96 balance, uint64 reqCount, address owner, address[] memory consumers) = s_vrfCoordinatorV2Mock
+ .getSubscription(subId);
+ assertEq(balance, 0);
+ assertEq(reqCount, 0);
+ assertEq(owner, s_subOwner);
+ assertEq(consumers.length, 0);
+ // s_testCoordinator.fundSubscriptionWithEth{value: 10 ether}(subId);
+
+ // Test if subId increments
+ vm.expectEmit(true, false, false, true);
+ emit SubscriptionCreated(2, s_subOwner);
+ subId = s_vrfCoordinatorV2Mock.createSubscription();
+ assertEq(subId, 2);
+ vm.stopPrank();
+ }
+
+ function testAddConsumer() public {
+ vm.startPrank(s_subOwner);
+ uint64 subId = s_vrfCoordinatorV2Mock.createSubscription();
+ vm.expectEmit(true, false, false, true);
+ emit ConsumerAdded(subId, address(s_vrfConsumerV2));
+ s_vrfCoordinatorV2Mock.addConsumer(subId, address(s_vrfConsumerV2));
+
+ (uint96 balance, uint64 reqCount, address owner, address[] memory consumers) = s_vrfCoordinatorV2Mock
+ .getSubscription(subId);
+ assertEq(balance, 0);
+ assertEq(reqCount, 0);
+ assertEq(owner, s_subOwner);
+ assertEq(consumers.length, 1);
+ assertEq(consumers[0], address(s_vrfConsumerV2));
+ vm.stopPrank();
+ }
+
+ // cannot add a consumer to a nonexistent subscription
+ function testAddConsumerToInvalidSub() public {
+ vm.startPrank(s_subOwner);
+ bytes4 reason = bytes4(keccak256("InvalidSubscription()"));
+ vm.expectRevert(toBytes(reason));
+ s_vrfCoordinatorV2Mock.addConsumer(1, address(s_vrfConsumerV2));
+ vm.stopPrank();
+ }
+
+ // cannot add more than the consumer maximum
+ function testAddMaxConsumers() public {
+ vm.startPrank(s_subOwner);
+ uint64 subId = s_vrfCoordinatorV2Mock.createSubscription();
+ // Add 100 consumers
+ for (uint64 i = 101; i <= 200; ++i) {
+ s_vrfCoordinatorV2Mock.addConsumer(subId, address(bytes20(keccak256(abi.encodePacked(i)))));
+ }
+ // Adding 101th consumer should revert
+ bytes4 reason = bytes4(keccak256("TooManyConsumers()"));
+ vm.expectRevert(toBytes(reason));
+ s_vrfCoordinatorV2Mock.addConsumer(subId, address(s_vrfConsumerV2));
+ vm.stopPrank();
+ }
+
+ // can remove a consumer from a subscription
+ function testRemoveConsumerFromSub() public {
+ vm.startPrank(s_subOwner);
+ uint64 subId = s_vrfCoordinatorV2Mock.createSubscription();
+
+ s_vrfCoordinatorV2Mock.addConsumer(subId, address(s_vrfConsumerV2));
+
+ (, , , address[] memory consumers) = s_vrfCoordinatorV2Mock.getSubscription(subId);
+ assertEq(consumers.length, 1);
+ assertEq(consumers[0], address(s_vrfConsumerV2));
+
+ vm.expectEmit(true, false, false, true);
+ emit ConsumerRemoved(subId, address(s_vrfConsumerV2));
+ s_vrfCoordinatorV2Mock.removeConsumer(subId, address(s_vrfConsumerV2));
+
+ vm.stopPrank();
+ }
+
+ // cannot remove a consumer from a nonexistent subscription
+ function testRemoveConsumerFromInvalidSub() public {
+ vm.startPrank(s_subOwner);
+ bytes4 reason = bytes4(keccak256("InvalidSubscription()"));
+ vm.expectRevert(toBytes(reason));
+ s_vrfCoordinatorV2Mock.removeConsumer(1, address(s_vrfConsumerV2));
+ vm.stopPrank();
+ }
+
+ // cannot remove a consumer after it is already removed
+ function testRemoveConsumerAgain() public {
+ vm.startPrank(s_subOwner);
+ uint64 subId = s_vrfCoordinatorV2Mock.createSubscription();
+
+ s_vrfCoordinatorV2Mock.addConsumer(subId, address(s_vrfConsumerV2));
+
+ (, , , address[] memory consumers) = s_vrfCoordinatorV2Mock.getSubscription(subId);
+ assertEq(consumers.length, 1);
+ assertEq(consumers[0], address(s_vrfConsumerV2));
+
+ vm.expectEmit(true, false, false, true);
+ emit ConsumerRemoved(subId, address(s_vrfConsumerV2));
+ s_vrfCoordinatorV2Mock.removeConsumer(subId, address(s_vrfConsumerV2));
+
+ // Removing consumer again should revert with InvalidConsumer
+ bytes4 reason = bytes4(keccak256("InvalidConsumer()"));
+ vm.expectRevert(toBytes(reason));
+ s_vrfCoordinatorV2Mock.removeConsumer(subId, address(s_vrfConsumerV2));
+ vm.stopPrank();
+ }
+
+ // can fund a subscription
+ function testFundSubscription() public {
+ vm.startPrank(s_subOwner);
+ uint64 subId = s_vrfCoordinatorV2Mock.createSubscription();
+
+ vm.expectEmit(true, false, false, true);
+ emit SubscriptionFunded(subId, 0, oneLink);
+ s_vrfCoordinatorV2Mock.fundSubscription(subId, oneLink);
+
+ (uint96 balance, , , address[] memory consumers) = s_vrfCoordinatorV2Mock.getSubscription(subId);
+ assertEq(balance, oneLink);
+ assertEq(consumers.length, 0);
+ vm.stopPrank();
+ }
+
+ // cannot fund a nonexistent subscription
+ function testFundInvalidSubscription() public {
+ vm.startPrank(s_subOwner);
+
+ // Removing consumer again should revert with InvalidConsumer
+ bytes4 reason = bytes4(keccak256("InvalidSubscription()"));
+ vm.expectRevert(toBytes(reason));
+ s_vrfCoordinatorV2Mock.removeConsumer(1, address(s_vrfConsumerV2));
+
+ vm.stopPrank();
+ }
+
+ // can cancel a subscription
+ function testCancelSubscription() public {
+ vm.startPrank(s_subOwner);
+ uint64 subId = s_vrfCoordinatorV2Mock.createSubscription();
+
+ s_vrfCoordinatorV2Mock.fundSubscription(subId, oneLink);
+
+ vm.expectEmit(true, false, false, true);
+ emit SubscriptionCanceled(subId, s_subOwner, oneLink);
+ s_vrfCoordinatorV2Mock.cancelSubscription(subId, s_subOwner);
+
+ bytes4 reason = bytes4(keccak256("InvalidSubscription()"));
+ vm.expectRevert(toBytes(reason));
+ s_vrfCoordinatorV2Mock.getSubscription(subId);
+
+ vm.stopPrank();
+ }
+
+ // fails to fulfill without being a valid consumer
+ function testRequestRandomWordsInvalidConsumer() public {
+ vm.startPrank(s_subOwner);
+ uint64 subId = s_vrfCoordinatorV2Mock.createSubscription();
+
+ s_vrfCoordinatorV2Mock.fundSubscription(subId, oneLink);
+
+ bytes4 reason = bytes4(keccak256("InvalidConsumer()"));
+ vm.expectRevert(toBytes(reason));
+ s_vrfCoordinatorV2Mock.requestRandomWords(
+ KEY_HASH,
+ subId,
+ DEFAULT_REQUEST_CONFIRMATIONS,
+ DEFAULT_CALLBACK_GAS_LIMIT,
+ DEFAULT_NUM_WORDS
+ );
+ vm.stopPrank();
+ }
+
+ // fails to fulfill with insufficient funds
+ function testRequestRandomWordsInsufficientFunds() public {
+ vm.startPrank(s_subOwner);
+ uint64 subId = s_vrfCoordinatorV2Mock.createSubscription();
+
+ address consumerAddr = address(s_vrfConsumerV2);
+ s_vrfCoordinatorV2Mock.addConsumer(subId, address(s_vrfConsumerV2));
+
+ vm.stopPrank();
+
+ vm.startPrank(consumerAddr);
+
+ vm.expectEmit(true, false, false, true);
+ emit RandomWordsRequested(
+ KEY_HASH,
+ 1,
+ 100,
+ subId,
+ DEFAULT_REQUEST_CONFIRMATIONS,
+ DEFAULT_CALLBACK_GAS_LIMIT,
+ DEFAULT_NUM_WORDS,
+ address(s_subOwner)
+ );
+ uint256 reqId = s_vrfCoordinatorV2Mock.requestRandomWords(
+ KEY_HASH,
+ subId,
+ DEFAULT_REQUEST_CONFIRMATIONS,
+ DEFAULT_CALLBACK_GAS_LIMIT,
+ DEFAULT_NUM_WORDS
+ );
+
+ bytes4 reason = bytes4(keccak256("InsufficientBalance()"));
+ vm.expectRevert(toBytes(reason));
+ s_vrfCoordinatorV2Mock.fulfillRandomWords(reqId, consumerAddr);
+
+ vm.stopPrank();
+ }
+
+ // can request and fulfill [ @skip-coverage ]
+ function testRequestRandomWordsHappyPath() public {
+ vm.startPrank(s_subOwner);
+ uint64 subId = s_vrfCoordinatorV2Mock.createSubscription();
+
+ s_vrfCoordinatorV2Mock.fundSubscription(subId, oneLink);
+
+ address consumerAddr = address(s_vrfConsumerV2);
+ s_vrfCoordinatorV2Mock.addConsumer(subId, consumerAddr);
+
+ vm.expectEmit(true, false, false, true);
+ emit RandomWordsRequested(
+ KEY_HASH,
+ 1,
+ 100,
+ subId,
+ DEFAULT_REQUEST_CONFIRMATIONS,
+ DEFAULT_CALLBACK_GAS_LIMIT,
+ DEFAULT_NUM_WORDS,
+ address(s_subOwner)
+ );
+ uint256 reqId = s_vrfConsumerV2.requestRandomness(
+ KEY_HASH,
+ subId,
+ DEFAULT_REQUEST_CONFIRMATIONS,
+ DEFAULT_CALLBACK_GAS_LIMIT,
+ DEFAULT_NUM_WORDS
+ );
+
+ vm.expectEmit(true, false, false, true);
+ emit RandomWordsFulfilled(reqId, 1, 100090236000000000, true);
+ s_vrfCoordinatorV2Mock.fulfillRandomWords(reqId, consumerAddr);
+
+ vm.stopPrank();
+ }
+
+ // Correctly allows for user override of fulfillRandomWords [ @skip-coverage ]
+ function testRequestRandomWordsUserOverride() public {
+ vm.startPrank(s_subOwner);
+ uint64 subId = s_vrfCoordinatorV2Mock.createSubscription();
+
+ s_vrfCoordinatorV2Mock.fundSubscription(subId, oneLink);
+
+ address consumerAddr = address(s_vrfConsumerV2);
+ s_vrfCoordinatorV2Mock.addConsumer(subId, consumerAddr);
+
+ vm.expectEmit(true, false, false, true);
+ emit RandomWordsRequested(
+ KEY_HASH,
+ 1,
+ 100,
+ subId,
+ DEFAULT_REQUEST_CONFIRMATIONS,
+ DEFAULT_CALLBACK_GAS_LIMIT,
+ 2,
+ address(s_subOwner)
+ );
+ uint256 reqId = s_vrfConsumerV2.requestRandomness(
+ KEY_HASH,
+ subId,
+ DEFAULT_REQUEST_CONFIRMATIONS,
+ DEFAULT_CALLBACK_GAS_LIMIT,
+ 2
+ );
+
+ bytes4 reason = bytes4(keccak256("InvalidRandomWords()"));
+ vm.expectRevert(toBytes(reason));
+ uint256[] memory words1 = new uint256[](5);
+ words1[0] = 1;
+ words1[1] = 2;
+ words1[2] = 3;
+ words1[3] = 4;
+ words1[4] = 5;
+ s_vrfCoordinatorV2Mock.fulfillRandomWordsWithOverride(reqId, consumerAddr, uint256[](words1));
+
+ vm.expectEmit(true, false, false, true);
+ uint256[] memory words2 = new uint256[](2);
+ words1[0] = 2533;
+ words1[1] = 1768;
+ emit RandomWordsFulfilled(reqId, 1, 100072314000000000, true);
+ s_vrfCoordinatorV2Mock.fulfillRandomWordsWithOverride(reqId, consumerAddr, words2);
+
+ vm.stopPrank();
+ }
+
+ function toBytes(bytes4 _data) public pure returns (bytes memory) {
+ return abi.encodePacked(_data);
+ }
+}
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 34271a129eb..a847bd5beee 100644
--- a/contracts/test/v0.8/foundry/vrf/VRFCoordinatorV2Plus_Migration.t.sol
+++ b/contracts/test/v0.8/foundry/vrf/VRFCoordinatorV2Plus_Migration.t.sol
@@ -2,12 +2,13 @@ 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";
import {MockV3Aggregator} from "../../../../src/v0.8/tests/MockV3Aggregator.sol";
+import {VRFV2PlusMaliciousMigrator} from "../../../../src/v0.8/dev/vrf/testhelpers/VRFV2PlusMaliciousMigrator.sol";
contract VRFCoordinatorV2Plus_Migration is BaseTest {
uint256 internal constant DEFAULT_LINK_FUNDING = 10 ether; // 10 LINK
@@ -23,15 +24,21 @@ contract VRFCoordinatorV2Plus_Migration is BaseTest {
hex"a0434d9e47f3c86235477c7b1ae6ae5d3442d49b1943c2b752a68e2a47e247c701";
bytes32 internal constant KEY_HASH = hex"9f2353bde94264dbc3d554a94cceba2d7d2b4fdce4304d3e09a1fea9fbeb1528";
- ExposedVRFCoordinatorV2Plus v1Coordinator;
+ ExposedVRFCoordinatorV2_5 v1Coordinator;
VRFCoordinatorV2Plus_V2Example v2Coordinator;
+ ExposedVRFCoordinatorV2_5 v1Coordinator_noLink;
+ VRFCoordinatorV2Plus_V2Example v2Coordinator_noLink;
uint256 subId;
+ uint256 subId_noLink;
VRFV2PlusConsumerExample testConsumer;
+ VRFV2PlusConsumerExample testConsumer_noLink;
MockLinkToken linkToken;
address linkTokenAddr;
- MockV3Aggregator linkEthFeed;
+ MockV3Aggregator linkNativeFeed;
address v1CoordinatorAddr;
address v2CoordinatorAddr;
+ address v1CoordinatorAddr_noLink;
+ address v2CoordinatorAddr_noLink;
event CoordinatorRegistered(address coordinatorAddress);
event CoordinatorDeregistered(address coordinatorAddress);
@@ -41,15 +48,20 @@ contract VRFCoordinatorV2Plus_Migration is BaseTest {
BaseTest.setUp();
vm.deal(OWNER, 100 ether);
address bhs = makeAddr("bhs");
- v1Coordinator = 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));
v1CoordinatorAddr = address(v1Coordinator);
v2CoordinatorAddr = address(v2Coordinator);
+ v1CoordinatorAddr_noLink = address(v1Coordinator_noLink);
+ v2CoordinatorAddr_noLink = address(v2Coordinator_noLink);
vm.expectEmit(
false, // no first indexed topic
@@ -61,17 +73,37 @@ contract VRFCoordinatorV2Plus_Migration is BaseTest {
v1Coordinator.registerMigratableCoordinator(v2CoordinatorAddr);
assertTrue(v1Coordinator.isTargetRegisteredExternal(v2CoordinatorAddr));
+ vm.expectEmit(
+ false, // no first indexed topic
+ false, // no second indexed topic
+ false, // no third indexed topic
+ true // check data (target coordinator address)
+ );
+ emit CoordinatorRegistered(v2CoordinatorAddr_noLink);
+ v1Coordinator_noLink.registerMigratableCoordinator(v2CoordinatorAddr_noLink);
+ assertTrue(v1Coordinator_noLink.isTargetRegisteredExternal(v2CoordinatorAddr_noLink));
+
testConsumer = new VRFV2PlusConsumerExample(address(v1Coordinator), address(linkToken));
+ testConsumer_noLink = new VRFV2PlusConsumerExample(address(v1Coordinator_noLink), address(0));
v1Coordinator.setConfig(
DEFAULT_REQUEST_CONFIRMATIONS,
DEFAULT_CALLBACK_GAS_LIMIT,
600,
10_000,
20_000,
- VRFCoordinatorV2Plus.FeeConfig({fulfillmentFlatFeeLinkPPM: 200, fulfillmentFlatFeeEthPPM: 100})
+ VRFCoordinatorV2_5.FeeConfig({fulfillmentFlatFeeLinkPPM: 200, fulfillmentFlatFeeNativePPM: 100})
+ );
+ v1Coordinator_noLink.setConfig(
+ DEFAULT_REQUEST_CONFIRMATIONS,
+ DEFAULT_CALLBACK_GAS_LIMIT,
+ 600,
+ 10_000,
+ 20_000,
+ VRFCoordinatorV2_5.FeeConfig({fulfillmentFlatFeeLinkPPM: 200, fulfillmentFlatFeeNativePPM: 100})
);
registerProvingKey();
testConsumer.setCoordinator(v1CoordinatorAddr);
+ testConsumer_noLink.setCoordinator(v1CoordinatorAddr_noLink);
}
function testDeregister() public {
@@ -85,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
@@ -114,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(
@@ -143,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);
@@ -180,11 +213,84 @@ contract VRFCoordinatorV2Plus_Migration is BaseTest {
);
}
+ function testMigrationNoLink() public {
+ 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 nativeBalance,
+ uint64 reqCount,
+ address owner,
+ address[] memory consumers
+ ) = v1Coordinator_noLink.getSubscription(subId_noLink);
+ assertEq(balance, 0);
+ 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_totalNativeBalance(), DEFAULT_NATIVE_FUNDING);
+
+ // Update consumer to point to the new coordinator
+ vm.expectEmit(
+ false, // no first indexed field
+ false, // no second indexed field
+ false, // no third indexed field
+ true // check data fields
+ );
+ emit MigrationCompleted(v2CoordinatorAddr_noLink, subId_noLink);
+ v1Coordinator_noLink.migrate(subId_noLink, v2CoordinatorAddr_noLink);
+
+ // subscription no longer exists in v1 coordinator after migration
+ vm.expectRevert(SubscriptionAPI.InvalidSubscription.selector);
+ v1Coordinator_noLink.getSubscription(subId);
+ assertEq(v1Coordinator_noLink.s_totalBalance(), 0);
+ assertEq(v1Coordinator_noLink.s_totalNativeBalance(), 0);
+ assertEq(linkToken.balanceOf(v1CoordinatorAddr_noLink), 0);
+ assertEq(v1CoordinatorAddr_noLink.balance, 0);
+
+ // subscription exists in v2 coordinator
+ (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(nativeBalance, DEFAULT_NATIVE_FUNDING);
+ assertEq(v2Coordinator_noLink.s_totalLinkBalance(), 0);
+ assertEq(v2Coordinator_noLink.s_totalNativeBalance(), DEFAULT_NATIVE_FUNDING);
+ assertEq(linkToken.balanceOf(v2CoordinatorAddr_noLink), 0);
+ assertEq(v2CoordinatorAddr_noLink.balance, DEFAULT_NATIVE_FUNDING);
+
+ // calling migrate again on V1 coordinator should fail
+ vm.expectRevert(SubscriptionAPI.InvalidSubscription.selector);
+ v1Coordinator_noLink.migrate(subId_noLink, v2CoordinatorAddr_noLink);
+
+ // test request still works after migration
+ testConsumer_noLink.requestRandomWords(
+ DEFAULT_CALLBACK_GAS_LIMIT,
+ DEFAULT_REQUEST_CONFIRMATIONS,
+ DEFAULT_NUM_WORDS,
+ KEY_HASH,
+ false
+ );
+ assertEq(testConsumer_noLink.s_recentRequestId(), 1);
+
+ v2Coordinator_noLink.fulfillRandomWords(testConsumer_noLink.s_recentRequestId());
+ assertEq(
+ testConsumer_noLink.getRandomness(testConsumer_noLink.s_recentRequestId(), 0),
+ v2Coordinator_noLink.generateFakeRandomness(testConsumer_noLink.s_recentRequestId())[0]
+ );
+ }
+
function testMigrateRevertsWhenInvalidCoordinator() external {
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);
}
@@ -210,9 +316,23 @@ contract VRFCoordinatorV2Plus_Migration is BaseTest {
v1Coordinator.migrate(subId, v2CoordinatorAddr);
}
+ function testMigrateRevertsWhenReentrant() public {
+ // deploy malicious contracts, subscriptions
+ address maliciousUser = makeAddr("maliciousUser");
+ changePrank(maliciousUser);
+ uint256 maliciousSubId = v1Coordinator.createSubscription();
+ VRFV2PlusMaliciousMigrator prankster = new VRFV2PlusMaliciousMigrator(address(v1Coordinator));
+ v1Coordinator.addConsumer(maliciousSubId, address(prankster));
+
+ // try to migrate malicious subscription, should fail
+ vm.expectRevert(abi.encodeWithSelector(SubscriptionAPI.Reentrant.selector));
+ v1Coordinator.migrate(maliciousSubId, v2CoordinatorAddr);
+ }
+
function registerProvingKey() public {
uint256[2] memory uncompressedKeyParts = this.getProvingKeyParts(UNCOMPRESSED_PUBLIC_KEY);
v1Coordinator.registerProvingKey(OWNER, uncompressedKeyParts);
+ v1Coordinator_noLink.registerProvingKey(OWNER, uncompressedKeyParts);
}
// note: Call this function via this.getProvingKeyParts to be able to pass memory as calldata and
diff --git a/contracts/test/v0.8/foundry/vrf/VRFV2Plus.t.sol b/contracts/test/v0.8/foundry/vrf/VRFV2Plus.t.sol
index 4e22008549c..13d52b676c5 100644
--- a/contracts/test/v0.8/foundry/vrf/VRFV2Plus.t.sol
+++ b/contracts/test/v0.8/foundry/vrf/VRFV2Plus.t.sol
@@ -4,8 +4,9 @@ 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";
import {VRFV2PlusClient} from "../../../../src/v0.8/dev/vrf/libraries/VRFV2PlusClient.sol";
@@ -30,13 +31,14 @@ contract VRFV2Plus is BaseTest {
hex"60806040523480156200001157600080fd5b5060405162001377380380620013778339810160408190526200003491620001cc565b8133806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf8162000103565b5050600280546001600160a01b03199081166001600160a01b0394851617909155600580548216958416959095179094555060038054909316911617905562000204565b6001600160a01b0381163314156200015e5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b0381168114620001c757600080fd5b919050565b60008060408385031215620001e057600080fd5b620001eb83620001af565b9150620001fb60208401620001af565b90509250929050565b61116380620002146000396000f3fe608060405234801561001057600080fd5b50600436106101005760003560e01c80638098004311610097578063cf62c8ab11610066578063cf62c8ab14610242578063de367c8e14610255578063eff2701714610268578063f2fde38b1461027b57600080fd5b806380980043146101ab5780638da5cb5b146101be5780638ea98117146101cf578063a168fa89146101e257600080fd5b80635d7d53e3116100d35780635d7d53e314610166578063706da1ca1461016f5780637725135b1461017857806379ba5097146101a357600080fd5b80631fe543e31461010557806329e5d8311461011a5780632fa4e4421461014057806336bfffed14610153575b600080fd5b610118610113366004610e4e565b61028e565b005b61012d610128366004610ef2565b6102fa565b6040519081526020015b60405180910390f35b61011861014e366004610f7f565b610410565b610118610161366004610d5b565b6104bc565b61012d60045481565b61012d60065481565b60035461018b906001600160a01b031681565b6040516001600160a01b039091168152602001610137565b6101186105c0565b6101186101b9366004610e1c565b600655565b6000546001600160a01b031661018b565b6101186101dd366004610d39565b61067e565b61021d6101f0366004610e1c565b6007602052600090815260409020805460019091015460ff82169161010090046001600160a01b03169083565b6040805193151584526001600160a01b03909216602084015290820152606001610137565b610118610250366004610f7f565b61073d565b60055461018b906001600160a01b031681565b610118610276366004610f14565b610880565b610118610289366004610d39565b610a51565b6002546001600160a01b031633146102ec576002546040517f1cf993f40000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b0390911660248201526044015b60405180910390fd5b6102f68282610a65565b5050565b60008281526007602090815260408083208151608081018352815460ff81161515825261010090046001600160a01b0316818501526001820154818401526002820180548451818702810187019095528085528695929460608601939092919083018282801561038957602002820191906000526020600020905b815481526020019060010190808311610375575b50505050508152505090508060400151600014156103e95760405162461bcd60e51b815260206004820152601760248201527f7265717565737420494420697320696e636f727265637400000000000000000060448201526064016102e3565b806060015183815181106103ff576103ff61111c565b602002602001015191505092915050565b6003546002546006546040805160208101929092526001600160a01b0393841693634000aea09316918591015b6040516020818303038152906040526040518463ffffffff1660e01b815260040161046a93929190610ffa565b602060405180830381600087803b15801561048457600080fd5b505af1158015610498573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102f69190610dff565b60065461050b5760405162461bcd60e51b815260206004820152600d60248201527f7375624944206e6f74207365740000000000000000000000000000000000000060448201526064016102e3565b60005b81518110156102f65760055460065483516001600160a01b039092169163bec4c08c91908590859081106105445761054461111c565b60200260200101516040518363ffffffff1660e01b815260040161057b9291909182526001600160a01b0316602082015260400190565b600060405180830381600087803b15801561059557600080fd5b505af11580156105a9573d6000803e3d6000fd5b5050505080806105b8906110f3565b91505061050e565b6001546001600160a01b0316331461061a5760405162461bcd60e51b815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016102e3565b600080543373ffffffffffffffffffffffffffffffffffffffff19808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6000546001600160a01b031633148015906106a457506002546001600160a01b03163314155b1561070e57336106bc6000546001600160a01b031690565b6002546040517f061db9c10000000000000000000000000000000000000000000000000000000081526001600160a01b03938416600482015291831660248301529190911660448201526064016102e3565b6002805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b60065461041057600560009054906101000a90046001600160a01b03166001600160a01b031663a21a23e46040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561079457600080fd5b505af11580156107a8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107cc9190610e35565b60068190556005546040517fbec4c08c00000000000000000000000000000000000000000000000000000000815260048101929092523060248301526001600160a01b03169063bec4c08c90604401600060405180830381600087803b15801561083557600080fd5b505af1158015610849573d6000803e3d6000fd5b505050506003546002546006546040516001600160a01b0393841693634000aea0931691859161043d919060200190815260200190565b60006040518060c0016040528084815260200160065481526020018661ffff1681526020018763ffffffff1681526020018563ffffffff1681526020016108d66040518060200160405280861515815250610af8565b90526002546040517f9b1c385e0000000000000000000000000000000000000000000000000000000081529192506000916001600160a01b0390911690639b1c385e90610927908590600401611039565b602060405180830381600087803b15801561094157600080fd5b505af1158015610955573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109799190610e35565b604080516080810182526000808252336020808401918252838501868152855184815280830187526060860190815287855260078352959093208451815493517fffffffffffffffffffffff0000000000000000000000000000000000000000009094169015157fffffffffffffffffffffff0000000000000000000000000000000000000000ff16176101006001600160a01b039094169390930292909217825591516001820155925180519495509193849392610a3f926002850192910190610ca9565b50505060049190915550505050505050565b610a59610b96565b610a6281610bf2565b50565b6004548214610ab65760405162461bcd60e51b815260206004820152601760248201527f7265717565737420494420697320696e636f727265637400000000000000000060448201526064016102e3565b60008281526007602090815260409091208251610adb92600290920191840190610ca9565b50506000908152600760205260409020805460ff19166001179055565b60607f92fd13387c7fe7befbc38d303d6468778fb9731bc4583f17d92989c6fcfdeaaa82604051602401610b3191511515815260200190565b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915292915050565b6000546001600160a01b03163314610bf05760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016102e3565b565b6001600160a01b038116331415610c4b5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016102e3565b6001805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b828054828255906000526020600020908101928215610ce4579160200282015b82811115610ce4578251825591602001919060010190610cc9565b50610cf0929150610cf4565b5090565b5b80821115610cf05760008155600101610cf5565b80356001600160a01b0381168114610d2057600080fd5b919050565b803563ffffffff81168114610d2057600080fd5b600060208284031215610d4b57600080fd5b610d5482610d09565b9392505050565b60006020808385031215610d6e57600080fd5b823567ffffffffffffffff811115610d8557600080fd5b8301601f81018513610d9657600080fd5b8035610da9610da4826110cf565b61109e565b80828252848201915084840188868560051b8701011115610dc957600080fd5b600094505b83851015610df357610ddf81610d09565b835260019490940193918501918501610dce565b50979650505050505050565b600060208284031215610e1157600080fd5b8151610d5481611148565b600060208284031215610e2e57600080fd5b5035919050565b600060208284031215610e4757600080fd5b5051919050565b60008060408385031215610e6157600080fd5b8235915060208084013567ffffffffffffffff811115610e8057600080fd5b8401601f81018613610e9157600080fd5b8035610e9f610da4826110cf565b80828252848201915084840189868560051b8701011115610ebf57600080fd5b600094505b83851015610ee2578035835260019490940193918501918501610ec4565b5080955050505050509250929050565b60008060408385031215610f0557600080fd5b50508035926020909101359150565b600080600080600060a08688031215610f2c57600080fd5b610f3586610d25565b9450602086013561ffff81168114610f4c57600080fd5b9350610f5a60408701610d25565b9250606086013591506080860135610f7181611148565b809150509295509295909350565b600060208284031215610f9157600080fd5b81356bffffffffffffffffffffffff81168114610d5457600080fd5b6000815180845260005b81811015610fd357602081850181015186830182015201610fb7565b81811115610fe5576000602083870101525b50601f01601f19169290920160200192915050565b6001600160a01b03841681526bffffffffffffffffffffffff831660208201526060604082015260006110306060830184610fad565b95945050505050565b60208152815160208201526020820151604082015261ffff60408301511660608201526000606083015163ffffffff80821660808501528060808601511660a0850152505060a083015160c08084015261109660e0840182610fad565b949350505050565b604051601f8201601f1916810167ffffffffffffffff811182821017156110c7576110c7611132565b604052919050565b600067ffffffffffffffff8211156110e9576110e9611132565b5060051b60200190565b600060001982141561111557634e487b7160e01b600052601160045260246000fd5b5060010190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b8015158114610a6257600080fdfea164736f6c6343000806000a";
BlockhashStore s_bhs;
- ExposedVRFCoordinatorV2Plus s_testCoordinator;
+ 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.
@@ -57,11 +59,10 @@ contract VRFV2Plus is BaseTest {
s_bhs = new BlockhashStore();
// Deploy coordinator and consumer.
- s_testCoordinator = new ExposedVRFCoordinatorV2Plus(address(s_bhs));
-
- // Deploy link token and link/eth feed.
+ // Note: adding contract deployments to this section will require the VRF proofs be regenerated.
+ 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.
@@ -81,11 +82,13 @@ contract VRFV2Plus is BaseTest {
}
s_testConsumer = VRFV2PlusConsumerExample(consumerCreate2Address);
+ 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
@@ -104,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);
}
@@ -120,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);
}
@@ -139,7 +142,19 @@ 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.fundSubscriptionWithNative{value: 1000 ether}(subId);
+
+ assertEq(LINK_WHALE.balance, 9000 ether);
+ s_testCoordinator_noLink.cancelSubscription(subId, LINK_WHALE);
+ assertEq(LINK_WHALE.balance, 10_000 ether);
+
+ vm.expectRevert(SubscriptionAPI.InvalidSubscription.selector);
+ s_testCoordinator_noLink.getSubscription(subId);
}
function testGetActiveSubscriptionIds() public {
@@ -189,7 +204,7 @@ contract VRFV2Plus is BaseTest {
}
function paginateSubscriptions(
- ExposedVRFCoordinatorV2Plus coordinator,
+ ExposedVRFCoordinatorV2_5 coordinator,
uint256 batchSize
) internal view returns (uint256[][] memory) {
uint arrIndex = 0;
@@ -229,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);
@@ -289,21 +304,21 @@ contract VRFV2Plus is BaseTest {
2973102176083872659982988645522968133664529102555885971868619302367987919116,
43610558806647181042154132372309425100765955827430056035281841579494767100593
],
- c: 75194344641067036522826220229162084868390366816380211563792760218107272249498,
- s: 108927968992343929608833704938910483045052376946991907425266794689988418576748,
+ c: 44558436621153210954487996771157467729629491520915192177070584116261579650304,
+ s: 18447217702001910909971999949841419857536434117467121546901211519652998560328,
seed: 53391429126065232382402681707515137895470547057819816488254124798726362946635,
- uWitness: 0x2fF1135666317726951c76126c8723d85CFD9F32,
+ uWitness: 0x61e70839187C12Fe136bdcC78D1D3765BecA245d,
cGammaWitness: [
- 46085870527299320975519920659984209079990358705974909475473962711525316439739,
- 95523996389945915706780830430209540746261656800207800796591631955877527338163
+ 57868024672571504735938309170346165090467827794150592801232968679608710558443,
+ 19249635816589941728350586356475545703589085434839461964712223344491075318152
],
sHashWitness: [
- 33452562099427047562641801544992972552164940262753954784240667763204805691450,
- 60260251393131215964980682331539706583150315372000173687277509360968942328689
+ 61151023867440095994162103308586528914977848168432699421313437043942463394142,
+ 107161674609768447269383119603000260750848712436031813376573304048979100187696
],
- zInv: 90963680785087352218671937531239943963498221959522740883795298137227163523089
+ zInv: 92231836131549905872346812799402691650433126386650679876913933650318463342041
});
- VRFCoordinatorV2Plus.RequestCommitment memory rc = VRFCoordinatorV2Plus.RequestCommitment({
+ VRFCoordinatorV2_5.RequestCommitment memory rc = VRFCoordinatorV2_5.RequestCommitment({
blockNum: requestBlock,
subId: subId,
callbackGasLimit: 1_000_000,
@@ -311,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();
@@ -337,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 {
@@ -405,21 +420,21 @@ contract VRFV2Plus is BaseTest {
33866404953216897461413961842321788789902210776565180957857448351149268461878,
115311460432520855364215812517921508651759645277579047898967111537639679255245
],
- c: 98175725525459014587207855195868784126328401309203602128167819356654355538256,
- s: 78212468144318845248263931834872020573314019987337100119712622816610913379348,
+ c: 32561838617228634441320154326890637858849550728945663611942735469609183032389,
+ s: 55806041637816588920133401262818662941786708593795051215322306020699218819370,
seed: 14817911724325909152780695848148728017190840227899344848185245004944693487904,
- uWitness: 0xA98F604595c018ca3A897a89A93335C4D9736200,
+ uWitness: 0x917554f18dB75eac206Ae5366B80c0b6A87b5996,
cGammaWitness: [
- 89663557576172659880527012694290366148297911460143038889658956042430644586923,
- 29419553942575420255373719124720052624389851192491471135797878382964991183413
+ 84076069514674055711740813040098459867759972960517070154541804330775196519927,
+ 23456142794899412334950030002327578074149212885334118042147040122102091306080
],
sHashWitness: [
- 108049980454753981965039838334334363963059423646097861676439703242702207924520,
- 30630879728902862732102533191211056668896962900771600171010644651087695869520
+ 67919054534004130885903575144858988177160334233773664996450084407340736891592,
+ 82934864721844704662104532515068228502043057799129930869203380251475000254135
],
- zInv: 20922890987701239032692501385659950984080522095093996771712575172616647361477
+ zInv: 37397948970756055003892765560695914630264479979131589134478580629419519112029
});
- VRFCoordinatorV2Plus.RequestCommitment memory rc = VRFCoordinatorV2Plus.RequestCommitment({
+ VRFCoordinatorV2_5.RequestCommitment memory rc = VRFCoordinatorV2_5.RequestCommitment({
blockNum: requestBlock,
subId: subId,
callbackGasLimit: 1000000,
@@ -447,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
new file mode 100644
index 00000000000..db9e11e059e
--- /dev/null
+++ b/contracts/test/v0.8/foundry/vrf/VRFV2PlusSubscriptionAPI.t.sol
@@ -0,0 +1,605 @@
+pragma solidity 0.8.6;
+
+import "../BaseTest.t.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";
+import "@openzeppelin/contracts/utils/Strings.sol"; // for Strings.toString
+
+contract VRFV2PlusSubscriptionAPITest is BaseTest {
+ event SubscriptionFunded(uint256 indexed subId, uint256 oldBalance, uint256 newBalance);
+ 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 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);
+
+ ExposedVRFCoordinatorV2_5 s_subscriptionAPI;
+
+ function setUp() public override {
+ BaseTest.setUp();
+ address bhs = makeAddr("bhs");
+ s_subscriptionAPI = new ExposedVRFCoordinatorV2_5(bhs);
+ }
+
+ function testDefaultState() public {
+ assertEq(address(s_subscriptionAPI.LINK()), 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_totalNativeBalance(), 0);
+ }
+
+ function testSetLINKAndLINKNativeFeed() public {
+ address link = makeAddr("link");
+ address linkNativeFeed = makeAddr("linkNativeFeed");
+ s_subscriptionAPI.setLINKAndLINKNativeFeed(link, linkNativeFeed);
+ assertEq(address(s_subscriptionAPI.LINK()), link);
+ assertEq(address(s_subscriptionAPI.LINK_NATIVE_FEED()), linkNativeFeed);
+
+ // try setting it again, should revert
+ vm.expectRevert(SubscriptionAPI.LinkAlreadySet.selector);
+ s_subscriptionAPI.setLINKAndLINKNativeFeed(link, linkNativeFeed);
+ }
+
+ function testOwnerCancelSubscriptionNoFunds() public {
+ // CASE: new subscription w/ no funds at all
+ // Should cancel trivially
+
+ // Note that the link token is not set, but this should still
+ // not fail in that case.
+
+ // Create the subscription from a separate address
+ address subOwner = makeAddr("subOwner");
+ changePrank(subOwner);
+ uint64 nonceBefore = s_subscriptionAPI.s_currentSubNonce();
+ uint256 subId = s_subscriptionAPI.createSubscription();
+ assertEq(s_subscriptionAPI.s_currentSubNonce(), nonceBefore + 1);
+
+ // change back to owner and cancel the subscription
+ changePrank(OWNER);
+ vm.expectEmit(true, false, false, true);
+ emit SubscriptionCanceled(subId, subOwner, 0, 0);
+ s_subscriptionAPI.ownerCancelSubscription(subId);
+
+ // assert that the subscription no longer exists
+ assertEq(s_subscriptionAPI.getActiveSubscriptionIdsLength(), 0);
+ assertEq(s_subscriptionAPI.getSubscriptionConfig(subId).owner, address(0));
+ // no point in checking s_subscriptions because all fields are zeroed out
+ // due to no balance and no requests made
+ }
+
+ function testOwnerCancelSubscriptionNativeFundsOnly() public {
+ // CASE: new subscription with native funds only
+ // no link funds.
+ // should cancel and return the native funds
+
+ // Create the subscription from a separate address
+ 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
+ vm.deal(subOwner, 10 ether);
+ vm.expectEmit(true, false, false, true);
+ emit SubscriptionFundedWithNative(subId, 0, 5 ether);
+ s_subscriptionAPI.fundSubscriptionWithNative{value: 5 ether}(subId);
+
+ // change back to owner and cancel the subscription
+ changePrank(OWNER);
+ vm.expectEmit(true, false, false, true);
+ emit SubscriptionCanceled(subId, subOwner, 0 /* link balance */, 5 ether /* native balance */);
+ s_subscriptionAPI.ownerCancelSubscription(subId);
+
+ // 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).nativeBalance, 0);
+
+ // check the native balance of the subOwner, should be 10 ether
+ assertEq(address(subOwner).balance, 10 ether);
+ }
+
+ function testOwnerCancelSubscriptionLinkFundsOnly() public {
+ // CASE: new subscription with link funds only
+ // no native funds.
+ // should cancel and return the link funds
+
+ // Create link token and set the link token on the subscription api object
+ MockLinkToken linkToken = new MockLinkToken();
+ s_subscriptionAPI.setLINKAndLINKNativeFeed(address(linkToken), address(0));
+ assertEq(address(s_subscriptionAPI.LINK()), address(linkToken));
+
+ // Create the subscription from a separate address
+ 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 link
+ // can do it from the owner acct because anyone can fund a subscription
+ changePrank(OWNER);
+ vm.expectEmit(true, false, false, true);
+ emit SubscriptionFunded(subId, 0, 5 ether);
+ bool success = linkToken.transferAndCall(address(s_subscriptionAPI), 5 ether, abi.encode(subId));
+ assertTrue(success, "failed link transfer and call");
+
+ // change back to owner and cancel the subscription
+ vm.expectEmit(true, false, false, true);
+ emit SubscriptionCanceled(subId, subOwner, 5 ether /* link balance */, 0 /* native balance */);
+ s_subscriptionAPI.ownerCancelSubscription(subId);
+
+ // 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).balance, 0);
+
+ // check the link balance of the sub owner, should be 5 LINK
+ assertEq(linkToken.balanceOf(subOwner), 5 ether);
+ }
+
+ function testOwnerCancelSubscriptionNativeAndLinkFunds() public {
+ // CASE: new subscription with link and native funds
+ // should cancel and return both link and native funds
+
+ // Create link token and set the link token on the subscription api object
+ MockLinkToken linkToken = new MockLinkToken();
+ s_subscriptionAPI.setLINKAndLINKNativeFeed(address(linkToken), address(0));
+ assertEq(address(s_subscriptionAPI.LINK()), address(linkToken));
+
+ // Create the subscription from a separate address
+ 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 link
+ changePrank(OWNER);
+ vm.expectEmit(true, false, false, true);
+ emit SubscriptionFunded(subId, 0, 5 ether);
+ bool success = linkToken.transferAndCall(address(s_subscriptionAPI), 5 ether, abi.encode(subId));
+ assertTrue(success, "failed link transfer and call");
+
+ // fund the subscription with ether
+ vm.deal(subOwner, 10 ether);
+ changePrank(subOwner);
+ vm.expectEmit(true, false, false, true);
+ emit SubscriptionFundedWithNative(subId, 0, 5 ether);
+ s_subscriptionAPI.fundSubscriptionWithNative{value: 5 ether}(subId);
+
+ // change back to owner and cancel the subscription
+ changePrank(OWNER);
+ vm.expectEmit(true, false, false, true);
+ emit SubscriptionCanceled(subId, subOwner, 5 ether /* link balance */, 5 ether /* native balance */);
+ s_subscriptionAPI.ownerCancelSubscription(subId);
+
+ // 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).balance, 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, "native balance incorrect");
+ }
+
+ function testRecoverFundsLINKNotSet() public {
+ // CASE: link token not set
+ // should revert with error LinkNotSet
+
+ // call recoverFunds
+ vm.expectRevert(SubscriptionAPI.LinkNotSet.selector);
+ s_subscriptionAPI.recoverFunds(OWNER);
+ }
+
+ function testRecoverFundsBalanceInvariantViolated() public {
+ // CASE: link token set
+ // and internal balance is greater than external balance
+
+ // Create link token and set the link token on the subscription api object
+ MockLinkToken linkToken = new MockLinkToken();
+ 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
+ // 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.setTotalBalanceTestingOnlyXXX(100 ether);
+
+ // call recoverFunds
+ vm.expectRevert(abi.encodeWithSelector(SubscriptionAPI.BalanceInvariantViolated.selector, 100 ether, 0));
+ s_subscriptionAPI.recoverFunds(OWNER);
+ }
+
+ function testRecoverFundsAmountToTransfer() public {
+ // CASE: link token set
+ // and internal balance is less than external balance
+ // (i.e invariant is not violated)
+ // should recover funds successfully
+
+ // Create link token and set the link token on the subscription api object
+ MockLinkToken linkToken = new MockLinkToken();
+ s_subscriptionAPI.setLINKAndLINKNativeFeed(address(linkToken), address(0));
+ assertEq(address(s_subscriptionAPI.LINK()), address(linkToken));
+
+ // transfer 10 LINK to the contract to recover
+ bool success = linkToken.transfer(address(s_subscriptionAPI), 10 ether);
+ assertTrue(success, "failed link transfer");
+
+ // call recoverFunds
+ vm.expectEmit(true, false, false, true);
+ emit FundsRecovered(OWNER, 10 ether);
+ s_subscriptionAPI.recoverFunds(OWNER);
+ }
+
+ function testRecoverFundsNothingToTransfer() public {
+ // CASE: link token set
+ // and there is nothing to transfer
+ // should do nothing at all
+
+ // Create link token and set the link token on the subscription api object
+ MockLinkToken linkToken = new MockLinkToken();
+ s_subscriptionAPI.setLINKAndLINKNativeFeed(address(linkToken), address(0));
+ assertEq(address(s_subscriptionAPI.LINK()), address(linkToken));
+
+ // create a subscription and fund it with 5 LINK
+ 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 link
+ changePrank(OWNER);
+ vm.expectEmit(true, false, false, true);
+ emit SubscriptionFunded(subId, 0, 5 ether);
+ bool success = linkToken.transferAndCall(address(s_subscriptionAPI), 5 ether, abi.encode(subId));
+ assertTrue(success, "failed link transfer and call");
+
+ // call recoverFunds, nothing should happen because external balance == internal balance
+ s_subscriptionAPI.recoverFunds(OWNER);
+ assertEq(linkToken.balanceOf(address(s_subscriptionAPI)), s_subscriptionAPI.s_totalBalance());
+ }
+
+ 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.setTotalNativeBalanceTestingOnlyXXX(100 ether);
+
+ // call recoverFunds
+ vm.expectRevert(abi.encodeWithSelector(SubscriptionAPI.BalanceInvariantViolated.selector, 100 ether, 0));
+ s_subscriptionAPI.recoverNativeFunds(payable(OWNER));
+ }
+
+ 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 NativeFundsRecovered(OWNER, 10 ether);
+ s_subscriptionAPI.recoverNativeFunds(payable(OWNER));
+ }
+
+ function testRecoverNativeFundsNothingToTransfer() public {
+ // create a subscription and fund it with 5 ether
+ 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
+ vm.deal(subOwner, 5 ether);
+ changePrank(subOwner);
+ vm.expectEmit(true, false, false, true);
+ emit SubscriptionFundedWithNative(subId, 0, 5 ether);
+ s_subscriptionAPI.fundSubscriptionWithNative{value: 5 ether}(subId);
+
+ // call recoverNativeFunds, nothing should happen because external balance == internal balance
+ changePrank(OWNER);
+ s_subscriptionAPI.recoverNativeFunds(payable(OWNER));
+ assertEq(address(s_subscriptionAPI).balance, s_subscriptionAPI.s_totalNativeBalance());
+ }
+
+ function testOracleWithdrawNoLink() public {
+ // CASE: no link token set
+ vm.expectRevert(SubscriptionAPI.LinkNotSet.selector);
+ s_subscriptionAPI.oracleWithdraw(OWNER, 1 ether);
+ }
+
+ function testOracleWithdrawInsufficientBalance() public {
+ // CASE: link token set, trying to withdraw
+ // more than balance
+ MockLinkToken linkToken = new MockLinkToken();
+ s_subscriptionAPI.setLINKAndLINKNativeFeed(address(linkToken), address(0));
+ assertEq(address(s_subscriptionAPI.LINK()), address(linkToken));
+
+ // call oracleWithdraw
+ vm.expectRevert(SubscriptionAPI.InsufficientBalance.selector);
+ s_subscriptionAPI.oracleWithdraw(OWNER, 1 ether);
+ }
+
+ function testOracleWithdrawSufficientBalanceLinkSet() public {
+ // CASE: link token set, trying to withdraw
+ // less than balance
+ MockLinkToken linkToken = new MockLinkToken();
+ s_subscriptionAPI.setLINKAndLINKNativeFeed(address(linkToken), address(0));
+ assertEq(address(s_subscriptionAPI.LINK()), address(linkToken));
+
+ // transfer 10 LINK to the contract to withdraw
+ bool success = linkToken.transfer(address(s_subscriptionAPI), 10 ether);
+ assertTrue(success, "failed link transfer");
+
+ // set the withdrawable tokens of the oracle to be 1 ether
+ address oracle = makeAddr("oracle");
+ s_subscriptionAPI.setWithdrawableTokensTestingOnlyXXX(oracle, 1 ether);
+ assertEq(s_subscriptionAPI.getWithdrawableTokensTestingOnlyXXX(oracle), 1 ether);
+
+ // set the total balance to be the same as the link balance for consistency
+ // (this is not necessary for the test, but just to be sane)
+ s_subscriptionAPI.setTotalBalanceTestingOnlyXXX(10 ether);
+
+ // call oracleWithdraw from oracle address
+ changePrank(oracle);
+ s_subscriptionAPI.oracleWithdraw(oracle, 1 ether);
+ // assert link balance of oracle
+ assertEq(linkToken.balanceOf(oracle), 1 ether, "oracle link balance incorrect");
+ // assert state of subscription api
+ assertEq(s_subscriptionAPI.getWithdrawableTokensTestingOnlyXXX(oracle), 0, "oracle withdrawable tokens incorrect");
+ // assert that total balance is changed by the withdrawn amount
+ assertEq(s_subscriptionAPI.s_totalBalance(), 9 ether, "total balance incorrect");
+ }
+
+ function testOracleWithdrawNativeInsufficientBalance() public {
+ // CASE: trying to withdraw more than balance
+ // should revert with InsufficientBalance
+
+ // call oracleWithdrawNative
+ vm.expectRevert(SubscriptionAPI.InsufficientBalance.selector);
+ s_subscriptionAPI.oracleWithdrawNative(payable(OWNER), 1 ether);
+ }
+
+ function testOracleWithdrawNativeSufficientBalance() public {
+ // CASE: trying to withdraw less than balance
+ // should withdraw successfully
+
+ // transfer 10 ether to the contract to withdraw
+ vm.deal(address(s_subscriptionAPI), 10 ether);
+
+ // set the withdrawable eth of the oracle to be 1 ether
+ address oracle = makeAddr("oracle");
+ 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.setTotalNativeBalanceTestingOnlyXXX(10 ether);
+
+ // call oracleWithdrawNative from oracle address
+ changePrank(oracle);
+ 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.getWithdrawableNativeTestingOnlyXXX(oracle), 0, "oracle withdrawable native incorrect");
+ // assert that total balance is changed by the withdrawn amount
+ assertEq(s_subscriptionAPI.s_totalNativeBalance(), 9 ether, "total native balance incorrect");
+ }
+
+ function testOnTokenTransferCallerNotLink() public {
+ vm.expectRevert(SubscriptionAPI.OnlyCallableFromLink.selector);
+ s_subscriptionAPI.onTokenTransfer(makeAddr("someaddress"), 1 ether, abi.encode(uint256(1)));
+ }
+
+ function testOnTokenTransferInvalidCalldata() public {
+ // create and set link token on subscription api
+ MockLinkToken linkToken = new MockLinkToken();
+ s_subscriptionAPI.setLINKAndLINKNativeFeed(address(linkToken), address(0));
+ assertEq(address(s_subscriptionAPI.LINK()), address(linkToken));
+
+ // call link.transferAndCall with invalid calldata
+ vm.expectRevert(SubscriptionAPI.InvalidCalldata.selector);
+ linkToken.transferAndCall(address(s_subscriptionAPI), 1 ether, abi.encode(uint256(1), address(1)));
+ }
+
+ function testOnTokenTransferInvalidSubscriptionId() public {
+ // create and set link token on subscription api
+ MockLinkToken linkToken = new MockLinkToken();
+ s_subscriptionAPI.setLINKAndLINKNativeFeed(address(linkToken), address(0));
+ assertEq(address(s_subscriptionAPI.LINK()), address(linkToken));
+
+ // generate bogus sub id
+ uint256 subId = uint256(keccak256("idontexist"));
+
+ // try to fund bogus sub id
+ vm.expectRevert(SubscriptionAPI.InvalidSubscription.selector);
+ linkToken.transferAndCall(address(s_subscriptionAPI), 1 ether, abi.encode(subId));
+ }
+
+ function testOnTokenTransferSuccess() public {
+ // happy path link funding test
+ // create and set link token on subscription api
+ MockLinkToken linkToken = new MockLinkToken();
+ s_subscriptionAPI.setLINKAndLINKNativeFeed(address(linkToken), address(0));
+ assertEq(address(s_subscriptionAPI.LINK()), address(linkToken));
+
+ // create a subscription and fund it with 5 LINK
+ 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 link
+ changePrank(OWNER);
+ vm.expectEmit(true, false, false, true);
+ emit SubscriptionFunded(subId, 0, 5 ether);
+ bool success = linkToken.transferAndCall(address(s_subscriptionAPI), 5 ether, abi.encode(subId));
+ assertTrue(success, "failed link transfer and call");
+
+ // assert that the subscription is funded
+ assertEq(s_subscriptionAPI.getSubscriptionStruct(subId).balance, 5 ether);
+ }
+
+ function testFundSubscriptionWithNativeInvalidSubscriptionId() public {
+ // CASE: invalid subscription id
+ // should revert with InvalidSubscription
+
+ uint256 subId = uint256(keccak256("idontexist"));
+
+ // 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.fundSubscriptionWithNative{value: 5 ether}(subId);
+ }
+
+ function testFundSubscriptionWithNative() public {
+ // happy path test
+ // funding subscription with native
+
+ // 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 native
+ vm.deal(subOwner, 5 ether);
+ changePrank(subOwner);
+ vm.expectEmit(true, false, false, true);
+ emit SubscriptionFundedWithNative(subId, 0, 5 ether);
+ s_subscriptionAPI.fundSubscriptionWithNative{value: 5 ether}(subId);
+
+ // assert that the subscription is funded
+ assertEq(s_subscriptionAPI.getSubscriptionStruct(subId).nativeBalance, 5 ether);
+ }
+
+ function testCreateSubscription() public {
+ // test that the subscription is created successfully
+ // and test the initial state of the subscription
+ address subOwner = makeAddr("subOwner");
+ changePrank(subOwner);
+ uint64 nonceBefore = s_subscriptionAPI.s_currentSubNonce();
+ uint256 subId = s_subscriptionAPI.createSubscription();
+ assertEq(s_subscriptionAPI.s_currentSubNonce(), nonceBefore + 1);
+ assertEq(s_subscriptionAPI.getActiveSubscriptionIdsLength(), 1);
+ assertEq(s_subscriptionAPI.getSubscriptionConfig(subId).owner, subOwner);
+ assertEq(s_subscriptionAPI.getSubscriptionConfig(subId).consumers.length, 0);
+ assertEq(s_subscriptionAPI.getSubscriptionConfig(subId).requestedOwner, address(0));
+ }
+
+ function testCreateSubscriptionRecreate() public {
+ // create two subscriptions from the same eoa
+ // they should never be the same due to nonce incrementation
+ address subOwner = makeAddr("subOwner");
+ changePrank(subOwner);
+ uint64 nonceBefore = s_subscriptionAPI.s_currentSubNonce();
+ uint256 subId1 = s_subscriptionAPI.createSubscription();
+ assertEq(s_subscriptionAPI.s_currentSubNonce(), nonceBefore + 1);
+ uint256 subId2 = s_subscriptionAPI.createSubscription();
+ assertEq(s_subscriptionAPI.s_currentSubNonce(), nonceBefore + 2);
+ assertTrue(subId1 != subId2);
+ }
+
+ function testSubscriptionOwnershipTransfer() public {
+ // create two eoa's, and create a subscription from one of them
+ // and transfer ownership to the other
+ // assert that the subscription is now owned by the other eoa
+ address oldOwner = makeAddr("oldOwner");
+ address newOwner = makeAddr("newOwner");
+
+ // create sub
+ changePrank(oldOwner);
+ uint256 subId = s_subscriptionAPI.createSubscription();
+ assertEq(s_subscriptionAPI.getSubscriptionConfig(subId).owner, oldOwner);
+
+ // request ownership transfer
+ changePrank(oldOwner);
+ vm.expectEmit(true, false, false, true);
+ emit SubscriptionOwnerTransferRequested(subId, oldOwner, newOwner);
+ s_subscriptionAPI.requestSubscriptionOwnerTransfer(subId, newOwner);
+
+ // accept ownership transfer from newOwner
+ changePrank(newOwner);
+ vm.expectEmit(true, false, false, true);
+ emit SubscriptionOwnerTransferred(subId, oldOwner, newOwner);
+ s_subscriptionAPI.acceptSubscriptionOwnerTransfer(subId);
+ assertEq(s_subscriptionAPI.getSubscriptionConfig(subId).requestedOwner, address(0));
+ }
+
+ function testAddConsumerTooManyConsumers() public {
+ // add 100 consumers to a sub and then
+ // try adding one more and see the revert
+ address subOwner = makeAddr("subOwner");
+ changePrank(subOwner);
+ uint256 subId = s_subscriptionAPI.createSubscription();
+ for (uint256 i = 0; i < 100; i++) {
+ address consumer = makeAddr(Strings.toString(i));
+ vm.expectEmit(true, false, false, true);
+ emit SubscriptionConsumerAdded(subId, consumer);
+ s_subscriptionAPI.addConsumer(subId, consumer);
+ }
+
+ // try adding one more consumer, should revert
+ address consumer = makeAddr("consumer");
+ changePrank(subOwner);
+ vm.expectRevert(SubscriptionAPI.TooManyConsumers.selector);
+ s_subscriptionAPI.addConsumer(subId, consumer);
+ }
+
+ function testAddConsumerReaddSameConsumer() public {
+ // try adding the same consumer twice
+ // should be a no-op
+ // assert state is unchanged after the 2nd add
+ address subOwner = makeAddr("subOwner");
+ address consumer = makeAddr("consumer");
+ changePrank(subOwner);
+ uint256 subId = s_subscriptionAPI.createSubscription();
+ assertEq(s_subscriptionAPI.getSubscriptionConfig(subId).consumers.length, 0);
+ changePrank(subOwner);
+ vm.expectEmit(true, false, false, true);
+ emit SubscriptionConsumerAdded(subId, consumer);
+ s_subscriptionAPI.addConsumer(subId, consumer);
+ assertEq(s_subscriptionAPI.getSubscriptionConfig(subId).consumers.length, 1);
+ assertEq(s_subscriptionAPI.getSubscriptionConfig(subId).consumers[0], consumer);
+
+ // add consumer again, should be no-op
+ changePrank(subOwner);
+ s_subscriptionAPI.addConsumer(subId, consumer);
+ assertEq(s_subscriptionAPI.getSubscriptionConfig(subId).consumers.length, 1);
+ assertEq(s_subscriptionAPI.getSubscriptionConfig(subId).consumers[0], consumer);
+ }
+
+ function testAddConsumer() public {
+ // create a subscription and add a consumer
+ // assert subscription state afterwards
+ address subOwner = makeAddr("subOwner");
+ address consumer = makeAddr("consumer");
+ changePrank(subOwner);
+ uint256 subId = s_subscriptionAPI.createSubscription();
+ assertEq(s_subscriptionAPI.getSubscriptionConfig(subId).consumers.length, 0);
+ changePrank(subOwner);
+ vm.expectEmit(true, false, false, true);
+ emit SubscriptionConsumerAdded(subId, consumer);
+ s_subscriptionAPI.addConsumer(subId, consumer);
+ assertEq(s_subscriptionAPI.getSubscriptionConfig(subId).consumers.length, 1);
+ assertEq(s_subscriptionAPI.getSubscriptionConfig(subId).consumers[0], consumer);
+ }
+}
diff --git a/contracts/test/v0.8/foundry/vrf/VRFV2Wrapper.t.sol b/contracts/test/v0.8/foundry/vrf/VRFV2Wrapper.t.sol
index 4b506bb8c50..8ed39093821 100644
--- a/contracts/test/v0.8/foundry/vrf/VRFV2Wrapper.t.sol
+++ b/contracts/test/v0.8/foundry/vrf/VRFV2Wrapper.t.sol
@@ -4,9 +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";
@@ -17,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();
@@ -34,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
@@ -70,6 +71,21 @@ contract VRFV2PlusWrapperTest is BaseTest {
vrfKeyHash, // keyHash
10 // max number of words
);
+ (
+ ,
+ ,
+ ,
+ uint32 _wrapperGasOverhead,
+ uint32 _coordinatorGasOverhead,
+ uint8 _wrapperPremiumPercentage,
+ bytes32 _keyHash,
+ uint8 _maxNumWords
+ ) = s_wrapper.getConfig();
+ assertEq(_wrapperGasOverhead, wrapperGasOverhead);
+ assertEq(_coordinatorGasOverhead, coordinatorGasOverhead);
+ assertEq(0, _wrapperPremiumPercentage);
+ assertEq(vrfKeyHash, _keyHash);
+ assertEq(10, _maxNumWords);
}
event RandomWordsRequested(
@@ -84,11 +100,42 @@ contract VRFV2PlusWrapperTest is BaseTest {
address indexed sender
);
+ function testSetLinkAndLinkNativeFeed() public {
+ VRFV2PlusWrapper wrapper = new VRFV2PlusWrapper(address(0), address(0), address(s_testCoordinator));
+
+ // Set LINK and LINK/Native feed on wrapper.
+ wrapper.setLINK(address(s_linkToken));
+ wrapper.setLinkNativeFeed(address(s_linkNativeFeed));
+ assertEq(address(wrapper.s_link()), address(s_linkToken));
+ assertEq(address(wrapper.s_linkNativeFeed()), address(s_linkNativeFeed));
+
+ // Revert for subsequent assignment.
+ vm.expectRevert(VRFV2PlusWrapper.LinkAlreadySet.selector);
+ wrapper.setLINK(address(s_linkToken));
+
+ // Consumer can set LINK token.
+ VRFV2PlusWrapperConsumerExample consumer = new VRFV2PlusWrapperConsumerExample(address(0), address(wrapper));
+ consumer.setLinkToken(address(s_linkToken));
+
+ // Revert for subsequent assignment.
+ vm.expectRevert(VRFV2PlusWrapperConsumerBase.LINKAlreadySet.selector);
+ consumer.setLinkToken(address(s_linkToken));
+ }
+
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.
+ assertEq(s_wrapper.typeAndVersion(), "VRFV2Wrapper 1.0.0");
+
+ // Cannot make request while disabled.
+ s_wrapper.disable();
+ vm.expectRevert("wrapper is disabled");
+ s_consumer.makeRequestNative(500_000, 0, 1);
+ s_wrapper.enable();
+
// Request randomness from wrapper.
uint32 callbackGasLimit = 1_000_000;
vm.expectEmit(true, true, true, true);
@@ -114,7 +161,11 @@ contract VRFV2PlusWrapperTest is BaseTest {
(uint256 paid, bool fulfilled, bool native) = s_consumer.s_requests(requestId);
uint32 expectedPaid = callbackGasLimit + wrapperGasOverhead + coordinatorGasOverhead;
+ uint256 wrapperNativeCostEstimate = s_wrapper.estimateRequestPriceNative(callbackGasLimit, tx.gasprice);
+ uint256 wrapperCostCalculation = s_wrapper.calculateRequestPriceNative(callbackGasLimit);
assertEq(paid, expectedPaid);
+ assertEq(uint256(paid), wrapperNativeCostEstimate);
+ assertEq(wrapperNativeCostEstimate, wrapperCostCalculation);
assertEq(fulfilled, false);
assertEq(native, true);
assertEq(address(s_consumer).balance, 10 ether - expectedPaid);
@@ -129,6 +180,13 @@ contract VRFV2PlusWrapperTest is BaseTest {
(, bool nowFulfilled, uint256[] memory storedWords) = s_consumer.getRequestStatus(requestId);
assertEq(nowFulfilled, true);
assertEq(storedWords[0], 123);
+
+ // Withdraw funds from wrapper.
+ changePrank(LINK_WHALE);
+ uint256 priorWhaleBalance = LINK_WHALE.balance;
+ s_wrapper.withdrawNative(LINK_WHALE, paid);
+ assertEq(LINK_WHALE.balance, priorWhaleBalance + paid);
+ assertEq(address(s_wrapper).balance, 0);
}
function testRequestAndFulfillRandomWordsLINKWrapper() public {
@@ -162,7 +220,11 @@ contract VRFV2PlusWrapperTest is BaseTest {
// Assert that the request was made correctly.
(uint256 paid, bool fulfilled, bool native) = s_consumer.s_requests(requestId);
uint32 expectedPaid = (callbackGasLimit + wrapperGasOverhead + coordinatorGasOverhead) * 2;
- assertEq(paid, expectedPaid); // 1_030_000 * 2 for link/eth ratio
+ uint256 wrapperCostEstimate = s_wrapper.estimateRequestPrice(callbackGasLimit, tx.gasprice);
+ uint256 wrapperCostCalculation = s_wrapper.calculateRequestPrice(callbackGasLimit);
+ assertEq(paid, expectedPaid); // 1_030_000 * 2 for link/native ratio
+ assertEq(uint256(paid), wrapperCostEstimate);
+ assertEq(wrapperCostEstimate, wrapperCostCalculation);
assertEq(fulfilled, false);
assertEq(native, false);
assertEq(s_linkToken.balanceOf(address(s_consumer)), 10 ether - expectedPaid);
@@ -177,5 +239,12 @@ contract VRFV2PlusWrapperTest is BaseTest {
(, bool nowFulfilled, uint256[] memory storedWords) = s_consumer.getRequestStatus(requestId);
assertEq(nowFulfilled, true);
assertEq(storedWords[0], 456);
+
+ // Withdraw funds from wrapper.
+ changePrank(LINK_WHALE);
+ uint256 priorWhaleBalance = s_linkToken.balanceOf(LINK_WHALE);
+ s_wrapper.withdraw(LINK_WHALE, paid);
+ assertEq(s_linkToken.balanceOf(LINK_WHALE), priorWhaleBalance + paid);
+ assertEq(s_linkToken.balanceOf(address(s_wrapper)), 0);
}
}
diff --git a/contracts/test/v0.8/functions/v0/Functions.test.ts b/contracts/test/v0.8/functions/v0/Functions.test.ts
index 0a4296c7636..242e5d57aad 100644
--- a/contracts/test/v0.8/functions/v0/Functions.test.ts
+++ b/contracts/test/v0.8/functions/v0/Functions.test.ts
@@ -17,7 +17,7 @@ let roles: Roles
before(async () => {
roles = (await getUsers()).roles
concreteFunctionsTestHelperFactory = await ethers.getContractFactory(
- 'src/v0.8/functions/tests/0_0_0/testhelpers/FunctionsTestHelper.sol:FunctionsTestHelper',
+ 'src/v0.8/functions/tests/v0_0_0/testhelpers/FunctionsTestHelper.sol:FunctionsTestHelper',
roles.defaultAccount,
)
})
diff --git a/contracts/test/v0.8/functions/v0/FunctionsBillingRegistry.test.ts b/contracts/test/v0.8/functions/v0/FunctionsBillingRegistry.test.ts
index b9110aea615..95160689d28 100644
--- a/contracts/test/v0.8/functions/v0/FunctionsBillingRegistry.test.ts
+++ b/contracts/test/v0.8/functions/v0/FunctionsBillingRegistry.test.ts
@@ -54,17 +54,17 @@ before(async () => {
roles = (await getUsers()).roles
functionsOracleFactory = await ethers.getContractFactory(
- 'src/v0.8/functions/tests/0_0_0/testhelpers/FunctionsOracleHelper.sol:FunctionsOracleHelper',
+ 'src/v0.8/functions/tests/v0_0_0/testhelpers/FunctionsOracleHelper.sol:FunctionsOracleHelper',
roles.defaultAccount,
)
clientTestHelperFactory = await ethers.getContractFactory(
- 'src/v0.8/functions/tests/0_0_0/testhelpers/FunctionsClientTestHelper.sol:FunctionsClientTestHelper',
+ 'src/v0.8/functions/tests/v0_0_0/testhelpers/FunctionsClientTestHelper.sol:FunctionsClientTestHelper',
roles.consumer,
)
functionsBillingRegistryFactory = await ethers.getContractFactory(
- 'src/v0.8/functions/tests/0_0_0/testhelpers/FunctionsBillingRegistryWithInit.sol:FunctionsBillingRegistryWithInit',
+ 'src/v0.8/functions/tests/v0_0_0/testhelpers/FunctionsBillingRegistryWithInit.sol:FunctionsBillingRegistryWithInit',
roles.consumer,
)
diff --git a/contracts/test/v0.8/functions/v0/FunctionsBillingRegistryUpgradeable.test.ts b/contracts/test/v0.8/functions/v0/FunctionsBillingRegistryUpgradeable.test.ts
index 04a7db0b2c0..5de99864525 100644
--- a/contracts/test/v0.8/functions/v0/FunctionsBillingRegistryUpgradeable.test.ts
+++ b/contracts/test/v0.8/functions/v0/FunctionsBillingRegistryUpgradeable.test.ts
@@ -53,17 +53,17 @@ before(async () => {
roles = (await getUsers()).roles
functionsOracleFactory = await ethers.getContractFactory(
- 'src/v0.8/functions/tests/0_0_0/testhelpers/FunctionsOracleHelper.sol:FunctionsOracleHelper',
+ 'src/v0.8/functions/tests/v0_0_0/testhelpers/FunctionsOracleHelper.sol:FunctionsOracleHelper',
roles.defaultAccount,
)
clientTestHelperFactory = await ethers.getContractFactory(
- 'src/v0.8/functions/tests/0_0_0/testhelpers/FunctionsClientTestHelper.sol:FunctionsClientTestHelper',
+ 'src/v0.8/functions/tests/v0_0_0/testhelpers/FunctionsClientTestHelper.sol:FunctionsClientTestHelper',
roles.consumer,
)
functionsBillingRegistryFactory = await ethers.getContractFactory(
- 'src/v0.8/functions/tests/0_0_0/testhelpers/mocks/FunctionsBillingRegistryOriginal.sol:FunctionsBillingRegistryOriginal',
+ 'src/v0.8/functions/tests/v0_0_0/testhelpers/mocks/FunctionsBillingRegistryOriginal.sol:FunctionsBillingRegistryOriginal',
roles.consumer,
)
@@ -223,7 +223,7 @@ describe('FunctionsRegistryUpgradeable', () => {
it('can be upgraded to a new implementation', async () => {
const upgradedRegistry = await migrateAndCheck(
- 'src/v0.8/functions/tests/0_0_0/testhelpers/mocks/FunctionsBillingRegistryMigration.sol:FunctionsBillingRegistryMigration',
+ 'src/v0.8/functions/tests/v0_0_0/testhelpers/mocks/FunctionsBillingRegistryMigration.sol:FunctionsBillingRegistryMigration',
)
// Check that upgrade was successful
@@ -242,7 +242,7 @@ describe('FunctionsRegistryUpgradeable', () => {
it('can be upgraded to the latest implementation', async () => {
await migrateAndCheck(
- 'src/v0.8/functions/dev/0_0_0/FunctionsBillingRegistry.sol:FunctionsBillingRegistry',
+ 'src/v0.8/functions/dev/v0_0_0/FunctionsBillingRegistry.sol:FunctionsBillingRegistry',
)
})
})
diff --git a/contracts/test/v0.8/functions/v0/FunctionsClient.test.ts b/contracts/test/v0.8/functions/v0/FunctionsClient.test.ts
index 4a474aadef2..94b06d8b37e 100644
--- a/contracts/test/v0.8/functions/v0/FunctionsClient.test.ts
+++ b/contracts/test/v0.8/functions/v0/FunctionsClient.test.ts
@@ -34,16 +34,16 @@ before(async () => {
roles = (await getUsers()).roles
concreteFunctionsClientFactory = await ethers.getContractFactory(
- 'src/v0.8/functions/tests/0_0_0/testhelpers/FunctionsClientTestHelper.sol:FunctionsClientTestHelper',
+ 'src/v0.8/functions/tests/v0_0_0/testhelpers/FunctionsClientTestHelper.sol:FunctionsClientTestHelper',
roles.defaultAccount,
)
functionsOracleFactory = await ethers.getContractFactory(
- 'src/v0.8/functions/tests/0_0_0/testhelpers/FunctionsOracleHelper.sol:FunctionsOracleHelper',
+ 'src/v0.8/functions/tests/v0_0_0/testhelpers/FunctionsOracleHelper.sol:FunctionsOracleHelper',
roles.defaultAccount,
)
functionsBillingRegistryFactory = await ethers.getContractFactory(
- 'src/v0.8/functions/tests/0_0_0/testhelpers/FunctionsBillingRegistryWithInit.sol:FunctionsBillingRegistryWithInit',
+ 'src/v0.8/functions/tests/v0_0_0/testhelpers/FunctionsBillingRegistryWithInit.sol:FunctionsBillingRegistryWithInit',
roles.defaultAccount,
)
diff --git a/contracts/test/v0.8/functions/v0/FunctionsOracle.test.ts b/contracts/test/v0.8/functions/v0/FunctionsOracle.test.ts
index ae44e1b037e..397cc3b397f 100644
--- a/contracts/test/v0.8/functions/v0/FunctionsOracle.test.ts
+++ b/contracts/test/v0.8/functions/v0/FunctionsOracle.test.ts
@@ -28,17 +28,17 @@ before(async () => {
roles = (await getUsers()).roles
functionsOracleFactory = await ethers.getContractFactory(
- 'src/v0.8/functions/tests/0_0_0/testhelpers/FunctionsOracleHelper.sol:FunctionsOracleHelper',
+ 'src/v0.8/functions/tests/v0_0_0/testhelpers/FunctionsOracleHelper.sol:FunctionsOracleHelper',
roles.defaultAccount,
)
clientTestHelperFactory = await ethers.getContractFactory(
- 'src/v0.8/functions/tests/0_0_0/testhelpers/FunctionsClientTestHelper.sol:FunctionsClientTestHelper',
+ 'src/v0.8/functions/tests/v0_0_0/testhelpers/FunctionsClientTestHelper.sol:FunctionsClientTestHelper',
roles.consumer,
)
functionsBillingRegistryFactory = await ethers.getContractFactory(
- 'src/v0.8/functions/tests/0_0_0/testhelpers/FunctionsBillingRegistryWithInit.sol:FunctionsBillingRegistryWithInit',
+ 'src/v0.8/functions/tests/v0_0_0/testhelpers/FunctionsBillingRegistryWithInit.sol:FunctionsBillingRegistryWithInit',
roles.defaultAccount,
)
@@ -351,9 +351,8 @@ describe('FunctionsOracle', () => {
})
it('#estimateCost correctly estimates cost [ @skip-coverage ]', async () => {
- const [subscriptionBalanceBefore] = await registry.getSubscription(
- subscriptionId,
- )
+ const [subscriptionBalanceBefore] =
+ await registry.getSubscription(subscriptionId)
const request = await client
.connect(roles.oracleNode)
@@ -376,9 +375,8 @@ describe('FunctionsOracle', () => {
.withArgs(requestId, transmitter)
.to.emit(registry, 'BillingEnd')
- const [subscriptionBalanceAfter] = await registry.getSubscription(
- subscriptionId,
- )
+ const [subscriptionBalanceAfter] =
+ await registry.getSubscription(subscriptionId)
const feeData = await ethers.provider.getFeeData()
const estimatedCost = await client.estimateJuelCost(
diff --git a/contracts/test/v0.8/functions/v0/FunctionsOracleUpgradeable.test.ts b/contracts/test/v0.8/functions/v0/FunctionsOracleUpgradeable.test.ts
index f127692373a..fe2dfdc9c3e 100644
--- a/contracts/test/v0.8/functions/v0/FunctionsOracleUpgradeable.test.ts
+++ b/contracts/test/v0.8/functions/v0/FunctionsOracleUpgradeable.test.ts
@@ -44,17 +44,17 @@ before(async () => {
roles = (await getUsers()).roles
functionsOracleOriginalFactory = await ethers.getContractFactory(
- 'src/v0.8/functions/tests/0_0_0/testhelpers/FunctionsOracleOriginalHelper.sol:FunctionsOracleOriginalHelper',
+ 'src/v0.8/functions/tests/v0_0_0/testhelpers/FunctionsOracleOriginalHelper.sol:FunctionsOracleOriginalHelper',
roles.defaultAccount,
)
clientTestHelperFactory = await ethers.getContractFactory(
- 'src/v0.8/functions/tests/0_0_0/testhelpers/FunctionsClientTestHelper.sol:FunctionsClientTestHelper',
+ 'src/v0.8/functions/tests/v0_0_0/testhelpers/FunctionsClientTestHelper.sol:FunctionsClientTestHelper',
roles.consumer,
)
functionsBillingRegistryFactory = await ethers.getContractFactory(
- 'src/v0.8/functions/tests/0_0_0/testhelpers/FunctionsBillingRegistryWithInit.sol:FunctionsBillingRegistryWithInit',
+ 'src/v0.8/functions/tests/v0_0_0/testhelpers/FunctionsBillingRegistryWithInit.sol:FunctionsBillingRegistryWithInit',
roles.defaultAccount,
)
@@ -221,7 +221,7 @@ describe('FunctionsOracleUpgradeable', () => {
it('can be upgraded to a new implementation', async () => {
const upgradedOracle = await migrateAndCheck(
- 'src/v0.8/functions/tests/0_0_0/testhelpers/FunctionsOracleMigrationHelper.sol:FunctionsOracleMigrationHelper',
+ 'src/v0.8/functions/tests/v0_0_0/testhelpers/FunctionsOracleMigrationHelper.sol:FunctionsOracleMigrationHelper',
)
// Check that upgrade was successful
@@ -240,7 +240,7 @@ describe('FunctionsOracleUpgradeable', () => {
it('can be upgraded to the latest implementation', async () => {
await migrateAndCheck(
- 'src/v0.8/functions/tests/0_0_0/testhelpers/FunctionsOracleUpgradeableHelper.sol:FunctionsOracleUpgradeableHelper',
+ 'src/v0.8/functions/tests/v0_0_0/testhelpers/FunctionsOracleUpgradeableHelper.sol:FunctionsOracleUpgradeableHelper',
)
})
})
diff --git a/contracts/test/v0.8/functions/v0/Gas.test.ts b/contracts/test/v0.8/functions/v0/Gas.test.ts
index c84e017972f..affa8052b9f 100644
--- a/contracts/test/v0.8/functions/v0/Gas.test.ts
+++ b/contracts/test/v0.8/functions/v0/Gas.test.ts
@@ -28,16 +28,16 @@ before(async () => {
roles = (await getUsers()).roles
concreteFunctionsClientFactory = await ethers.getContractFactory(
- 'src/v0.8/functions/tests/0_0_0/testhelpers/FunctionsClientTestHelper.sol:FunctionsClientTestHelper',
+ 'src/v0.8/functions/tests/v0_0_0/testhelpers/FunctionsClientTestHelper.sol:FunctionsClientTestHelper',
roles.defaultAccount,
)
functionsOracleFactory = await ethers.getContractFactory(
- 'src/v0.8/functions/tests/0_0_0/testhelpers/FunctionsOracleHelper.sol:FunctionsOracleHelper',
+ 'src/v0.8/functions/tests/v0_0_0/testhelpers/FunctionsOracleHelper.sol:FunctionsOracleHelper',
roles.defaultAccount,
)
functionsBillingRegistryFactory = await ethers.getContractFactory(
- 'src/v0.8/functions/tests/0_0_0/testhelpers/FunctionsBillingRegistryWithInit.sol:FunctionsBillingRegistryWithInit',
+ 'src/v0.8/functions/tests/v0_0_0/testhelpers/FunctionsBillingRegistryWithInit.sol:FunctionsBillingRegistryWithInit',
roles.defaultAccount,
)
diff --git a/contracts/test/v0.8/functions/v1/Functions.test.ts b/contracts/test/v0.8/functions/v1/Functions.test.ts
index b0128b90204..4de281c0b74 100644
--- a/contracts/test/v0.8/functions/v1/Functions.test.ts
+++ b/contracts/test/v0.8/functions/v1/Functions.test.ts
@@ -17,7 +17,7 @@ let roles: Roles
before(async () => {
roles = (await getUsers()).roles
concreteFunctionsTestHelperFactory = await ethers.getContractFactory(
- 'src/v0.8/functions/tests/1_0_0/testhelpers/FunctionsTestHelper.sol:FunctionsTestHelper',
+ 'src/v0.8/functions/tests/v1_0_0/testhelpers/FunctionsTestHelper.sol:FunctionsTestHelper',
roles.defaultAccount,
)
})
@@ -41,7 +41,6 @@ describe('FunctionsTestHelper', () => {
'addSecretsReference',
'addTwoArgs',
'addEmptyArgs',
- 'addSignature',
]),
).to.equal(true)
})
@@ -170,29 +169,4 @@ describe('FunctionsTestHelper', () => {
await expect(ctr.addEmptyArgs()).to.be.revertedWith('EmptyArgs()')
})
})
-
- describe('#addSignature', () => {
- it('emits CBOR encoded request with js source and signature', async () => {
- const signatureHex = 'aabbccddeeff'
- const js = 'function run(args, responses) {}'
- await ctr.initializeRequestForInlineJavaScript(js)
- await ctr.addSignature('0x' + signatureHex)
- const tx = await ctr.closeEvent()
- const [payload] = await parseRequestDataEvent(tx)
- const decoded = await decodeDietCBOR(payload)
- assert.deepEqual(
- {
- ...decoded,
- language: decoded.language.toNumber(),
- codeLocation: decoded.codeLocation.toNumber(),
- },
- {
- language: 0,
- codeLocation: 0,
- source: js,
- requestSignature: Buffer.from(signatureHex, 'hex'),
- },
- )
- })
- })
})
diff --git a/contracts/test/v0.8/functions/v1/FunctionsClient.test.ts b/contracts/test/v0.8/functions/v1/FunctionsClient.test.ts
index ccb059a5a3f..dad78769b75 100644
--- a/contracts/test/v0.8/functions/v1/FunctionsClient.test.ts
+++ b/contracts/test/v0.8/functions/v1/FunctionsClient.test.ts
@@ -178,7 +178,7 @@ describe('Faulty Functions Client', () => {
it('can complete requests with an empty callback', async () => {
const clientWithEmptyCallbackTestHelperFactory =
await ethers.getContractFactory(
- 'src/v0.8/functions/tests/1_0_0/testhelpers/FunctionsClientWithEmptyCallback.sol:FunctionsClientWithEmptyCallback',
+ 'src/v0.8/functions/tests/v1_0_0/testhelpers/FunctionsClientWithEmptyCallback.sol:FunctionsClientWithEmptyCallback',
roles.consumer,
)
diff --git a/contracts/test/v0.8/functions/v1/FunctionsSubscriptions.test.ts b/contracts/test/v0.8/functions/v1/FunctionsSubscriptions.test.ts
index e2f0372be15..86cfb9dd5fc 100644
--- a/contracts/test/v0.8/functions/v1/FunctionsSubscriptions.test.ts
+++ b/contracts/test/v0.8/functions/v1/FunctionsSubscriptions.test.ts
@@ -370,6 +370,9 @@ describe('Functions Router - Subscriptions', () => {
).to.be.revertedWith(`MustBeSubscriptionOwner()`)
})
it('can cancel', async function () {
+ const strangerBalanceBefore = await contracts.linkToken.balanceOf(
+ roles.strangerAddress,
+ )
await contracts.linkToken
.connect(roles.subOwner)
.transferAndCall(
@@ -383,11 +386,13 @@ describe('Functions Router - Subscriptions', () => {
.cancelSubscription(subId, roles.strangerAddress),
)
.to.emit(contracts.router, 'SubscriptionCanceled')
- .withArgs(subId, roles.strangerAddress, BigNumber.from('1000'))
+ .withArgs(subId, roles.strangerAddress, BigNumber.from('0'))
const strangerBalance = await contracts.linkToken.balanceOf(
roles.strangerAddress,
)
- expect(strangerBalance.toString()).to.equal('1000000000000001000')
+ expect(strangerBalance.toString()).to.equal(
+ strangerBalanceBefore.toString(),
+ )
await expect(
contracts.router.connect(roles.subOwner).getSubscription(subId),
).to.be.revertedWith('InvalidSubscription')
@@ -493,7 +498,7 @@ describe('Functions Router - Subscriptions', () => {
.connect(roles.subOwner)
.cancelSubscription(subId, roles.strangerAddress)
},
- BigNumber.from('-1000'),
+ BigNumber.from('0'),
],
]
for (const [fn, expectedBalanceChange] of balanceChangingFns) {
diff --git a/contracts/test/v0.8/functions/v1/utils.ts b/contracts/test/v0.8/functions/v1/utils.ts
index a7a89871f32..98f6143dee3 100644
--- a/contracts/test/v0.8/functions/v1/utils.ts
+++ b/contracts/test/v0.8/functions/v1/utils.ts
@@ -52,7 +52,7 @@ export const encodeReport = async (
offchainMetadata: string,
) => {
const functionsResponse = await ethers.getContractFactory(
- 'src/v0.8/functions/dev/1_0_0/FunctionsCoordinator.sol:FunctionsCoordinator',
+ 'src/v0.8/functions/dev/v1_0_0/FunctionsCoordinator.sol:FunctionsCoordinator',
)
const onchainMetadataBytes = functionsResponse.interface._abiCoder.encode(
[
@@ -77,6 +77,8 @@ export type FunctionsRouterConfig = {
handleOracleFulfillmentSelector: string
maxCallbackGasLimits: number[]
gasForCallExactCheck: number
+ subscriptionDepositMinimumRequests: number
+ subscriptionDepositJuels: BigNumber
}
export const functionsRouterConfig: FunctionsRouterConfig = {
maxConsumersPerSubscription: 100,
@@ -84,9 +86,10 @@ export const functionsRouterConfig: FunctionsRouterConfig = {
handleOracleFulfillmentSelector: '0x0ca76175',
maxCallbackGasLimits: [300_000, 500_000, 1_000_000],
gasForCallExactCheck: 5000,
+ subscriptionDepositMinimumRequests: 10,
+ subscriptionDepositJuels: BigNumber.from('1000000000000000000'),
}
export type CoordinatorConfig = {
- maxCallbackGasLimit: number
feedStalenessSeconds: number
gasOverheadBeforeCallback: number
gasOverheadAfterCallback: number
@@ -98,7 +101,6 @@ export type CoordinatorConfig = {
}
const fallbackNativePerUnitLink = 5000000000000000
export const coordinatorConfig: CoordinatorConfig = {
- maxCallbackGasLimit: 1_000_000,
feedStalenessSeconds: 86_400,
gasOverheadBeforeCallback: 44_615,
gasOverheadAfterCallback: 44_615,
@@ -128,19 +130,19 @@ export async function setupRolesAndFactories(): Promise<{
}> {
const roles = (await getUsers()).roles
const functionsRouterFactory = await ethers.getContractFactory(
- 'src/v0.8/functions/dev/1_0_0/FunctionsRouter.sol:FunctionsRouter',
+ 'src/v0.8/functions/dev/v1_0_0/FunctionsRouter.sol:FunctionsRouter',
roles.defaultAccount,
)
const functionsCoordinatorFactory = await ethers.getContractFactory(
- 'src/v0.8/functions/tests/1_0_0/testhelpers/FunctionsCoordinatorTestHelper.sol:FunctionsCoordinatorTestHelper',
+ 'src/v0.8/functions/tests/v1_0_0/testhelpers/FunctionsCoordinatorTestHelper.sol:FunctionsCoordinatorTestHelper',
roles.defaultAccount,
)
const accessControlFactory = await ethers.getContractFactory(
- 'src/v0.8/functions/dev/1_0_0/accessControl/TermsOfServiceAllowList.sol:TermsOfServiceAllowList',
+ 'src/v0.8/functions/dev/v1_0_0/accessControl/TermsOfServiceAllowList.sol:TermsOfServiceAllowList',
roles.defaultAccount,
)
const clientTestHelperFactory = await ethers.getContractFactory(
- 'src/v0.8/functions/tests/1_0_0/testhelpers/FunctionsClientTestHelper.sol:FunctionsClientTestHelper',
+ 'src/v0.8/functions/tests/v1_0_0/testhelpers/FunctionsClientTestHelper.sol:FunctionsClientTestHelper',
roles.consumer,
)
const linkTokenFactory = await ethers.getContractFactory(
diff --git a/core/chainlink.Dockerfile b/core/chainlink.Dockerfile
index 5daa4bf85ca..be1fdb9053b 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 e538f8c863b..9ec061ae40d 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/chain_kv.go b/core/chains/chain_kv.go
index 6292ef10197..5094f2885e5 100644
--- a/core/chains/chain_kv.go
+++ b/core/chains/chain_kv.go
@@ -5,17 +5,18 @@ import (
"fmt"
"golang.org/x/exp/maps"
+
+ "github.com/smartcontractkit/chainlink-relay/pkg/types"
)
-type ChainsKV[T ChainService] struct {
+type ChainsKV[T types.ChainService] struct {
// note: this is read only after construction so no need for mutex
chains map[string]T
}
var ErrNoSuchChainID = errors.New("chain id does not exist")
-func NewChainsKV[T ChainService](cs map[string]T) *ChainsKV[T] {
-
+func NewChainsKV[T types.ChainService](cs map[string]T) *ChainsKV[T] {
return &ChainsKV[T]{
chains: cs,
}
diff --git a/core/chains/chain_kv_test.go b/core/chains/chain_kv_test.go
index c042eea20f1..a30de3090b8 100644
--- a/core/chains/chain_kv_test.go
+++ b/core/chains/chain_kv_test.go
@@ -7,6 +7,7 @@ import (
"github.com/stretchr/testify/assert"
+ "github.com/smartcontractkit/chainlink-relay/pkg/types"
"github.com/smartcontractkit/chainlink/v2/core/chains"
)
@@ -88,6 +89,13 @@ func (s *testChainService) HealthReport() map[string]error {
return map[string]error{}
}
-func (s *testChainService) SendTx(ctx context.Context, from string, to string, amount *big.Int, balanceCheck bool) error {
+// Implement [types.ChainService] interface
+func (s *testChainService) GetChainStatus(ctx context.Context) (stat types.ChainStatus, err error) {
+ return
+}
+func (s *testChainService) ListNodeStatuses(ctx context.Context, pageSize int32, pageToken string) (stats []types.NodeStatus, nextPageToken string, total int, err error) {
+ return
+}
+func (s *testChainService) Transact(ctx context.Context, from string, to string, amount *big.Int, balanceCheck bool) error {
return nil
}
diff --git a/core/chains/chain_set.go b/core/chains/chain_set.go
deleted file mode 100644
index ed5ee918366..00000000000
--- a/core/chains/chain_set.go
+++ /dev/null
@@ -1,166 +0,0 @@
-package chains
-
-import (
- "context"
- "fmt"
- "math/big"
-
- "github.com/pkg/errors"
- "go.uber.org/multierr"
- "golang.org/x/exp/maps"
-
- "github.com/smartcontractkit/chainlink-relay/pkg/logger"
- "github.com/smartcontractkit/chainlink-relay/pkg/types"
-
- "github.com/smartcontractkit/chainlink/v2/core/services"
- "github.com/smartcontractkit/chainlink/v2/core/utils"
-)
-
-var (
- // ErrChainIDEmpty is returned when chain is required but was empty.
- ErrChainIDEmpty = errors.New("chain id empty")
- ErrNotFound = errors.New("not found")
-)
-
-// ChainStatuser is a generic interface for chain configuration.
-type ChainStatuser interface {
- // must return [ErrNotFound] if the id is not found
- ChainStatus(ctx context.Context, id string) (types.ChainStatus, error)
- ChainStatuses(ctx context.Context, offset, limit int) ([]types.ChainStatus, int, error)
-}
-
-// NodesStatuser is an interface for node configuration and state.
-// TODO BCF2440, BCF-2511 may need Node(ctx,name) to get a node status by name
-type NodesStatuser interface {
- NodeStatuses(ctx context.Context, offset, limit int, chainIDs ...string) (nodes []types.NodeStatus, count int, err error)
-}
-
-// ChainService is a live, runtime chain instance, with supporting services.
-type ChainService interface {
- services.ServiceCtx
- SendTx(ctx context.Context, from, to string, amount *big.Int, balanceCheck bool) error
-}
-
-// ChainSetOpts holds options for configuring a ChainSet via NewChainSet.
-type ChainSetOpts[I ID, N Node] interface {
- Validate() error
- ConfigsAndLogger() (Configs[I, N], logger.Logger)
-}
-
-type chainSet[N Node, S ChainService] struct {
- utils.StartStopOnce
- opts ChainSetOpts[string, N]
- configs Configs[string, N]
- lggr logger.Logger
- chains map[string]S
-}
-
-// NewChainSet returns a new immutable ChainSet for the given ChainSetOpts.
-func NewChainSet[N Node, S ChainService](
- chains map[string]S,
- opts ChainSetOpts[string, N],
-) (types.ChainSet[string, S], error) {
- if err := opts.Validate(); err != nil {
- return nil, err
- }
- cfgs, lggr := opts.ConfigsAndLogger()
- cs := chainSet[N, S]{
- opts: opts,
- configs: cfgs,
- lggr: logger.Named(lggr, "ChainSet"),
- chains: chains,
- }
-
- return &cs, nil
-}
-
-func (c *chainSet[N, S]) Chain(ctx context.Context, id string) (s S, err error) {
- if err = c.StartStopOnce.Ready(); err != nil {
- return
- }
- ch, ok := c.chains[id]
- if !ok {
- err = fmt.Errorf("chain %s: %w", id, ErrNotFound)
- return
- }
- return ch, nil
-}
-
-func (c *chainSet[N, S]) ChainStatus(ctx context.Context, id string) (cfg types.ChainStatus, err error) {
- var cs []types.ChainStatus
- cs, _, err = c.configs.Chains(0, -1, id)
- if err != nil {
- return
- }
- l := len(cs)
- if l == 0 {
- err = fmt.Errorf("chain %s: %w", id, ErrNotFound)
- return
- }
- if l > 1 {
- err = fmt.Errorf("multiple chains found: %d", len(cs))
- return
- }
- cfg = cs[0]
- return
-}
-
-func (c *chainSet[N, S]) ChainStatuses(ctx context.Context, offset, limit int) ([]types.ChainStatus, int, error) {
- return c.configs.Chains(offset, limit)
-}
-
-func (c *chainSet[N, S]) NodeStatuses(ctx context.Context, offset, limit int, chainIDs ...string) (nodes []types.NodeStatus, count int, err error) {
- return c.configs.NodeStatusesPaged(offset, limit, chainIDs...)
-}
-
-func (c *chainSet[N, S]) SendTx(ctx context.Context, chainID, from, to string, amount *big.Int, balanceCheck bool) error {
- chain, err := c.Chain(ctx, chainID)
- if err != nil {
- return err
- }
-
- return chain.SendTx(ctx, from, to, amount, balanceCheck)
-}
-
-func (c *chainSet[N, S]) Start(ctx context.Context) error {
- return c.StartOnce("ChainSet", func() error {
- c.lggr.Debug("Starting")
-
- var ms services.MultiStart
- for id, ch := range c.chains {
- if err := ms.Start(ctx, ch); err != nil {
- return errors.Wrapf(err, "failed to start chain %q", id)
- }
- }
- c.lggr.Info(fmt.Sprintf("Started %d chains", len(c.chains)))
- return nil
- })
-}
-
-func (c *chainSet[N, S]) Close() error {
- return c.StopOnce("ChainSet", func() error {
- c.lggr.Debug("Stopping")
-
- return services.MultiCloser(maps.Values(c.chains)).Close()
- })
-}
-
-func (c *chainSet[N, S]) Ready() (err error) {
- err = c.StartStopOnce.Ready()
- for _, c := range c.chains {
- err = multierr.Combine(err, c.Ready())
- }
- return
-}
-
-func (c *chainSet[N, S]) Name() string {
- return c.lggr.Name()
-}
-
-func (c *chainSet[N, S]) HealthReport() map[string]error {
- report := map[string]error{c.Name(): c.StartStopOnce.Healthy()}
- for _, c := range c.chains {
- maps.Copy(report, c.HealthReport())
- }
- return report
-}
diff --git a/core/chains/config.go b/core/chains/config.go
index 54f1bb4bf8a..3556c33a785 100644
--- a/core/chains/config.go
+++ b/core/chains/config.go
@@ -1,23 +1,16 @@
package chains
import (
- "github.com/smartcontractkit/chainlink-relay/pkg/types"
+ "errors"
)
-type ChainConfigs interface {
- Chains(offset, limit int, ids ...string) ([]types.ChainStatus, int, error)
-}
-
-type NodeConfigs[I ID, N Node] interface {
- Node(name string) (N, error)
- Nodes(chainID I) (nodes []N, err error)
-
- NodeStatus(name string) (types.NodeStatus, error)
- NodeStatusesPaged(offset, limit int, chainIDs ...string) (nodes []types.NodeStatus, count int, err error)
-}
+var (
+ // ErrChainIDEmpty is returned when chain is required but was empty.
+ ErrChainIDEmpty = errors.New("chain id empty")
+ ErrNotFound = errors.New("not found")
+)
-// Configs holds chain and node configurations.
-type Configs[I ID, N Node] interface {
- ChainConfigs
- NodeConfigs[I, N]
+// ChainOpts holds options for configuring a Chain
+type ChainOpts interface {
+ Validate() error
}
diff --git a/core/chains/config_v2.go b/core/chains/config_v2.go
deleted file mode 100644
index 414179d8495..00000000000
--- a/core/chains/config_v2.go
+++ /dev/null
@@ -1,86 +0,0 @@
-package chains
-
-import "github.com/smartcontractkit/chainlink-relay/pkg/types"
-
-type configsV2AsV1[I ID, N Node] struct {
- *configChains
- *configNodes[I, N]
-}
-
-type ConfigsV2[I ID, N Node] interface {
- chainConfigsV2
- nodeConfigsV2[I, N]
-}
-
-// NewConfigs returns a [Configs] backed by [ConfigsV2].
-func NewConfigs[I ID, N Node](cfgs ConfigsV2[I, N]) Configs[I, N] {
- return configsV2AsV1[I, N]{
- newConfigChains[I](cfgs),
- newConfigNodes[I, N](cfgs),
- }
-}
-
-// configChains is a generic, immutable Configs for chains.
-type configChains struct {
- v2 chainConfigsV2
-}
-
-type chainConfigsV2 interface {
- Chains(ids ...string) ([]types.ChainStatus, error)
-}
-
-// newConfigChains returns a chains backed by chains.
-func newConfigChains[I ID](d chainConfigsV2) *configChains {
- return &configChains{v2: d}
-}
-
-func (o *configChains) Chains(offset, limit int, ids ...string) (chains []types.ChainStatus, count int, err error) {
- chains, err = o.v2.Chains(ids...)
- if err != nil {
- return
- }
- count = len(chains)
- if offset < len(chains) {
- chains = chains[offset:]
- } else {
- chains = nil
- }
- if limit > 0 && len(chains) > limit {
- chains = chains[:limit]
- }
- return
-}
-
-type nodeConfigsV2[I ID, N Node] interface {
- Node(name string) (N, error)
- Nodes(chainID I) ([]N, error)
-
- NodeStatus(name string) (types.NodeStatus, error)
- NodeStatuses(chainIDs ...string) (nodes []types.NodeStatus, err error)
-}
-
-// configNodes is a generic Configs for nodes.
-type configNodes[I ID, N Node] struct {
- nodeConfigsV2[I, N]
-}
-
-func newConfigNodes[I ID, N Node](d nodeConfigsV2[I, N]) *configNodes[I, N] {
- return &configNodes[I, N]{d}
-}
-
-func (o *configNodes[I, N]) NodeStatusesPaged(offset, limit int, chainIDs ...string) (nodes []types.NodeStatus, count int, err error) {
- nodes, err = o.nodeConfigsV2.NodeStatuses(chainIDs...)
- if err != nil {
- return
- }
- count = len(nodes)
- if offset < len(nodes) {
- nodes = nodes[offset:]
- } else {
- nodes = nil
- }
- if limit > 0 && len(nodes) > limit {
- nodes = nodes[:limit]
- }
- return
-}
diff --git a/core/chains/cosmos/chain.go b/core/chains/cosmos/chain.go
index 82d9a87f4d1..6323806cc1f 100644
--- a/core/chains/cosmos/chain.go
+++ b/core/chains/cosmos/chain.go
@@ -20,12 +20,14 @@ import (
"github.com/smartcontractkit/chainlink-cosmos/pkg/cosmos/db"
"github.com/smartcontractkit/chainlink-relay/pkg/logger"
+ "github.com/smartcontractkit/chainlink-relay/pkg/loop"
+ relaytypes "github.com/smartcontractkit/chainlink-relay/pkg/types"
"github.com/smartcontractkit/chainlink/v2/core/chains"
"github.com/smartcontractkit/chainlink/v2/core/chains/cosmos/cosmostxm"
- "github.com/smartcontractkit/chainlink/v2/core/chains/cosmos/types"
- "github.com/smartcontractkit/chainlink/v2/core/services/keystore"
+ "github.com/smartcontractkit/chainlink/v2/core/chains/internal"
"github.com/smartcontractkit/chainlink/v2/core/services/pg"
+ "github.com/smartcontractkit/chainlink/v2/core/services/relay"
"github.com/smartcontractkit/chainlink/v2/core/utils"
)
@@ -37,23 +39,73 @@ import (
// TODO(BCI-979): Remove this, or make this configurable with the updated client.
const DefaultRequestTimeout = 30 * time.Second
+var (
+ // ErrChainIDEmpty is returned when chain is required but was empty.
+ ErrChainIDEmpty = errors.New("chain id empty")
+ // ErrChainIDInvalid is returned when a chain id does not match any configured chains.
+ ErrChainIDInvalid = errors.New("chain id does not match any local chains")
+)
+
+// Chain is a wrap for easy use in other places in the core node
+type Chain = adapters.Chain
+
+// ChainOpts holds options for configuring a Chain.
+type ChainOpts struct {
+ QueryConfig pg.QConfig
+ Logger logger.Logger
+ DB *sqlx.DB
+ KeyStore loop.Keystore
+ EventBroadcaster pg.EventBroadcaster
+}
+
+func (o *ChainOpts) Validate() (err error) {
+ required := func(s string) error {
+ return fmt.Errorf("%s is required", s)
+ }
+ if o.QueryConfig == nil {
+ err = multierr.Append(err, required("Config"))
+ }
+ if o.Logger == nil {
+ err = multierr.Append(err, required("Logger'"))
+ }
+ if o.DB == nil {
+ err = multierr.Append(err, required("DB"))
+ }
+ if o.KeyStore == nil {
+ err = multierr.Append(err, required("KeyStore"))
+ }
+ if o.EventBroadcaster == nil {
+ err = multierr.Append(err, required("EventBroadcaster"))
+ }
+ return
+}
+
+func NewChain(cfg *CosmosConfig, opts ChainOpts) (adapters.Chain, error) {
+ if !cfg.IsEnabled() {
+ return nil, fmt.Errorf("cannot create new chain with ID %s, the chain is disabled", *cfg.ChainID)
+ }
+ c, err := newChain(*cfg.ChainID, cfg, opts.DB, opts.KeyStore, opts.QueryConfig, opts.EventBroadcaster, opts.Logger)
+ if err != nil {
+ return nil, err
+ }
+ return c, nil
+}
+
var _ adapters.Chain = (*chain)(nil)
type chain struct {
utils.StartStopOnce
id string
- cfg coscfg.Config
+ cfg *CosmosConfig
txm *cosmostxm.Txm
- cfgs types.Configs
lggr logger.Logger
}
-func newChain(id string, cfg coscfg.Config, db *sqlx.DB, ks keystore.Cosmos, logCfg pg.QConfig, eb pg.EventBroadcaster, cfgs types.Configs, lggr logger.Logger) (*chain, error) {
+func newChain(id string, cfg *CosmosConfig, db *sqlx.DB, ks loop.Keystore, logCfg pg.QConfig, eb pg.EventBroadcaster, lggr logger.Logger) (*chain, error) {
lggr = logger.With(lggr, "cosmosChainID", id)
var ch = chain{
id: id,
cfg: cfg,
- cfgs: cfgs,
lggr: logger.Named(lggr, "Chain"),
}
tc := func() (cosmosclient.ReaderWriter, error) {
@@ -62,7 +114,7 @@ func newChain(id string, cfg coscfg.Config, db *sqlx.DB, ks keystore.Cosmos, log
gpe := cosmosclient.NewMustGasPriceEstimator([]cosmosclient.GasPricesEstimator{
cosmosclient.NewClosureGasPriceEstimator(func() (map[string]sdk.DecCoin, error) {
return map[string]sdk.DecCoin{
- cfg.FeeToken(): sdk.NewDecCoinFromDec(cfg.FeeToken(), cfg.FallbackGasPrice()),
+ cfg.GasToken(): sdk.NewDecCoinFromDec(cfg.GasToken(), cfg.FallbackGasPrice()),
}, nil
}),
}, lggr)
@@ -79,6 +131,10 @@ func (c *chain) ID() string {
return c.id
}
+func (c *chain) ChainID() relay.ChainID {
+ return relay.ChainID(c.id)
+}
+
func (c *chain) Config() coscfg.Config {
return c.cfg
}
@@ -95,31 +151,31 @@ func (c *chain) Reader(name string) (cosmosclient.Reader, error) {
func (c *chain) getClient(name string) (cosmosclient.ReaderWriter, error) {
var node db.Node
if name == "" { // Any node
- nodes, err := c.cfgs.Nodes(c.id)
+ nodes, err := c.cfg.ListNodes()
if err != nil {
- return nil, errors.Wrap(err, "failed to get nodes")
+ return nil, fmt.Errorf("failed to list nodes: %w", err)
}
if len(nodes) == 0 {
return nil, errors.New("no nodes available")
}
nodeIndex, err := rand.Int(rand.Reader, big.NewInt(int64(len(nodes))))
if err != nil {
- return nil, errors.Wrap(err, "could not generate a random node index")
+ return nil, fmt.Errorf("could not generate a random node index: %w", err)
}
node = nodes[nodeIndex.Int64()]
} else { // Named node
var err error
- node, err = c.cfgs.Node(name)
+ node, err = c.cfg.GetNode(name)
if err != nil {
- return nil, errors.Wrapf(err, "failed to get node named %s", name)
+ return nil, fmt.Errorf("failed to get node named %s: %w", name, err)
}
if node.CosmosChainID != c.id {
return nil, fmt.Errorf("failed to create client for chain %s with node %s: wrong chain id %s", c.id, name, node.CosmosChainID)
}
}
- client, err := cosmosclient.NewClient(c.id, node.TendermintURL, DefaultRequestTimeout, logger.Named(c.lggr, "Client-"+name))
+ client, err := cosmosclient.NewClient(c.id, node.TendermintURL, DefaultRequestTimeout, logger.Named(c.lggr, "Client."+name))
if err != nil {
- return nil, errors.Wrap(err, "failed to create client")
+ return nil, fmt.Errorf("failed to create client: %w", err)
}
c.lggr.Debugw("Created client", "name", node.Name, "tendermint-url", node.TendermintURL)
return client, nil
@@ -155,6 +211,43 @@ func (c *chain) HealthReport() map[string]error {
}
}
-func (c *chain) SendTx(ctx context.Context, from, to string, amount *big.Int, balanceCheck bool) error {
+// ChainService interface
+func (c *chain) GetChainStatus(ctx context.Context) (relaytypes.ChainStatus, error) {
+ toml, err := c.cfg.TOMLString()
+ if err != nil {
+ return relaytypes.ChainStatus{}, err
+ }
+ return relaytypes.ChainStatus{
+ ID: c.id,
+ Enabled: *c.cfg.Enabled,
+ Config: toml,
+ }, nil
+}
+func (c *chain) ListNodeStatuses(ctx context.Context, pageSize int32, pageToken string) (stats []relaytypes.NodeStatus, nextPageToken string, total int, err error) {
+ return internal.ListNodeStatuses(int(pageSize), pageToken, c.listNodeStatuses)
+}
+
+func (c *chain) Transact(ctx context.Context, from, to string, amount *big.Int, balanceCheck bool) error {
return chains.ErrLOOPPUnsupported
}
+
+// TODO BCF-2602 statuses are static for non-evm chain and should be dynamic
+func (c *chain) listNodeStatuses(start, end int) ([]relaytypes.NodeStatus, int, error) {
+ stats := make([]relaytypes.NodeStatus, 0)
+ total := len(c.cfg.Nodes)
+ if start >= total {
+ return stats, total, internal.ErrOutOfRange
+ }
+ if end > total {
+ end = total
+ }
+ nodes := c.cfg.Nodes[start:end]
+ for _, node := range nodes {
+ stat, err := nodeStatus(node, c.ChainID())
+ if err != nil {
+ return stats, total, err
+ }
+ stats = append(stats, stat)
+ }
+ return stats, total, nil
+}
diff --git a/core/chains/cosmos/chain_set.go b/core/chains/cosmos/chain_set.go
deleted file mode 100644
index 008c62c3ffd..00000000000
--- a/core/chains/cosmos/chain_set.go
+++ /dev/null
@@ -1,179 +0,0 @@
-package cosmos
-
-import (
- "context"
- "errors"
- "fmt"
-
- "go.uber.org/multierr"
-
- "github.com/smartcontractkit/sqlx"
-
- "github.com/smartcontractkit/chainlink-cosmos/pkg/cosmos/adapters"
- "github.com/smartcontractkit/chainlink-cosmos/pkg/cosmos/db"
-
- "github.com/smartcontractkit/chainlink-relay/pkg/logger"
- "github.com/smartcontractkit/chainlink-relay/pkg/loop"
-
- pkgcosmos "github.com/smartcontractkit/chainlink-cosmos/pkg/cosmos"
- "github.com/smartcontractkit/chainlink/v2/core/chains"
- "github.com/smartcontractkit/chainlink/v2/core/chains/cosmos/types"
- "github.com/smartcontractkit/chainlink/v2/core/services/keystore"
- "github.com/smartcontractkit/chainlink/v2/core/services/pg"
- "github.com/smartcontractkit/chainlink/v2/core/services/relay"
-)
-
-var (
- // ErrChainIDEmpty is returned when chain is required but was empty.
- ErrChainIDEmpty = errors.New("chain id empty")
- // ErrChainIDInvalid is returned when a chain id does not match any configured chains.
- ErrChainIDInvalid = errors.New("chain id does not match any local chains")
-)
-
-// Chain is a wrap for easy use in other places in the core node
-type Chain = adapters.Chain
-
-// ChainSetOpts holds options for configuring a ChainSet.
-type ChainSetOpts struct {
- QueryConfig pg.QConfig
- Logger logger.Logger
- DB *sqlx.DB
- KeyStore keystore.Cosmos
- EventBroadcaster pg.EventBroadcaster
- Configs types.Configs
-}
-
-func (o *ChainSetOpts) Validate() (err error) {
- required := func(s string) error {
- return fmt.Errorf("%s is required", s)
- }
- if o.QueryConfig == nil {
- err = multierr.Append(err, required("Config"))
- }
- if o.Logger == nil {
- err = multierr.Append(err, required("Logger'"))
- }
- if o.DB == nil {
- err = multierr.Append(err, required("DB"))
- }
- if o.KeyStore == nil {
- err = multierr.Append(err, required("KeyStore"))
- }
- if o.EventBroadcaster == nil {
- err = multierr.Append(err, required("EventBroadcaster"))
- }
- if o.Configs == nil {
- err = multierr.Append(err, required("Configs"))
- }
- return
-}
-
-func (o *ChainSetOpts) ConfigsAndLogger() (chains.Configs[string, db.Node], logger.Logger) {
- return o.Configs, o.Logger
-}
-
-func (o *ChainSetOpts) NewTOMLChain(cfg *CosmosConfig) (adapters.Chain, error) {
- if !cfg.IsEnabled() {
- return nil, fmt.Errorf("cannot create new chain with ID %s, the chain is disabled", *cfg.ChainID)
- }
- c, err := newChain(*cfg.ChainID, cfg, o.DB, o.KeyStore, o.QueryConfig, o.EventBroadcaster, o.Configs, o.Logger)
- if err != nil {
- return nil, err
- }
- return c, nil
-}
-
-// LegacyChainContainer is container interface for Cosmos chains
-type LegacyChainContainer interface {
- Get(id string) (adapters.Chain, error)
- Len() int
- List(ids ...string) ([]adapters.Chain, error)
- Slice() []adapters.Chain
-}
-
-type LegacyChains = chains.ChainsKV[adapters.Chain]
-
-var _ LegacyChainContainer = &LegacyChains{}
-
-func NewLegacyChains(m map[string]adapters.Chain) *LegacyChains {
- return chains.NewChainsKV[adapters.Chain](m)
-}
-
-type LoopRelayerChainer interface {
- loop.Relayer
- Chain() adapters.Chain
-}
-
-type LoopRelayerSingleChain struct {
- loop.Relayer
- singleChain *SingleChainSet
-}
-
-func NewLoopRelayerSingleChain(r *pkgcosmos.Relayer, s *SingleChainSet) *LoopRelayerSingleChain {
- ra := relay.NewRelayerAdapter(r, s)
- return &LoopRelayerSingleChain{
- Relayer: ra,
- singleChain: s,
- }
-}
-func (r *LoopRelayerSingleChain) Chain() adapters.Chain {
- return r.singleChain.chain
-}
-
-var _ LoopRelayerChainer = &LoopRelayerSingleChain{}
-
-func newChainSet(opts ChainSetOpts, cfgs CosmosConfigs) (adapters.ChainSet, map[string]adapters.Chain, error) {
- cosmosChains := map[string]adapters.Chain{}
- var err error
- for _, chain := range cfgs {
- if !chain.IsEnabled() {
- continue
- }
- var err2 error
- cosmosChains[*chain.ChainID], err2 = opts.NewTOMLChain(chain)
- if err2 != nil {
- err = multierr.Combine(err, err2)
- continue
- }
- }
- if err != nil {
- return nil, nil, fmt.Errorf("failed to load some Cosmos chains: %w", err)
- }
-
- cs, err := chains.NewChainSet[db.Node, adapters.Chain](cosmosChains, &opts)
- if err != nil {
- return nil, nil, err
- }
-
- return cs, cosmosChains, nil
-}
-
-// SingleChainSet is a chainset with 1 chain. TODO remove when relayer interface is updated
-type SingleChainSet struct {
- adapters.ChainSet
- ID string
- chain adapters.Chain
-}
-
-func (s *SingleChainSet) Chain(ctx context.Context, id string) (adapters.Chain, error) {
- return s.chain, nil
-}
-
-func NewSingleChainSet(opts ChainSetOpts, cfg *CosmosConfig) (*SingleChainSet, error) {
- cs, m, err := newChainSet(opts, CosmosConfigs{cfg})
- if err != nil {
- return nil, err
- }
- if len(m) != 1 {
- return nil, fmt.Errorf("invalid Single chain: more than one chain %d", len(m))
- }
- var chain adapters.Chain
- for _, ch := range m {
- chain = ch
- }
- return &SingleChainSet{
- ChainSet: cs,
- ID: *cfg.ChainID,
- chain: chain,
- }, nil
-}
diff --git a/core/chains/cosmos/config.go b/core/chains/cosmos/config.go
index 62a76be44d1..fda791d0dc2 100644
--- a/core/chains/cosmos/config.go
+++ b/core/chains/cosmos/config.go
@@ -16,7 +16,7 @@ import (
relaytypes "github.com/smartcontractkit/chainlink-relay/pkg/types"
"github.com/smartcontractkit/chainlink/v2/core/chains"
- "github.com/smartcontractkit/chainlink/v2/core/chains/cosmos/types"
+ "github.com/smartcontractkit/chainlink/v2/core/services/relay"
"github.com/smartcontractkit/chainlink/v2/core/utils/config"
)
@@ -77,119 +77,9 @@ func (cs *CosmosConfigs) SetFrom(fs *CosmosConfigs) (err error) {
return
}
-func (cs CosmosConfigs) Chains(ids ...string) (r []relaytypes.ChainStatus, err error) {
- for _, ch := range cs {
- if ch == nil {
- continue
- }
- if len(ids) > 0 {
- var match bool
- for _, id := range ids {
- if id == *ch.ChainID {
- match = true
- break
- }
- }
- if !match {
- continue
- }
- }
- ch2 := relaytypes.ChainStatus{
- ID: *ch.ChainID,
- Enabled: ch.IsEnabled(),
- }
- ch2.Config, err = ch.TOMLString()
- if err != nil {
- return
- }
- r = append(r, ch2)
- }
- return
-}
-
-func (cs CosmosConfigs) Node(name string) (n db.Node, err error) {
- for i := range cs {
- for _, n := range cs[i].Nodes {
- if n.Name != nil && *n.Name == name {
- return legacyNode(n, *cs[i].ChainID), nil
- }
- }
- }
- err = fmt.Errorf("node %s: %w", name, chains.ErrNotFound)
- return
-}
-
-func (cs CosmosConfigs) nodes(chainID string) (ns CosmosNodes) {
- for _, c := range cs {
- if *c.ChainID == chainID {
- return c.Nodes
- }
- }
- return nil
-}
-
-func (cs CosmosConfigs) Nodes(chainID string) (ns []db.Node, err error) {
- nodes := cs.nodes(chainID)
- if nodes == nil {
- err = fmt.Errorf("no nodes: chain %s: %w", chainID, chains.ErrNotFound)
- return
- }
- for _, n := range nodes {
- if n == nil {
- continue
- }
- ns = append(ns, legacyNode(n, chainID))
- }
- return
-
-}
-
-func (cs CosmosConfigs) NodeStatus(name string) (n relaytypes.NodeStatus, err error) {
- for i := range cs {
- for _, n := range cs[i].Nodes {
- if n.Name != nil && *n.Name == name {
- return nodeStatus(n, *cs[i].ChainID)
- }
- }
- }
- err = fmt.Errorf("node %s: %w", name, chains.ErrNotFound)
- return
-}
-
-func (cs CosmosConfigs) NodeStatuses(chainIDs ...string) (ns []relaytypes.NodeStatus, err error) {
- if len(chainIDs) == 0 {
- for i := range cs {
- for _, n := range cs[i].Nodes {
- if n == nil {
- continue
- }
- n2, err := nodeStatus(n, *cs[i].ChainID)
- if err != nil {
- return nil, err
- }
- ns = append(ns, n2)
- }
- }
- return
- }
- for _, id := range chainIDs {
- for _, n := range cs.nodes(id) {
- if n == nil {
- continue
- }
- n2, err := nodeStatus(n, id)
- if err != nil {
- return nil, err
- }
- ns = append(ns, n2)
- }
- }
- return
-}
-
-func nodeStatus(n *coscfg.Node, chainID string) (relaytypes.NodeStatus, error) {
+func nodeStatus(n *coscfg.Node, id relay.ChainID) (relaytypes.NodeStatus, error) {
var s relaytypes.NodeStatus
- s.ChainID = chainID
+ s.ChainID = id
s.Name = *n.Name
b, err := toml.Marshal(n)
if err != nil {
@@ -234,6 +124,7 @@ func legacyNode(n *coscfg.Node, id string) db.Node {
type CosmosConfig struct {
ChainID *string
+ // Do not access directly. Use [IsEnabled]
Enabled *bool
coscfg.Chain
Nodes CosmosNodes
@@ -270,8 +161,8 @@ func setFromChain(c, f *coscfg.Chain) {
if f.FallbackGasPrice != nil {
c.FallbackGasPrice = f.FallbackGasPrice
}
- if f.FeeToken != nil {
- c.FeeToken = f.FeeToken
+ if f.GasToken != nil {
+ c.GasToken = f.GasToken
}
if f.GasLimitMultiplier != nil {
c.GasLimitMultiplier = f.GasLimitMultiplier
@@ -334,8 +225,8 @@ func (c *CosmosConfig) FallbackGasPrice() sdk.Dec {
return sdkDecFromDecimal(c.Chain.FallbackGasPrice)
}
-func (c *CosmosConfig) FeeToken() string {
- return *c.Chain.FeeToken
+func (c *CosmosConfig) GasToken() string {
+ return *c.Chain.GasToken
}
func (c *CosmosConfig) GasLimitMultiplier() float64 {
@@ -363,6 +254,19 @@ func sdkDecFromDecimal(d *decimal.Decimal) sdk.Dec {
return sdk.NewDecFromBigIntWithPrec(i.BigInt(), sdk.Precision)
}
-func NewConfigs(cfgs chains.ConfigsV2[string, db.Node]) types.Configs {
- return chains.NewConfigs(cfgs)
+func (c *CosmosConfig) GetNode(name string) (db.Node, error) {
+ for _, n := range c.Nodes {
+ if *n.Name == name {
+ return legacyNode(n, *c.ChainID), nil
+ }
+ }
+ return db.Node{}, fmt.Errorf("%w: node %q", chains.ErrNotFound, name)
+}
+
+func (c *CosmosConfig) ListNodes() ([]db.Node, error) {
+ var allNodes []db.Node
+ for _, n := range c.Nodes {
+ allNodes = append(allNodes, legacyNode(n, *c.ChainID))
+ }
+ return allNodes, nil
}
diff --git a/core/chains/cosmos/config_test.go b/core/chains/cosmos/config_test.go
index 3446e7bcb01..54f91a13620 100644
--- a/core/chains/cosmos/config_test.go
+++ b/core/chains/cosmos/config_test.go
@@ -1,11 +1,16 @@
package cosmos
import (
+ "reflect"
"testing"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/shopspring/decimal"
"github.com/stretchr/testify/assert"
+
+ coscfg "github.com/smartcontractkit/chainlink-cosmos/pkg/cosmos/config"
+ "github.com/smartcontractkit/chainlink-cosmos/pkg/cosmos/db"
+ "github.com/smartcontractkit/chainlink-relay/pkg/utils"
)
func Test_sdkDecFromDecimal(t *testing.T) {
@@ -23,3 +28,69 @@ func Test_sdkDecFromDecimal(t *testing.T) {
})
}
}
+
+func TestCosmosConfig_GetNode(t *testing.T) {
+ type fields struct {
+ ChainID *string
+ Nodes CosmosNodes
+ }
+ type args struct {
+ name string
+ }
+ tests := []struct {
+ name string
+ fields fields
+ args args
+ want db.Node
+ wantErr bool
+ }{
+ {
+ name: "not found",
+ args: args{
+ name: "not a node",
+ },
+ fields: fields{Nodes: CosmosNodes{}},
+ want: db.Node{},
+ wantErr: true,
+ },
+ {
+ name: "success",
+ args: args{
+ name: "node",
+ },
+ fields: fields{
+ ChainID: ptr("chainID"),
+ Nodes: []*coscfg.Node{
+ &coscfg.Node{
+ Name: ptr("node"),
+ TendermintURL: &utils.URL{},
+ },
+ }},
+ want: db.Node{
+ CosmosChainID: "chainID",
+ Name: "node",
+ TendermintURL: "",
+ },
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ c := &CosmosConfig{
+ Nodes: tt.fields.Nodes,
+ ChainID: tt.fields.ChainID,
+ }
+ got, err := c.GetNode(tt.args.name)
+ if (err != nil) != tt.wantErr {
+ t.Errorf("CosmosConfig.GetNode() error = %v, wantErr %v", err, tt.wantErr)
+ return
+ }
+ if !reflect.DeepEqual(got, tt.want) {
+ t.Errorf("CosmosConfig.GetNode() = %v, want %v", got, tt.want)
+ }
+ })
+ }
+}
+
+func ptr[T any](t T) *T {
+ return &t
+}
diff --git a/core/chains/cosmos/cosmostxm/helpers_test.go b/core/chains/cosmos/cosmostxm/helpers_test.go
index 217160c3e80..ad93189082e 100644
--- a/core/chains/cosmos/cosmostxm/helpers_test.go
+++ b/core/chains/cosmos/cosmostxm/helpers_test.go
@@ -5,6 +5,7 @@ import (
"time"
sdk "github.com/cosmos/cosmos-sdk/types"
+ "golang.org/x/exp/maps"
cosmosclient "github.com/smartcontractkit/chainlink-cosmos/pkg/cosmos/client"
)
@@ -28,3 +29,15 @@ func (txm *Txm) MarshalMsg(msg sdk.Msg) (string, []byte, error) {
func (txm *Txm) SendMsgBatch(ctx context.Context) {
txm.sendMsgBatch(ctx)
}
+
+func (ka *KeystoreAdapter) Accounts(ctx context.Context) ([]string, error) {
+ ka.mutex.Lock()
+ defer ka.mutex.Unlock()
+ err := ka.updateMappingLocked()
+ if err != nil {
+ return nil, err
+ }
+ addresses := maps.Keys(ka.addressToPubKey)
+
+ return addresses, nil
+}
diff --git a/core/chains/cosmos/cosmostxm/key_wrapper.go b/core/chains/cosmos/cosmostxm/key_wrapper.go
index 6bc36f5aea7..1d2d686c8c0 100644
--- a/core/chains/cosmos/cosmostxm/key_wrapper.go
+++ b/core/chains/cosmos/cosmostxm/key_wrapper.go
@@ -1,56 +1,62 @@
package cosmostxm
import (
- cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
+ "bytes"
+ "context"
- "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/cosmoskey"
+ "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
+ cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
)
-var _ cryptotypes.PrivKey = KeyWrapper{}
-
-// KeyWrapper wrapper around a cosmos transmitter key
-// for use in the cosmos txbuilder and client, see chainlink-cosmos.
+// KeyWrapper uses a KeystoreAdapter to implement the cosmos-sdk PrivKey interface for a specific key.
type KeyWrapper struct {
- key cosmoskey.Key
+ adapter *KeystoreAdapter
+ account string
}
-// NewKeyWrapper create a key wrapper
-func NewKeyWrapper(key cosmoskey.Key) KeyWrapper {
- return KeyWrapper{key: key}
+var _ cryptotypes.PrivKey = &KeyWrapper{}
+
+func NewKeyWrapper(adapter *KeystoreAdapter, account string) *KeyWrapper {
+ return &KeyWrapper{
+ adapter: adapter,
+ account: account,
+ }
}
-// Reset nop
-func (k KeyWrapper) Reset() {}
+func (a *KeyWrapper) Bytes() []byte {
+ // don't expose the private key.
+ return nil
+}
-// ProtoMessage nop
-func (k KeyWrapper) ProtoMessage() {}
+func (a *KeyWrapper) Sign(msg []byte) ([]byte, error) {
+ return a.adapter.Sign(context.Background(), a.account, msg)
+}
-// String nop
-func (k KeyWrapper) String() string {
- return ""
+func (a *KeyWrapper) PubKey() cryptotypes.PubKey {
+ pubKey, err := a.adapter.PubKey(a.account)
+ if err != nil {
+ // return an empty pubkey if it's not found.
+ return &secp256k1.PubKey{Key: []byte{}}
+ }
+ return pubKey
}
-// Bytes does not expose private key
-func (k KeyWrapper) Bytes() []byte {
- return []byte{}
+func (a *KeyWrapper) Equals(other cryptotypes.LedgerPrivKey) bool {
+ return bytes.Equal(a.PubKey().Bytes(), other.PubKey().Bytes())
}
-// Sign sign a message with key
-func (k KeyWrapper) Sign(msg []byte) ([]byte, error) {
- return k.key.ToPrivKey().Sign(msg)
+func (a *KeyWrapper) Type() string {
+ return "secp256k1"
}
-// PubKey get the pubkey
-func (k KeyWrapper) PubKey() cryptotypes.PubKey {
- return k.key.PublicKey()
+func (a *KeyWrapper) Reset() {
+ // no-op
}
-// Equals compare against another key
-func (k KeyWrapper) Equals(a cryptotypes.LedgerPrivKey) bool {
- return k.PubKey().Address().String() == a.PubKey().Address().String()
+func (a *KeyWrapper) String() string {
+ return ""
}
-// Type nop
-func (k KeyWrapper) Type() string {
- return ""
+func (a *KeyWrapper) ProtoMessage() {
+ // no-op
}
diff --git a/core/chains/cosmos/cosmostxm/keystore_adapter.go b/core/chains/cosmos/cosmostxm/keystore_adapter.go
new file mode 100644
index 00000000000..c8556015c6e
--- /dev/null
+++ b/core/chains/cosmos/cosmostxm/keystore_adapter.go
@@ -0,0 +1,129 @@
+package cosmostxm
+
+import (
+ "context"
+ "crypto/sha256"
+ "encoding/hex"
+ "sync"
+
+ "github.com/cometbft/cometbft/crypto"
+ "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
+ cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
+ "github.com/cosmos/cosmos-sdk/types/bech32"
+ "github.com/pkg/errors"
+ "golang.org/x/crypto/ripemd160" //nolint: staticcheck
+
+ "github.com/smartcontractkit/chainlink-relay/pkg/loop"
+)
+
+type accountInfo struct {
+ Account string
+ PubKey *secp256k1.PubKey
+}
+
+// An adapter for a Cosmos loop.Keystore to translate public keys into bech32-prefixed account addresses.
+type KeystoreAdapter struct {
+ keystore loop.Keystore
+ accountPrefix string
+ mutex sync.RWMutex
+ addressToPubKey map[string]*accountInfo
+}
+
+func NewKeystoreAdapter(keystore loop.Keystore, accountPrefix string) *KeystoreAdapter {
+ return &KeystoreAdapter{
+ keystore: keystore,
+ accountPrefix: accountPrefix,
+ addressToPubKey: make(map[string]*accountInfo),
+ }
+}
+
+func (ka *KeystoreAdapter) updateMappingLocked() error {
+ accounts, err := ka.keystore.Accounts(context.Background())
+ if err != nil {
+ return err
+ }
+
+ // similar to cosmos-sdk, cache and re-use calculated bech32 addresses to prevent duplicated work.
+ // ref: https://github.com/cosmos/cosmos-sdk/blob/3b509c187e1643757f5ef8a0b5ae3decca0c7719/types/address.go#L705
+
+ type cacheEntry struct {
+ bech32Addr string
+ accountInfo *accountInfo
+ }
+ accountCache := make(map[string]cacheEntry, len(ka.addressToPubKey))
+ for bech32Addr, accountInfo := range ka.addressToPubKey {
+ accountCache[accountInfo.Account] = cacheEntry{bech32Addr: bech32Addr, accountInfo: accountInfo}
+ }
+
+ addressToPubKey := make(map[string]*accountInfo, len(accounts))
+ for _, account := range accounts {
+ if prevEntry, ok := accountCache[account]; ok {
+ addressToPubKey[prevEntry.bech32Addr] = prevEntry.accountInfo
+ continue
+ }
+ pubKeyBytes, err := hex.DecodeString(account)
+ if err != nil {
+ return err
+ }
+
+ if len(pubKeyBytes) != secp256k1.PubKeySize {
+ return errors.New("length of pubkey is incorrect")
+ }
+
+ sha := sha256.Sum256(pubKeyBytes)
+ hasherRIPEMD160 := ripemd160.New()
+ _, _ = hasherRIPEMD160.Write(sha[:])
+ address := crypto.Address(hasherRIPEMD160.Sum(nil))
+
+ bech32Addr, err := bech32.ConvertAndEncode(ka.accountPrefix, address)
+ if err != nil {
+ return err
+ }
+
+ addressToPubKey[bech32Addr] = &accountInfo{
+ Account: account,
+ PubKey: &secp256k1.PubKey{Key: pubKeyBytes},
+ }
+ }
+
+ ka.addressToPubKey = addressToPubKey
+ return nil
+}
+
+func (ka *KeystoreAdapter) lookup(id string) (*accountInfo, error) {
+ ka.mutex.RLock()
+ ai, ok := ka.addressToPubKey[id]
+ ka.mutex.RUnlock()
+ if !ok {
+ // try updating the mapping once, incase there was an update on the keystore.
+ ka.mutex.Lock()
+ err := ka.updateMappingLocked()
+ if err != nil {
+ ka.mutex.Unlock()
+ return nil, err
+ }
+ ai, ok = ka.addressToPubKey[id]
+ ka.mutex.Unlock()
+ if !ok {
+ return nil, errors.New("No such id")
+ }
+ }
+ return ai, nil
+}
+
+func (ka *KeystoreAdapter) Sign(ctx context.Context, id string, hash []byte) ([]byte, error) {
+ accountInfo, err := ka.lookup(id)
+ if err != nil {
+ return nil, err
+ }
+ return ka.keystore.Sign(ctx, accountInfo.Account, hash)
+}
+
+// Returns the cosmos PubKey associated with the prefixed address.
+func (ka *KeystoreAdapter) PubKey(address string) (cryptotypes.PubKey, error) {
+ accountInfo, err := ka.lookup(address)
+ if err != nil {
+ return nil, err
+ }
+ return accountInfo.PubKey, nil
+}
diff --git a/core/chains/cosmos/cosmostxm/txm.go b/core/chains/cosmos/cosmostxm/txm.go
index 7b0e2ad2887..de741e8934f 100644
--- a/core/chains/cosmos/cosmostxm/txm.go
+++ b/core/chains/cosmos/cosmostxm/txm.go
@@ -25,10 +25,9 @@ import (
"github.com/smartcontractkit/chainlink-cosmos/pkg/cosmos/db"
"github.com/smartcontractkit/chainlink-relay/pkg/logger"
+ "github.com/smartcontractkit/chainlink-relay/pkg/loop"
"github.com/smartcontractkit/chainlink/v2/core/services"
- "github.com/smartcontractkit/chainlink/v2/core/services/keystore"
- "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/cosmoskey"
"github.com/smartcontractkit/chainlink/v2/core/services/pg"
"github.com/smartcontractkit/chainlink/v2/core/utils"
)
@@ -40,32 +39,33 @@ var (
// Txm manages transactions for the cosmos blockchain.
type Txm struct {
- starter utils.StartStopOnce
- eb pg.EventBroadcaster
- sub pg.Subscription
- orm *ORM
- lggr logger.Logger
- tc func() (cosmosclient.ReaderWriter, error)
- ks keystore.Cosmos
- stop, done chan struct{}
- cfg coscfg.Config
- gpe cosmosclient.ComposedGasPriceEstimator
+ starter utils.StartStopOnce
+ eb pg.EventBroadcaster
+ sub pg.Subscription
+ orm *ORM
+ lggr logger.Logger
+ tc func() (cosmosclient.ReaderWriter, error)
+ keystoreAdapter *KeystoreAdapter
+ stop, done chan struct{}
+ cfg coscfg.Config
+ gpe cosmosclient.ComposedGasPriceEstimator
}
// NewTxm creates a txm. Uses simulation so should only be used to send txes to trusted contracts i.e. OCR.
-func NewTxm(db *sqlx.DB, tc func() (cosmosclient.ReaderWriter, error), gpe cosmosclient.ComposedGasPriceEstimator, chainID string, cfg coscfg.Config, ks keystore.Cosmos, lggr logger.Logger, logCfg pg.QConfig, eb pg.EventBroadcaster) *Txm {
+func NewTxm(db *sqlx.DB, tc func() (cosmosclient.ReaderWriter, error), gpe cosmosclient.ComposedGasPriceEstimator, chainID string, cfg coscfg.Config, ks loop.Keystore, lggr logger.Logger, logCfg pg.QConfig, eb pg.EventBroadcaster) *Txm {
lggr = logger.Named(lggr, "Txm")
+ keystoreAdapter := NewKeystoreAdapter(ks, cfg.Bech32Prefix())
return &Txm{
- starter: utils.StartStopOnce{},
- eb: eb,
- orm: NewORM(chainID, db, lggr, logCfg),
- ks: ks,
- tc: tc,
- lggr: lggr,
- stop: make(chan struct{}),
- done: make(chan struct{}),
- cfg: cfg,
- gpe: gpe,
+ starter: utils.StartStopOnce{},
+ eb: eb,
+ orm: NewORM(chainID, db, lggr, logCfg),
+ lggr: lggr,
+ tc: tc,
+ keystoreAdapter: keystoreAdapter,
+ stop: make(chan struct{}),
+ done: make(chan struct{}),
+ cfg: cfg,
+ gpe: gpe,
}
}
@@ -259,14 +259,11 @@ func (txm *Txm) sendMsgBatch(ctx context.Context) {
}
for s, msgs := range msgsByFrom {
sender, _ := sdk.AccAddressFromBech32(s) // Already checked validity above
- key, err := txm.ks.Get(sender.String())
+ err := txm.sendMsgBatchFromAddress(ctx, gasPrice, sender, msgs)
if err != nil {
- txm.lggr.Errorw("unable to find key for from address", "err", err, "from", sender.String())
- // We check the transmitter key exists when the job is added. So it would have to be deleted
- // after it was added for this to happen. Retry on next poll should the key be re-added.
+ txm.lggr.Errorw("Could not send message batch", "err", err, "from", sender.String())
continue
}
- txm.sendMsgBatchFromAddress(ctx, gasPrice, sender, key, msgs)
if ctx.Err() != nil {
return
}
@@ -274,18 +271,18 @@ func (txm *Txm) sendMsgBatch(ctx context.Context) {
}
-func (txm *Txm) sendMsgBatchFromAddress(ctx context.Context, gasPrice sdk.DecCoin, sender sdk.AccAddress, key cosmoskey.Key, msgs adapters.Msgs) {
+func (txm *Txm) sendMsgBatchFromAddress(ctx context.Context, gasPrice sdk.DecCoin, sender sdk.AccAddress, msgs adapters.Msgs) error {
tc, err := txm.tc()
if err != nil {
logger.Criticalw(txm.lggr, "unable to get client", "err", err)
- return
+ return err
}
an, sn, err := tc.Account(sender)
if err != nil {
txm.lggr.Warnw("unable to read account", "err", err, "from", sender.String())
// If we can't read the account, assume transient api issues and leave msgs unstarted
// to retry on next poll.
- return
+ return err
}
txm.lggr.Debugw("simulating batch", "from", sender, "msgs", msgs, "seqnum", sn)
@@ -296,27 +293,27 @@ func (txm *Txm) sendMsgBatchFromAddress(ctx context.Context, gasPrice sdk.DecCoi
// Note one rare scenario in which this can happen: the cosmos node misbehaves
// in that it confirms a txhash is present but still gives an old seq num.
// This is benign as the next retry will succeeds.
- return
+ return err
}
txm.lggr.Debugw("simulation results", "from", sender, "succeeded", simResults.Succeeded, "failed", simResults.Failed)
err = txm.orm.UpdateMsgs(simResults.Failed.GetSimMsgsIDs(), db.Errored, nil)
if err != nil {
txm.lggr.Errorw("unable to mark failed sim txes as errored", "err", err, "from", sender.String())
// If we can't mark them as failed retry on next poll. Presumably same ones will fail.
- return
+ return err
}
// Continue if there are no successful txes
if len(simResults.Succeeded) == 0 {
txm.lggr.Warnw("all sim msgs errored, not sending tx", "from", sender.String())
- return
+ return errors.New("all sim msgs errored")
}
// Get the gas limit for the successful batch
s, err := tc.SimulateUnsigned(simResults.Succeeded.GetMsgs(), sn)
if err != nil {
// In the OCR context this should only happen upon stale report
txm.lggr.Warnw("unexpected failure after successful simulation", "err", err)
- return
+ return err
}
gasLimit := s.GasInfo.GasUsed
@@ -324,14 +321,14 @@ func (txm *Txm) sendMsgBatchFromAddress(ctx context.Context, gasPrice sdk.DecCoi
if err != nil {
txm.lggr.Warnw("unable to get latest block", "err", err, "from", sender.String())
// Assume transient api issue and retry.
- return
+ return err
}
timeoutHeight := uint64(lb.Block.Header.Height) + uint64(txm.cfg.BlocksUntilTxTimeout())
signedTx, err := tc.CreateAndSign(simResults.Succeeded.GetMsgs(), an, sn, gasLimit, txm.cfg.GasLimitMultiplier(),
- gasPrice, NewKeyWrapper(key), timeoutHeight)
+ gasPrice, NewKeyWrapper(txm.keystoreAdapter, sender.String()), timeoutHeight)
if err != nil {
txm.lggr.Errorw("unable to sign tx", "err", err, "from", sender.String())
- return
+ return err
}
// We need to ensure that we either broadcast successfully and mark the tx as
@@ -367,14 +364,16 @@ func (txm *Txm) sendMsgBatchFromAddress(ctx context.Context, gasPrice sdk.DecCoi
if err != nil {
txm.lggr.Errorw("error broadcasting tx", "err", err, "from", sender.String())
// Was unable to broadcast, retry on next poll
- return
+ return err
}
maxPolls, pollPeriod := txm.confirmPollConfig()
if err := txm.confirmTx(ctx, tc, resp.TxResponse.TxHash, simResults.Succeeded.GetSimMsgsIDs(), maxPolls, pollPeriod); err != nil {
txm.lggr.Errorw("error confirming tx", "err", err, "hash", resp.TxResponse.TxHash)
- return
+ return err
}
+
+ return nil
}
func (txm *Txm) confirmPollConfig() (maxPolls int, pollPeriod time.Duration) {
@@ -501,7 +500,7 @@ func (txm *Txm) GetMsgs(ids ...int64) (adapters.Msgs, error) {
// GasPrice returns the gas price from the estimator in the configured fee token.
func (txm *Txm) GasPrice() (sdk.DecCoin, error) {
prices := txm.gpe.GasPrices()
- gasPrice, ok := prices[txm.cfg.FeeToken()]
+ gasPrice, ok := prices[txm.cfg.GasToken()]
if !ok {
return sdk.DecCoin{}, errors.New("unexpected empty gas price")
}
diff --git a/core/chains/cosmos/cosmostxm/txm_internal_test.go b/core/chains/cosmos/cosmostxm/txm_internal_test.go
index 6a9944a1a53..2f0b4fda06f 100644
--- a/core/chains/cosmos/cosmostxm/txm_internal_test.go
+++ b/core/chains/cosmos/cosmostxm/txm_internal_test.go
@@ -54,34 +54,39 @@ func TestTxm(t *testing.T) {
lggr := testutils.LoggerAssertMaxLevel(t, zapcore.ErrorLevel)
ks := keystore.New(db, utils.FastScryptParams, lggr, pgtest.NewQConfig(true))
require.NoError(t, ks.Unlock("blah"))
- k1, err := ks.Cosmos().Create()
- require.NoError(t, err)
- sender1, err := cosmostypes.AccAddressFromBech32(k1.PublicKeyStr())
- require.NoError(t, err)
- k2, err := ks.Cosmos().Create()
- require.NoError(t, err)
- sender2, err := cosmostypes.AccAddressFromBech32(k2.PublicKeyStr())
+
+ for i := 0; i < 4; i++ {
+ _, err := ks.Cosmos().Create()
+ require.NoError(t, err)
+ }
+
+ loopKs := &keystore.CosmosLoopKeystore{Cosmos: ks.Cosmos()}
+ adapter := cosmostxm.NewKeystoreAdapter(loopKs, "wasm")
+ accounts, err := adapter.Accounts(testutils.Context(t))
require.NoError(t, err)
- k3, err := ks.Cosmos().Create()
+ require.Equal(t, len(accounts), 4)
+
+ sender1, err := cosmostypes.AccAddressFromBech32(accounts[0])
require.NoError(t, err)
- contract, err := cosmostypes.AccAddressFromBech32(k3.PublicKeyStr())
+ sender2, err := cosmostypes.AccAddressFromBech32(accounts[1])
require.NoError(t, err)
- k4, err := ks.Cosmos().Create()
+ contract, err := cosmostypes.AccAddressFromBech32(accounts[2])
require.NoError(t, err)
- contract2, err := cosmostypes.AccAddressFromBech32(k4.PublicKeyStr())
+ contract2, err := cosmostypes.AccAddressFromBech32(accounts[3])
require.NoError(t, err)
+
logCfg := pgtest.NewQConfig(true)
chainID := cosmostest.RandomChainID()
two := int64(2)
- feeToken := "ucosm"
+ gasToken := "ucosm"
cfg := &cosmos.CosmosConfig{Chain: coscfg.Chain{
MaxMsgsPerBatch: &two,
- FeeToken: &feeToken,
+ GasToken: &gasToken,
}}
cfg.SetDefaults()
gpe := cosmosclient.NewMustGasPriceEstimator([]cosmosclient.GasPricesEstimator{
cosmosclient.NewFixedGasPriceEstimator(map[string]cosmostypes.DecCoin{
- cfg.FeeToken(): cosmostypes.NewDecCoinFromDec(cfg.FeeToken(), cosmostypes.MustNewDecFromStr("0.01")),
+ cfg.GasToken(): cosmostypes.NewDecCoinFromDec(cfg.GasToken(), cosmostypes.MustNewDecFromStr("0.01")),
},
lggr.(logger.SugaredLogger),
),
@@ -90,7 +95,8 @@ func TestTxm(t *testing.T) {
t.Run("single msg", func(t *testing.T) {
tc := newReaderWriterMock(t)
tcFn := func() (cosmosclient.ReaderWriter, error) { return tc, nil }
- txm := cosmostxm.NewTxm(db, tcFn, *gpe, chainID, cfg, ks.Cosmos(), lggr, logCfg, nil)
+ loopKs := &keystore.CosmosLoopKeystore{Cosmos: ks.Cosmos()}
+ txm := cosmostxm.NewTxm(db, tcFn, *gpe, chainID, cfg, loopKs, lggr, logCfg, nil)
// Enqueue a single msg, then send it in a batch
id1, err := txm.Enqueue(contract.String(), generateExecuteMsg(t, []byte(`1`), sender1, contract))
@@ -126,7 +132,8 @@ func TestTxm(t *testing.T) {
t.Run("two msgs different accounts", func(t *testing.T) {
tc := newReaderWriterMock(t)
tcFn := func() (cosmosclient.ReaderWriter, error) { return tc, nil }
- txm := cosmostxm.NewTxm(db, tcFn, *gpe, chainID, cfg, ks.Cosmos(), lggr, pgtest.NewQConfig(true), nil)
+ loopKs := &keystore.CosmosLoopKeystore{Cosmos: ks.Cosmos()}
+ txm := cosmostxm.NewTxm(db, tcFn, *gpe, chainID, cfg, loopKs, lggr, pgtest.NewQConfig(true), nil)
id1, err := txm.Enqueue(contract.String(), generateExecuteMsg(t, []byte(`0`), sender1, contract))
require.NoError(t, err)
@@ -181,7 +188,8 @@ func TestTxm(t *testing.T) {
t.Run("two msgs different contracts", func(t *testing.T) {
tc := newReaderWriterMock(t)
tcFn := func() (cosmosclient.ReaderWriter, error) { return tc, nil }
- txm := cosmostxm.NewTxm(db, tcFn, *gpe, chainID, cfg, ks.Cosmos(), lggr, pgtest.NewQConfig(true), nil)
+ loopKs := &keystore.CosmosLoopKeystore{Cosmos: ks.Cosmos()}
+ txm := cosmostxm.NewTxm(db, tcFn, *gpe, chainID, cfg, loopKs, lggr, pgtest.NewQConfig(true), nil)
id1, err := txm.Enqueue(contract.String(), generateExecuteMsg(t, []byte(`0`), sender1, contract))
require.NoError(t, err)
@@ -244,7 +252,8 @@ func TestTxm(t *testing.T) {
TxResponse: &cosmostypes.TxResponse{TxHash: "0x123"},
}, errors.New("not found")).Twice()
tcFn := func() (cosmosclient.ReaderWriter, error) { return tc, nil }
- txm := cosmostxm.NewTxm(db, tcFn, *gpe, chainID, cfg, ks.Cosmos(), lggr, pgtest.NewQConfig(true), nil)
+ loopKs := &keystore.CosmosLoopKeystore{Cosmos: ks.Cosmos()}
+ txm := cosmostxm.NewTxm(db, tcFn, *gpe, chainID, cfg, loopKs, lggr, pgtest.NewQConfig(true), nil)
i, err := txm.ORM().InsertMsg("blah", "", []byte{0x01})
require.NoError(t, err)
txh := "0x123"
@@ -274,7 +283,8 @@ func TestTxm(t *testing.T) {
TxResponse: &cosmostypes.TxResponse{TxHash: txHash3},
}, nil).Once()
tcFn := func() (cosmosclient.ReaderWriter, error) { return tc, nil }
- txm := cosmostxm.NewTxm(db, tcFn, *gpe, chainID, cfg, ks.Cosmos(), lggr, pgtest.NewQConfig(true), nil)
+ loopKs := &keystore.CosmosLoopKeystore{Cosmos: ks.Cosmos()}
+ txm := cosmostxm.NewTxm(db, tcFn, *gpe, chainID, cfg, loopKs, lggr, pgtest.NewQConfig(true), nil)
// Insert and broadcast 3 msgs with different txhashes.
id1, err := txm.ORM().InsertMsg("blah", "", []byte{0x01})
@@ -317,7 +327,8 @@ func TestTxm(t *testing.T) {
TxMsgTimeout: &timeout,
}}
cfgShortExpiry.SetDefaults()
- txm := cosmostxm.NewTxm(db, tcFn, *gpe, chainID, cfgShortExpiry, ks.Cosmos(), lggr, pgtest.NewQConfig(true), nil)
+ loopKs := &keystore.CosmosLoopKeystore{Cosmos: ks.Cosmos()}
+ txm := cosmostxm.NewTxm(db, tcFn, *gpe, chainID, cfgShortExpiry, loopKs, lggr, pgtest.NewQConfig(true), nil)
// Send a single one expired
id1, err := txm.ORM().InsertMsg("blah", "", []byte{0x03})
@@ -362,7 +373,8 @@ func TestTxm(t *testing.T) {
MaxMsgsPerBatch: &two,
}}
cfgMaxMsgs.SetDefaults()
- txm := cosmostxm.NewTxm(db, tcFn, *gpe, chainID, cfgMaxMsgs, ks.Cosmos(), lggr, pgtest.NewQConfig(true), nil)
+ loopKs := &keystore.CosmosLoopKeystore{Cosmos: ks.Cosmos()}
+ txm := cosmostxm.NewTxm(db, tcFn, *gpe, chainID, cfgMaxMsgs, loopKs, lggr, pgtest.NewQConfig(true), nil)
// Leftover started is processed
msg1 := generateExecuteMsg(t, []byte{0x03}, sender1, contract)
diff --git a/core/chains/cosmos/cosmostxm/txm_test.go b/core/chains/cosmos/cosmostxm/txm_test.go
index 7bfd76e1d8c..a3322ed2744 100644
--- a/core/chains/cosmos/cosmostxm/txm_test.go
+++ b/core/chains/cosmos/cosmostxm/txm_test.go
@@ -38,7 +38,7 @@ func TestTxm_Integration(t *testing.T) {
chainID := cosmostest.RandomChainID()
cosmosChain := coscfg.Chain{}
cosmosChain.SetDefaults()
- fallbackGasPrice := sdk.NewDecCoinFromDec(*cosmosChain.FeeToken, sdk.MustNewDecFromStr("0.01"))
+ fallbackGasPrice := sdk.NewDecCoinFromDec(*cosmosChain.GasToken, sdk.MustNewDecFromStr("0.01"))
chainConfig := cosmos.CosmosConfig{ChainID: &chainID, Enabled: ptr(true), Chain: cosmosChain}
cfg, db := heavyweight.FullTestDBNoFixturesV2(t, "cosmos_txm", func(c *chainlink.Config, s *chainlink.Secrets) {
c.Cosmos = cosmos.CosmosConfigs{&chainConfig}
@@ -47,7 +47,7 @@ func TestTxm_Integration(t *testing.T) {
logCfg := pgtest.NewQConfig(true)
gpe := cosmosclient.NewMustGasPriceEstimator([]cosmosclient.GasPricesEstimator{
cosmosclient.NewFixedGasPriceEstimator(map[string]sdk.DecCoin{
- *cosmosChain.FeeToken: fallbackGasPrice,
+ *cosmosChain.GasToken: fallbackGasPrice,
},
lggr.(logger.SugaredLogger),
),
@@ -59,20 +59,26 @@ func TestTxm_Integration(t *testing.T) {
ks := keystore.New(db, utils.FastScryptParams, lggr, pgtest.NewQConfig(true))
zeConfig := sdk.GetConfig()
fmt.Println(zeConfig)
- accounts, testdir, tendermintURL := cosmosclient.SetupLocalCosmosNode(t, chainID, *cosmosChain.FeeToken)
+ accounts, testdir, tendermintURL := cosmosclient.SetupLocalCosmosNode(t, chainID, *cosmosChain.GasToken)
tc, err := cosmosclient.NewClient(chainID, tendermintURL, cosmos.DefaultRequestTimeout, lggr)
require.NoError(t, err)
+ loopKs := &keystore.CosmosLoopKeystore{Cosmos: ks.Cosmos()}
+ keystoreAdapter := cosmostxm.NewKeystoreAdapter(loopKs, *cosmosChain.Bech32Prefix)
+
// First create a transmitter key and fund it with 1k native tokens
require.NoError(t, ks.Unlock("blah"))
- transmitterKey, err := ks.Cosmos().Create()
+ err = ks.Cosmos().EnsureKey()
+ require.NoError(t, err)
+ ksAccounts, err := keystoreAdapter.Accounts(testutils.Context(t))
require.NoError(t, err)
- transmitterID, err := sdk.AccAddressFromBech32(transmitterKey.PublicKeyStr())
+ transmitterAddress := ksAccounts[0]
+ transmitterID, err := sdk.AccAddressFromBech32(transmitterAddress)
require.NoError(t, err)
an, sn, err := tc.Account(accounts[0].Address)
require.NoError(t, err)
- resp, err := tc.SignAndBroadcast([]sdk.Msg{banktypes.NewMsgSend(accounts[0].Address, transmitterID, sdk.NewCoins(sdk.NewInt64Coin(*cosmosChain.FeeToken, 100000)))},
- an, sn, gpe.GasPrices()[*cosmosChain.FeeToken], accounts[0].PrivateKey, txtypes.BroadcastMode_BROADCAST_MODE_SYNC)
+ resp, err := tc.SignAndBroadcast([]sdk.Msg{banktypes.NewMsgSend(accounts[0].Address, transmitterID, sdk.NewCoins(sdk.NewInt64Coin(*cosmosChain.GasToken, 100000)))},
+ an, sn, gpe.GasPrices()[*cosmosChain.GasToken], accounts[0].PrivateKey, txtypes.BroadcastMode_BROADCAST_MODE_SYNC)
tx, success := cosmosclient.AwaitTxCommitted(t, tc, resp.TxResponse.TxHash)
require.True(t, success)
require.Equal(t, types.CodeTypeOK, tx.TxResponse.Code)
@@ -80,15 +86,15 @@ func TestTxm_Integration(t *testing.T) {
// TODO: find a way to pull this test artifact from
// the chainlink-cosmos repo instead of copying it to cores testdata
- contractID := cosmosclient.DeployTestContract(t, tendermintURL, chainID, *cosmosChain.FeeToken, accounts[0], cosmosclient.Account{
+ contractID := cosmosclient.DeployTestContract(t, tendermintURL, chainID, *cosmosChain.GasToken, accounts[0], cosmosclient.Account{
Name: "transmitter",
- PrivateKey: cosmostxm.NewKeyWrapper(transmitterKey),
+ PrivateKey: cosmostxm.NewKeyWrapper(keystoreAdapter, transmitterAddress),
Address: transmitterID,
}, tc, testdir, "../../../testdata/cosmos/my_first_contract.wasm")
tcFn := func() (cosmosclient.ReaderWriter, error) { return tc, nil }
// Start txm
- txm := cosmostxm.NewTxm(db, tcFn, *gpe, chainID, &chainConfig, ks.Cosmos(), lggr, pgtest.NewQConfig(true), eb)
+ txm := cosmostxm.NewTxm(db, tcFn, *gpe, chainID, &chainConfig, loopKs, lggr, pgtest.NewQConfig(true), eb)
require.NoError(t, txm.Start(testutils.Context(t)))
// Change the contract state
diff --git a/core/chains/cosmos/relayer_adapter.go b/core/chains/cosmos/relayer_adapter.go
new file mode 100644
index 00000000000..ffe4181ceb0
--- /dev/null
+++ b/core/chains/cosmos/relayer_adapter.go
@@ -0,0 +1,50 @@
+package cosmos
+
+import (
+ "github.com/smartcontractkit/chainlink-cosmos/pkg/cosmos/adapters"
+
+ "github.com/smartcontractkit/chainlink-relay/pkg/loop"
+
+ pkgcosmos "github.com/smartcontractkit/chainlink-cosmos/pkg/cosmos"
+ "github.com/smartcontractkit/chainlink/v2/core/chains"
+ "github.com/smartcontractkit/chainlink/v2/core/services/relay"
+)
+
+// LegacyChainContainer is container interface for Cosmos chains
+type LegacyChainContainer interface {
+ Get(id string) (adapters.Chain, error)
+ Len() int
+ List(ids ...string) ([]adapters.Chain, error)
+ Slice() []adapters.Chain
+}
+
+type LegacyChains = chains.ChainsKV[adapters.Chain]
+
+var _ LegacyChainContainer = &LegacyChains{}
+
+func NewLegacyChains(m map[string]adapters.Chain) *LegacyChains {
+ return chains.NewChainsKV[adapters.Chain](m)
+}
+
+type LoopRelayerChainer interface {
+ loop.Relayer
+ Chain() adapters.Chain
+}
+
+type LoopRelayerChain struct {
+ loop.Relayer
+ chain adapters.Chain
+}
+
+func NewLoopRelayerChain(r *pkgcosmos.Relayer, s adapters.Chain) *LoopRelayerChain {
+ ra := relay.NewRelayerServerAdapter(r, s)
+ return &LoopRelayerChain{
+ Relayer: ra,
+ chain: s,
+ }
+}
+func (r *LoopRelayerChain) Chain() adapters.Chain {
+ return r.chain
+}
+
+var _ LoopRelayerChainer = &LoopRelayerChain{}
diff --git a/core/chains/cosmos/types/types.go b/core/chains/cosmos/types/types.go
index 082ffe1b4cc..69b086a9706 100644
--- a/core/chains/cosmos/types/types.go
+++ b/core/chains/cosmos/types/types.go
@@ -1,17 +1,5 @@
package types
-import (
- "github.com/smartcontractkit/chainlink-cosmos/pkg/cosmos/db"
-
- "github.com/smartcontractkit/chainlink/v2/core/chains"
-)
-
-// Configs manages cosmos chains and nodes.
-type Configs interface {
- chains.ChainConfigs
- chains.NodeConfigs[string, db.Node]
-}
-
// NewNode defines a new node to create.
type NewNode struct {
Name string `json:"name"`
diff --git a/core/chains/errors.go b/core/chains/errors.go
index a87c134f7f4..f13317bb14a 100644
--- a/core/chains/errors.go
+++ b/core/chains/errors.go
@@ -2,4 +2,7 @@ package chains
import "errors"
-var ErrLOOPPUnsupported = errors.New("LOOPP not yet supported")
+var (
+ ErrLOOPPUnsupported = errors.New("LOOPP not yet supported")
+ ErrChainDisabled = errors.New("chain is disabled")
+)
diff --git a/core/chains/evm/chain.go b/core/chains/evm/chain.go
index 619b3e2db77..8704d0c1fc8 100644
--- a/core/chains/evm/chain.go
+++ b/core/chains/evm/chain.go
@@ -6,7 +6,6 @@ import (
"fmt"
"math/big"
"net/url"
- "sync"
"time"
"go.uber.org/multierr"
@@ -14,6 +13,8 @@ import (
"github.com/smartcontractkit/sqlx"
+ gotoml "github.com/pelletier/go-toml/v2"
+
"github.com/smartcontractkit/chainlink-relay/pkg/types"
"github.com/smartcontractkit/chainlink/v2/core/chains"
@@ -29,6 +30,7 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/monitor"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr"
evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types"
+ "github.com/smartcontractkit/chainlink/v2/core/chains/internal"
"github.com/smartcontractkit/chainlink/v2/core/config"
"github.com/smartcontractkit/chainlink/v2/core/logger"
"github.com/smartcontractkit/chainlink/v2/core/services"
@@ -65,60 +67,45 @@ type LegacyChains struct {
*chains.ChainsKV[Chain]
dflt Chain
- cfgs evmtypes.Configs
+ cfgs toml.EVMConfigs
}
// LegacyChainContainer is container for EVM chains.
//
//go:generate mockery --quiet --name LegacyChainContainer --output ./mocks/ --case=underscore
type LegacyChainContainer interface {
- SetDefault(Chain)
- Default() (Chain, error)
Get(id string) (Chain, error)
Len() int
List(ids ...string) ([]Chain, error)
Slice() []Chain
+ // BCF-2516: this is only used for EVMORM. When we delete that
+ // we can promote/move the needed funcs from it to LegacyChainContainer
+ // so instead of EVMORM().XYZ() we'd have something like legacyChains.XYZ()
ChainNodeConfigs() evmtypes.Configs
}
var _ LegacyChainContainer = &LegacyChains{}
-func NewLegacyChains(cfg AppConfig, m map[string]Chain) (*LegacyChains, error) {
- if cfg == nil {
- return nil, fmt.Errorf("must provide non-nil app config")
- }
+func NewLegacyChains(m map[string]Chain, evmCfgs toml.EVMConfigs) *LegacyChains {
return &LegacyChains{
ChainsKV: chains.NewChainsKV[Chain](m),
- cfgs: chains.NewConfigs[utils.Big, evmtypes.Node](cfg.EVMConfigs()),
- }, nil
+ cfgs: evmCfgs,
+ }
}
func (c *LegacyChains) ChainNodeConfigs() evmtypes.Configs {
return c.cfgs
}
-// TODO BCR-2510 this may not be needed if EVM is not enabled by default
-func (c *LegacyChains) SetDefault(dflt Chain) {
- c.dflt = dflt
-}
-
-func (c *LegacyChains) Default() (Chain, error) {
- if c.dflt == nil {
- return nil, fmt.Errorf("no default chain specified")
- }
- return c.dflt, nil
-}
-
// backward compatibility.
// eth keys are represented as multiple types in the code base;
-// *big.Int, string, and int64. this lead to special 'default' handling
-// of nil big.Int and empty string.
+// *big.Int, string, and int64.
//
// TODO BCF-2507 unify the type system
func (c *LegacyChains) Get(id string) (Chain, error) {
if id == nilBigInt.String() || id == emptyString {
- return c.Default()
+ return nil, fmt.Errorf("invalid chain id requested: %q", id)
}
return c.ChainsKV.Get(id)
}
@@ -126,7 +113,7 @@ func (c *LegacyChains) Get(id string) (Chain, error) {
type chain struct {
utils.StartStopOnce
id *big.Int
- cfg evmconfig.ChainScopedConfig
+ cfg *evmconfig.ChainScoped
client evmclient.Client
txm txmgr.TxManager
logger logger.Logger
@@ -155,24 +142,33 @@ type AppConfig interface {
type ChainRelayExtenderConfig struct {
Logger logger.Logger
- DB *sqlx.DB
KeyStore keystore.Eth
- RelayerConfig
+ ChainOpts
+}
+
+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
}
-// 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 {
+type ChainOpts struct {
AppConfig AppConfig
EventBroadcaster pg.EventBroadcaster
MailMon *utils.MailboxMonitor
GasEstimator gas.EvmFeeEstimator
- init sync.Once
- operationalConfigs evmtypes.Configs
+ *sqlx.DB
// TODO BCF-2513 remove test code from the API
// Gen-functions are useful for dependency injection by tests
@@ -184,15 +180,31 @@ type RelayerConfig struct {
GenGasEstimator func(*big.Int) gas.EvmFeeEstimator
}
-func (r *RelayerConfig) EVMConfigs() evmtypes.Configs {
- if r.operationalConfigs == nil {
- r.init.Do(func() {
- r.operationalConfigs = chains.NewConfigs[utils.Big, evmtypes.Node](r.AppConfig.EVMConfigs())
- })
+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"))
}
- return r.operationalConfigs
+ 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() {
@@ -203,9 +215,9 @@ func NewTOMLChain(ctx context.Context, chain *toml.EVMConfig, opts ChainRelayExt
return newChain(ctx, cfg, chain.Nodes, opts)
}
-func newChain(ctx context.Context, cfg evmconfig.ChainScopedConfig, nodes []*toml.Node, opts ChainRelayExtenderConfig) (*chain, error) {
+func newChain(ctx context.Context, cfg *evmconfig.ChainScoped, nodes []*toml.Node, opts ChainRelayExtenderConfig) (*chain, error) {
chainID, chainType := cfg.EVM().ChainID(), cfg.EVM().ChainType()
- l := opts.Logger.Named(chainID.String()).With("evmChainID", chainID.String())
+ l := opts.Logger
var client evmclient.Client
if !cfg.EVMRPCEnabled() {
client = evmclient.NewNullClient(chainID, l)
@@ -380,10 +392,71 @@ func (c *chain) HealthReport() map[string]error {
return report
}
-func (c *chain) SendTx(ctx context.Context, from, to string, amount *big.Int, balanceCheck bool) error {
+func (c *chain) Transact(ctx context.Context, from, to string, amount *big.Int, balanceCheck bool) error {
return chains.ErrLOOPPUnsupported
}
+func (c *chain) SendTx(ctx context.Context, from, to string, amount *big.Int, balanceCheck bool) error {
+ return c.Transact(ctx, from, to, amount, balanceCheck)
+}
+
+func (c *chain) GetChainStatus(ctx context.Context) (types.ChainStatus, error) {
+ toml, err := c.cfg.EVM().TOMLString()
+ if err != nil {
+ return types.ChainStatus{}, err
+ }
+ return types.ChainStatus{
+ ID: c.ID().String(),
+ Enabled: c.cfg.EVM().IsEnabled(),
+ Config: toml,
+ }, nil
+}
+
+// TODO BCF-2602 statuses are static for non-evm chain and should be dynamic
+func (c *chain) listNodeStatuses(start, end int) ([]types.NodeStatus, int, error) {
+ nodes := c.cfg.Nodes()
+ total := len(nodes)
+ if start >= total {
+ return nil, total, internal.ErrOutOfRange
+ }
+ if end > total {
+ end = total
+ }
+ stats := make([]types.NodeStatus, 0)
+
+ states := c.Client().NodeStates()
+ for _, n := range nodes[start:end] {
+ var (
+ nodeState string
+ exists bool
+ )
+ toml, err := gotoml.Marshal(n)
+ if err != nil {
+ return nil, -1, err
+ }
+ if states == nil {
+ nodeState = "Unknown"
+ } else {
+ nodeState, exists = states[*n.Name]
+ if !exists {
+ // The node is in the DB and the chain is enabled but it's not running
+ nodeState = "NotLoaded"
+ }
+ }
+ stats = append(stats, types.NodeStatus{
+ ChainID: c.ID().String(),
+ Name: *n.Name,
+ Config: string(toml),
+ State: nodeState,
+ })
+ }
+ return stats, total, nil
+}
+
+func (c *chain) ListNodeStatuses(ctx context.Context, pageSize int32, pageToken string) (stats []types.NodeStatus, nextPageToken string, total int, err error) {
+ return internal.ListNodeStatuses(int(pageSize), pageToken, c.listNodeStatuses)
+}
+
func (c *chain) ID() *big.Int { return c.id }
func (c *chain) Client() evmclient.Client { return c.client }
func (c *chain) Config() evmconfig.ChainScopedConfig { return c.cfg }
@@ -421,15 +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")
- }
-
- opts.operationalConfigs = chains.NewConfigs[utils.Big, evmtypes.Node](opts.AppConfig.EVMConfigs())
- return nil
-}
diff --git a/core/chains/evm/chain_test.go b/core/chains/evm/chain_test.go
index e80bfc02934..09395ff4c97 100644
--- a/core/chains/evm/chain_test.go
+++ b/core/chains/evm/chain_test.go
@@ -4,12 +4,14 @@ 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/services/chainlink"
+ "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest"
+ "github.com/smartcontractkit/chainlink/v2/core/services/pg"
"github.com/smartcontractkit/chainlink/v2/core/utils"
)
@@ -20,35 +22,57 @@ func TestLegacyChains(t *testing.T) {
c.On("ID").Return(big.NewInt(7))
m := map[string]evm.Chain{c.ID().String(): c}
- l, err := evm.NewLegacyChains(evmCfg, m)
- assert.NoError(t, err)
+ l := evm.NewLegacyChains(m, evmCfg.EVMConfigs())
assert.NotNil(t, l.ChainNodeConfigs())
got, err := l.Get(c.ID().String())
assert.NoError(t, err)
assert.Equal(t, c, got)
- l, err = evm.NewLegacyChains(nil, m)
- assert.Error(t, err)
- assert.Nil(t, l)
}
-func TestRelayConfigInit(t *testing.T) {
- appCfg := configtest.NewGeneralConfig(t, nil)
- rCfg := evm.RelayerConfig{
- AppConfig: appCfg,
+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)
+ }
+ })
}
-
- evmCfg := rCfg.EVMConfigs()
- assert.NotNil(t, evmCfg)
-
- // test lazy init is done only once
- // note this kind of swapping should never happen in prod
- appCfg2 := configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) {
- c.EVM[0].ChainID = utils.NewBig(big.NewInt(27))
- })
- rCfg.AppConfig = appCfg2
-
- newEvmCfg := rCfg.EVMConfigs()
- assert.NotNil(t, newEvmCfg)
- assert.Equal(t, evmCfg, newEvmCfg)
}
diff --git a/core/chains/evm/client/doc.go b/core/chains/evm/client/doc.go
new file mode 100644
index 00000000000..f3cba4a0db2
--- /dev/null
+++ b/core/chains/evm/client/doc.go
@@ -0,0 +1,10 @@
+/*
+The simulated backend cannot access old blocks and will return an error if
+anything other than `latest`, `nil`, or the latest block are passed to
+`CallContract`.
+
+The simulated client avoids the old block error from the simulated backend by
+passing `nil` to `CallContract` when calling `CallContext` or `BatchCallContext`
+and will not return an error when an old block is used.
+*/
+package client
diff --git a/core/chains/evm/client/null_client.go b/core/chains/evm/client/null_client.go
index 394f792eeaa..8e271aea1e7 100644
--- a/core/chains/evm/client/null_client.go
+++ b/core/chains/evm/client/null_client.go
@@ -72,7 +72,7 @@ type nullSubscription struct {
}
func newNullSubscription(lggr logger.Logger) *nullSubscription {
- return &nullSubscription{lggr: lggr.Named("nullSubscription")}
+ return &nullSubscription{lggr: lggr.Named("NullSubscription")}
}
func (ns *nullSubscription) Unsubscribe() {
diff --git a/core/chains/evm/client/simulated_backend_client.go b/core/chains/evm/client/simulated_backend_client.go
index 74b7aa54ece..dd79c549bfe 100644
--- a/core/chains/evm/client/simulated_backend_client.go
+++ b/core/chains/evm/client/simulated_backend_client.go
@@ -3,6 +3,7 @@ package client
import (
"bytes"
"context"
+ "errors"
"fmt"
"math/big"
"strings"
@@ -16,7 +17,6 @@ import (
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/rpc"
- "github.com/pkg/errors"
clienttypes "github.com/smartcontractkit/chainlink/v2/common/chains/client"
"github.com/smartcontractkit/chainlink/v2/core/assets"
@@ -64,37 +64,85 @@ func (c *SimulatedBackendClient) checkEthCallArgs(
"must be an eth.CallArgs, got %+#v", args[0])
}
blockNumber, err := c.blockNumber(args[1])
- if err != nil || blockNumber.Cmp(c.currentBlockNumber()) != 0 {
+ if err != nil {
return nil, nil, fmt.Errorf("fourth arg to SimulatedBackendClient.Call "+
- "must be the string \"latest\", or a *big.Int equal to current "+
- "blocknumber, got %#+v", args[1])
+ "must be the string \"latest\", or a *big.Int, got %#+v", args[1])
}
+
+ // to and from need to map to a common.Address but could come in as a string
+ var (
+ toAddr common.Address
+ frmAddr common.Address
+ )
+
+ toAddr, err = interfaceToAddress(callArgs["to"])
+ if err != nil {
+ return nil, nil, err
+ }
+
+ // from is optional in the standard client; default to 0x when missing
+ if value, ok := callArgs["from"]; ok {
+ addr, err := interfaceToAddress(value)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ frmAddr = addr
+ } else {
+ frmAddr = common.HexToAddress("0x")
+ }
+
ca := CallArgs{
- From: callArgs["from"].(common.Address),
- To: *callArgs["to"].(*common.Address),
+ To: toAddr,
+ From: frmAddr,
Data: callArgs["data"].(hexutil.Bytes),
}
+
return &ca, blockNumber, nil
}
+func interfaceToAddress(value interface{}) (common.Address, error) {
+ switch v := value.(type) {
+ case common.Address:
+ return v, nil
+ case string:
+ return common.HexToAddress(v), nil
+ case *big.Int:
+ return common.BigToAddress(v), nil
+ default:
+ return common.HexToAddress("0x"), fmt.Errorf("unrecognized value type for converting value to common.Address; try string, *big.Int, or common.Address")
+ }
+}
+
// CallContext mocks the ethereum client RPC calls used by chainlink, copying the
// return value into result.
+// The simulated client avoids the old block error from the simulated backend by
+// passing `nil` to `CallContract` when calling `CallContext` or `BatchCallContext`
+// and will not return an error when an old block is used.
func (c *SimulatedBackendClient) CallContext(ctx context.Context, result interface{}, method string, args ...interface{}) error {
switch method {
case "eth_call":
- callArgs, _, err := c.checkEthCallArgs(args)
- if err != nil {
+ var (
+ callArgs *CallArgs
+ b []byte
+ err error
+ )
+
+ if callArgs, _, err = c.checkEthCallArgs(args); err != nil {
return err
}
+
callMsg := ethereum.CallMsg{From: callArgs.From, To: &callArgs.To, Data: callArgs.Data}
- b, err := c.b.CallContract(ctx, callMsg, nil /* always latest block */)
- if err != nil {
- return errors.Wrapf(err, "while calling contract at address %x with "+
- "data %x", callArgs.To, callArgs.Data)
+
+ if b, err = c.b.CallContract(ctx, callMsg, nil /* always latest block */); err != nil {
+ return fmt.Errorf("%w: while calling contract at address %x with "+
+ "data %x", err, callArgs.To, callArgs.Data)
}
+
switch r := result.(type) {
case *hexutil.Bytes:
*r = append(*r, b...)
+
if !bytes.Equal(*r, b) {
return fmt.Errorf("was passed a non-empty array, or failed to copy "+
"answer. Expected %x = %x", *r, b)
@@ -155,26 +203,26 @@ func init() {
var err error
balanceOfABI, err = abi.JSON(strings.NewReader(balanceOfABIString))
if err != nil {
- panic(errors.Wrapf(err, "while parsing erc20ABI"))
+ panic(fmt.Errorf("%w: while parsing erc20ABI", err))
}
}
func (c *SimulatedBackendClient) TokenBalance(ctx context.Context, address common.Address, contractAddress common.Address) (balance *big.Int, err error) {
callData, err := balanceOfABI.Pack("balanceOf", address)
if err != nil {
- return nil, errors.Wrapf(err, "while seeking the ERC20 balance of %s on %s",
+ return nil, fmt.Errorf("%w: while seeking the ERC20 balance of %s on %s", err,
address, contractAddress)
}
b, err := c.b.CallContract(ctx, ethereum.CallMsg{
To: &contractAddress, Data: callData},
c.currentBlockNumber())
if err != nil {
- return nil, errors.Wrapf(err, "while calling ERC20 balanceOf method on %s "+
- "for balance of %s", contractAddress, address)
+ return nil, fmt.Errorf("%w: while calling ERC20 balanceOf method on %s "+
+ "for balance of %s", err, contractAddress, address)
}
err = balanceOfABI.UnpackIntoInterface(balance, "balanceOf", b)
if err != nil {
- return nil, errors.New("unable to unpack balance")
+ return nil, fmt.Errorf("unable to unpack balance")
}
return balance, nil
}
@@ -208,8 +256,8 @@ func (c *SimulatedBackendClient) blockNumber(number interface{}) (blockNumber *b
default:
blockNumber, err = utils.HexToUint256(n)
if err != nil {
- return nil, errors.Wrapf(err, "while parsing '%s' as hex-encoded"+
- "block number", n)
+ return nil, fmt.Errorf("%w: while parsing '%s' as hex-encoded"+
+ "block number", err, n)
}
return blockNumber, nil
}
@@ -328,8 +376,8 @@ func (c *SimulatedBackendClient) SubscribeNewHead(
var err error
subscription.subscription, err = c.b.SubscribeNewHead(ctx, ch)
if err != nil {
- return nil, errors.Wrapf(err, "could not subscribe to new heads on "+
- "simulated backend")
+ return nil, fmt.Errorf("%w: could not subscribe to new heads on "+
+ "simulated backend", err)
}
go func() {
var lastHead *evmtypes.Head
@@ -428,8 +476,7 @@ func (c *SimulatedBackendClient) CallContract(ctx context.Context, msg ethereum.
res, err := c.b.CallContract(ctx, msg, blockNumber)
if err != nil {
dataErr := revertError{}
- isCustomRevert := errors.As(err, &dataErr)
- if isCustomRevert {
+ if errors.Is(err, &dataErr) {
return nil, &JsonError{Data: dataErr.ErrorData(), Message: dataErr.Error(), Code: 3}
}
// Generic revert, no data
@@ -459,6 +506,9 @@ func (c *SimulatedBackendClient) SuggestGasPrice(ctx context.Context) (*big.Int,
}
// BatchCallContext makes a batch rpc call.
+// The simulated client avoids the old block error from the simulated backend by
+// passing `nil` to `CallContract` when calling `CallContext` or `BatchCallContext`
+// and will not return an error when an old block is used.
func (c *SimulatedBackendClient) BatchCallContext(ctx context.Context, b []rpc.BatchElem) error {
select {
case <-ctx.Done():
@@ -471,14 +521,14 @@ func (c *SimulatedBackendClient) BatchCallContext(ctx context.Context, b []rpc.B
switch elem.Method {
case "eth_getTransactionReceipt":
if _, ok := elem.Result.(*evmtypes.Receipt); !ok {
- return errors.Errorf("SimulatedBackendClient expected return type of *evmtypes.Receipt for eth_getTransactionReceipt, got type %T", elem.Result)
+ return fmt.Errorf("SimulatedBackendClient expected return type of *evmtypes.Receipt for eth_getTransactionReceipt, got type %T", elem.Result)
}
if len(elem.Args) != 1 {
- return errors.Errorf("SimulatedBackendClient expected 1 arg, got %d for eth_getTransactionReceipt", len(elem.Args))
+ return fmt.Errorf("SimulatedBackendClient expected 1 arg, got %d for eth_getTransactionReceipt", len(elem.Args))
}
hash, is := elem.Args[0].(common.Hash)
if !is {
- return errors.Errorf("SimulatedBackendClient expected arg to be a hash, got: %T", elem.Args[0])
+ return fmt.Errorf("SimulatedBackendClient expected arg to be a hash, got: %T", elem.Args[0])
}
receipt, err := c.b.TransactionReceipt(ctx, hash)
if receipt != nil {
@@ -490,22 +540,22 @@ func (c *SimulatedBackendClient) BatchCallContext(ctx context.Context, b []rpc.B
case *evmtypes.Head:
case *evmtypes.Block:
default:
- return errors.Errorf("SimulatedBackendClient expected return type of [*evmtypes.Head] or [*evmtypes.Block] for eth_getBlockByNumber, got type %T", v)
+ return fmt.Errorf("SimulatedBackendClient expected return type of [*evmtypes.Head] or [*evmtypes.Block] for eth_getBlockByNumber, got type %T", v)
}
if len(elem.Args) != 2 {
- return errors.Errorf("SimulatedBackendClient expected 2 args, got %d for eth_getBlockByNumber", len(elem.Args))
+ return fmt.Errorf("SimulatedBackendClient expected 2 args, got %d for eth_getBlockByNumber", len(elem.Args))
}
blockNum, is := elem.Args[0].(string)
if !is {
- return errors.Errorf("SimulatedBackendClient expected first arg to be a string for eth_getBlockByNumber, got: %T", elem.Args[0])
+ return fmt.Errorf("SimulatedBackendClient expected first arg to be a string for eth_getBlockByNumber, got: %T", elem.Args[0])
}
_, is = elem.Args[1].(bool)
if !is {
- return errors.Errorf("SimulatedBackendClient expected second arg to be a boolean for eth_getBlockByNumber, got: %T", elem.Args[1])
+ return fmt.Errorf("SimulatedBackendClient expected second arg to be a boolean for eth_getBlockByNumber, got: %T", elem.Args[1])
}
n, ok := new(big.Int).SetString(blockNum, 0)
if !ok {
- return errors.Errorf("error while converting block number string: %s to big.Int ", blockNum)
+ return fmt.Errorf("error while converting block number string: %s to big.Int ", blockNum)
}
header, err := c.b.HeaderByNumber(ctx, n)
if err != nil {
@@ -525,33 +575,33 @@ func (c *SimulatedBackendClient) BatchCallContext(ctx context.Context, b []rpc.B
Timestamp: time.Unix(int64(header.Time), 0),
}
default:
- return errors.Errorf("SimulatedBackendClient Unexpected Type %T", v)
+ return fmt.Errorf("SimulatedBackendClient Unexpected Type %T", v)
}
b[i].Error = err
case "eth_call":
if len(elem.Args) != 2 {
- return errors.Errorf("SimulatedBackendClient expected 2 args, got %d for eth_call", len(elem.Args))
+ return fmt.Errorf("SimulatedBackendClient expected 2 args, got %d for eth_call", len(elem.Args))
}
_, ok := elem.Result.(*string)
if !ok {
- return errors.Errorf("SimulatedBackendClient expected result to be *string for eth_call, got: %T", elem.Result)
+ return fmt.Errorf("SimulatedBackendClient expected result to be *string for eth_call, got: %T", elem.Result)
}
params, ok := elem.Args[0].(map[string]interface{})
if !ok {
- return errors.Errorf("SimulatedBackendClient expected first arg to be map[string]interface{} for eth_call, got: %T", elem.Args[0])
+ return fmt.Errorf("SimulatedBackendClient expected first arg to be map[string]interface{} for eth_call, got: %T", elem.Args[0])
}
blockNum, ok := elem.Args[1].(string)
if !ok {
- return errors.Errorf("SimulatedBackendClient expected second arg to be a string for eth_call, got: %T", elem.Args[1])
+ return fmt.Errorf("SimulatedBackendClient expected second arg to be a string for eth_call, got: %T", elem.Args[1])
}
if blockNum != "" {
if _, ok = new(big.Int).SetString(blockNum, 0); !ok {
- return errors.Errorf("error while converting block number string: %s to big.Int ", blockNum)
+ return fmt.Errorf("error while converting block number string: %s to big.Int ", blockNum)
}
}
@@ -561,15 +611,15 @@ func (c *SimulatedBackendClient) BatchCallContext(ctx context.Context, b []rpc.B
b[i].Error = err
case "eth_getHeaderByNumber":
if len(elem.Args) != 1 {
- return errors.Errorf("SimulatedBackendClient expected 2 args, got %d for eth_getHeaderByNumber", len(elem.Args))
+ return fmt.Errorf("SimulatedBackendClient expected 2 args, got %d for eth_getHeaderByNumber", len(elem.Args))
}
blockNum, is := elem.Args[0].(string)
if !is {
- return errors.Errorf("SimulatedBackendClient expected first arg to be a string for eth_getHeaderByNumber, got: %T", elem.Args[0])
+ return fmt.Errorf("SimulatedBackendClient expected first arg to be a string for eth_getHeaderByNumber, got: %T", elem.Args[0])
}
n, err := hexutil.DecodeBig(blockNum)
if err != nil {
- return errors.Errorf("error while converting hex block number %s to big.Int ", blockNum)
+ return fmt.Errorf("error while converting hex block number %s to big.Int ", blockNum)
}
header, err := c.b.HeaderByNumber(ctx, n)
if err != nil {
@@ -579,10 +629,10 @@ func (c *SimulatedBackendClient) BatchCallContext(ctx context.Context, b []rpc.B
case *types.Header:
b[i].Result = header
default:
- return errors.Errorf("SimulatedBackendClient Unexpected Type %T", v)
+ return fmt.Errorf("SimulatedBackendClient Unexpected Type %T", v)
}
default:
- return errors.Errorf("SimulatedBackendClient got unsupported method %s", elem.Method)
+ return fmt.Errorf("SimulatedBackendClient got unsupported method %s", elem.Method)
}
}
return nil
diff --git a/core/chains/evm/config/chain_scoped.go b/core/chains/evm/config/chain_scoped.go
index 260043ba252..7971a18d4db 100644
--- a/core/chains/evm/config/chain_scoped.go
+++ b/core/chains/evm/config/chain_scoped.go
@@ -15,9 +15,9 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/logger"
)
-func NewTOMLChainScopedConfig(genCfg gencfg.AppConfig, tomlConfig *toml.EVMConfig, lggr logger.Logger) *ChainScoped {
+func NewTOMLChainScopedConfig(appCfg gencfg.AppConfig, tomlConfig *toml.EVMConfig, lggr logger.Logger) *ChainScoped {
return &ChainScoped{
- AppConfig: genCfg,
+ AppConfig: appCfg,
evmConfig: &evmConfig{c: tomlConfig},
lggr: lggr}
}
@@ -34,6 +34,10 @@ func (c *ChainScoped) EVM() EVM {
return c.evmConfig
}
+func (c *ChainScoped) Nodes() toml.EVMNodes {
+ return c.evmConfig.c.Nodes
+}
+
func (c *ChainScoped) BlockEmissionIdleWarningThreshold() time.Duration {
return c.EVM().NodeNoNewHeadsThreshold()
}
@@ -60,6 +64,14 @@ type evmConfig struct {
c *toml.EVMConfig
}
+func (e *evmConfig) IsEnabled() bool {
+ return e.c.IsEnabled()
+}
+
+func (e *evmConfig) TOMLString() (string, error) {
+ return e.c.TOMLString()
+}
+
func (e *evmConfig) BalanceMonitor() BalanceMonitor {
return &balanceMonitorConfig{c: e.c.BalanceMonitor}
}
diff --git a/core/chains/evm/config/config.go b/core/chains/evm/config/config.go
index 05c65a8f997..18c075dc24a 100644
--- a/core/chains/evm/config/config.go
+++ b/core/chains/evm/config/config.go
@@ -38,6 +38,9 @@ type EVM interface {
OperatorFactoryAddress() string
RPCDefaultBatchSize() uint32
NodeNoNewHeadsThreshold() time.Duration
+
+ IsEnabled() bool
+ TOMLString() (string, error)
}
type OCR interface {
diff --git a/core/chains/evm/config/mocks/chain_scoped_config.go b/core/chains/evm/config/mocks/chain_scoped_config.go
index bf84164cd3e..b8347f6e4bb 100644
--- a/core/chains/evm/config/mocks/chain_scoped_config.go
+++ b/core/chains/evm/config/mocks/chain_scoped_config.go
@@ -3,8 +3,6 @@
package mocks
import (
- big "math/big"
-
config "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config"
coreconfig "github.com/smartcontractkit/chainlink/v2/core/config"
@@ -100,22 +98,6 @@ func (_m *ChainScopedConfig) Database() coreconfig.Database {
return r0
}
-// DefaultChainID provides a mock function with given fields:
-func (_m *ChainScopedConfig) DefaultChainID() *big.Int {
- ret := _m.Called()
-
- var r0 *big.Int
- if rf, ok := ret.Get(0).(func() *big.Int); ok {
- r0 = rf()
- } else {
- if ret.Get(0) != nil {
- r0 = ret.Get(0).(*big.Int)
- }
- }
-
- return r0
-}
-
// EVM provides a mock function with given fields:
func (_m *ChainScopedConfig) EVM() config.EVM {
ret := _m.Called()
@@ -160,22 +142,6 @@ func (_m *ChainScopedConfig) EVMRPCEnabled() bool {
return r0
}
-// Explorer provides a mock function with given fields:
-func (_m *ChainScopedConfig) Explorer() coreconfig.Explorer {
- ret := _m.Called()
-
- var r0 coreconfig.Explorer
- if rf, ok := ret.Get(0).(func() coreconfig.Explorer); ok {
- r0 = rf()
- } else {
- if ret.Get(0) != nil {
- r0 = ret.Get(0).(coreconfig.Explorer)
- }
- }
-
- return r0
-}
-
// Feature provides a mock function with given fields:
func (_m *ChainScopedConfig) Feature() coreconfig.Feature {
ret := _m.Called()
diff --git a/core/chains/evm/config/toml/config.go b/core/chains/evm/config/toml/config.go
index fdfce23a877..a62c554a21e 100644
--- a/core/chains/evm/config/toml/config.go
+++ b/core/chains/evm/config/toml/config.go
@@ -3,6 +3,7 @@ package toml
import (
"fmt"
"net/url"
+ "strconv"
"github.com/ethereum/go-ethereum/core/txpool"
"github.com/pelletier/go-toml/v2"
@@ -18,6 +19,7 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/types"
"github.com/smartcontractkit/chainlink/v2/core/config"
"github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ethkey"
+ "github.com/smartcontractkit/chainlink/v2/core/services/relay"
"github.com/smartcontractkit/chainlink/v2/core/store/models"
"github.com/smartcontractkit/chainlink/v2/core/utils"
configutils "github.com/smartcontractkit/chainlink/v2/core/utils/config"
@@ -94,7 +96,18 @@ func (cs *EVMConfigs) SetFrom(fs *EVMConfigs) (err error) {
return
}
-func (cs EVMConfigs) Chains(ids ...string) (r []relaytypes.ChainStatus, err error) {
+func (cs EVMConfigs) totalChains() int {
+ total := 0
+ for _, ch := range cs {
+ if ch == nil {
+ continue
+ }
+ total++
+ }
+ return total
+}
+func (cs EVMConfigs) Chains(ids ...relay.ChainID) (r []relaytypes.ChainStatus, total int, err error) {
+ total = cs.totalChains()
for _, ch := range cs {
if ch == nil {
continue
@@ -140,7 +153,7 @@ func (cs EVMConfigs) NodeStatus(name string) (relaytypes.NodeStatus, error) {
for i := range cs {
for _, n := range cs[i].Nodes {
if n.Name != nil && *n.Name == name {
- return nodeStatus(n, cs[i].ChainID.String())
+ return nodeStatus(n, relay.ChainID(cs[i].ChainID.String()))
}
}
}
@@ -165,7 +178,7 @@ func legacyNode(n *Node, chainID *utils.Big) (v2 types.Node) {
return
}
-func nodeStatus(n *Node, chainID string) (relaytypes.NodeStatus, error) {
+func nodeStatus(n *Node, chainID relay.ChainID) (relaytypes.NodeStatus, error) {
var s relaytypes.NodeStatus
s.ChainID = chainID
s.Name = *n.Name
@@ -177,39 +190,43 @@ func nodeStatus(n *Node, chainID string) (relaytypes.NodeStatus, error) {
return s, nil
}
-func (cs EVMConfigs) nodes(chainID string) (ns EVMNodes) {
+func (cs EVMConfigs) nodes(id relay.ChainID) (ns EVMNodes) {
for _, c := range cs {
- if c.ChainID.String() == chainID {
+ if c.ChainID.String() == id {
return c.Nodes
}
}
return nil
}
-func (cs EVMConfigs) Nodes(chainID utils.Big) (ns []types.Node, err error) {
- id := chainID.String()
- nodes := cs.nodes(id)
+func (cs EVMConfigs) Nodes(chainID relay.ChainID) (ns []types.Node, err error) {
+ evmID, err := ChainIDInt64(chainID)
+ if err != nil {
+ return nil, fmt.Errorf("invalid evm chain id %q : %w", chainID, err)
+ }
+ nodes := cs.nodes(chainID)
if nodes == nil {
- err = fmt.Errorf("no nodes: chain %s: %w", &chainID, chains.ErrNotFound)
+ err = fmt.Errorf("no nodes: chain %q: %w", chainID, chains.ErrNotFound)
return
}
for _, n := range nodes {
if n == nil {
continue
}
- ns = append(ns, legacyNode(n, &chainID))
+
+ ns = append(ns, legacyNode(n, utils.NewBigI(evmID)))
}
return
}
-func (cs EVMConfigs) NodeStatuses(chainIDs ...string) (ns []relaytypes.NodeStatus, err error) {
+func (cs EVMConfigs) NodeStatuses(chainIDs ...relay.ChainID) (ns []relaytypes.NodeStatus, err error) {
if len(chainIDs) == 0 {
for i := range cs {
for _, n := range cs[i].Nodes {
if n == nil {
continue
}
- n2, err := nodeStatus(n, cs[i].ChainID.String())
+ n2, err := nodeStatus(n, relay.ChainID(cs[i].ChainID.String()))
if err != nil {
return nil, err
}
@@ -785,3 +802,7 @@ func (n *Node) SetFrom(f *Node) {
n.Order = f.Order
}
}
+
+func ChainIDInt64(cid relay.ChainID) (int64, error) {
+ 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 8c32b81301d..239a97f585b 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/config/toml/defaults/Arbitrum_Goerli.toml b/core/chains/evm/config/toml/defaults/Arbitrum_Goerli.toml
index a2c710265cf..598b571352d 100644
--- a/core/chains/evm/config/toml/defaults/Arbitrum_Goerli.toml
+++ b/core/chains/evm/config/toml/defaults/Arbitrum_Goerli.toml
@@ -22,3 +22,6 @@ BlockHistorySize = 0
[NodePool]
SyncThreshold = 10
+
+[OCR2.Automation]
+GasLimit = 14500000
diff --git a/core/chains/evm/config/toml/defaults/Arbitrum_Mainnet.toml b/core/chains/evm/config/toml/defaults/Arbitrum_Mainnet.toml
index 55ceef406c6..350d15cfccb 100644
--- a/core/chains/evm/config/toml/defaults/Arbitrum_Mainnet.toml
+++ b/core/chains/evm/config/toml/defaults/Arbitrum_Mainnet.toml
@@ -24,3 +24,6 @@ BlockHistorySize = 0
[NodePool]
SyncThreshold = 10
+
+[OCR2.Automation]
+GasLimit = 14500000
diff --git a/core/chains/evm/config/toml/defaults/Scroll_Mainnet.toml b/core/chains/evm/config/toml/defaults/Scroll_Mainnet.toml
index b7d290feb89..63c08559016 100644
--- a/core/chains/evm/config/toml/defaults/Scroll_Mainnet.toml
+++ b/core/chains/evm/config/toml/defaults/Scroll_Mainnet.toml
@@ -1,15 +1,11 @@
ChainID = '534352'
FinalityDepth = 1
-# extended time setting, due to sporadic block production rate
-LogPollInterval = '30s'
+LogPollInterval = '3s'
MinIncomingConfirmations = 1
# Scroll only emits blocks when a new tx is received, so this method of liveness detection is not useful
NoNewHeadsThreshold = '0'
OCR.ContractConfirmations = 1
-[Transactions]
-ResendAfterThreshold = '2m'
-
[GasEstimator]
Mode = 'L2Suggested'
# Scroll uses the L2Suggested estimator; we don't want to place any limits on the minimum gas price
diff --git a/core/chains/evm/config/toml/defaults/Scroll_Sepolia.toml b/core/chains/evm/config/toml/defaults/Scroll_Sepolia.toml
index 263f57c4c67..5a1a0f9ba7d 100644
--- a/core/chains/evm/config/toml/defaults/Scroll_Sepolia.toml
+++ b/core/chains/evm/config/toml/defaults/Scroll_Sepolia.toml
@@ -1,15 +1,11 @@
ChainID = '534351'
FinalityDepth = 1
-# extended time setting, due to sporadic block production rate
-LogPollInterval = '30s'
+LogPollInterval = '3s'
MinIncomingConfirmations = 1
# Scroll only emits blocks when a new tx is received, so this method of liveness detection is not useful
NoNewHeadsThreshold = '0'
OCR.ContractConfirmations = 1
-[Transactions]
-ResendAfterThreshold = '2m'
-
[GasEstimator]
Mode = 'L2Suggested'
# Scroll uses the L2Suggested estimator; we don't want to place any limits on the minimum gas price
diff --git a/core/chains/evm/forwarders/orm.go b/core/chains/evm/forwarders/orm.go
index 594d4d442b2..287698d22f6 100644
--- a/core/chains/evm/forwarders/orm.go
+++ b/core/chains/evm/forwarders/orm.go
@@ -34,7 +34,7 @@ func NewORM(db *sqlx.DB, lggr logger.Logger, cfg pg.QConfig) *orm {
// CreateForwarder creates the Forwarder address associated with the current EVM chain id.
func (o *orm) CreateForwarder(addr common.Address, evmChainId utils.Big) (fwd Forwarder, err error) {
- sql := `INSERT INTO evm_forwarders (address, evm_chain_id, created_at, updated_at) VALUES ($1, $2, now(), now()) RETURNING *`
+ sql := `INSERT INTO evm.forwarders (address, evm_chain_id, created_at, updated_at) VALUES ($1, $2, now(), now()) RETURNING *`
err = o.q.Get(&fwd, sql, addr, evmChainId)
return fwd, err
}
@@ -50,7 +50,7 @@ func (o *orm) DeleteForwarder(id int64, cleanup func(tx pg.Queryer, evmChainID i
var rowsAffected int64
err = o.q.Transaction(func(tx pg.Queryer) error {
- err = tx.Get(&dest, `SELECT evm_chain_id, address FROM evm_forwarders WHERE id = $1`, id)
+ err = tx.Get(&dest, `SELECT evm_chain_id, address FROM evm.forwarders WHERE id = $1`, id)
if err != nil {
return err
}
@@ -60,7 +60,7 @@ func (o *orm) DeleteForwarder(id int64, cleanup func(tx pg.Queryer, evmChainID i
}
}
- result, err2 := o.q.Exec(`DELETE FROM evm_forwarders WHERE id = $1`, id)
+ result, err2 := o.q.Exec(`DELETE FROM evm.forwarders WHERE id = $1`, id)
// If the forwarder wasn't found, we still want to delete the filter.
// In that case, the transaction must return nil, even though DeleteForwarder
// will return sql.ErrNoRows
@@ -80,12 +80,12 @@ func (o *orm) DeleteForwarder(id int64, cleanup func(tx pg.Queryer, evmChainID i
// FindForwarders returns all forwarder addresses from offset up until limit.
func (o *orm) FindForwarders(offset, limit int) (fwds []Forwarder, count int, err error) {
- sql := `SELECT count(*) FROM evm_forwarders`
+ sql := `SELECT count(*) FROM evm.forwarders`
if err = o.q.Get(&count, sql); err != nil {
return
}
- sql = `SELECT * FROM evm_forwarders ORDER BY created_at DESC, id DESC LIMIT $1 OFFSET $2`
+ sql = `SELECT * FROM evm.forwarders ORDER BY created_at DESC, id DESC LIMIT $1 OFFSET $2`
if err = o.q.Select(&fwds, sql, limit, offset); err != nil {
return
}
@@ -94,7 +94,7 @@ func (o *orm) FindForwarders(offset, limit int) (fwds []Forwarder, count int, er
// FindForwardersByChain returns all forwarder addresses for a chain.
func (o *orm) FindForwardersByChain(evmChainId utils.Big) (fwds []Forwarder, err error) {
- sql := `SELECT * FROM evm_forwarders where evm_chain_id = $1 ORDER BY created_at DESC, id DESC`
+ sql := `SELECT * FROM evm.forwarders where evm_chain_id = $1 ORDER BY created_at DESC, id DESC`
err = o.q.Select(&fwds, sql, evmChainId)
return
}
@@ -108,7 +108,7 @@ func (o *orm) FindForwardersInListByChain(evmChainId utils.Big, addrs []common.A
}
query, args, err := sqlx.Named(`
- SELECT * FROM evm_forwarders
+ SELECT * FROM evm.forwarders
WHERE evm_chain_id = :chainid
AND address IN (:addresses)
ORDER BY created_at DESC, id DESC`,
diff --git a/core/chains/evm/gas/block_history_estimator_test.go b/core/chains/evm/gas/block_history_estimator_test.go
index c44e68002d2..e418e0d6873 100644
--- a/core/chains/evm/gas/block_history_estimator_test.go
+++ b/core/chains/evm/gas/block_history_estimator_test.go
@@ -1316,13 +1316,17 @@ func TestBlockHistoryEstimator_IsUsable(t *testing.T) {
assert.Equal(t, true, bhe.IsUsable(tx, block, cfg.ChainType(), geCfg.PriceMin(), logger.TestLogger(t)))
})
- t.Run("returns false if transaction is of type 0x7c only on Celo", func(t *testing.T) {
+ t.Run("returns false if transaction is of type 0x7c or 0x7b only on Celo", func(t *testing.T) {
cfg.ChainTypeF = "celo"
tx := evmtypes.Transaction{Type: 0x7c, GasPrice: assets.NewWeiI(10), GasLimit: 42, Hash: utils.NewHash()}
assert.Equal(t, false, bhe.IsUsable(tx, block, cfg.ChainType(), geCfg.PriceMin(), logger.TestLogger(t)))
+ tx2 := evmtypes.Transaction{Type: 0x7b, GasPrice: assets.NewWeiI(10), GasLimit: 42, Hash: utils.NewHash()}
+ assert.Equal(t, false, bhe.IsUsable(tx2, block, cfg.ChainType(), geCfg.PriceMin(), logger.TestLogger(t)))
+
cfg.ChainTypeF = ""
assert.Equal(t, true, bhe.IsUsable(tx, block, cfg.ChainType(), geCfg.PriceMin(), logger.TestLogger(t)))
+ assert.Equal(t, true, bhe.IsUsable(tx2, block, cfg.ChainType(), geCfg.PriceMin(), logger.TestLogger(t)))
})
t.Run("returns false if transaction has base fee higher than the gas price only on Celo", func(t *testing.T) {
diff --git a/core/chains/evm/gas/chain_specific.go b/core/chains/evm/gas/chain_specific.go
index f2bcbf82dfa..cd38f49ee0b 100644
--- a/core/chains/evm/gas/chain_specific.go
+++ b/core/chains/evm/gas/chain_specific.go
@@ -30,8 +30,8 @@ func chainSpecificIsUsable(tx evmtypes.Transaction, baseFee *assets.Wei, chainTy
}
}
if chainType == config.ChainCelo {
- // Celo specific transaction type that utilizes the feeCurrency field.
- if tx.Type == 0x7c {
+ // Celo specific transaction types that utilize the feeCurrency field.
+ if tx.Type == 0x7c || tx.Type == 0x7b {
return false
}
// Celo has not yet fully migrated to the 0x7c type for special feeCurrency transactions
@@ -40,7 +40,6 @@ func chainSpecificIsUsable(tx evmtypes.Transaction, baseFee *assets.Wei, chainTy
// until they fully migrate to 0x7c.
if baseFee != nil && tx.GasPrice.Cmp(baseFee) < 0 {
return false
-
}
}
return true
diff --git a/core/chains/evm/gas/mocks/evm_fee_estimator.go b/core/chains/evm/gas/mocks/evm_fee_estimator.go
index 20e6c940f7e..dbca58dcdd5 100644
--- a/core/chains/evm/gas/mocks/evm_fee_estimator.go
+++ b/core/chains/evm/gas/mocks/evm_fee_estimator.go
@@ -15,6 +15,8 @@ import (
mock "github.com/stretchr/testify/mock"
+ rollups "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas/rollups"
+
types "github.com/smartcontractkit/chainlink/v2/common/fee/types"
)
@@ -155,6 +157,22 @@ func (_m *EvmFeeEstimator) HealthReport() map[string]error {
return r0
}
+// L1Oracle provides a mock function with given fields:
+func (_m *EvmFeeEstimator) L1Oracle() rollups.L1Oracle {
+ ret := _m.Called()
+
+ var r0 rollups.L1Oracle
+ if rf, ok := ret.Get(0).(func() rollups.L1Oracle); ok {
+ r0 = rf()
+ } else {
+ if ret.Get(0) != nil {
+ r0 = ret.Get(0).(rollups.L1Oracle)
+ }
+ }
+
+ return r0
+}
+
// Name provides a mock function with given fields:
func (_m *EvmFeeEstimator) Name() string {
ret := _m.Called()
diff --git a/core/chains/evm/gas/models.go b/core/chains/evm/gas/models.go
index 8b6580685b5..c6f8edbf04b 100644
--- a/core/chains/evm/gas/models.go
+++ b/core/chains/evm/gas/models.go
@@ -8,6 +8,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/pkg/errors"
+ "golang.org/x/exp/maps"
commonfee "github.com/smartcontractkit/chainlink/v2/common/fee"
feetypes "github.com/smartcontractkit/chainlink/v2/common/fee/types"
@@ -15,11 +16,13 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/assets"
evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client"
evmconfig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config"
+ "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas/rollups"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/label"
evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types"
"github.com/smartcontractkit/chainlink/v2/core/config"
"github.com/smartcontractkit/chainlink/v2/core/logger"
"github.com/smartcontractkit/chainlink/v2/core/services"
+ "github.com/smartcontractkit/chainlink/v2/core/utils"
bigmath "github.com/smartcontractkit/chainlink/v2/core/utils/big_math"
)
@@ -30,6 +33,8 @@ type EvmFeeEstimator interface {
services.ServiceCtx
commontypes.HeadTrackable[*evmtypes.Head, common.Hash]
+ // L1Oracle returns the L1 gas price oracle only if the chain has one, e.g. OP stack L2s and Arbitrum.
+ L1Oracle() rollups.L1Oracle
GetFee(ctx context.Context, calldata []byte, feeLimit uint32, maxFeePrice *assets.Wei, opts ...feetypes.Opt) (fee EvmFee, chainSpecificFeeLimit uint32, err error)
BumpFee(ctx context.Context, originalFee EvmFee, feeLimit uint32, maxFeePrice *assets.Wei, attempts []EvmPriorAttempt) (bumpedFee EvmFee, chainSpecificFeeLimit uint32, err error)
@@ -61,18 +66,24 @@ func NewEstimator(lggr logger.Logger, ethClient evmclient.Client, cfg Config, ge
"priceMin", geCfg.PriceMin(),
)
df := geCfg.EIP1559DynamicFees()
+
+ // create l1Oracle only if it is supported for the chain
+ var l1Oracle rollups.L1Oracle
+ if rollups.IsRollupWithL1Support(cfg.ChainType()) {
+ l1Oracle = rollups.NewL1GasPriceOracle(lggr, ethClient, cfg.ChainType())
+ }
switch s {
case "Arbitrum":
- return NewWrappedEvmEstimator(NewArbitrumEstimator(lggr, geCfg, ethClient, ethClient), df)
+ return NewWrappedEvmEstimator(NewArbitrumEstimator(lggr, geCfg, ethClient, ethClient), df, l1Oracle)
case "BlockHistory":
- return NewWrappedEvmEstimator(NewBlockHistoryEstimator(lggr, ethClient, cfg, geCfg, bh, *ethClient.ConfiguredChainID()), df)
+ return NewWrappedEvmEstimator(NewBlockHistoryEstimator(lggr, ethClient, cfg, geCfg, bh, *ethClient.ConfiguredChainID()), df, l1Oracle)
case "FixedPrice":
- return NewWrappedEvmEstimator(NewFixedPriceEstimator(geCfg, bh, lggr), df)
+ return NewWrappedEvmEstimator(NewFixedPriceEstimator(geCfg, bh, lggr), df, l1Oracle)
case "Optimism2", "L2Suggested":
- return NewWrappedEvmEstimator(NewL2SuggestedPriceEstimator(lggr, ethClient), df)
+ return NewWrappedEvmEstimator(NewL2SuggestedPriceEstimator(lggr, ethClient), df, l1Oracle)
default:
lggr.Warnf("GasEstimator: unrecognised mode '%s', falling back to FixedPriceEstimator", s)
- return NewWrappedEvmEstimator(NewFixedPriceEstimator(geCfg, bh, lggr), df)
+ return NewWrappedEvmEstimator(NewFixedPriceEstimator(geCfg, bh, lggr), df, l1Oracle)
}
}
@@ -141,18 +152,82 @@ func (fee EvmFee) ValidDynamic() bool {
type WrappedEvmEstimator struct {
EvmEstimator
EIP1559Enabled bool
+ l1Oracle rollups.L1Oracle
+ utils.StartStopOnce
}
var _ EvmFeeEstimator = (*WrappedEvmEstimator)(nil)
-func NewWrappedEvmEstimator(e EvmEstimator, eip1559Enabled bool) EvmFeeEstimator {
+func NewWrappedEvmEstimator(e EvmEstimator, eip1559Enabled bool, l1Oracle rollups.L1Oracle) EvmFeeEstimator {
return &WrappedEvmEstimator{
EvmEstimator: e,
EIP1559Enabled: eip1559Enabled,
+ l1Oracle: l1Oracle,
}
}
-func (e WrappedEvmEstimator) GetFee(ctx context.Context, calldata []byte, feeLimit uint32, maxFeePrice *assets.Wei, opts ...feetypes.Opt) (fee EvmFee, chainSpecificFeeLimit uint32, err error) {
+func (e *WrappedEvmEstimator) Name() string {
+ return fmt.Sprintf("WrappedEvmEstimator(%s)", e.EvmEstimator.Name())
+}
+
+func (e *WrappedEvmEstimator) Start(ctx context.Context) error {
+ return e.StartOnce(e.Name(), func() error {
+ if err := e.EvmEstimator.Start(ctx); err != nil {
+ return errors.Wrap(err, "failed to start EVMEstimator")
+ }
+ if e.l1Oracle != nil {
+ if err := e.l1Oracle.Start(ctx); err != nil {
+ return errors.Wrap(err, "failed to start L1Oracle")
+ }
+ }
+ return nil
+ })
+}
+func (e *WrappedEvmEstimator) Close() error {
+ return e.StopOnce(e.Name(), func() error {
+ var errEVM, errOracle error
+
+ errEVM = errors.Wrap(e.EvmEstimator.Close(), "failed to stop EVMEstimator")
+ if e.l1Oracle != nil {
+ errOracle = errors.Wrap(e.l1Oracle.Close(), "failed to stop L1Oracle")
+ }
+
+ if errEVM != nil {
+ return errEVM
+ }
+ return errOracle
+ })
+}
+
+func (e *WrappedEvmEstimator) Ready() error {
+ var errEVM, errOracle error
+
+ errEVM = e.EvmEstimator.Ready()
+ if e.l1Oracle != nil {
+ errOracle = e.l1Oracle.Ready()
+ }
+
+ if errEVM != nil {
+ return errEVM
+ }
+ return errOracle
+}
+
+func (e *WrappedEvmEstimator) HealthReport() map[string]error {
+ report := map[string]error{e.Name(): e.StartStopOnce.Healthy()}
+ maps.Copy(report, e.EvmEstimator.HealthReport())
+ if e.l1Oracle != nil {
+ maps.Copy(report, e.l1Oracle.HealthReport())
+ }
+
+ return report
+}
+
+func (e *WrappedEvmEstimator) L1Oracle() rollups.L1Oracle {
+ return e.l1Oracle
+}
+
+func (e *WrappedEvmEstimator) GetFee(ctx context.Context, calldata []byte, feeLimit uint32, maxFeePrice *assets.Wei, opts ...feetypes.Opt) (fee EvmFee, chainSpecificFeeLimit uint32, err error) {
// get dynamic fee
if e.EIP1559Enabled {
var dynamicFee DynamicFee
@@ -167,7 +242,7 @@ func (e WrappedEvmEstimator) GetFee(ctx context.Context, calldata []byte, feeLim
return
}
-func (e WrappedEvmEstimator) GetMaxCost(ctx context.Context, amount assets.Eth, calldata []byte, feeLimit uint32, maxFeePrice *assets.Wei, opts ...feetypes.Opt) (*big.Int, error) {
+func (e *WrappedEvmEstimator) GetMaxCost(ctx context.Context, amount assets.Eth, calldata []byte, feeLimit uint32, maxFeePrice *assets.Wei, opts ...feetypes.Opt) (*big.Int, error) {
fees, gasLimit, err := e.GetFee(ctx, calldata, feeLimit, maxFeePrice, opts...)
if err != nil {
return nil, err
@@ -185,7 +260,7 @@ func (e WrappedEvmEstimator) GetMaxCost(ctx context.Context, amount assets.Eth,
return amountWithFees, nil
}
-func (e WrappedEvmEstimator) BumpFee(ctx context.Context, originalFee EvmFee, feeLimit uint32, maxFeePrice *assets.Wei, attempts []EvmPriorAttempt) (bumpedFee EvmFee, chainSpecificFeeLimit uint32, err error) {
+func (e *WrappedEvmEstimator) BumpFee(ctx context.Context, originalFee EvmFee, feeLimit uint32, maxFeePrice *assets.Wei, attempts []EvmPriorAttempt) (bumpedFee EvmFee, chainSpecificFeeLimit uint32, err error) {
// validate only 1 fee type is present
if (!originalFee.ValidDynamic() && originalFee.Legacy == nil) || (originalFee.ValidDynamic() && originalFee.Legacy != nil) {
err = errors.New("only one dynamic or legacy fee can be defined")
diff --git a/core/chains/evm/gas/models_test.go b/core/chains/evm/gas/models_test.go
index 048646a980c..c1dd9e44ffc 100644
--- a/core/chains/evm/gas/models_test.go
+++ b/core/chains/evm/gas/models_test.go
@@ -5,6 +5,7 @@ import (
"math/big"
"testing"
+ "github.com/pkg/errors"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
@@ -12,6 +13,7 @@ import (
"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"
+ rollupMocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas/rollups/mocks"
)
func TestWrappedEvmEstimator(t *testing.T) {
@@ -36,11 +38,28 @@ func TestWrappedEvmEstimator(t *testing.T) {
e.On("BumpLegacyGas", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).
Return(legacyFee, gasLimit, nil).Once()
+ mockEvmEstimatorName := "MockEstimator"
+ mockEstimatorName := "WrappedEvmEstimator(MockEstimator)"
+
+ // L1Oracle returns the correct L1Oracle interface
+ t.Run("L1Oracle", func(t *testing.T) {
+ // expect nil
+ estimator := gas.NewWrappedEvmEstimator(e, false, nil)
+ l1Oracle := estimator.L1Oracle()
+ assert.Nil(t, l1Oracle)
+
+ // expect l1Oracle
+ oracle := rollupMocks.NewL1Oracle(t)
+ estimator = gas.NewWrappedEvmEstimator(e, false, oracle)
+ l1Oracle = estimator.L1Oracle()
+ assert.Equal(t, oracle, l1Oracle)
+ })
+
// GetFee returns gas estimation based on configuration value
t.Run("GetFee", func(t *testing.T) {
// expect legacy fee data
dynamicFees := false
- estimator := gas.NewWrappedEvmEstimator(e, dynamicFees)
+ estimator := gas.NewWrappedEvmEstimator(e, dynamicFees, nil)
fee, max, err := estimator.GetFee(ctx, nil, 0, nil)
require.NoError(t, err)
assert.Equal(t, gasLimit, max)
@@ -50,7 +69,7 @@ func TestWrappedEvmEstimator(t *testing.T) {
// expect dynamic fee data
dynamicFees = true
- estimator = gas.NewWrappedEvmEstimator(e, dynamicFees)
+ estimator = gas.NewWrappedEvmEstimator(e, dynamicFees, nil)
fee, max, err = estimator.GetFee(ctx, nil, 0, nil)
require.NoError(t, err)
assert.Equal(t, gasLimit, max)
@@ -62,7 +81,7 @@ func TestWrappedEvmEstimator(t *testing.T) {
// BumpFee returns bumped fee type based on original fee calculation
t.Run("BumpFee", func(t *testing.T) {
dynamicFees := false
- estimator := gas.NewWrappedEvmEstimator(e, dynamicFees)
+ estimator := gas.NewWrappedEvmEstimator(e, dynamicFees, nil)
// expect legacy fee data
fee, max, err := estimator.BumpFee(ctx, gas.EvmFee{Legacy: assets.NewWeiI(0)}, 0, nil, nil)
@@ -99,7 +118,7 @@ func TestWrappedEvmEstimator(t *testing.T) {
// expect legacy fee data
dynamicFees := false
- estimator := gas.NewWrappedEvmEstimator(e, dynamicFees)
+ estimator := gas.NewWrappedEvmEstimator(e, dynamicFees, nil)
total, err := estimator.GetMaxCost(ctx, val, nil, gasLimit, nil)
require.NoError(t, err)
fee := new(big.Int).Mul(legacyFee.ToInt(), big.NewInt(int64(gasLimit)))
@@ -107,10 +126,86 @@ func TestWrappedEvmEstimator(t *testing.T) {
// expect dynamic fee data
dynamicFees = true
- estimator = gas.NewWrappedEvmEstimator(e, dynamicFees)
+ estimator = gas.NewWrappedEvmEstimator(e, dynamicFees, nil)
total, err = estimator.GetMaxCost(ctx, val, nil, gasLimit, nil)
require.NoError(t, err)
fee = new(big.Int).Mul(dynamicFee.FeeCap.ToInt(), big.NewInt(int64(gasLimit)))
assert.Equal(t, new(big.Int).Add(val.ToInt(), fee), total)
})
+
+ t.Run("Name", func(t *testing.T) {
+ evmEstimator := mocks.NewEvmEstimator(t)
+ oracle := rollupMocks.NewL1Oracle(t)
+
+ evmEstimator.On("Name").Return(mockEvmEstimatorName, nil).Once()
+
+ estimator := gas.NewWrappedEvmEstimator(evmEstimator, false, oracle)
+ name := estimator.Name()
+ require.Equal(t, mockEstimatorName, name)
+ })
+
+ t.Run("Start and stop calls both EVM estimator and L1Oracle", func(t *testing.T) {
+ evmEstimator := mocks.NewEvmEstimator(t)
+ oracle := rollupMocks.NewL1Oracle(t)
+
+ evmEstimator.On("Name").Return(mockEvmEstimatorName, nil).Times(4)
+ evmEstimator.On("Start", mock.Anything).Return(nil).Twice()
+ evmEstimator.On("Close").Return(nil).Twice()
+ oracle.On("Start", mock.Anything).Return(nil).Once()
+ oracle.On("Close").Return(nil).Once()
+
+ estimator := gas.NewWrappedEvmEstimator(evmEstimator, false, nil)
+ err := estimator.Start(ctx)
+ require.NoError(t, err)
+ err = estimator.Close()
+ require.NoError(t, err)
+
+ estimator = gas.NewWrappedEvmEstimator(evmEstimator, false, oracle)
+ err = estimator.Start(ctx)
+ require.NoError(t, err)
+ err = estimator.Close()
+ require.NoError(t, err)
+ })
+
+ t.Run("Read calls both EVM estimator and L1Oracle", func(t *testing.T) {
+ evmEstimator := mocks.NewEvmEstimator(t)
+ oracle := rollupMocks.NewL1Oracle(t)
+
+ evmEstimator.On("Ready").Return(nil).Twice()
+ oracle.On("Ready").Return(nil).Once()
+
+ estimator := gas.NewWrappedEvmEstimator(evmEstimator, false, nil)
+ err := estimator.Ready()
+ require.NoError(t, err)
+
+ estimator = gas.NewWrappedEvmEstimator(evmEstimator, false, oracle)
+ err = estimator.Ready()
+ require.NoError(t, err)
+ })
+
+ t.Run("HealthReport merges report from EVM estimator and L1Oracle", func(t *testing.T) {
+ evmEstimator := mocks.NewEvmEstimator(t)
+ oracle := rollupMocks.NewL1Oracle(t)
+
+ evmEstimatorKey := "evm"
+ evmEstimatorError := errors.New("evm error")
+ oracleKey := "oracle"
+ oracleError := errors.New("oracle error")
+
+ evmEstimator.On("Name").Return(mockEvmEstimatorName, nil).Twice()
+ evmEstimator.On("HealthReport").Return(map[string]error{evmEstimatorKey: evmEstimatorError}).Twice()
+ oracle.On("HealthReport").Return(map[string]error{oracleKey: oracleError}).Once()
+
+ estimator := gas.NewWrappedEvmEstimator(evmEstimator, false, nil)
+ report := estimator.HealthReport()
+ require.True(t, errors.Is(report[evmEstimatorKey], evmEstimatorError))
+ require.Nil(t, report[oracleKey])
+ require.NotNil(t, report[mockEstimatorName])
+
+ estimator = gas.NewWrappedEvmEstimator(evmEstimator, false, oracle)
+ report = estimator.HealthReport()
+ require.True(t, errors.Is(report[evmEstimatorKey], evmEstimatorError))
+ require.True(t, errors.Is(report[oracleKey], oracleError))
+ require.NotNil(t, report[mockEstimatorName])
+ })
}
diff --git a/core/chains/evm/gas/rollups/l1_gas_price_oracle.go b/core/chains/evm/gas/rollups/l1_gas_price_oracle.go
new file mode 100644
index 00000000000..13ec5e29dd8
--- /dev/null
+++ b/core/chains/evm/gas/rollups/l1_gas_price_oracle.go
@@ -0,0 +1,176 @@
+package rollups
+
+import (
+ "context"
+ "errors"
+ "fmt"
+ "math/big"
+ "sync"
+ "time"
+
+ "github.com/ethereum/go-ethereum"
+ "github.com/ethereum/go-ethereum/common"
+ "golang.org/x/exp/slices"
+
+ "github.com/smartcontractkit/chainlink/v2/core/assets"
+ evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client"
+ "github.com/smartcontractkit/chainlink/v2/core/config"
+ "github.com/smartcontractkit/chainlink/v2/core/logger"
+ "github.com/smartcontractkit/chainlink/v2/core/utils"
+)
+
+//go:generate mockery --quiet --name ethClient --output ./mocks/ --case=underscore --structname ETHClient
+type ethClient interface {
+ CallContract(ctx context.Context, msg ethereum.CallMsg, blockNumber *big.Int) ([]byte, error)
+}
+
+// Reads L2-specific precompiles and caches the l1GasPrice set by the L2.
+type l1GasPriceOracle struct {
+ client ethClient
+ pollPeriod time.Duration
+ logger logger.Logger
+ address string
+ callArgs string
+
+ l1GasPriceMu sync.RWMutex
+ l1GasPrice *assets.Wei
+
+ chInitialised chan struct{}
+ chStop utils.StopChan
+ chDone chan struct{}
+ utils.StartStopOnce
+}
+
+const (
+ // ArbGasInfoAddress is the address of the "Precompiled contract that exists in every Arbitrum chain."
+ // https://github.com/OffchainLabs/nitro/blob/f7645453cfc77bf3e3644ea1ac031eff629df325/contracts/src/precompiles/ArbGasInfo.sol
+ ArbGasInfoAddress = "0x000000000000000000000000000000000000006C"
+ // ArbGasInfo_getL1BaseFeeEstimate is the a hex encoded call to:
+ // `function getL1BaseFeeEstimate() external view returns (uint256);`
+ ArbGasInfo_getL1BaseFeeEstimate = "f5d6ded7"
+
+ // GasOracleAddress is the address of the precompiled contract that exists on OP stack chain.
+ // This is the case for Optimism and Base.
+ OPGasOracleAddress = "0x420000000000000000000000000000000000000F"
+ // GasOracle_l1BaseFee is the a hex encoded call to:
+ // `function l1BaseFee() external view returns (uint256);`
+ OPGasOracle_l1BaseFee = "519b4bd3"
+
+ // Interval at which to poll for L1BaseFee. A good starting point is the L1 block time.
+ PollPeriod = 12 * time.Second
+)
+
+var supportedChainTypes = []config.ChainType{config.ChainArbitrum, config.ChainOptimismBedrock}
+
+func IsRollupWithL1Support(chainType config.ChainType) bool {
+ return slices.Contains(supportedChainTypes, chainType)
+}
+
+func NewL1GasPriceOracle(lggr logger.Logger, ethClient ethClient, chainType config.ChainType) L1Oracle {
+ var address, callArgs string
+ switch chainType {
+ case config.ChainArbitrum:
+ address = ArbGasInfoAddress
+ callArgs = ArbGasInfo_getL1BaseFeeEstimate
+ case config.ChainOptimismBedrock:
+ address = OPGasOracleAddress
+ callArgs = OPGasOracle_l1BaseFee
+ default:
+ panic(fmt.Sprintf("Received unspported chaintype %s", chainType))
+ }
+
+ return &l1GasPriceOracle{
+ client: ethClient,
+ pollPeriod: PollPeriod,
+ logger: lggr.Named(fmt.Sprintf("L1GasPriceOracle(%s)", chainType)),
+ address: address,
+ callArgs: callArgs,
+ chInitialised: make(chan struct{}),
+ chStop: make(chan struct{}),
+ chDone: make(chan struct{}),
+ }
+}
+
+func (o *l1GasPriceOracle) Name() string {
+ return o.logger.Name()
+}
+
+func (o *l1GasPriceOracle) Start(ctx context.Context) error {
+ return o.StartOnce(o.Name(), func() error {
+ go o.run()
+ <-o.chInitialised
+ return nil
+ })
+}
+func (o *l1GasPriceOracle) Close() error {
+ return o.StopOnce(o.Name(), func() error {
+ close(o.chStop)
+ <-o.chDone
+ return nil
+ })
+}
+
+func (o *l1GasPriceOracle) Ready() error { return o.StartStopOnce.Ready() }
+
+func (o *l1GasPriceOracle) HealthReport() map[string]error {
+ return map[string]error{o.Name(): o.StartStopOnce.Healthy()}
+}
+
+func (o *l1GasPriceOracle) run() {
+ defer close(o.chDone)
+
+ t := o.refresh()
+ close(o.chInitialised)
+
+ for {
+ select {
+ case <-o.chStop:
+ return
+ case <-t.C:
+ t = o.refresh()
+ }
+ }
+}
+
+func (o *l1GasPriceOracle) refresh() (t *time.Timer) {
+ t = time.NewTimer(utils.WithJitter(o.pollPeriod))
+
+ ctx, cancel := o.chStop.CtxCancel(evmclient.ContextWithDefaultTimeout())
+ defer cancel()
+
+ precompile := common.HexToAddress(o.address)
+ b, err := o.client.CallContract(ctx, ethereum.CallMsg{
+ To: &precompile,
+ Data: common.Hex2Bytes(o.callArgs),
+ }, nil)
+ if err != nil {
+ o.logger.Errorf("gas oracle contract call failed: %v", err)
+ return
+ }
+
+ if len(b) != 32 { // returns uint256;
+ o.logger.Criticalf("return data length (%d) different than expected (%d)", len(b), 32)
+ return
+ }
+ price := new(big.Int).SetBytes(b)
+
+ o.l1GasPriceMu.Lock()
+ defer o.l1GasPriceMu.Unlock()
+ o.l1GasPrice = assets.NewWei(price)
+ return
+}
+
+func (o *l1GasPriceOracle) GasPrice(_ context.Context) (l1GasPrice *assets.Wei, err error) {
+ ok := o.IfStarted(func() {
+ o.l1GasPriceMu.RLock()
+ l1GasPrice = o.l1GasPrice
+ o.l1GasPriceMu.RUnlock()
+ })
+ if !ok {
+ return l1GasPrice, errors.New("L1GasPriceOracle is not started; cannot estimate gas")
+ }
+ if l1GasPrice == nil {
+ return l1GasPrice, errors.New("failed to get l1 gas price; gas price not set")
+ }
+ return
+}
diff --git a/core/chains/evm/gas/rollups/l1_gas_price_oracle_test.go b/core/chains/evm/gas/rollups/l1_gas_price_oracle_test.go
new file mode 100644
index 00000000000..9fd2a66201c
--- /dev/null
+++ b/core/chains/evm/gas/rollups/l1_gas_price_oracle_test.go
@@ -0,0 +1,83 @@
+package rollups
+
+import (
+ "fmt"
+ "math/big"
+ "testing"
+
+ "github.com/ethereum/go-ethereum"
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/mock"
+ "github.com/stretchr/testify/require"
+
+ "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas/rollups/mocks"
+
+ "github.com/smartcontractkit/chainlink/v2/core/assets"
+ "github.com/smartcontractkit/chainlink/v2/core/config"
+ "github.com/smartcontractkit/chainlink/v2/core/internal/testutils"
+ "github.com/smartcontractkit/chainlink/v2/core/logger"
+)
+
+func TestL1GasPriceOracle(t *testing.T) {
+ t.Parallel()
+
+ t.Run("Unsupported ChainType returns nil", func(t *testing.T) {
+ ethClient := mocks.NewETHClient(t)
+
+ assert.Panicsf(t, func() { NewL1GasPriceOracle(logger.TestLogger(t), ethClient, config.ChainCelo) }, "Received unspported chaintype %s", config.ChainCelo)
+ })
+
+ t.Run("Calling L1GasPrice on unstarted L1Oracle returns error", func(t *testing.T) {
+ ethClient := mocks.NewETHClient(t)
+
+ oracle := NewL1GasPriceOracle(logger.TestLogger(t), ethClient, config.ChainOptimismBedrock)
+
+ _, err := oracle.GasPrice(testutils.Context(t))
+ assert.EqualError(t, err, "L1GasPriceOracle is not started; cannot estimate gas")
+ })
+
+ t.Run("Calling GasPrice on started Arbitrum L1Oracle returns Arbitrum l1GasPrice", func(t *testing.T) {
+ l1BaseFee := big.NewInt(100)
+
+ ethClient := mocks.NewETHClient(t)
+ ethClient.On("CallContract", mock.Anything, mock.IsType(ethereum.CallMsg{}), mock.IsType(&big.Int{})).Run(func(args mock.Arguments) {
+ callMsg := args.Get(1).(ethereum.CallMsg)
+ blockNumber := args.Get(2).(*big.Int)
+ assert.Equal(t, ArbGasInfoAddress, callMsg.To.String())
+ assert.Equal(t, ArbGasInfo_getL1BaseFeeEstimate, fmt.Sprintf("%x", callMsg.Data))
+ assert.Nil(t, blockNumber)
+ }).Return(common.BigToHash(l1BaseFee).Bytes(), nil)
+
+ oracle := NewL1GasPriceOracle(logger.TestLogger(t), ethClient, config.ChainArbitrum)
+ require.NoError(t, oracle.Start(testutils.Context(t)))
+ t.Cleanup(func() { assert.NoError(t, oracle.Close()) })
+
+ gasPrice, err := oracle.GasPrice(testutils.Context(t))
+ require.NoError(t, err)
+
+ assert.Equal(t, assets.NewWei(l1BaseFee), gasPrice)
+ })
+
+ t.Run("Calling GasPrice on started OPStack L1Oracle returns OPStack l1GasPrice", func(t *testing.T) {
+ l1BaseFee := big.NewInt(200)
+
+ ethClient := mocks.NewETHClient(t)
+ ethClient.On("CallContract", mock.Anything, mock.IsType(ethereum.CallMsg{}), mock.IsType(&big.Int{})).Run(func(args mock.Arguments) {
+ callMsg := args.Get(1).(ethereum.CallMsg)
+ blockNumber := args.Get(2).(*big.Int)
+ assert.Equal(t, OPGasOracleAddress, callMsg.To.String())
+ assert.Equal(t, OPGasOracle_l1BaseFee, fmt.Sprintf("%x", callMsg.Data))
+ assert.Nil(t, blockNumber)
+ }).Return(common.BigToHash(l1BaseFee).Bytes(), nil)
+
+ oracle := NewL1GasPriceOracle(logger.TestLogger(t), ethClient, config.ChainOptimismBedrock)
+ require.NoError(t, oracle.Start(testutils.Context(t)))
+ t.Cleanup(func() { assert.NoError(t, oracle.Close()) })
+
+ gasPrice, err := oracle.GasPrice(testutils.Context(t))
+ require.NoError(t, err)
+
+ assert.Equal(t, assets.NewWei(l1BaseFee), gasPrice)
+ })
+}
diff --git a/core/chains/evm/gas/rollups/mocks/eth_client.go b/core/chains/evm/gas/rollups/mocks/eth_client.go
new file mode 100644
index 00000000000..5389661bc56
--- /dev/null
+++ b/core/chains/evm/gas/rollups/mocks/eth_client.go
@@ -0,0 +1,58 @@
+// Code generated by mockery v2.28.1. DO NOT EDIT.
+
+package mocks
+
+import (
+ context "context"
+ big "math/big"
+
+ ethereum "github.com/ethereum/go-ethereum"
+
+ mock "github.com/stretchr/testify/mock"
+)
+
+// ETHClient is an autogenerated mock type for the ethClient type
+type ETHClient struct {
+ mock.Mock
+}
+
+// CallContract provides a mock function with given fields: ctx, msg, blockNumber
+func (_m *ETHClient) CallContract(ctx context.Context, msg ethereum.CallMsg, blockNumber *big.Int) ([]byte, error) {
+ ret := _m.Called(ctx, msg, blockNumber)
+
+ var r0 []byte
+ var r1 error
+ if rf, ok := ret.Get(0).(func(context.Context, ethereum.CallMsg, *big.Int) ([]byte, error)); ok {
+ return rf(ctx, msg, blockNumber)
+ }
+ if rf, ok := ret.Get(0).(func(context.Context, ethereum.CallMsg, *big.Int) []byte); ok {
+ r0 = rf(ctx, msg, blockNumber)
+ } else {
+ if ret.Get(0) != nil {
+ r0 = ret.Get(0).([]byte)
+ }
+ }
+
+ if rf, ok := ret.Get(1).(func(context.Context, ethereum.CallMsg, *big.Int) error); ok {
+ r1 = rf(ctx, msg, blockNumber)
+ } else {
+ r1 = ret.Error(1)
+ }
+
+ return r0, r1
+}
+
+type mockConstructorTestingTNewETHClient interface {
+ mock.TestingT
+ Cleanup(func())
+}
+
+// NewETHClient creates a new instance of ETHClient. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+func NewETHClient(t mockConstructorTestingTNewETHClient) *ETHClient {
+ mock := ÐClient{}
+ mock.Mock.Test(t)
+
+ t.Cleanup(func() { mock.AssertExpectations(t) })
+
+ return mock
+}
diff --git a/core/chains/evm/gas/rollups/mocks/l1_oracle.go b/core/chains/evm/gas/rollups/mocks/l1_oracle.go
new file mode 100644
index 00000000000..e148c0e9ac4
--- /dev/null
+++ b/core/chains/evm/gas/rollups/mocks/l1_oracle.go
@@ -0,0 +1,129 @@
+// Code generated by mockery v2.28.1. DO NOT EDIT.
+
+package mocks
+
+import (
+ context "context"
+
+ assets "github.com/smartcontractkit/chainlink/v2/core/assets"
+
+ mock "github.com/stretchr/testify/mock"
+)
+
+// L1Oracle is an autogenerated mock type for the L1Oracle type
+type L1Oracle struct {
+ mock.Mock
+}
+
+// Close provides a mock function with given fields:
+func (_m *L1Oracle) Close() error {
+ ret := _m.Called()
+
+ var r0 error
+ if rf, ok := ret.Get(0).(func() error); ok {
+ r0 = rf()
+ } else {
+ r0 = ret.Error(0)
+ }
+
+ return r0
+}
+
+// GasPrice provides a mock function with given fields: ctx
+func (_m *L1Oracle) GasPrice(ctx context.Context) (*assets.Wei, error) {
+ ret := _m.Called(ctx)
+
+ var r0 *assets.Wei
+ var r1 error
+ if rf, ok := ret.Get(0).(func(context.Context) (*assets.Wei, error)); ok {
+ return rf(ctx)
+ }
+ if rf, ok := ret.Get(0).(func(context.Context) *assets.Wei); ok {
+ r0 = rf(ctx)
+ } else {
+ if ret.Get(0) != nil {
+ r0 = ret.Get(0).(*assets.Wei)
+ }
+ }
+
+ if rf, ok := ret.Get(1).(func(context.Context) error); ok {
+ r1 = rf(ctx)
+ } else {
+ r1 = ret.Error(1)
+ }
+
+ return r0, r1
+}
+
+// HealthReport provides a mock function with given fields:
+func (_m *L1Oracle) HealthReport() map[string]error {
+ ret := _m.Called()
+
+ var r0 map[string]error
+ if rf, ok := ret.Get(0).(func() map[string]error); ok {
+ r0 = rf()
+ } else {
+ if ret.Get(0) != nil {
+ r0 = ret.Get(0).(map[string]error)
+ }
+ }
+
+ return r0
+}
+
+// Name provides a mock function with given fields:
+func (_m *L1Oracle) Name() string {
+ ret := _m.Called()
+
+ var r0 string
+ if rf, ok := ret.Get(0).(func() string); ok {
+ r0 = rf()
+ } else {
+ r0 = ret.Get(0).(string)
+ }
+
+ return r0
+}
+
+// Ready provides a mock function with given fields:
+func (_m *L1Oracle) Ready() error {
+ ret := _m.Called()
+
+ var r0 error
+ if rf, ok := ret.Get(0).(func() error); ok {
+ r0 = rf()
+ } else {
+ r0 = ret.Error(0)
+ }
+
+ return r0
+}
+
+// Start provides a mock function with given fields: _a0
+func (_m *L1Oracle) Start(_a0 context.Context) error {
+ ret := _m.Called(_a0)
+
+ var r0 error
+ if rf, ok := ret.Get(0).(func(context.Context) error); ok {
+ r0 = rf(_a0)
+ } else {
+ r0 = ret.Error(0)
+ }
+
+ return r0
+}
+
+type mockConstructorTestingTNewL1Oracle interface {
+ mock.TestingT
+ Cleanup(func())
+}
+
+// NewL1Oracle creates a new instance of L1Oracle. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+func NewL1Oracle(t mockConstructorTestingTNewL1Oracle) *L1Oracle {
+ mock := &L1Oracle{}
+ mock.Mock.Test(t)
+
+ t.Cleanup(func() { mock.AssertExpectations(t) })
+
+ return mock
+}
diff --git a/core/chains/evm/gas/rollups/models.go b/core/chains/evm/gas/rollups/models.go
new file mode 100644
index 00000000000..83ae29f4ea9
--- /dev/null
+++ b/core/chains/evm/gas/rollups/models.go
@@ -0,0 +1,18 @@
+package rollups
+
+import (
+ "context"
+
+ "github.com/smartcontractkit/chainlink/v2/core/assets"
+ "github.com/smartcontractkit/chainlink/v2/core/services"
+)
+
+// L1Oracle provides interface for fetching L1-specific fee components if the chain is an L2.
+// For example, on Optimistic Rollups, this oracle can return rollup-specific l1BaseFee
+//
+//go:generate mockery --quiet --name L1Oracle --output ./mocks/ --case=underscore
+type L1Oracle interface {
+ services.ServiceCtx
+
+ GasPrice(ctx context.Context) (*assets.Wei, error)
+}
diff --git a/core/chains/evm/headtracker/head_tracker_test.go b/core/chains/evm/headtracker/head_tracker_test.go
index cf8399ceeda..330142b9dc0 100644
--- a/core/chains/evm/headtracker/head_tracker_test.go
+++ b/core/chains/evm/headtracker/head_tracker_test.go
@@ -38,7 +38,7 @@ import (
)
func firstHead(t *testing.T, db *sqlx.DB) (h evmtypes.Head) {
- if err := db.Get(&h, `SELECT * FROM evm_heads ORDER BY number ASC LIMIT 1`); err != nil {
+ if err := db.Get(&h, `SELECT * FROM evm.heads ORDER BY number ASC LIMIT 1`); err != nil {
t.Fatal(err)
}
return h
@@ -428,7 +428,7 @@ func TestHeadTracker_SwitchesToLongestChainWithHeadSamplingEnabled(t *testing.T)
ethClient := evmtest.NewEthClientMockWithDefaultChain(t)
checker := commonmocks.NewHeadTrackable[*evmtypes.Head, gethCommon.Hash](t)
- orm := headtracker.NewORM(db, logger, config.Database(), *config.DefaultChainID())
+ orm := headtracker.NewORM(db, logger, config.Database(), *evmtest.MustGetDefaultChainID(t, config.EVMConfigs()))
csCfg := evmtest.NewChainScopedConfig(t, config)
ht := createHeadTrackerWithChecker(t, ethClient, csCfg.EVM(), csCfg.EVM().HeadTracker(), orm, checker)
@@ -779,7 +779,7 @@ func TestHeadTracker_Backfill(t *testing.T) {
}
ethClient := evmtest.NewEthClientMock(t)
- ethClient.On("ConfiguredChainID", mock.Anything).Return(cfg.DefaultChainID(), nil)
+ ethClient.On("ConfiguredChainID", mock.Anything).Return(evmtest.MustGetDefaultChainID(t, cfg.EVMConfigs()), nil)
ht := createHeadTrackerWithNeverSleeper(t, ethClient, cfg, orm)
err := ht.Backfill(ctx, &h12, 2)
@@ -796,7 +796,7 @@ func TestHeadTracker_Backfill(t *testing.T) {
}
ethClient := evmtest.NewEthClientMock(t)
- ethClient.On("ConfiguredChainID", mock.Anything).Return(cfg.DefaultChainID(), nil)
+ ethClient.On("ConfiguredChainID", mock.Anything).Return(evmtest.MustGetDefaultChainID(t, cfg.EVMConfigs()), nil)
ethClient.On("HeadByHash", mock.Anything, head10.Hash).
Return(&head10, nil)
@@ -832,7 +832,7 @@ func TestHeadTracker_Backfill(t *testing.T) {
}
ethClient := evmtest.NewEthClientMock(t)
- ethClient.On("ConfiguredChainID", mock.Anything).Return(cfg.DefaultChainID(), nil)
+ ethClient.On("ConfiguredChainID", mock.Anything).Return(evmtest.MustGetDefaultChainID(t, cfg.EVMConfigs()), nil)
ht := createHeadTrackerWithNeverSleeper(t, ethClient, cfg, orm)
@@ -865,7 +865,7 @@ func TestHeadTracker_Backfill(t *testing.T) {
}
ethClient := evmtest.NewEthClientMock(t)
- ethClient.On("ConfiguredChainID", mock.Anything).Return(cfg.DefaultChainID(), nil)
+ ethClient.On("ConfiguredChainID", mock.Anything).Return(evmtest.MustGetDefaultChainID(t, cfg.EVMConfigs()), nil)
ht := createHeadTrackerWithNeverSleeper(t, ethClient, cfg, orm)
@@ -883,7 +883,7 @@ func TestHeadTracker_Backfill(t *testing.T) {
orm := headtracker.NewORM(db, logger, cfg.Database(), cltest.FixtureChainID)
ethClient := evmtest.NewEthClientMock(t)
- ethClient.On("ConfiguredChainID", mock.Anything).Return(cfg.DefaultChainID(), nil)
+ ethClient.On("ConfiguredChainID", mock.Anything).Return(evmtest.MustGetDefaultChainID(t, cfg.EVMConfigs()), nil)
ethClient.On("HeadByHash", mock.Anything, head0.Hash).
Return(&head0, nil)
@@ -911,7 +911,7 @@ func TestHeadTracker_Backfill(t *testing.T) {
}
ethClient := evmtest.NewEthClientMock(t)
- ethClient.On("ConfiguredChainID", mock.Anything).Return(cfg.DefaultChainID(), nil)
+ ethClient.On("ConfiguredChainID", mock.Anything).Return(evmtest.MustGetDefaultChainID(t, cfg.EVMConfigs()), nil)
ethClient.On("HeadByHash", mock.Anything, head10.Hash).
Return(&head10, nil).
Once()
@@ -942,7 +942,7 @@ func TestHeadTracker_Backfill(t *testing.T) {
}
ethClient := evmtest.NewEthClientMock(t)
- ethClient.On("ConfiguredChainID", mock.Anything).Return(cfg.DefaultChainID(), nil)
+ ethClient.On("ConfiguredChainID", mock.Anything).Return(evmtest.MustGetDefaultChainID(t, cfg.EVMConfigs()), nil)
ethClient.On("HeadByHash", mock.Anything, head10.Hash).
Return(&head10, nil)
ethClient.On("HeadByHash", mock.Anything, head8.Hash).
@@ -967,7 +967,7 @@ func TestHeadTracker_Backfill(t *testing.T) {
logger := logger.TestLogger(t)
orm := headtracker.NewORM(db, logger, cfg.Database(), cltest.FixtureChainID)
ethClient := evmtest.NewEthClientMock(t)
- ethClient.On("ConfiguredChainID", mock.Anything).Return(cfg.DefaultChainID(), nil)
+ ethClient.On("ConfiguredChainID", mock.Anything).Return(evmtest.MustGetDefaultChainID(t, cfg.EVMConfigs()), nil)
ethClient.On("HeadByHash", mock.Anything, h14.Hash).Return(&h14, nil).Once()
ethClient.On("HeadByHash", mock.Anything, h13.Hash).Return(&h13, nil).Once()
ethClient.On("HeadByHash", mock.Anything, h12.Hash).Return(nil, errors.New("not found")).Once()
diff --git a/core/chains/evm/headtracker/orm.go b/core/chains/evm/headtracker/orm.go
index 02747752148..426df68b301 100644
--- a/core/chains/evm/headtracker/orm.go
+++ b/core/chains/evm/headtracker/orm.go
@@ -43,7 +43,7 @@ func (orm *orm) IdempotentInsertHead(ctx context.Context, head *evmtypes.Head) e
// listener guarantees head.EVMChainID to be equal to orm.chainID
q := orm.q.WithOpts(pg.WithParentCtx(ctx))
query := `
- INSERT INTO evm_heads (hash, number, parent_hash, created_at, timestamp, l1_block_number, evm_chain_id, base_fee_per_gas) VALUES (
+ INSERT INTO evm.heads (hash, number, parent_hash, created_at, timestamp, l1_block_number, evm_chain_id, base_fee_per_gas) VALUES (
:hash, :number, :parent_hash, :created_at, :timestamp, :l1_block_number, :evm_chain_id, :base_fee_per_gas)
ON CONFLICT (evm_chain_id, hash) DO NOTHING`
err := q.ExecQNamed(query, head)
@@ -53,11 +53,11 @@ func (orm *orm) IdempotentInsertHead(ctx context.Context, head *evmtypes.Head) e
func (orm *orm) TrimOldHeads(ctx context.Context, n uint) (err error) {
q := orm.q.WithOpts(pg.WithParentCtx(ctx))
return q.ExecQ(`
- DELETE FROM evm_heads
+ DELETE FROM evm.heads
WHERE evm_chain_id = $1 AND number < (
SELECT min(number) FROM (
SELECT number
- FROM evm_heads
+ FROM evm.heads
WHERE evm_chain_id = $1
ORDER BY number DESC
LIMIT $2
@@ -68,7 +68,7 @@ func (orm *orm) TrimOldHeads(ctx context.Context, n uint) (err error) {
func (orm *orm) LatestHead(ctx context.Context) (head *evmtypes.Head, err error) {
head = new(evmtypes.Head)
q := orm.q.WithOpts(pg.WithParentCtx(ctx))
- err = q.Get(head, `SELECT * FROM evm_heads WHERE evm_chain_id = $1 ORDER BY number DESC, created_at DESC, id DESC LIMIT 1`, orm.chainID)
+ err = q.Get(head, `SELECT * FROM evm.heads WHERE evm_chain_id = $1 ORDER BY number DESC, created_at DESC, id DESC LIMIT 1`, orm.chainID)
if errors.Is(err, sql.ErrNoRows) {
return nil, nil
}
@@ -78,7 +78,7 @@ func (orm *orm) LatestHead(ctx context.Context) (head *evmtypes.Head, err error)
func (orm *orm) LatestHeads(ctx context.Context, limit uint) (heads []*evmtypes.Head, err error) {
q := orm.q.WithOpts(pg.WithParentCtx(ctx))
- err = q.Select(&heads, `SELECT * FROM evm_heads WHERE evm_chain_id = $1 ORDER BY number DESC, created_at DESC, id DESC LIMIT $2`, orm.chainID, limit)
+ err = q.Select(&heads, `SELECT * FROM evm.heads WHERE evm_chain_id = $1 ORDER BY number DESC, created_at DESC, id DESC LIMIT $2`, orm.chainID, limit)
err = errors.Wrap(err, "LatestHeads failed")
return
}
@@ -86,7 +86,7 @@ func (orm *orm) LatestHeads(ctx context.Context, limit uint) (heads []*evmtypes.
func (orm *orm) HeadByHash(ctx context.Context, hash common.Hash) (head *evmtypes.Head, err error) {
q := orm.q.WithOpts(pg.WithParentCtx(ctx))
head = new(evmtypes.Head)
- err = q.Get(head, `SELECT * FROM evm_heads WHERE evm_chain_id = $1 AND hash = $2`, orm.chainID, hash)
+ err = q.Get(head, `SELECT * FROM evm.heads WHERE evm_chain_id = $1 AND hash = $2`, orm.chainID, hash)
if errors.Is(err, sql.ErrNoRows) {
return nil, nil
}
diff --git a/core/chains/evm/log/helpers_test.go b/core/chains/evm/log/helpers_test.go
index e11c9faaf46..d55a44373f2 100644
--- a/core/chains/evm/log/helpers_test.go
+++ b/core/chains/evm/log/helpers_test.go
@@ -121,8 +121,7 @@ func (c broadcasterHelperCfg) newWithEthClient(t *testing.T, ethClient evmclient
LogBroadcaster: &log.NullBroadcaster{},
MailMon: mailMon,
})
- legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(cc)
- require.NoError(t, err)
+ legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(cc)
pipelineHelper := cltest.NewJobPipelineV2(t, config.WebServer(), config.JobPipeline(), config.Database(), legacyChains, c.db, kst, nil, nil)
return &broadcasterHelper{
diff --git a/core/chains/evm/logpoller/disabled.go b/core/chains/evm/logpoller/disabled.go
index 80a5550b0a5..d6fb2b7cb0d 100644
--- a/core/chains/evm/logpoller/disabled.go
+++ b/core/chains/evm/logpoller/disabled.go
@@ -37,6 +37,8 @@ func (disabled) RegisterFilter(filter Filter, qopts ...pg.QOpt) error { return E
func (disabled) UnregisterFilter(name string, qopts ...pg.QOpt) error { return ErrDisabled }
+func (disabled) HasFilter(name string) bool { return false }
+
func (disabled) LatestBlock(qopts ...pg.QOpt) (int64, error) { return -1, ErrDisabled }
func (disabled) GetBlocksRange(ctx context.Context, numbers []uint64, qopts ...pg.QOpt) ([]LogPollerBlock, error) {
@@ -67,6 +69,10 @@ func (disabled) IndexedLogsByBlockRange(start, end int64, eventSig common.Hash,
return nil, ErrDisabled
}
+func (d disabled) IndexedLogsByTxHash(eventSig common.Hash, txHash common.Hash, qopts ...pg.QOpt) ([]Log, error) {
+ return nil, ErrDisabled
+}
+
func (disabled) IndexedLogsTopicGreaterThan(eventSig common.Hash, address common.Address, topicIndex int, topicValueMin common.Hash, confs int, qopts ...pg.QOpt) ([]Log, error) {
return nil, ErrDisabled
}
@@ -98,3 +104,7 @@ func (d disabled) IndexedLogsCreatedAfter(eventSig common.Hash, address common.A
func (d disabled) LatestBlockByEventSigsAddrsWithConfs(fromBlock int64, eventSigs []common.Hash, addresses []common.Address, confs int, qopts ...pg.QOpt) (int64, error) {
return 0, ErrDisabled
}
+
+func (d disabled) LogsUntilBlockHashDataWordGreaterThan(eventSig common.Hash, address common.Address, wordIndex int, wordValueMin common.Hash, untilBlockHash common.Hash, qopts ...pg.QOpt) ([]Log, error) {
+ return nil, ErrDisabled
+}
diff --git a/core/chains/evm/logpoller/log_poller.go b/core/chains/evm/logpoller/log_poller.go
index 60767970289..d6e55286029 100644
--- a/core/chains/evm/logpoller/log_poller.go
+++ b/core/chains/evm/logpoller/log_poller.go
@@ -36,6 +36,7 @@ type LogPoller interface {
ReplayAsync(fromBlock int64)
RegisterFilter(filter Filter, qopts ...pg.QOpt) error
UnregisterFilter(name string, qopts ...pg.QOpt) error
+ HasFilter(name string) bool
LatestBlock(qopts ...pg.QOpt) (int64, error)
GetBlocksRange(ctx context.Context, numbers []uint64, qopts ...pg.QOpt) ([]LogPollerBlock, error)
@@ -51,11 +52,13 @@ type LogPoller interface {
IndexedLogs(eventSig common.Hash, address common.Address, topicIndex int, topicValues []common.Hash, confs int, qopts ...pg.QOpt) ([]Log, error)
IndexedLogsByBlockRange(start, end int64, eventSig common.Hash, address common.Address, topicIndex int, topicValues []common.Hash, qopts ...pg.QOpt) ([]Log, error)
IndexedLogsCreatedAfter(eventSig common.Hash, address common.Address, topicIndex int, topicValues []common.Hash, after time.Time, confs int, qopts ...pg.QOpt) ([]Log, error)
+ IndexedLogsByTxHash(eventSig common.Hash, txHash common.Hash, qopts ...pg.QOpt) ([]Log, error)
IndexedLogsTopicGreaterThan(eventSig common.Hash, address common.Address, topicIndex int, topicValueMin common.Hash, confs int, qopts ...pg.QOpt) ([]Log, error)
IndexedLogsTopicRange(eventSig common.Hash, address common.Address, topicIndex int, topicValueMin common.Hash, topicValueMax common.Hash, confs int, qopts ...pg.QOpt) ([]Log, error)
IndexedLogsWithSigsExcluding(address common.Address, eventSigA, eventSigB common.Hash, topicIndex int, fromBlock, toBlock int64, confs int, qopts ...pg.QOpt) ([]Log, error)
LogsDataWordRange(eventSig common.Hash, address common.Address, wordIndex int, wordValueMin, wordValueMax common.Hash, confs int, qopts ...pg.QOpt) ([]Log, error)
LogsDataWordGreaterThan(eventSig common.Hash, address common.Address, wordIndex int, wordValueMin common.Hash, confs int, qopts ...pg.QOpt) ([]Log, error)
+ LogsUntilBlockHashDataWordGreaterThan(eventSig common.Hash, address common.Address, wordIndex int, wordValueMin common.Hash, untilBlockHash common.Hash, qopts ...pg.QOpt) ([]Log, error)
}
type LogPollerTest interface {
@@ -258,6 +261,15 @@ func (lp *logPoller) UnregisterFilter(name string, qopts ...pg.QOpt) error {
return nil
}
+// HasFilter returns true if the log poller has an active filter with the given name.
+func (lp *logPoller) HasFilter(name string) bool {
+ lp.filterMu.RLock()
+ defer lp.filterMu.RUnlock()
+
+ _, ok := lp.filters[name]
+ return ok
+}
+
func (lp *logPoller) Filter(from, to *big.Int, bh *common.Hash) ethereum.FilterQuery {
lp.filterMu.Lock()
defer lp.filterMu.Unlock()
@@ -647,7 +659,7 @@ func (lp *logPoller) backfill(ctx context.Context, start, end int64) error {
}
}
if batchSize == 1 {
- lp.lggr.Criticalw("Too many log results in a single block, failed to retrieve logs! Node may run in a degraded state unless LogBackfillBatchSize is increased", "err", err, "from", from, "to", to, "LogBackfillBatchSize", lp.backfillBatchSize)
+ lp.lggr.Criticalw("Too many log results in a single block, failed to retrieve logs! Node may be running in a degraded state.", "err", err, "from", from, "to", to, "LogBackfillBatchSize", lp.backfillBatchSize)
return err
}
batchSize /= 2
@@ -733,7 +745,7 @@ func (lp *logPoller) getCurrentBlockMaybeHandleReorg(ctx context.Context, curren
// that applications see them and take action upon it, however that
// results in significantly slower reads since we must then compute
// the canonical set per read. Typically, if an application took action on a log
- // it would be saved elsewhere e.g. eth_txes, so it seems better to just support the fast reads.
+ // 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 {
// These deletes are bounded by reorg depth, so they are
@@ -950,6 +962,10 @@ func (lp *logPoller) IndexedLogsCreatedAfter(eventSig common.Hash, address commo
return lp.orm.SelectIndexedLogsCreatedAfter(address, eventSig, topicIndex, topicValues, after, confs, qopts...)
}
+func (lp *logPoller) IndexedLogsByTxHash(eventSig common.Hash, txHash common.Hash, qopts ...pg.QOpt) ([]Log, error) {
+ return lp.orm.SelectIndexedLogsByTxHash(eventSig, txHash, qopts...)
+}
+
// 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...)
@@ -966,6 +982,12 @@ func (lp *logPoller) IndexedLogsTopicGreaterThan(eventSig common.Hash, address c
return lp.orm.SelectIndexLogsTopicGreaterThan(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...)
+}
+
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...)
}
@@ -1033,7 +1055,7 @@ func (lp *logPoller) GetBlocksRange(ctx context.Context, numbers []uint64, qopts
}
// Fill any remaining blocks from the client.
- blocksFoundFromRPC, err := lp.fillRemainingBlocksFromRPC(ctx, numbers, blocksFound)
+ blocksFoundFromRPC, err := lp.fillRemainingBlocksFromRPC(ctx, blocksRequested, blocksFound)
if err != nil {
return nil, err
}
@@ -1059,12 +1081,12 @@ func (lp *logPoller) GetBlocksRange(ctx context.Context, numbers []uint64, qopts
func (lp *logPoller) fillRemainingBlocksFromRPC(
ctx context.Context,
- blocksRequested []uint64,
+ blocksRequested map[uint64]struct{},
blocksFound map[uint64]LogPollerBlock,
) (map[uint64]LogPollerBlock, error) {
var reqs []rpc.BatchElem
var remainingBlocks []uint64
- for _, num := range blocksRequested {
+ for num := range blocksRequested {
if _, ok := blocksFound[num]; !ok {
req := rpc.BatchElem{
Method: "eth_getBlockByNumber",
diff --git a/core/chains/evm/logpoller/log_poller_internal_test.go b/core/chains/evm/logpoller/log_poller_internal_test.go
index 13ec0262391..5f1c21a5b81 100644
--- a/core/chains/evm/logpoller/log_poller_internal_test.go
+++ b/core/chains/evm/logpoller/log_poller_internal_test.go
@@ -56,10 +56,6 @@ func TestLogPoller_RegisterFilter(t *testing.T) {
orm := NewORM(chainID, db, lggr, pgtest.NewQConfig(true))
- db.Close()
- db = pgtest.NewSqlxDB(t)
- orm = NewORM(chainID, db, lggr, pgtest.NewQConfig(true))
-
// Set up a test chain with a log emitting contract deployed.
lp := NewLogPoller(orm, nil, lggr, time.Hour, 1, 1, 2, 1000)
diff --git a/core/chains/evm/logpoller/log_poller_test.go b/core/chains/evm/logpoller/log_poller_test.go
index 17df4dc6291..c434d18c999 100644
--- a/core/chains/evm/logpoller/log_poller_test.go
+++ b/core/chains/evm/logpoller/log_poller_test.go
@@ -760,6 +760,13 @@ func TestLogPoller_LoadFilters(t *testing.T) {
require.True(t, ok)
assert.True(t, filter.Contains(&filter3))
assert.True(t, filter3.Contains(&filter))
+
+ t.Run("HasFilter", func(t *testing.T) {
+ assert.True(t, th.LogPoller.HasFilter("first Filter"))
+ assert.True(t, th.LogPoller.HasFilter("second Filter"))
+ assert.True(t, th.LogPoller.HasFilter("third Filter"))
+ assert.False(t, th.LogPoller.HasFilter("fourth Filter"))
+ })
}
func TestLogPoller_GetBlocks_Range(t *testing.T) {
diff --git a/core/chains/evm/logpoller/mocks/log_poller.go b/core/chains/evm/logpoller/mocks/log_poller.go
index 9e96947abc7..39d37f31a32 100644
--- a/core/chains/evm/logpoller/mocks/log_poller.go
+++ b/core/chains/evm/logpoller/mocks/log_poller.go
@@ -68,6 +68,20 @@ func (_m *LogPoller) GetBlocksRange(ctx context.Context, numbers []uint64, qopts
return r0, r1
}
+// HasFilter provides a mock function with given fields: name
+func (_m *LogPoller) HasFilter(name string) bool {
+ ret := _m.Called(name)
+
+ var r0 bool
+ if rf, ok := ret.Get(0).(func(string) bool); ok {
+ r0 = rf(name)
+ } else {
+ r0 = ret.Get(0).(bool)
+ }
+
+ return r0
+}
+
// HealthReport provides a mock function with given fields:
func (_m *LogPoller) HealthReport() map[string]error {
ret := _m.Called()
@@ -150,6 +164,39 @@ func (_m *LogPoller) IndexedLogsByBlockRange(start int64, end int64, eventSig co
return r0, r1
}
+// IndexedLogsByTxHash provides a mock function with given fields: eventSig, txHash, qopts
+func (_m *LogPoller) IndexedLogsByTxHash(eventSig common.Hash, txHash common.Hash, qopts ...pg.QOpt) ([]logpoller.Log, error) {
+ _va := make([]interface{}, len(qopts))
+ for _i := range qopts {
+ _va[_i] = qopts[_i]
+ }
+ var _ca []interface{}
+ _ca = append(_ca, eventSig, txHash)
+ _ca = append(_ca, _va...)
+ ret := _m.Called(_ca...)
+
+ var r0 []logpoller.Log
+ var r1 error
+ if rf, ok := ret.Get(0).(func(common.Hash, common.Hash, ...pg.QOpt) ([]logpoller.Log, error)); ok {
+ return rf(eventSig, txHash, qopts...)
+ }
+ if rf, ok := ret.Get(0).(func(common.Hash, common.Hash, ...pg.QOpt) []logpoller.Log); ok {
+ r0 = rf(eventSig, txHash, qopts...)
+ } else {
+ if ret.Get(0) != nil {
+ r0 = ret.Get(0).([]logpoller.Log)
+ }
+ }
+
+ if rf, ok := ret.Get(1).(func(common.Hash, common.Hash, ...pg.QOpt) error); ok {
+ r1 = rf(eventSig, txHash, qopts...)
+ } else {
+ r1 = ret.Error(1)
+ }
+
+ return r0, r1
+}
+
// IndexedLogsCreatedAfter provides a mock function with given fields: eventSig, address, topicIndex, topicValues, after, confs, qopts
func (_m *LogPoller) IndexedLogsCreatedAfter(eventSig common.Hash, address common.Address, topicIndex int, topicValues []common.Hash, after time.Time, confs int, qopts ...pg.QOpt) ([]logpoller.Log, error) {
_va := make([]interface{}, len(qopts))
@@ -541,6 +588,39 @@ func (_m *LogPoller) LogsDataWordRange(eventSig common.Hash, address common.Addr
return r0, r1
}
+// LogsUntilBlockHashDataWordGreaterThan provides a mock function with given fields: eventSig, address, wordIndex, wordValueMin, untilBlockHash, qopts
+func (_m *LogPoller) LogsUntilBlockHashDataWordGreaterThan(eventSig common.Hash, address common.Address, wordIndex int, wordValueMin common.Hash, untilBlockHash common.Hash, qopts ...pg.QOpt) ([]logpoller.Log, error) {
+ _va := make([]interface{}, len(qopts))
+ for _i := range qopts {
+ _va[_i] = qopts[_i]
+ }
+ var _ca []interface{}
+ _ca = append(_ca, eventSig, address, wordIndex, wordValueMin, untilBlockHash)
+ _ca = append(_ca, _va...)
+ ret := _m.Called(_ca...)
+
+ var r0 []logpoller.Log
+ var r1 error
+ if rf, ok := ret.Get(0).(func(common.Hash, common.Address, int, common.Hash, common.Hash, ...pg.QOpt) ([]logpoller.Log, error)); ok {
+ return rf(eventSig, address, wordIndex, wordValueMin, untilBlockHash, qopts...)
+ }
+ if rf, ok := ret.Get(0).(func(common.Hash, common.Address, int, common.Hash, common.Hash, ...pg.QOpt) []logpoller.Log); ok {
+ r0 = rf(eventSig, address, wordIndex, wordValueMin, untilBlockHash, qopts...)
+ } else {
+ if ret.Get(0) != nil {
+ r0 = ret.Get(0).([]logpoller.Log)
+ }
+ }
+
+ if rf, ok := ret.Get(1).(func(common.Hash, common.Address, int, common.Hash, common.Hash, ...pg.QOpt) error); ok {
+ r1 = rf(eventSig, address, wordIndex, wordValueMin, untilBlockHash, qopts...)
+ } else {
+ r1 = ret.Error(1)
+ }
+
+ return r0, r1
+}
+
// LogsWithSigs provides a mock function with given fields: start, end, eventSigs, address, qopts
func (_m *LogPoller) LogsWithSigs(start int64, end int64, eventSigs []common.Hash, address common.Address, qopts ...pg.QOpt) ([]logpoller.Log, error) {
_va := make([]interface{}, len(qopts))
diff --git a/core/chains/evm/logpoller/observability.go b/core/chains/evm/logpoller/observability.go
index f52d2878597..8dfa6e81d0d 100644
--- a/core/chains/evm/logpoller/observability.go
+++ b/core/chains/evm/logpoller/observability.go
@@ -110,6 +110,12 @@ func (o *ObservedLogPoller) IndexedLogsCreatedAfter(eventSig common.Hash, addres
})
}
+func (o *ObservedLogPoller) 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...)
+ })
+}
+
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...)
@@ -140,6 +146,12 @@ func (o *ObservedLogPoller) LogsDataWordGreaterThan(eventSig common.Hash, addres
})
}
+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 withObservedQueryAndResults[T any](o *ObservedLogPoller, queryName string, query func() ([]T, error)) ([]T, error) {
results, err := withObservedQuery(o, queryName, query)
if err == nil {
diff --git a/core/chains/evm/logpoller/observability_test.go b/core/chains/evm/logpoller/observability_test.go
index 8c9b18d9222..5bd0a772d96 100644
--- a/core/chains/evm/logpoller/observability_test.go
+++ b/core/chains/evm/logpoller/observability_test.go
@@ -36,8 +36,9 @@ func TestMultipleMetricsArePublished(t *testing.T) {
_, _ = 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, 11, testutil.CollectAndCount(lp.queryDuration))
+ require.Equal(t, 12, testutil.CollectAndCount(lp.queryDuration))
require.Equal(t, 10, testutil.CollectAndCount(lp.datasetSize))
resetMetrics(*lp)
}
diff --git a/core/chains/evm/logpoller/orm.go b/core/chains/evm/logpoller/orm.go
index e8ced08a1e7..c062ef3e080 100644
--- a/core/chains/evm/logpoller/orm.go
+++ b/core/chains/evm/logpoller/orm.go
@@ -1,6 +1,7 @@
package logpoller
import (
+ "context"
"database/sql"
"math/big"
"time"
@@ -33,7 +34,7 @@ func NewORM(chainID *big.Int, db *sqlx.DB, lggr logger.Logger, cfg pg.QConfig) *
// InsertBlock is idempotent to support replays.
func (o *ORM) 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)
+ 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)
return err
}
@@ -53,7 +54,7 @@ func (o *ORM) InsertFilter(filter Filter, qopts ...pg.QOpt) (err error) {
for _, ev := range filter.EventSigs {
events = append(events, ev.Bytes())
}
- return q.ExecQ(`INSERT INTO evm_log_poller_filters
+ return q.ExecQ(`INSERT INTO evm.log_poller_filters
(name, evm_chain_id, retention, created_at, address, event)
SELECT * FROM
(SELECT $1, $2::NUMERIC, $3::BIGINT, NOW()) x,
@@ -66,7 +67,7 @@ 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 {
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))
+ 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
@@ -77,7 +78,7 @@ func (o *ORM) LoadFilters(qopts ...pg.QOpt) (map[string]Filter, error) {
ARRAY_AGG(DISTINCT address)::BYTEA[] AS addresses,
ARRAY_AGG(DISTINCT event)::BYTEA[] AS event_sigs,
MAX(retention) AS retention
- FROM evm_log_poller_filters WHERE evm_chain_id = $1
+ FROM evm.log_poller_filters WHERE evm_chain_id = $1
GROUP BY name`, utils.NewBig(o.chainID))
filters := make(map[string]Filter)
for _, filter := range rows {
@@ -90,7 +91,7 @@ func (o *ORM) LoadFilters(qopts ...pg.QOpt) (map[string]Filter, error) {
func (o *ORM) 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 {
+ 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 {
return nil, err
}
return &b, nil
@@ -99,7 +100,7 @@ func (o *ORM) SelectBlockByHash(h common.Hash, qopts ...pg.QOpt) (*LogPollerBloc
func (o *ORM) 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 {
+ 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 {
return nil, err
}
return &b, nil
@@ -108,7 +109,7 @@ func (o *ORM) SelectBlockByNumber(n int64, qopts ...pg.QOpt) (*LogPollerBlock, e
func (o *ORM) 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 {
+ 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 {
return nil, err
}
return &b, nil
@@ -117,11 +118,11 @@ func (o *ORM) SelectLatestBlock(qopts ...pg.QOpt) (*LogPollerBlock, error) {
func (o *ORM) SelectLatestLogEventSigWithConfs(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
+ 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 + $4) <= (SELECT COALESCE(block_number, 0) FROM evm.log_poller_blocks WHERE evm_chain_id = $1 ORDER BY block_number DESC LIMIT 1)
ORDER BY (block_number, log_index) DESC LIMIT 1`, utils.NewBig(o.chainID), eventSig, address, confs); err != nil {
return nil, err
}
@@ -131,19 +132,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 {
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))
+ 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 {
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))
+ _, 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 {
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))
+ return q.ExecQ(`DELETE FROM evm.logs WHERE block_number >= $1 AND evm_chain_id = $2`, start, utils.NewBig(o.chainID))
}
type Exp struct {
@@ -160,9 +161,9 @@ func (o *ORM) DeleteExpiredLogs(qopts ...pg.QOpt) error {
return q.ExecQ(`WITH r AS
( SELECT address, event, MAX(retention) AS retention
- FROM evm_log_poller_filters WHERE evm_chain_id=$1
+ FROM evm.log_poller_filters WHERE evm_chain_id=$1
GROUP BY evm_chain_id,address, event HAVING NOT 0 = ANY(ARRAY_AGG(retention))
- ) DELETE FROM evm_logs l USING r
+ ) DELETE FROM evm.logs l USING r
WHERE l.evm_chain_id = $1 AND l.address=r.address AND l.event_sig=r.event
AND l.created_at <= STATEMENT_TIMESTAMP() - (r.retention / 10^9 * interval '1 second')`, // retention is in nanoseconds (time.Duration aka BIGINT)
utils.NewBig(o.chainID))
@@ -184,11 +185,17 @@ func (o *ORM) InsertLogs(logs []Log, qopts ...pg.QOpt) error {
end = len(logs)
}
- err := q.ExecQNamed(`INSERT INTO evm_logs
+ err := q.ExecQNamed(`INSERT INTO evm.logs
(evm_chain_id, log_index, block_hash, block_number, block_timestamp, address, event_sig, topics, tx_hash, data, created_at) VALUES
(:evm_chain_id, :log_index, :block_hash, :block_number, :block_timestamp, :address, :event_sig, :topics, :tx_hash, :data, NOW()) ON CONFLICT DO NOTHING`, logs[start:end])
if err != nil {
+ if errors.Is(err, context.DeadlineExceeded) && batchInsertSize > 500 {
+ // In case of DB timeouts, try to insert again with a smaller batch upto a limit
+ batchInsertSize /= 2
+ i -= batchInsertSize // counteract +=batchInsertSize on next loop iteration
+ continue
+ }
return err
}
}
@@ -199,7 +206,7 @@ func (o *ORM) InsertLogs(logs []Log, qopts ...pg.QOpt) error {
func (o *ORM) SelectLogsByBlockRange(start, end int64) ([]Log, error) {
var logs []Log
err := o.q.Select(&logs, `
- SELECT * FROM evm_logs
+ SELECT * FROM evm.logs
WHERE block_number >= $1 AND block_number <= $2 AND evm_chain_id = $3
ORDER BY (block_number, log_index, created_at)`, start, end, utils.NewBig(o.chainID))
if err != nil {
@@ -213,10 +220,10 @@ func (o *ORM) SelectLogsByBlockRangeFilter(start, end int64, address common.Addr
var logs []Log
q := o.q.WithOpts(qopts...)
err := q.Select(&logs, `
- SELECT * FROM evm_logs
- WHERE evm_logs.block_number >= $1 AND evm_logs.block_number <= $2 AND evm_logs.evm_chain_id = $3
+ SELECT * FROM evm.logs
+ WHERE evm.logs.block_number >= $1 AND evm.logs.block_number <= $2 AND evm.logs.evm_chain_id = $3
AND address = $4 AND event_sig = $5
- ORDER BY (evm_logs.block_number, evm_logs.log_index)`, start, end, utils.NewBig(o.chainID), address, eventSig.Bytes())
+ ORDER BY (evm.logs.block_number, evm.logs.log_index)`, start, end, utils.NewBig(o.chainID), address, eventSig.Bytes())
if err != nil {
return nil, err
}
@@ -228,12 +235,12 @@ func (o *ORM) SelectLogsCreatedAfter(eventSig []byte, address common.Address, af
var logs []Log
q := o.q.WithOpts(qopts...)
err := q.Select(&logs, `
- SELECT * FROM evm_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)
+ 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)
if err != nil {
return nil, err
@@ -260,12 +267,12 @@ func (o *ORM) SelectLogsWithSigsByBlockRangeFilter(start, end int64, address com
`
SELECT
*
-FROM evm_logs
-WHERE evm_logs.block_number BETWEEN :start AND :end
- AND evm_logs.evm_chain_id = :chainid
- AND evm_logs.address = :address
- AND evm_logs.event_sig IN (:EventSigs)
-ORDER BY (evm_logs.block_number, evm_logs.log_index)`, a)
+FROM evm.logs
+WHERE evm.logs.block_number BETWEEN :start AND :end
+ AND evm.logs.evm_chain_id = :chainid
+ AND evm.logs.address = :address
+ AND evm.logs.event_sig IN (:EventSigs)
+ORDER BY (evm.logs.block_number, evm.logs.log_index)`, a)
if err != nil {
return nil, errors.Wrap(err, "sqlx Named")
}
@@ -285,7 +292,7 @@ func (o *ORM) GetBlocksRange(start uint64, end uint64, qopts ...pg.QOpt) ([]LogP
var blocks []LogPollerBlock
q := o.q.WithOpts(qopts...)
err := q.Select(&blocks, `
- SELECT * FROM evm_log_poller_blocks
+ SELECT * FROM evm.log_poller_blocks
WHERE block_number >= $1 AND block_number <= $2 AND evm_chain_id = $3
ORDER BY block_number ASC`, start, end, utils.NewBig(o.chainID))
if err != nil {
@@ -302,13 +309,13 @@ func (o *ORM) SelectLatestLogEventSigsAddrsWithConfs(fromBlock int64, addresses
q := o.q.WithOpts(qopts...)
err := q.Select(&logs, `
- SELECT * FROM evm_logs WHERE (block_number, address, event_sig) IN (
- SELECT MAX(block_number), address, event_sig FROM evm_logs
+ SELECT * FROM evm.logs WHERE (block_number, address, event_sig) IN (
+ SELECT MAX(block_number), address, event_sig FROM evm.logs
WHERE evm_chain_id = $1 AND
event_sig = ANY($2) AND
address = ANY($3) AND
block_number > $4 AND
- block_number <= (SELECT COALESCE(block_number, 0) FROM evm_log_poller_blocks WHERE evm_chain_id = $1 ORDER BY block_number DESC LIMIT 1) - $5
+ block_number <= (SELECT COALESCE(block_number, 0) FROM evm.log_poller_blocks WHERE evm_chain_id = $1 ORDER BY block_number DESC LIMIT 1) - $5
GROUP BY event_sig, address
)
ORDER BY block_number ASC
@@ -327,12 +334,12 @@ func (o *ORM) SelectLatestBlockNumberEventSigsAddrsWithConfs(fromBlock int64, ev
q := o.q.WithOpts(qopts...)
err := q.Get(&blockNumber, `
- SELECT COALESCE(MAX(block_number), 0) FROM evm_logs
+ SELECT COALESCE(MAX(block_number), 0) FROM evm.logs
WHERE evm_chain_id = $1 AND
event_sig = ANY($2) AND
address = ANY($3) AND
block_number > $4 AND
- block_number <= (SELECT COALESCE(block_number, 0) FROM evm_log_poller_blocks WHERE evm_chain_id = $1 ORDER BY block_number DESC LIMIT 1) - $5`,
+ block_number <= (SELECT COALESCE(block_number, 0) FROM evm.log_poller_blocks WHERE evm_chain_id = $1 ORDER BY block_number DESC LIMIT 1) - $5`,
o.chainID.Int64(), sigs, addrs, fromBlock, confs)
if err != nil {
return 0, err
@@ -344,13 +351,13 @@ func (o *ORM) SelectDataWordRange(address common.Address, eventSig common.Hash,
var logs []Log
q := o.q.WithOpts(qopts...)
err := q.Select(&logs,
- `SELECT * FROM evm_logs
- WHERE evm_logs.evm_chain_id = $1
+ `SELECT * FROM evm.logs
+ WHERE evm.logs.evm_chain_id = $1
AND address = $2 AND event_sig = $3
AND substring(data from 32*$4+1 for 32) >= $5
AND substring(data from 32*$4+1 for 32) <= $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 (evm_logs.block_number, evm_logs.log_index)`, utils.NewBig(o.chainID), address, eventSig.Bytes(), wordIndex, wordValueMin.Bytes(), wordValueMax.Bytes(), confs)
+ AND block_number <= (SELECT COALESCE(block_number, 0) FROM evm.log_poller_blocks WHERE evm_chain_id = $1 ORDER BY block_number DESC LIMIT 1) - $7
+ ORDER BY (evm.logs.block_number, evm.logs.log_index)`, utils.NewBig(o.chainID), address, eventSig.Bytes(), wordIndex, wordValueMin.Bytes(), wordValueMax.Bytes(), confs)
if err != nil {
return nil, err
}
@@ -361,12 +368,12 @@ func (o *ORM) SelectDataWordGreaterThan(address common.Address, eventSig common.
var logs []Log
q := o.q.WithOpts(qopts...)
err := q.Select(&logs,
- `SELECT * FROM evm_logs
- WHERE evm_logs.evm_chain_id = $1
+ `SELECT * FROM evm.logs
+ WHERE evm.logs.evm_chain_id = $1
AND address = $2 AND event_sig = $3
AND substring(data from 32*$4+1 for 32) >= $5
- AND block_number <= (SELECT COALESCE(block_number, 0) FROM evm_log_poller_blocks WHERE evm_chain_id = $1 ORDER BY block_number DESC LIMIT 1) - $6
- ORDER BY (evm_logs.block_number, evm_logs.log_index)`, utils.NewBig(o.chainID), address, eventSig.Bytes(), wordIndex, wordValueMin.Bytes(), confs)
+ AND block_number <= (SELECT COALESCE(block_number, 0) FROM evm.log_poller_blocks WHERE evm_chain_id = $1 ORDER BY block_number DESC LIMIT 1) - $6
+ ORDER BY (evm.logs.block_number, evm.logs.log_index)`, utils.NewBig(o.chainID), address, eventSig.Bytes(), wordIndex, wordValueMin.Bytes(), confs)
if err != nil {
return nil, err
}
@@ -381,12 +388,37 @@ func (o *ORM) SelectIndexLogsTopicGreaterThan(address common.Address, eventSig c
var logs []Log
q := o.q.WithOpts(qopts...)
err := q.Select(&logs,
- `SELECT * FROM evm_logs
- WHERE evm_logs.evm_chain_id = $1
+ `SELECT * FROM evm.logs
+ WHERE evm.logs.evm_chain_id = $1
AND address = $2 AND event_sig = $3
AND topics[$4] >= $5
- AND block_number <= (SELECT COALESCE(block_number, 0) FROM evm_log_poller_blocks WHERE evm_chain_id = $1 ORDER BY block_number DESC LIMIT 1) - $6
- ORDER BY (evm_logs.block_number, evm_logs.log_index)`, utils.NewBig(o.chainID), address, eventSig.Bytes(), topicIndex+1, topicValueMin.Bytes(), confs)
+ AND block_number <= (SELECT COALESCE(block_number, 0) FROM evm.log_poller_blocks WHERE evm_chain_id = $1 ORDER BY block_number DESC LIMIT 1) - $6
+ ORDER BY (evm.logs.block_number, evm.logs.log_index)`, utils.NewBig(o.chainID), address, eventSig.Bytes(), topicIndex+1, topicValueMin.Bytes(), confs)
+ if err != nil {
+ return nil, err
+ }
+ 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) {
+ var logs []Log
+ q := o.q.WithOpts(qopts...)
+ err := q.Transaction(func(tx pg.Queryer) error {
+ // We want to mimic the behaviour of the ETH RPC which errors if blockhash not found.
+ var block LogPollerBlock
+ if err := tx.Get(&block,
+ `SELECT * FROM evm.log_poller_blocks
+ WHERE evm_chain_id = $1 AND block_hash = $2`, utils.NewBig(o.chainID), untilBlockHash); err != nil {
+ return err
+ }
+ return q.Select(&logs,
+ `SELECT * FROM evm.logs
+ WHERE evm_chain_id = $1
+ AND address = $2 AND event_sig = $3
+ AND substring(data from 32*$4+1 for 32) >= $5
+ AND block_number <= $6
+ ORDER BY (block_number, log_index)`, utils.NewBig(o.chainID), address, eventSig.Bytes(), wordIndex, wordValueMin.Bytes(), block.BlockNumber)
+ })
if err != nil {
return nil, err
}
@@ -401,13 +433,13 @@ func (o *ORM) SelectIndexLogsTopicRange(address common.Address, eventSig common.
var logs []Log
q := o.q.WithOpts(qopts...)
err := q.Select(&logs,
- `SELECT * FROM evm_logs
- WHERE evm_logs.evm_chain_id = $1
+ `SELECT * FROM evm.logs
+ WHERE evm.logs.evm_chain_id = $1
AND address = $2 AND event_sig = $3
AND topics[$4] >= $5
AND topics[$4] <= $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 (evm_logs.block_number, evm_logs.log_index)`, utils.NewBig(o.chainID), address, eventSig.Bytes(), topicIndex+1, topicValueMin.Bytes(), topicValueMax.Bytes(), confs)
+ AND block_number <= (SELECT COALESCE(block_number, 0) FROM evm.log_poller_blocks WHERE evm_chain_id = $1 ORDER BY block_number DESC LIMIT 1) - $7
+ ORDER BY (evm.logs.block_number, evm.logs.log_index)`, utils.NewBig(o.chainID), address, eventSig.Bytes(), topicIndex+1, topicValueMin.Bytes(), topicValueMax.Bytes(), confs)
if err != nil {
return nil, err
}
@@ -424,12 +456,12 @@ func (o *ORM) SelectIndexedLogs(address common.Address, eventSig common.Hash, to
topicValuesBytes := concatBytes(topicValues)
// Add 1 since postgresql arrays are 1-indexed.
err := q.Select(&logs, `
- SELECT * FROM evm_logs
- WHERE evm_logs.evm_chain_id = $1
+ SELECT * FROM evm.logs
+ WHERE evm.logs.evm_chain_id = $1
AND address = $2 AND event_sig = $3
AND topics[$4] = ANY($5)
- AND block_number <= (SELECT COALESCE(block_number, 0) FROM evm_log_poller_blocks WHERE evm_chain_id = $1 ORDER BY block_number DESC LIMIT 1) - $6
- ORDER BY (evm_logs.block_number, evm_logs.log_index)`, utils.NewBig(o.chainID), address, eventSig.Bytes(), topicIndex+1, topicValuesBytes, confs)
+ AND block_number <= (SELECT COALESCE(block_number, 0) FROM evm.log_poller_blocks WHERE evm_chain_id = $1 ORDER BY block_number DESC LIMIT 1) - $6
+ ORDER BY (evm.logs.block_number, evm.logs.log_index)`, utils.NewBig(o.chainID), address, eventSig.Bytes(), topicIndex+1, topicValuesBytes, confs)
if err != nil {
return nil, err
}
@@ -446,11 +478,11 @@ func (o *ORM) SelectIndexedLogsByBlockRangeFilter(start, end int64, address comm
topicValuesBytes := concatBytes(topicValues)
q := o.q.WithOpts(qopts...)
err := q.Select(&logs, `
- SELECT * FROM evm_logs
- WHERE evm_logs.block_number >= $1 AND evm_logs.block_number <= $2 AND evm_logs.evm_chain_id = $3
+ SELECT * FROM evm.logs
+ WHERE evm.logs.block_number >= $1 AND evm.logs.block_number <= $2 AND evm.logs.evm_chain_id = $3
AND address = $4 AND event_sig = $5
AND topics[$6] = ANY($7)
- ORDER BY (evm_logs.block_number, evm_logs.log_index)`, start, end, utils.NewBig(o.chainID), address, eventSig.Bytes(), topicIndex+1, topicValuesBytes)
+ ORDER BY (evm.logs.block_number, evm.logs.log_index)`, start, end, utils.NewBig(o.chainID), address, eventSig.Bytes(), topicIndex+1, topicValuesBytes)
if err != nil {
return nil, err
}
@@ -471,12 +503,12 @@ func (o *ORM) SelectIndexedLogsCreatedAfter(address common.Address, eventSig com
topicValuesBytes := concatBytes(topicValues)
// Add 1 since postgresql arrays are 1-indexed.
err := q.Select(&logs, `
- SELECT * FROM evm_logs
- WHERE evm_logs.evm_chain_id = $1
+ SELECT * FROM evm.logs
+ WHERE evm.logs.evm_chain_id = $1
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
+ AND block_number <= (SELECT COALESCE(block_number, 0) FROM evm.log_poller_blocks WHERE evm_chain_id = $1 ORDER BY block_number DESC LIMIT 1) - $7
ORDER BY created_at ASC`, utils.NewBig(o.chainID), address, eventSig.Bytes(), topicIndex+1, topicValuesBytes, after, confs)
if err != nil {
return nil, err
@@ -484,6 +516,22 @@ func (o *ORM) SelectIndexedLogsCreatedAfter(address common.Address, eventSig com
return logs, nil
}
+func (o *ORM) SelectIndexedLogsByTxHash(eventSig common.Hash, txHash common.Hash, qopts ...pg.QOpt) ([]Log, error) {
+ q := o.q.WithOpts(qopts...)
+ var logs []Log
+ err := q.Select(&logs, `
+ SELECT * FROM evm.logs
+ WHERE evm.logs.evm_chain_id = $1
+ AND tx_hash = $2
+ AND event_sig = $3
+ ORDER BY (evm.logs.block_number, evm.logs.log_index)`,
+ utils.NewBig(o.chainID), txHash.Bytes(), eventSig.Bytes())
+ if err != nil {
+ return nil, err
+ }
+ return logs, nil
+}
+
// 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) {
if err := validateTopicIndex(topicIndex); err != nil {
@@ -495,25 +543,25 @@ func (o *ORM) SelectIndexedLogsWithSigsExcluding(sigA, sigB common.Hash, topicIn
err := q.Select(&logs, `
SELECT *
- FROM evm_logs
+ FROM evm.logs
WHERE evm_chain_id = $1
AND address = $2
AND event_sig = $3
AND block_number BETWEEN $6 AND $7
- AND block_number <= (SELECT COALESCE(block_number, 0) FROM evm_log_poller_blocks WHERE evm_chain_id = $1 ORDER BY block_number DESC LIMIT 1) - $8
+ AND block_number <= (SELECT COALESCE(block_number, 0) FROM evm.log_poller_blocks WHERE evm_chain_id = $1 ORDER BY block_number DESC LIMIT 1) - $8
EXCEPT
SELECT a.*
- FROM evm_logs AS a
- INNER JOIN evm_logs B
+ FROM evm.logs AS a
+ INNER JOIN evm.logs B
ON a.evm_chain_id = b.evm_chain_id
AND a.address = b.address
AND a.topics[$5] = b.topics[$5]
AND a.event_sig = $3
AND b.event_sig = $4
AND b.block_number BETWEEN $6 AND $7
- AND b.block_number <= (SELECT COALESCE(block_number, 0) FROM evm_log_poller_blocks WHERE evm_chain_id = $1 ORDER BY block_number DESC LIMIT 1) - $8
+ AND b.block_number <= (SELECT COALESCE(block_number, 0) FROM evm.log_poller_blocks WHERE evm_chain_id = $1 ORDER BY block_number DESC LIMIT 1) - $8
ORDER BY block_number,log_index ASC
`, utils.NewBig(o.chainID), address, sigA.Bytes(), sigB.Bytes(), topicIndex+1, startBlock, endBlock, confs)
diff --git a/core/chains/evm/logpoller/orm_test.go b/core/chains/evm/logpoller/orm_test.go
index 73128c311d8..28f3e8da8e6 100644
--- a/core/chains/evm/logpoller/orm_test.go
+++ b/core/chains/evm/logpoller/orm_test.go
@@ -502,6 +502,72 @@ func TestORM_IndexedLogs(t *testing.T) {
assert.Equal(t, 1, len(lgs))
}
+func TestORM_SelectIndexedLogsByTxHash(t *testing.T) {
+ th := SetupTH(t, 0, 3, 2)
+ o1 := th.ORM
+ eventSig := common.HexToHash("0x1599")
+ txHash := common.HexToHash("0x1888")
+ addr := common.HexToAddress("0x1234")
+
+ require.NoError(t, o1.InsertBlock(common.HexToHash("0x1"), 1, time.Now()))
+ logs := []logpoller.Log{
+ {
+ EvmChainId: utils.NewBig(th.ChainID),
+ LogIndex: int64(0),
+ BlockHash: common.HexToHash("0x1"),
+ BlockNumber: int64(1),
+ EventSig: eventSig,
+ Topics: [][]byte{eventSig[:]},
+ Address: addr,
+ TxHash: txHash,
+ Data: logpoller.EvmWord(1).Bytes(),
+ },
+ {
+ EvmChainId: utils.NewBig(th.ChainID),
+ LogIndex: int64(1),
+ BlockHash: common.HexToHash("0x1"),
+ BlockNumber: int64(1),
+ EventSig: eventSig,
+ Topics: [][]byte{eventSig[:]},
+ Address: addr,
+ TxHash: txHash,
+ Data: append(logpoller.EvmWord(2).Bytes(), logpoller.EvmWord(3).Bytes()...),
+ },
+ // Different txHash
+ {
+ EvmChainId: utils.NewBig(th.ChainID),
+ LogIndex: int64(2),
+ BlockHash: common.HexToHash("0x1"),
+ BlockNumber: int64(1),
+ EventSig: eventSig,
+ Topics: [][]byte{eventSig[:]},
+ Address: addr,
+ TxHash: common.HexToHash("0x1889"),
+ Data: append(logpoller.EvmWord(2).Bytes(), logpoller.EvmWord(3).Bytes()...),
+ },
+ // Different eventSig
+ {
+ EvmChainId: utils.NewBig(th.ChainID),
+ LogIndex: int64(3),
+ BlockHash: common.HexToHash("0x1"),
+ BlockNumber: int64(1),
+ EventSig: common.HexToHash("0x1600"),
+ Topics: [][]byte{eventSig[:]},
+ Address: addr,
+ TxHash: txHash,
+ Data: append(logpoller.EvmWord(2).Bytes(), logpoller.EvmWord(3).Bytes()...),
+ },
+ }
+ require.NoError(t, o1.InsertLogs(logs))
+
+ retrievedLogs, err := o1.SelectIndexedLogsByTxHash(eventSig, txHash)
+ require.NoError(t, err)
+
+ require.Equal(t, 2, len(retrievedLogs))
+ require.Equal(t, retrievedLogs[0].LogIndex, logs[0].LogIndex)
+ require.Equal(t, retrievedLogs[1].LogIndex, logs[1].LogIndex)
+}
+
func TestORM_DataWords(t *testing.T) {
th := SetupTH(t, 2, 3, 2)
o1 := th.ORM
@@ -563,6 +629,21 @@ func TestORM_DataWords(t *testing.T) {
lgs, err = o1.SelectDataWordGreaterThan(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"))
+ 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"))
+ 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"))
+ require.NoError(t, err)
+ assert.Equal(t, 2, len(lgs))
}
func TestORM_SelectLogsWithSigsByBlockRangeFilter(t *testing.T) {
diff --git a/core/chains/evm/mocks/chain.go b/core/chains/evm/mocks/chain.go
index 081d18edc01..bf4d1581e22 100644
--- a/core/chains/evm/mocks/chain.go
+++ b/core/chains/evm/mocks/chain.go
@@ -8,6 +8,8 @@ import (
common "github.com/ethereum/go-ethereum/common"
client "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client"
+ commontypes "github.com/smartcontractkit/chainlink/v2/common/types"
+
config "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config"
context "context"
@@ -28,7 +30,7 @@ import (
txmgr "github.com/smartcontractkit/chainlink/v2/common/txmgr"
- types "github.com/smartcontractkit/chainlink/v2/common/types"
+ types "github.com/smartcontractkit/chainlink-relay/pkg/types"
)
// Chain is an autogenerated mock type for the Chain type
@@ -114,16 +116,40 @@ func (_m *Chain) GasEstimator() gas.EvmFeeEstimator {
return r0
}
+// GetChainStatus provides a mock function with given fields: ctx
+func (_m *Chain) GetChainStatus(ctx context.Context) (types.ChainStatus, error) {
+ ret := _m.Called(ctx)
+
+ var r0 types.ChainStatus
+ var r1 error
+ if rf, ok := ret.Get(0).(func(context.Context) (types.ChainStatus, error)); ok {
+ return rf(ctx)
+ }
+ if rf, ok := ret.Get(0).(func(context.Context) types.ChainStatus); ok {
+ r0 = rf(ctx)
+ } else {
+ r0 = ret.Get(0).(types.ChainStatus)
+ }
+
+ if rf, ok := ret.Get(1).(func(context.Context) error); ok {
+ r1 = rf(ctx)
+ } else {
+ r1 = ret.Error(1)
+ }
+
+ return r0, r1
+}
+
// HeadBroadcaster provides a mock function with given fields:
-func (_m *Chain) HeadBroadcaster() types.HeadBroadcaster[*evmtypes.Head, common.Hash] {
+func (_m *Chain) HeadBroadcaster() commontypes.HeadBroadcaster[*evmtypes.Head, common.Hash] {
ret := _m.Called()
- var r0 types.HeadBroadcaster[*evmtypes.Head, common.Hash]
- if rf, ok := ret.Get(0).(func() types.HeadBroadcaster[*evmtypes.Head, common.Hash]); ok {
+ var r0 commontypes.HeadBroadcaster[*evmtypes.Head, common.Hash]
+ if rf, ok := ret.Get(0).(func() commontypes.HeadBroadcaster[*evmtypes.Head, common.Hash]); ok {
r0 = rf()
} else {
if ret.Get(0) != nil {
- r0 = ret.Get(0).(types.HeadBroadcaster[*evmtypes.Head, common.Hash])
+ r0 = ret.Get(0).(commontypes.HeadBroadcaster[*evmtypes.Head, common.Hash])
}
}
@@ -131,15 +157,15 @@ func (_m *Chain) HeadBroadcaster() types.HeadBroadcaster[*evmtypes.Head, common.
}
// HeadTracker provides a mock function with given fields:
-func (_m *Chain) HeadTracker() types.HeadTracker[*evmtypes.Head, common.Hash] {
+func (_m *Chain) HeadTracker() commontypes.HeadTracker[*evmtypes.Head, common.Hash] {
ret := _m.Called()
- var r0 types.HeadTracker[*evmtypes.Head, common.Hash]
- if rf, ok := ret.Get(0).(func() types.HeadTracker[*evmtypes.Head, common.Hash]); ok {
+ var r0 commontypes.HeadTracker[*evmtypes.Head, common.Hash]
+ if rf, ok := ret.Get(0).(func() commontypes.HeadTracker[*evmtypes.Head, common.Hash]); ok {
r0 = rf()
} else {
if ret.Get(0) != nil {
- r0 = ret.Get(0).(types.HeadTracker[*evmtypes.Head, common.Hash])
+ r0 = ret.Get(0).(commontypes.HeadTracker[*evmtypes.Head, common.Hash])
}
}
@@ -178,6 +204,46 @@ func (_m *Chain) ID() *big.Int {
return r0
}
+// ListNodeStatuses provides a mock function with given fields: ctx, pageSize, pageToken
+func (_m *Chain) ListNodeStatuses(ctx context.Context, pageSize int32, pageToken string) ([]types.NodeStatus, string, int, error) {
+ ret := _m.Called(ctx, pageSize, pageToken)
+
+ var r0 []types.NodeStatus
+ var r1 string
+ var r2 int
+ var r3 error
+ if rf, ok := ret.Get(0).(func(context.Context, int32, string) ([]types.NodeStatus, string, int, error)); ok {
+ return rf(ctx, pageSize, pageToken)
+ }
+ if rf, ok := ret.Get(0).(func(context.Context, int32, string) []types.NodeStatus); ok {
+ r0 = rf(ctx, pageSize, pageToken)
+ } else {
+ if ret.Get(0) != nil {
+ r0 = ret.Get(0).([]types.NodeStatus)
+ }
+ }
+
+ if rf, ok := ret.Get(1).(func(context.Context, int32, string) string); ok {
+ r1 = rf(ctx, pageSize, pageToken)
+ } else {
+ r1 = ret.Get(1).(string)
+ }
+
+ if rf, ok := ret.Get(2).(func(context.Context, int32, string) int); ok {
+ r2 = rf(ctx, pageSize, pageToken)
+ } else {
+ r2 = ret.Get(2).(int)
+ }
+
+ if rf, ok := ret.Get(3).(func(context.Context, int32, string) error); ok {
+ r3 = rf(ctx, pageSize, pageToken)
+ } else {
+ r3 = ret.Error(3)
+ }
+
+ return r0, r1, r2, r3
+}
+
// LogBroadcaster provides a mock function with given fields:
func (_m *Chain) LogBroadcaster() log.Broadcaster {
ret := _m.Called()
@@ -254,13 +320,13 @@ func (_m *Chain) Ready() error {
return r0
}
-// SendTx provides a mock function with given fields: ctx, from, to, amount, balanceCheck
-func (_m *Chain) SendTx(ctx context.Context, from string, to string, amount *big.Int, balanceCheck bool) error {
- ret := _m.Called(ctx, from, to, amount, balanceCheck)
+// Start provides a mock function with given fields: _a0
+func (_m *Chain) Start(_a0 context.Context) error {
+ ret := _m.Called(_a0)
var r0 error
- if rf, ok := ret.Get(0).(func(context.Context, string, string, *big.Int, bool) error); ok {
- r0 = rf(ctx, from, to, amount, balanceCheck)
+ if rf, ok := ret.Get(0).(func(context.Context) error); ok {
+ r0 = rf(_a0)
} else {
r0 = ret.Error(0)
}
@@ -268,13 +334,13 @@ func (_m *Chain) SendTx(ctx context.Context, from string, to string, amount *big
return r0
}
-// Start provides a mock function with given fields: _a0
-func (_m *Chain) Start(_a0 context.Context) error {
- ret := _m.Called(_a0)
+// Transact provides a mock function with given fields: ctx, from, to, amount, balanceCheck
+func (_m *Chain) Transact(ctx context.Context, from string, to string, amount *big.Int, balanceCheck bool) error {
+ ret := _m.Called(ctx, from, to, amount, balanceCheck)
var r0 error
- if rf, ok := ret.Get(0).(func(context.Context) error); ok {
- r0 = rf(_a0)
+ if rf, ok := ret.Get(0).(func(context.Context, string, string, *big.Int, bool) error); ok {
+ r0 = rf(ctx, from, to, amount, balanceCheck)
} else {
r0 = ret.Error(0)
}
diff --git a/core/chains/evm/mocks/legacy_chain_container.go b/core/chains/evm/mocks/legacy_chain_container.go
index fe906234f16..d8dfa209a08 100644
--- a/core/chains/evm/mocks/legacy_chain_container.go
+++ b/core/chains/evm/mocks/legacy_chain_container.go
@@ -30,32 +30,6 @@ func (_m *LegacyChainContainer) ChainNodeConfigs() types.Configs {
return r0
}
-// Default provides a mock function with given fields:
-func (_m *LegacyChainContainer) Default() (evm.Chain, error) {
- ret := _m.Called()
-
- var r0 evm.Chain
- var r1 error
- if rf, ok := ret.Get(0).(func() (evm.Chain, error)); ok {
- return rf()
- }
- if rf, ok := ret.Get(0).(func() evm.Chain); ok {
- r0 = rf()
- } else {
- if ret.Get(0) != nil {
- r0 = ret.Get(0).(evm.Chain)
- }
- }
-
- if rf, ok := ret.Get(1).(func() error); ok {
- r1 = rf()
- } else {
- r1 = ret.Error(1)
- }
-
- return r0, r1
-}
-
// Get provides a mock function with given fields: id
func (_m *LegacyChainContainer) Get(id string) (evm.Chain, error) {
ret := _m.Called(id)
@@ -128,11 +102,6 @@ func (_m *LegacyChainContainer) List(ids ...string) ([]evm.Chain, error) {
return r0, r1
}
-// SetDefault provides a mock function with given fields: _a0
-func (_m *LegacyChainContainer) SetDefault(_a0 evm.Chain) {
- _m.Called(_a0)
-}
-
// Slice provides a mock function with given fields:
func (_m *LegacyChainContainer) Slice() []evm.Chain {
ret := _m.Called()
diff --git a/core/chains/evm/monitor/balance.go b/core/chains/evm/monitor/balance.go
index 653f1b4bd0c..8dbd4ed8507 100644
--- a/core/chains/evm/monitor/balance.go
+++ b/core/chains/evm/monitor/balance.go
@@ -116,7 +116,7 @@ func (bm *balanceMonitor) updateBalance(ethBal assets.Eth, address gethCommon.Ad
bm.ethBalances[address] = ðBal
bm.ethBalancesMtx.Unlock()
- lgr := bm.logger.Named("balance_log").With(
+ lgr := bm.logger.Named("BalanceLog").With(
"address", address.Hex(),
"ethBalance", ethBal.String(),
"weiBalance", ethBal.ToInt())
diff --git a/core/chains/evm/txmgr/broadcaster_test.go b/core/chains/evm/txmgr/broadcaster_test.go
index 2e3a1e0f731..e1133e8ef21 100644
--- a/core/chains/evm/txmgr/broadcaster_test.go
+++ b/core/chains/evm/txmgr/broadcaster_test.go
@@ -58,24 +58,25 @@ func NewTestEthBroadcaster(
config evmconfig.ChainScopedConfig,
checkerFactory txmgr.TransmitCheckerFactory,
nonceAutoSync bool,
-) (*txmgr.Broadcaster, error) {
+) *txmgr.Broadcaster {
t.Helper()
- eventBroadcaster := cltest.NewEventBroadcaster(t, config.Database().URL())
- err := eventBroadcaster.Start(testutils.Context(t.(*testing.T)))
- require.NoError(t, err)
- t.Cleanup(func() { assert.NoError(t, eventBroadcaster.Close()) })
+ eb := cltest.NewEventBroadcaster(t, config.Database().URL())
+ ctx := testutils.Context(t)
+ require.NoError(t, eb.Start(ctx))
+ t.Cleanup(func() { assert.NoError(t, eb.Close()) })
+
lggr := logger.TestLogger(t)
ge := config.EVM().GasEstimator()
- estimator := gas.NewWrappedEvmEstimator(gas.NewFixedPriceEstimator(config.EVM().GasEstimator(), ge.BlockHistory(), lggr), ge.EIP1559DynamicFees())
+ estimator := gas.NewWrappedEvmEstimator(gas.NewFixedPriceEstimator(config.EVM().GasEstimator(), ge.BlockHistory(), lggr), ge.EIP1559DynamicFees(), nil)
txBuilder := txmgr.NewEvmTxAttemptBuilder(*ethClient.ConfiguredChainID(), ge, keyStore, estimator)
txNonceSyncer := txmgr.NewNonceSyncer(txStore, lggr, ethClient, keyStore)
- ethBroadcaster := txmgr.NewEvmBroadcaster(txStore, txmgr.NewEvmTxmClient(ethClient), txmgr.NewEvmTxmConfig(config.EVM()), txmgr.NewEvmTxmFeeConfig(config.EVM().GasEstimator()), config.EVM().Transactions(), config.Database().Listener(), keyStore, eventBroadcaster, txBuilder, txNonceSyncer, lggr, checkerFactory, nonceAutoSync)
+ ethBroadcaster := txmgr.NewEvmBroadcaster(txStore, txmgr.NewEvmTxmClient(ethClient), txmgr.NewEvmTxmConfig(config.EVM()), txmgr.NewEvmTxmFeeConfig(config.EVM().GasEstimator()), config.EVM().Transactions(), config.Database().Listener(), keyStore, eb, txBuilder, txNonceSyncer, lggr, checkerFactory, nonceAutoSync)
// Mark instance as test
ethBroadcaster.XXXTestDisableUnstartedTxAutoProcessing()
- err = ethBroadcaster.Start(testutils.Context(t))
+ require.NoError(t, ethBroadcaster.Start(ctx))
t.Cleanup(func() { assert.NoError(t, ethBroadcaster.Close()) })
- return ethBroadcaster, err
+ return ethBroadcaster
}
func TestEthBroadcaster_Lifecycle(t *testing.T) {
@@ -150,8 +151,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_Success(t *testing.T) {
evmcfg := evmtest.NewChainScopedConfig(t, cfg)
checkerFactory := &txmgr.CheckerFactory{Client: ethClient}
- eb, err := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, evmcfg, checkerFactory, false)
- require.NoError(t, err)
+ eb := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, evmcfg, checkerFactory, false)
toAddress := gethCommon.HexToAddress("0x6C03DDA95a2AEd917EeCc6eddD4b9D16E6380411")
timeNow := time.Now()
@@ -351,8 +351,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_Success(t *testing.T) {
c.EVM[0].GasEstimator.PriceMax = assets.NewWeiI(rnd + 2)
})
evmcfg = evmtest.NewChainScopedConfig(t, cfg)
- eb, err = NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, evmcfg, checkerFactory, false)
- require.NoError(t, err)
+ eb = NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, evmcfg, checkerFactory, false)
t.Run("sends transactions with type 0x2 in EIP-1559 mode", func(t *testing.T) {
ethClient.On("SendTransactionReturnCode", mock.Anything, mock.MatchedBy(func(tx *gethTypes.Transaction) bool {
@@ -500,8 +499,7 @@ func TestEthBroadcaster_TransmitChecking(t *testing.T) {
evmcfg := evmtest.NewChainScopedConfig(t, cfg)
checkerFactory := &testCheckerFactory{}
- eb, err := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, evmcfg, checkerFactory, false)
- require.NoError(t, err)
+ eb := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, evmcfg, checkerFactory, false)
checker := txmgr.TransmitCheckerSpec{
CheckerType: txmgr.TransmitCheckerTypeSimulate,
@@ -620,7 +618,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_OptimisticLockingOnEthTx(t *testi
}
// Simulate a "PruneQueue" call
- assert.NoError(t, utils.JustError(db.Exec(`DELETE FROM eth_txes WHERE state = 'unstarted'`)))
+ assert.NoError(t, utils.JustError(db.Exec(`DELETE FROM evm.txes WHERE state = 'unstarted'`)))
close(chBlock)
}()
@@ -648,8 +646,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_Success_WithMultiplier(t *testing
ethClient := evmtest.NewEthClientMockWithDefaultChain(t)
- eb, err := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, evmcfg, &testCheckerFactory{}, false)
- require.NoError(t, err)
+ eb := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, evmcfg, &testCheckerFactory{}, false)
ethClient.On("SendTransactionReturnCode", mock.Anything, mock.MatchedBy(func(tx *gethTypes.Transaction) bool {
assert.Equal(t, int(1600), int(tx.Gas()))
@@ -729,11 +726,10 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_ResumingFromCrash(t *testing.T) {
ethClient := evmtest.NewEthClientMockWithDefaultChain(t)
- eb, err := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, evmcfg, &testCheckerFactory{}, false)
- require.NoError(t, err)
+ eb := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, evmcfg, &testCheckerFactory{}, false)
// Crashed right after we commit the database transaction that saved
- // the nonce to the eth_tx so evm_key_states.next_nonce has not been
+ // the nonce to the eth_tx so evm.key_states.next_nonce has not been
// incremented yet
inProgressEthTx := cltest.MustInsertInProgressEthTxWithAttempt(t, txStore, firstNonce, fromAddress)
@@ -768,8 +764,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_ResumingFromCrash(t *testing.T) {
ethClient := evmtest.NewEthClientMockWithDefaultChain(t)
- eb, err := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, evmcfg, &testCheckerFactory{}, false)
- require.NoError(t, err)
+ eb := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, evmcfg, &testCheckerFactory{}, false)
// Crashed right after we commit the database transaction that saved
// the nonce to the eth_tx so keys.next_nonce has not been
@@ -807,8 +802,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_ResumingFromCrash(t *testing.T) {
ethClient := evmtest.NewEthClientMockWithDefaultChain(t)
- eb, err := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, evmcfg, &testCheckerFactory{}, false)
- require.NoError(t, err)
+ eb := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, evmcfg, &testCheckerFactory{}, false)
// Crashed right after we commit the database transaction that saved
// the nonce to the eth_tx so keys.next_nonce has not been
@@ -845,8 +839,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_ResumingFromCrash(t *testing.T) {
ethClient := evmtest.NewEthClientMockWithDefaultChain(t)
- eb, err := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, evmcfg, &testCheckerFactory{}, false)
- require.NoError(t, err)
+ eb := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, evmcfg, &testCheckerFactory{}, false)
// Crashed right after we commit the database transaction that saved
// the nonce to the eth_tx so keys.next_nonce has not been
@@ -885,8 +878,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_ResumingFromCrash(t *testing.T) {
ethClient := evmtest.NewEthClientMockWithDefaultChain(t)
- eb, err := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, evmcfg, &testCheckerFactory{}, false)
- require.NoError(t, err)
+ eb := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, evmcfg, &testCheckerFactory{}, false)
// Crashed right after we commit the database transaction that saved
// the nonce to the eth_tx so keys.next_nonce has not been
@@ -929,8 +921,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_ResumingFromCrash(t *testing.T) {
ethClient := evmtest.NewEthClientMockWithDefaultChain(t)
- eb, err := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, evmcfg, &testCheckerFactory{}, false)
- require.NoError(t, err)
+ eb := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, evmcfg, &testCheckerFactory{}, false)
// Crashed right after we commit the database transaction that saved
// the nonce to the eth_tx so keys.next_nonce has not been
@@ -996,8 +987,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_Errors(t *testing.T) {
evmcfg := evmtest.NewChainScopedConfig(t, cfg)
ethClient := evmtest.NewEthClientMockWithDefaultChain(t)
- eb, err := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, evmcfg, &testCheckerFactory{}, false)
- require.NoError(t, err)
+ eb := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, evmcfg, &testCheckerFactory{}, false)
require.NoError(t, utils.JustError(db.Exec(`SET CONSTRAINTS pipeline_runs_pipeline_spec_id_fkey DEFERRED`)))
@@ -1019,7 +1009,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_Errors(t *testing.T) {
// We assume success and hand off to eth confirmer to eventually mark it as failed
var latestID int64
var etx1 txmgr.Tx
- require.NoError(t, db.Get(&latestID, "SELECT max(id) FROM eth_txes"))
+ require.NoError(t, db.Get(&latestID, "SELECT max(id) FROM evm.txes"))
etx1, err = txStore.FindTxWithAttempts(latestID)
require.NoError(t, err)
require.NotNil(t, etx1.BroadcastAt)
@@ -1066,7 +1056,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_Errors(t *testing.T) {
// Check that the key had its nonce reset
var nonce int64
- err := db.Get(&nonce, `SELECT next_nonce FROM evm_key_states WHERE address = $1 ORDER BY created_at ASC, id ASC`, fromAddress)
+ err = db.Get(&nonce, `SELECT next_nonce FROM evm.key_states WHERE address = $1 ORDER BY created_at ASC, id ASC`, fromAddress)
require.NoError(t, err)
// Saved NextNonce must be the same as before because this transaction
// was not accepted by the eth node and never can be
@@ -1133,10 +1123,9 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_Errors(t *testing.T) {
require.NoError(t, err)
t.Cleanup(func() { assert.NoError(t, eventBroadcaster.Close()) })
lggr := logger.TestLogger(t)
- estimator := gas.NewWrappedEvmEstimator(gas.NewFixedPriceEstimator(evmcfg.EVM().GasEstimator(), evmcfg.EVM().GasEstimator().BlockHistory(), lggr), evmcfg.EVM().GasEstimator().EIP1559DynamicFees())
+ estimator := gas.NewWrappedEvmEstimator(gas.NewFixedPriceEstimator(evmcfg.EVM().GasEstimator(), evmcfg.EVM().GasEstimator().BlockHistory(), lggr), evmcfg.EVM().GasEstimator().EIP1559DynamicFees(), nil)
txBuilder := txmgr.NewEvmTxAttemptBuilder(*ethClient.ConfiguredChainID(), evmcfg.EVM().GasEstimator(), ethKeyStore, estimator)
eb = txmgr.NewEvmBroadcaster(txStore, txmgr.NewEvmTxmClient(ethClient), txmgr.NewEvmTxmConfig(evmcfg.EVM()), txmgr.NewEvmTxmFeeConfig(evmcfg.EVM().GasEstimator()), evmcfg.EVM().Transactions(), evmcfg.Database().Listener(), ethKeyStore, eventBroadcaster, txBuilder, nil, lggr, &testCheckerFactory{}, false)
- require.NoError(t, err)
{
retryable, err := eb.ProcessUnstartedTxs(testutils.Context(t), fromAddress)
assert.NoError(t, err)
@@ -1184,7 +1173,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_Errors(t *testing.T) {
// Check that the key had its nonce reset
var nonce int64
- err := db.Get(&nonce, `SELECT next_nonce FROM evm_key_states WHERE address = $1 ORDER BY created_at ASC, id ASC`, fromAddress)
+ err = db.Get(&nonce, `SELECT next_nonce FROM evm.key_states WHERE address = $1 ORDER BY created_at ASC, id ASC`, fromAddress)
require.NoError(t, err)
// Saved NextNonce must be the same as before because this transaction
// was not accepted by the eth node and never can be
@@ -1474,8 +1463,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_Errors(t *testing.T) {
c.EVM[0].GasEstimator.BumpMin = assets.NewWeiI(0)
c.EVM[0].GasEstimator.BumpPercent = ptr[uint16](0)
}))
- eb2, err := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, evmcfg2, &testCheckerFactory{}, false)
- require.NoError(t, err)
+ eb2 := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, evmcfg2, &testCheckerFactory{}, false)
cltest.MustCreateUnstartedTx(t, txStore, fromAddress, toAddress, encodedPayload, gasLimit, value, &cltest.FixtureChainID)
// First was underpriced
@@ -1490,7 +1478,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_Errors(t *testing.T) {
assert.True(t, retryable)
// TEARDOWN: Clear out the unsent tx before the next test
- pgtest.MustExec(t, db, `DELETE FROM eth_txes WHERE nonce = $1`, localNextNonce)
+ pgtest.MustExec(t, db, `DELETE FROM evm.txes WHERE nonce = $1`, localNextNonce)
})
t.Run("eth tx is left in progress if eth node returns insufficient eth", func(t *testing.T) {
@@ -1521,7 +1509,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_Errors(t *testing.T) {
assert.Nil(t, attempt.BroadcastBeforeBlockNum)
})
- pgtest.MustExec(t, db, `DELETE FROM eth_txes`)
+ pgtest.MustExec(t, db, `DELETE FROM evm.txes`)
t.Run("eth tx is left in progress if nonce is too high", func(t *testing.T) {
localNextNonce := getLocalNextNonce(t, ethKeyStore, fromAddress)
@@ -1549,7 +1537,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_Errors(t *testing.T) {
assert.Equal(t, txmgrtypes.TxAttemptInProgress, attempt.State)
assert.Nil(t, attempt.BroadcastBeforeBlockNum)
- pgtest.MustExec(t, db, `DELETE FROM eth_txes`)
+ pgtest.MustExec(t, db, `DELETE FROM evm.txes`)
})
t.Run("eth node returns underpriced transaction and bumping gas doesn't increase it in EIP-1559 mode", func(t *testing.T) {
@@ -1565,8 +1553,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_Errors(t *testing.T) {
c.EVM[0].GasEstimator.BumpMin = assets.NewWeiI(0)
c.EVM[0].GasEstimator.BumpPercent = ptr[uint16](0)
}))
- eb2, err := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, evmcfg2, &testCheckerFactory{}, false)
- require.NoError(t, err)
+ eb2 := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, evmcfg2, &testCheckerFactory{}, false)
cltest.MustCreateUnstartedTx(t, txStore, fromAddress, toAddress, encodedPayload, gasLimit, value, &cltest.FixtureChainID)
underpricedError := "transaction underpriced"
localNextNonce := getLocalNextNonce(t, ethKeyStore, fromAddress)
@@ -1580,7 +1567,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_Errors(t *testing.T) {
require.Contains(t, err.Error(), "bumped gas tip cap of 1 wei is less than or equal to original gas tip cap of 1 wei")
assert.True(t, retryable)
- pgtest.MustExec(t, db, `DELETE FROM eth_txes`)
+ pgtest.MustExec(t, db, `DELETE FROM evm.txes`)
})
t.Run("eth node returns underpriced transaction in EIP-1559 mode, bumps until inclusion", func(t *testing.T) {
@@ -1596,8 +1583,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_Errors(t *testing.T) {
c.EVM[0].GasEstimator.EIP1559DynamicFees = ptr(true)
c.EVM[0].GasEstimator.TipCapDefault = assets.NewWeiI(0)
}))
- eb2, err := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, evmcfg2, &testCheckerFactory{}, false)
- require.NoError(t, err)
+ eb2 := NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, evmcfg2, &testCheckerFactory{}, false)
retryable, err := eb2.ProcessUnstartedTxs(testutils.Context(t), fromAddress)
require.Error(t, err)
@@ -1610,8 +1596,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_Errors(t *testing.T) {
c.EVM[0].GasEstimator.EIP1559DynamicFees = ptr(true)
c.EVM[0].GasEstimator.TipCapDefault = gasTipCapDefault
}))
- eb2, err = NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, evmcfg2, &testCheckerFactory{}, false)
- require.NoError(t, err)
+ eb2 = NewTestEthBroadcaster(t, txStore, ethClient, ethKeyStore, evmcfg2, &testCheckerFactory{}, false)
// Second was underpriced but above minimum
ethClient.On("SendTransactionReturnCode", mock.Anything, mock.MatchedBy(func(tx *gethTypes.Transaction) bool {
@@ -1631,7 +1616,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_Errors(t *testing.T) {
assert.False(t, retryable)
// TEARDOWN: Clear out the unsent tx before the next test
- pgtest.MustExec(t, db, `DELETE FROM eth_txes WHERE nonce = $1`, localNextNonce)
+ pgtest.MustExec(t, db, `DELETE FROM evm.txes WHERE nonce = $1`, localNextNonce)
})
}
@@ -1659,8 +1644,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_KeystoreErrors(t *testing.T) {
next, err := realKeystore.Eth().NextSequence(fromAddress, testutils.FixtureChainID)
require.NoError(t, err)
kst.On("NextSequence", fromAddress, testutils.FixtureChainID, mock.Anything).Return(next, nil).Once()
- eb, err := NewTestEthBroadcaster(t, txStore, ethClient, kst, evmcfg, &testCheckerFactory{}, false)
- require.NoError(t, err)
+ eb := NewTestEthBroadcaster(t, txStore, ethClient, kst, evmcfg, &testCheckerFactory{}, false)
t.Run("tx signing fails", func(t *testing.T) {
etx := cltest.MustCreateUnstartedTx(t, txStore, fromAddress, toAddress, encodedPayload, gasLimit, value, &cltest.FixtureChainID)
@@ -1687,7 +1671,7 @@ func TestEthBroadcaster_ProcessUnstartedEthTxs_KeystoreErrors(t *testing.T) {
// Check that the key did not have its nonce incremented
var nonce int64
- err = db.Get(&nonce, `SELECT next_nonce FROM evm_key_states WHERE address = $1 ORDER BY created_at ASC, id ASC`, fromAddress)
+ err = db.Get(&nonce, `SELECT next_nonce FROM evm.key_states WHERE address = $1 ORDER BY created_at ASC, id ASC`, fromAddress)
require.NoError(t, err)
require.Equal(t, int64(localNonce), nonce)
})
@@ -1719,7 +1703,7 @@ func TestEthBroadcaster_IncrementNextNonce(t *testing.T) {
// Nonce bumped to 1
var nonce int64
- err := db.Get(&nonce, `SELECT next_nonce FROM evm_key_states WHERE address = $1 ORDER BY created_at ASC, id ASC`, keyState.Address.Address())
+ err := db.Get(&nonce, `SELECT next_nonce FROM evm.key_states WHERE address = $1 ORDER BY created_at ASC, id ASC`, keyState.Address.Address())
require.NoError(t, err)
require.Equal(t, int64(1), nonce)
}
@@ -1734,8 +1718,7 @@ func TestEthBroadcaster_Trigger(t *testing.T) {
txStore := cltest.NewTestTxStore(t, db, cfg.Database())
evmcfg := evmtest.NewChainScopedConfig(t, cfg)
ethKeyStore := cltest.NewKeyStore(t, db, cfg.Database()).Eth()
- eb, err := NewTestEthBroadcaster(t, txStore, evmtest.NewEthClientMockWithDefaultChain(t), ethKeyStore, evmcfg, &testCheckerFactory{}, false)
- require.NoError(t, err)
+ eb := NewTestEthBroadcaster(t, txStore, evmtest.NewEthClientMockWithDefaultChain(t), ethKeyStore, evmcfg, &testCheckerFactory{}, false)
eb.Trigger(testutils.NewAddress())
eb.Trigger(testutils.NewAddress())
@@ -1787,8 +1770,8 @@ func TestEthBroadcaster_SyncNonce(t *testing.T) {
sub := pgmocks.NewSubscription(t)
sub.On("Events").Return(make(<-chan pg.Event))
sub.On("Close")
- eventBroadcaster.On("Subscribe", "insert_on_eth_txes", "").Return(sub, nil)
- estimator := gas.NewWrappedEvmEstimator(gas.NewFixedPriceEstimator(evmcfg.EVM().GasEstimator(), evmcfg.EVM().GasEstimator().BlockHistory(), lggr), evmcfg.EVM().GasEstimator().EIP1559DynamicFees())
+ eventBroadcaster.On("Subscribe", "evm.insert_on_txes", "").Return(sub, nil)
+ estimator := gas.NewWrappedEvmEstimator(gas.NewFixedPriceEstimator(evmcfg.EVM().GasEstimator(), evmcfg.EVM().GasEstimator().BlockHistory(), lggr), evmcfg.EVM().GasEstimator().EIP1559DynamicFees(), nil)
checkerFactory := &testCheckerFactory{}
ge := evmcfg.EVM().GasEstimator()
@@ -1824,12 +1807,12 @@ func TestEthBroadcaster_SyncNonce(t *testing.T) {
// Check keyState to make sure it has correct nonce assigned
var nonce int64
- err := db.Get(&nonce, `SELECT next_nonce FROM evm_key_states WHERE address = $1 ORDER BY created_at ASC, id ASC`, fromAddress)
+ err := db.Get(&nonce, `SELECT next_nonce FROM evm.key_states WHERE address = $1 ORDER BY created_at ASC, id ASC`, fromAddress)
require.NoError(t, err)
assert.Equal(t, int64(ethNodeNonce), nonce)
// The disabled key did not get updated
- err = db.Get(&nonce, `SELECT next_nonce FROM evm_key_states WHERE address = $1 ORDER BY created_at ASC, id ASC`, disabledAddress)
+ err = db.Get(&nonce, `SELECT next_nonce FROM evm.key_states WHERE address = $1 ORDER BY created_at ASC, id ASC`, disabledAddress)
require.NoError(t, err)
assert.Equal(t, int64(0), nonce)
})
@@ -1858,12 +1841,12 @@ func TestEthBroadcaster_SyncNonce(t *testing.T) {
// Check keyState to make sure it has correct nonce assigned
var nonce int64
- err := db.Get(&nonce, `SELECT next_nonce FROM evm_key_states WHERE address = $1 ORDER BY created_at ASC, id ASC`, fromAddress)
+ err := db.Get(&nonce, `SELECT next_nonce FROM evm.key_states WHERE address = $1 ORDER BY created_at ASC, id ASC`, fromAddress)
require.NoError(t, err)
assert.Equal(t, int64(ethNodeNonce), nonce)
// The disabled key did not get updated
- err = db.Get(&nonce, `SELECT next_nonce FROM evm_key_states WHERE address = $1 ORDER BY created_at ASC, id ASC`, disabledAddress)
+ err = db.Get(&nonce, `SELECT next_nonce FROM evm.key_states WHERE address = $1 ORDER BY created_at ASC, id ASC`, disabledAddress)
require.NoError(t, err)
assert.Equal(t, int64(0), nonce)
})
diff --git a/core/chains/evm/txmgr/confirmer_test.go b/core/chains/evm/txmgr/confirmer_test.go
index 3de0c1079bf..e0070e35b17 100644
--- a/core/chains/evm/txmgr/confirmer_test.go
+++ b/core/chains/evm/txmgr/confirmer_test.go
@@ -122,7 +122,7 @@ func TestEthConfirmer_Lifecycle(t *testing.T) {
estimator := gasmocks.NewEvmEstimator(t)
lggr := logger.TestLogger(t)
ge := config.EVM().GasEstimator()
- feeEstimator := gas.NewWrappedEvmEstimator(estimator, ge.EIP1559DynamicFees())
+ feeEstimator := gas.NewWrappedEvmEstimator(estimator, ge.EIP1559DynamicFees(), nil)
txBuilder := txmgr.NewEvmTxAttemptBuilder(*ethClient.ConfiguredChainID(), ge, ethKeyStore, feeEstimator)
ec := txmgr.NewEvmConfirmer(txStore, txmgr.NewEvmTxmClient(ethClient), txmgr.NewEvmTxmConfig(config.EVM()), txmgr.NewEvmTxmFeeConfig(ge), config.EVM().Transactions(), config.Database(), ethKeyStore, txBuilder, lggr)
ctx := testutils.Context(t)
@@ -824,7 +824,7 @@ func TestEthConfirmer_CheckForReceipts_confirmed_missing_receipt_scoped_to_key(t
etx2_9 := cltest.MustInsertUnconfirmedEthTx(t, txStore, 3, fromAddress1_2)
// there also happens to be a confirmed tx with a higher nonce from a different chain in the DB
etx_other_chain := cltest.MustInsertUnconfirmedEthTx(t, txStore, 8, fromAddress2_1)
- pgtest.MustExec(t, db, `UPDATE eth_txes SET state='confirmed' WHERE id = $1`, etx_other_chain.ID)
+ pgtest.MustExec(t, db, `UPDATE evm.txes SET state='confirmed' WHERE id = $1`, etx_other_chain.ID)
attempt2_9 := newBroadcastLegacyEthTxAttempt(t, etx2_9.ID, int64(1))
require.NoError(t, txStore.InsertTxAttempt(&attempt2_9))
@@ -914,7 +914,7 @@ func TestEthConfirmer_CheckForReceipts_confirmed_missing_receipt(t *testing.T) {
attempt3_1 := newBroadcastLegacyEthTxAttempt(t, etx3.ID, int64(1))
require.NoError(t, txStore.InsertTxAttempt(&attempt3_1))
- pgtest.MustExec(t, db, `UPDATE eth_tx_attempts SET broadcast_before_block_num = 41 WHERE broadcast_before_block_num IS NULL`)
+ pgtest.MustExec(t, db, `UPDATE evm.tx_attempts SET broadcast_before_block_num = 41 WHERE broadcast_before_block_num IS NULL`)
t.Run("marks buried eth_txes as 'confirmed_missing_receipt'", func(t *testing.T) {
txmReceipt0 := evmtypes.Receipt{
@@ -1399,8 +1399,9 @@ func TestEthConfirmer_FindTxsRequiringRebroadcast(t *testing.T) {
etx1 := cltest.MustInsertUnconfirmedEthTxWithBroadcastLegacyAttempt(t, txStore, nonce, fromAddress)
nonce++
attempt1_1 := etx1.TxAttempts[0]
- dbAttempt := txmgr.DbEthTxAttemptFromEthTxAttempt(&attempt1_1)
- require.NoError(t, db.Get(&dbAttempt, `UPDATE eth_tx_attempts SET broadcast_before_block_num=$1 WHERE id=$2 RETURNING *`, tooNew, attempt1_1.ID))
+ 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
attempt1_2.TxFee = gas.EvmFee{Legacy: assets.NewWeiI(30000)}
@@ -1416,8 +1417,9 @@ func TestEthConfirmer_FindTxsRequiringRebroadcast(t *testing.T) {
etx2 := cltest.MustInsertUnconfirmedEthTxWithBroadcastLegacyAttempt(t, txStore, nonce, fromAddress)
nonce++
attempt2_1 := etx2.TxAttempts[0]
- dbAttempt = txmgr.DbEthTxAttemptFromEthTxAttempt(&attempt2_1)
- require.NoError(t, db.Get(&dbAttempt, `UPDATE eth_tx_attempts SET broadcast_before_block_num=$1 WHERE id=$2 RETURNING *`, tooNew, attempt2_1.ID))
+ 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) {
etxs, err := ec.FindTxsRequiringRebroadcast(testutils.Context(t), lggr, evmFromAddress, currentHead, gasBumpThreshold, 10, 0, &cltest.FixtureChainID)
@@ -1463,14 +1465,16 @@ func TestEthConfirmer_FindTxsRequiringRebroadcast(t *testing.T) {
etx3 := cltest.MustInsertUnconfirmedEthTxWithBroadcastLegacyAttempt(t, txStore, nonce, fromAddress)
nonce++
attempt3_1 := etx3.TxAttempts[0]
- dbAttempt = txmgr.DbEthTxAttemptFromEthTxAttempt(&attempt3_1)
- require.NoError(t, db.Get(&dbAttempt, `UPDATE eth_tx_attempts SET broadcast_before_block_num=$1 WHERE id=$2 RETURNING *`, oldEnough, attempt3_1.ID))
+ 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)
- require.NoError(t, db.Get(&dbAttempt, `UPDATE eth_tx_attempts SET broadcast_before_block_num=$1 WHERE id=$2 RETURNING *`, oldEnough, attemptOther1.ID))
+ 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) {
etxs, err := ec.FindTxsRequiringRebroadcast(testutils.Context(t), lggr, evmFromAddress, currentHead, gasBumpThreshold, 10, 0, &cltest.FixtureChainID)
@@ -1519,15 +1523,17 @@ func TestEthConfirmer_FindTxsRequiringRebroadcast(t *testing.T) {
etx4 := cltest.MustInsertUnconfirmedEthTxWithBroadcastLegacyAttempt(t, txStore, nonce, fromAddress)
nonce++
attempt4_1 := etx4.TxAttempts[0]
- dbAttempt = txmgr.DbEthTxAttemptFromEthTxAttempt(&attemptOther1)
- require.NoError(t, db.Get(&dbAttempt, `UPDATE eth_tx_attempts SET broadcast_before_block_num=$1 WHERE id=$2 RETURNING *`, oldEnough, attempt4_1.ID))
+ 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)
- require.NoError(t, db.Get(&dbAttempt, `UPDATE eth_tx_attempts SET broadcast_before_block_num=$1 WHERE id=$2 RETURNING *`, oldEnough, aOther.ID))
+ 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)
require.NoError(t, err)
@@ -1645,7 +1651,7 @@ func TestEthConfirmer_RebroadcastWhereNecessary_WithConnectivityCheck(t *testing
estimator := gasmocks.NewEvmEstimator(t)
estimator.On("BumpLegacyGas", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil, uint32(0), pkgerrors.Wrapf(commonfee.ErrConnectivity, "transaction..."))
ge := ccfg.EVM().GasEstimator()
- feeEstimator := gas.NewWrappedEvmEstimator(estimator, ge.EIP1559DynamicFees())
+ feeEstimator := gas.NewWrappedEvmEstimator(estimator, ge.EIP1559DynamicFees(), nil)
txBuilder := txmgr.NewEvmTxAttemptBuilder(*ethClient.ConfiguredChainID(), ge, kst, feeEstimator)
addresses := []gethCommon.Address{fromAddress}
kst.On("EnabledAddressesForChain", &cltest.FixtureChainID).Return(addresses, nil).Maybe()
@@ -1659,8 +1665,9 @@ func TestEthConfirmer_RebroadcastWhereNecessary_WithConnectivityCheck(t *testing
etx := cltest.MustInsertUnconfirmedEthTxWithBroadcastLegacyAttempt(t, txStore, nonce, fromAddress, originalBroadcastAt)
attempt1 := etx.TxAttempts[0]
- dbAttempt := txmgr.DbEthTxAttemptFromEthTxAttempt(&attempt1)
- require.NoError(t, db.Get(&dbAttempt, `UPDATE eth_tx_attempts SET broadcast_before_block_num=$1 WHERE id=$2 RETURNING *`, oldEnough, attempt1.ID))
+ 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.
ethClient.On("SendTransactionReturnCode", mock.Anything, mock.Anything, fromAddress).Return(clienttypes.Successful, nil).Once()
@@ -1690,7 +1697,7 @@ func TestEthConfirmer_RebroadcastWhereNecessary_WithConnectivityCheck(t *testing
estimator.On("BumpDynamicFee", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(gas.DynamicFee{}, uint32(0), pkgerrors.Wrapf(commonfee.ErrConnectivity, "transaction..."))
// Create confirmer with necessary state
ge := ccfg.EVM().GasEstimator()
- feeEstimator := gas.NewWrappedEvmEstimator(estimator, ge.EIP1559DynamicFees())
+ feeEstimator := gas.NewWrappedEvmEstimator(estimator, ge.EIP1559DynamicFees(), nil)
txBuilder := txmgr.NewEvmTxAttemptBuilder(*ethClient.ConfiguredChainID(), ge, kst, feeEstimator)
addresses := []gethCommon.Address{fromAddress}
kst.On("EnabledAddressesForChain", &cltest.FixtureChainID).Return(addresses, nil).Maybe()
@@ -1703,8 +1710,9 @@ func TestEthConfirmer_RebroadcastWhereNecessary_WithConnectivityCheck(t *testing
etx := cltest.MustInsertUnconfirmedEthTxWithBroadcastDynamicFeeAttempt(t, txStore, nonce, fromAddress, originalBroadcastAt)
attempt1 := etx.TxAttempts[0]
- dbAttempt := txmgr.DbEthTxAttemptFromEthTxAttempt(&attempt1)
- require.NoError(t, db.Get(&dbAttempt, `UPDATE eth_tx_attempts SET broadcast_before_block_num=$1 WHERE id=$2 RETURNING *`, oldEnough, attempt1.ID))
+ 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.
ethClient.On("SendTransactionReturnCode", mock.Anything, mock.Anything, fromAddress).Return(clienttypes.Successful, nil).Once()
@@ -1754,7 +1762,7 @@ func TestEthConfirmer_RebroadcastWhereNecessary(t *testing.T) {
nonce++
attempt1_1 := etx.TxAttempts[0]
var dbAttempt txmgr.DbEthTxAttempt
- require.NoError(t, db.Get(&dbAttempt, `UPDATE eth_tx_attempts SET broadcast_before_block_num=$1 WHERE id=$2 RETURNING *`, oldEnough, attempt1_1.ID))
+ require.NoError(t, db.Get(&dbAttempt, `UPDATE evm.tx_attempts SET broadcast_before_block_num=$1 WHERE id=$2 RETURNING *`, oldEnough, attempt1_1.ID))
t.Run("re-sends previous transaction on keystore error", func(t *testing.T) {
// simulate bumped transaction that is somehow impossible to sign
@@ -1889,7 +1897,7 @@ func TestEthConfirmer_RebroadcastWhereNecessary(t *testing.T) {
require.Len(t, etx.TxAttempts, 2)
})
- require.NoError(t, db.Get(&dbAttempt, `UPDATE eth_tx_attempts SET broadcast_before_block_num=$1 WHERE id=$2 RETURNING *`, oldEnough, attempt1_2.ID))
+ require.NoError(t, db.Get(&dbAttempt, `UPDATE evm.tx_attempts SET broadcast_before_block_num=$1 WHERE id=$2 RETURNING *`, oldEnough, attempt1_2.ID))
var attempt1_3 txmgr.TxAttempt
t.Run("creates new attempt with higher gas price if transaction is already in mempool (e.g. due to previous crash before we could save the new attempt)", func(t *testing.T) {
@@ -1927,7 +1935,7 @@ func TestEthConfirmer_RebroadcastWhereNecessary(t *testing.T) {
assert.Equal(t, txmgrtypes.TxAttemptBroadcast, attempt1_3.State)
})
- require.NoError(t, db.Get(&dbAttempt, `UPDATE eth_tx_attempts SET broadcast_before_block_num=$1 WHERE id=$2 RETURNING *`, oldEnough, attempt1_3.ID))
+ require.NoError(t, db.Get(&dbAttempt, `UPDATE evm.tx_attempts SET broadcast_before_block_num=$1 WHERE id=$2 RETURNING *`, oldEnough, attempt1_3.ID))
var attempt1_4 txmgr.TxAttempt
t.Run("saves new attempt even for transaction that has already been confirmed (nonce already used)", func(t *testing.T) {
@@ -1974,13 +1982,13 @@ 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
- pgtest.MustExec(t, db, `UPDATE eth_txes SET state = 'confirmed'`)
+ // 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)
nonce++
attempt2_1 := etx2.TxAttempts[0]
- require.NoError(t, db.Get(&dbAttempt, `UPDATE eth_tx_attempts SET broadcast_before_block_num=$1 WHERE id=$2 RETURNING *`, oldEnough, attempt2_1.ID))
+ require.NoError(t, db.Get(&dbAttempt, `UPDATE evm.tx_attempts SET broadcast_before_block_num=$1 WHERE id=$2 RETURNING *`, oldEnough, attempt2_1.ID))
var attempt2_2 txmgr.TxAttempt
t.Run("saves in_progress attempt on temporary error and returns error", func(t *testing.T) {
@@ -2048,7 +2056,7 @@ func TestEthConfirmer_RebroadcastWhereNecessary(t *testing.T) {
})
// Set BroadcastBeforeBlockNum again so the next test will pick it up
- require.NoError(t, db.Get(&dbAttempt, `UPDATE eth_tx_attempts SET broadcast_before_block_num=$1 WHERE id=$2 RETURNING *`, oldEnough, attempt2_2.ID))
+ require.NoError(t, db.Get(&dbAttempt, `UPDATE evm.tx_attempts SET broadcast_before_block_num=$1 WHERE id=$2 RETURNING *`, oldEnough, attempt2_2.ID))
t.Run("assumes that 'nonce too low' error means confirmed_missing_receipt", func(t *testing.T) {
expectedBumpedGasPrice := big.NewInt(25000000000)
@@ -2083,11 +2091,11 @@ 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]
- require.NoError(t, db.Get(&dbAttempt, `UPDATE eth_tx_attempts SET broadcast_before_block_num=$1, gas_price=$2 WHERE id=$3 RETURNING *`, oldEnough, assets.NewWeiI(35000000000), attempt3_1.ID))
+ require.NoError(t, db.Get(&dbAttempt, `UPDATE evm.tx_attempts SET broadcast_before_block_num=$1, gas_price=$2 WHERE id=$3 RETURNING *`, oldEnough, assets.NewWeiI(35000000000), attempt3_1.ID))
var attempt3_2 txmgr.TxAttempt
@@ -2125,7 +2133,7 @@ func TestEthConfirmer_RebroadcastWhereNecessary(t *testing.T) {
assert.Equal(t, expectedBumpedGasPrice.Int64(), attempt3_2.TxFee.Legacy.ToInt().Int64())
})
- require.NoError(t, db.Get(&dbAttempt, `UPDATE eth_tx_attempts SET broadcast_before_block_num=$1 WHERE id=$2 RETURNING *`, oldEnough, attempt3_2.ID))
+ require.NoError(t, db.Get(&dbAttempt, `UPDATE evm.tx_attempts SET broadcast_before_block_num=$1 WHERE id=$2 RETURNING *`, oldEnough, attempt3_2.ID))
var attempt3_3 txmgr.TxAttempt
t.Run("handles case where transaction is already known somehow", func(t *testing.T) {
@@ -2160,7 +2168,7 @@ func TestEthConfirmer_RebroadcastWhereNecessary(t *testing.T) {
assert.Equal(t, expectedBumpedGasPrice.Int64(), attempt3_3.TxFee.Legacy.ToInt().Int64())
})
- require.NoError(t, db.Get(&dbAttempt, `UPDATE eth_tx_attempts SET broadcast_before_block_num=$1 WHERE id=$2 RETURNING *`, oldEnough, attempt3_3.ID))
+ require.NoError(t, db.Get(&dbAttempt, `UPDATE evm.tx_attempts SET broadcast_before_block_num=$1 WHERE id=$2 RETURNING *`, oldEnough, attempt3_3.ID))
var attempt3_4 txmgr.TxAttempt
t.Run("pretends it was accepted and continues the cycle if rejected for being temporarily underpriced", func(t *testing.T) {
@@ -2199,7 +2207,7 @@ func TestEthConfirmer_RebroadcastWhereNecessary(t *testing.T) {
assert.Equal(t, expectedBumpedGasPrice.Int64(), attempt3_4.TxFee.Legacy.ToInt().Int64())
})
- require.NoError(t, db.Get(&dbAttempt, `UPDATE eth_tx_attempts SET broadcast_before_block_num=$1 WHERE id=$2 RETURNING *`, oldEnough, attempt3_4.ID))
+ require.NoError(t, db.Get(&dbAttempt, `UPDATE evm.tx_attempts SET broadcast_before_block_num=$1 WHERE id=$2 RETURNING *`, oldEnough, attempt3_4.ID))
t.Run("resubmits at the old price and does not create a new attempt if one of the bumped transactions would exceed EVM.GasEstimator.PriceMax", func(t *testing.T) {
// Set price such that the next bump will exceed EVM.GasEstimator.PriceMax
@@ -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))
@@ -2230,7 +2238,7 @@ func TestEthConfirmer_RebroadcastWhereNecessary(t *testing.T) {
assert.Equal(t, gasPrice.Int64(), attempt3_4.TxFee.Legacy.ToInt().Int64())
})
- require.NoError(t, db.Get(&dbAttempt, `UPDATE eth_tx_attempts SET broadcast_before_block_num=$1 WHERE id=$2 RETURNING *`, oldEnough, attempt3_4.ID))
+ require.NoError(t, db.Get(&dbAttempt, `UPDATE evm.tx_attempts SET broadcast_before_block_num=$1 WHERE id=$2 RETURNING *`, oldEnough, attempt3_4.ID))
t.Run("resubmits at the old price and does not create a new attempt if the current price is exactly EVM.GasEstimator.PriceMax", func(t *testing.T) {
// Set price such that the current price is already at EVM.GasEstimator.PriceMax
@@ -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))
@@ -2264,7 +2272,7 @@ func TestEthConfirmer_RebroadcastWhereNecessary(t *testing.T) {
// The EIP-1559 etx and attempt
etx4 := cltest.MustInsertUnconfirmedEthTxWithBroadcastDynamicFeeAttempt(t, txStore, nonce, fromAddress)
attempt4_1 := etx4.TxAttempts[0]
- require.NoError(t, db.Get(&dbAttempt, `UPDATE eth_tx_attempts SET broadcast_before_block_num=$1, gas_tip_cap=$2, gas_fee_cap=$3 WHERE id=$4 RETURNING *`,
+ require.NoError(t, db.Get(&dbAttempt, `UPDATE evm.tx_attempts SET broadcast_before_block_num=$1, gas_tip_cap=$2, gas_fee_cap=$3 WHERE id=$4 RETURNING *`,
oldEnough, assets.GWei(35), assets.GWei(100), attempt4_1.ID))
var attempt4_2 txmgr.TxAttempt
@@ -2301,7 +2309,7 @@ func TestEthConfirmer_RebroadcastWhereNecessary(t *testing.T) {
assert.Equal(t, txmgrtypes.TxAttemptBroadcast, attempt1_2.State)
})
- require.NoError(t, db.Get(&dbAttempt, `UPDATE eth_tx_attempts SET broadcast_before_block_num=$1, gas_tip_cap=$2, gas_fee_cap=$3 WHERE id=$4 RETURNING *`,
+ require.NoError(t, db.Get(&dbAttempt, `UPDATE evm.tx_attempts SET broadcast_before_block_num=$1, gas_tip_cap=$2, gas_fee_cap=$3 WHERE id=$4 RETURNING *`,
oldEnough, assets.GWei(999), assets.GWei(1000), attempt4_2.ID))
t.Run("EIP-1559: resubmits at the old price and does not create a new attempt if one of the bumped EIP-1559 transactions would have its tip cap exceed EVM.GasEstimator.PriceMax", func(t *testing.T) {
@@ -2331,7 +2339,7 @@ func TestEthConfirmer_RebroadcastWhereNecessary(t *testing.T) {
assert.Equal(t, assets.GWei(1000).Int64(), attempt4_2.TxFee.DynamicFeeCap.ToInt().Int64())
})
- require.NoError(t, db.Get(&dbAttempt, `UPDATE eth_tx_attempts SET broadcast_before_block_num=$1, gas_tip_cap=$2, gas_fee_cap=$3 WHERE id=$4 RETURNING *`,
+ require.NoError(t, db.Get(&dbAttempt, `UPDATE evm.tx_attempts SET broadcast_before_block_num=$1, gas_tip_cap=$2, gas_fee_cap=$3 WHERE id=$4 RETURNING *`,
oldEnough, assets.GWei(45), assets.GWei(100), attempt4_2.ID))
t.Run("EIP-1559: saves attempt anyway if replacement transaction is underpriced because the bumped gas price is insufficiently higher than the previous one", func(t *testing.T) {
@@ -2430,8 +2438,9 @@ func TestEthConfirmer_RebroadcastWhereNecessary_TerminallyUnderpriced_ThenGoesTh
etx := cltest.MustInsertUnconfirmedEthTxWithBroadcastLegacyAttempt(t, txStore, nonce, fromAddress)
nonce++
legacyAttempt := etx.TxAttempts[0]
- dbAttempt := txmgr.DbEthTxAttemptFromEthTxAttempt(&legacyAttempt)
- require.NoError(t, db.Get(&dbAttempt, `UPDATE eth_tx_attempts SET broadcast_before_block_num=$1 WHERE id=$2 RETURNING *`, oldEnough, legacyAttempt.ID))
+ 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
ethClient.On("SendTransactionReturnCode", mock.Anything, mock.Anything, fromAddress).Return(
@@ -2462,8 +2471,9 @@ func TestEthConfirmer_RebroadcastWhereNecessary_TerminallyUnderpriced_ThenGoesTh
etx := cltest.MustInsertUnconfirmedEthTxWithBroadcastDynamicFeeAttempt(t, txStore, nonce, fromAddress)
nonce++
dxFeeAttempt := etx.TxAttempts[0]
- dbAttempt := txmgr.DbEthTxAttemptFromEthTxAttempt(&dxFeeAttempt)
- require.NoError(t, db.Get(&dbAttempt, `UPDATE eth_tx_attempts SET broadcast_before_block_num=$1 WHERE id=$2 RETURNING *`, oldEnough, dxFeeAttempt.ID))
+ 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
ethClient.On("SendTransactionReturnCode", mock.Anything, mock.Anything, fromAddress).Return(
@@ -2513,8 +2523,9 @@ 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)
- require.NoError(t, db.Get(&dbAttempt, `UPDATE eth_tx_attempts SET broadcast_before_block_num=$1 WHERE id=$2 RETURNING *`, oldEnough, attempt1_1.ID))
+ 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
insufficientEthError := errors.New("insufficient funds for gas * price + value")
@@ -2623,7 +2634,7 @@ func TestEthConfirmer_RebroadcastWhereNecessary_WhenOutOfEth(t *testing.T) {
var dbAttempts []txmgr.DbEthTxAttempt
- require.NoError(t, db.Select(&dbAttempts, "SELECT * FROM eth_tx_attempts WHERE state = 'insufficient_eth'"))
+ require.NoError(t, db.Select(&dbAttempts, "SELECT * FROM evm.tx_attempts WHERE state = 'insufficient_eth'"))
require.Len(t, dbAttempts, 0)
})
}
@@ -2954,7 +2965,7 @@ func TestEthConfirmer_ResumePendingRuns(t *testing.T) {
etx := cltest.MustInsertConfirmedEthTxWithLegacyAttempt(t, txStore, 1, 1, fromAddress)
cltest.MustInsertEthReceipt(t, txStore, head.Number-minConfirmations, head.Hash, etx.TxAttempts[0].Hash)
- pgtest.MustExec(t, db, `UPDATE eth_txes SET pipeline_task_run_id = $1, min_confirmations = $2 WHERE id = $3`, &tr.ID, minConfirmations, etx.ID)
+ pgtest.MustExec(t, db, `UPDATE evm.txes SET pipeline_task_run_id = $1, min_confirmations = $2 WHERE id = $3`, &tr.ID, minConfirmations, etx.ID)
err = ec.ResumePendingTaskRuns(testutils.Context(t), &head)
require.NoError(t, err)
@@ -2974,7 +2985,7 @@ func TestEthConfirmer_ResumePendingRuns(t *testing.T) {
etx := cltest.MustInsertConfirmedEthTxWithLegacyAttempt(t, txStore, 2, 1, fromAddress)
cltest.MustInsertEthReceipt(t, txStore, head.Number, head.Hash, etx.TxAttempts[0].Hash)
- pgtest.MustExec(t, db, `UPDATE eth_txes SET pipeline_task_run_id = $1, min_confirmations = $2 WHERE id = $3`, &tr.ID, minConfirmations, etx.ID)
+ pgtest.MustExec(t, db, `UPDATE evm.txes SET pipeline_task_run_id = $1, min_confirmations = $2 WHERE id = $3`, &tr.ID, minConfirmations, etx.ID)
err = ec.ResumePendingTaskRuns(testutils.Context(t), &head)
require.NoError(t, err)
@@ -2996,10 +3007,10 @@ func TestEthConfirmer_ResumePendingRuns(t *testing.T) {
pgtest.MustExec(t, db, `UPDATE pipeline_runs SET state = 'suspended' WHERE id = $1`, run.ID)
etx := cltest.MustInsertConfirmedEthTxWithLegacyAttempt(t, txStore, 3, 1, fromAddress)
- pgtest.MustExec(t, db, `UPDATE eth_txes SET meta='{"FailOnRevert": true}'`)
+ pgtest.MustExec(t, db, `UPDATE evm.txes SET meta='{"FailOnRevert": true}'`)
receipt := cltest.MustInsertEthReceipt(t, txStore, head.Number-minConfirmations, head.Hash, etx.TxAttempts[0].Hash)
- pgtest.MustExec(t, db, `UPDATE eth_txes SET pipeline_task_run_id = $1, min_confirmations = $2 WHERE id = $3`, &tr.ID, minConfirmations, etx.ID)
+ pgtest.MustExec(t, db, `UPDATE evm.txes SET pipeline_task_run_id = $1, min_confirmations = $2 WHERE id = $3`, &tr.ID, minConfirmations, etx.ID)
go func() {
err2 := ec.ResumePendingTaskRuns(testutils.Context(t), &head)
@@ -3036,12 +3047,12 @@ func TestEthConfirmer_ResumePendingRuns(t *testing.T) {
pgtest.MustExec(t, db, `UPDATE pipeline_runs SET state = 'suspended' WHERE id = $1`, run.ID)
etx := cltest.MustInsertConfirmedEthTxWithLegacyAttempt(t, txStore, 4, 1, fromAddress)
- pgtest.MustExec(t, db, `UPDATE eth_txes SET meta='{"FailOnRevert": true}'`)
+ pgtest.MustExec(t, db, `UPDATE evm.txes SET meta='{"FailOnRevert": true}'`)
// receipt is not passed through as a value since it reverted and caused an error
cltest.MustInsertRevertedEthReceipt(t, txStore, head.Number-minConfirmations, head.Hash, etx.TxAttempts[0].Hash)
- pgtest.MustExec(t, db, `UPDATE eth_txes SET pipeline_task_run_id = $1, min_confirmations = $2 WHERE id = $3`, &tr.ID, minConfirmations, etx.ID)
+ pgtest.MustExec(t, db, `UPDATE evm.txes SET pipeline_task_run_id = $1, min_confirmations = $2 WHERE id = $3`, &tr.ID, minConfirmations, etx.ID)
go func() {
err2 := ec.ResumePendingTaskRuns(testutils.Context(t), &head)
diff --git a/core/chains/evm/txmgr/evm_tx_store.go b/core/chains/evm/txmgr/evm_tx_store.go
index d7aed3774e4..52cd50cba32 100644
--- a/core/chains/evm/txmgr/evm_tx_store.go
+++ b/core/chains/evm/txmgr/evm_tx_store.go
@@ -57,6 +57,7 @@ type TxStoreWebApi interface {
TxAttempts(offset, limit int) ([]TxAttempt, int, error)
TransactionsWithAttempts(offset, limit int) ([]Tx, int, error)
FindTxAttempt(hash common.Hash) (*TxAttempt, error)
+ FindTxWithAttempts(etxID int64) (etx Tx, err error)
}
type TestEvmTxStore interface {
@@ -66,7 +67,6 @@ type TestEvmTxStore interface {
InsertReceipt(receipt *evmtypes.Receipt) (int64, error)
InsertTx(etx *Tx) error
FindTxAttemptsByTxIDs(ids []int64) ([]TxAttempt, error)
- FindTxWithAttempts(etxID int64) (etx Tx, err error)
InsertTxAttempt(attempt *TxAttempt) error
LoadTxesAttempts(etxs []*Tx, qopts ...pg.QOpt) error
}
@@ -81,7 +81,7 @@ type evmTxStore struct {
var _ EvmTxStore = (*evmTxStore)(nil)
var _ TestEvmTxStore = (*evmTxStore)(nil)
-// Directly maps to columns of database table "eth_receipts".
+// Directly maps to columns of database table "evm.receipts".
// Do not modify type unless you
// intend to modify the database schema
type dbReceipt struct {
@@ -148,10 +148,11 @@ func toOnchainReceipt(rs []*evmtypes.Receipt) []rawOnchainReceipt {
return receipts
}
-// Directly maps to columns of database table "eth_txes".
+// Directly maps to columns of database table "evm.txes".
// This is exported, as tests and other external code still directly reads DB using this schema.
type DbEthTx struct {
ID int64
+ IdempotencyKey *string
Nonce *int64
FromAddress common.Address
ToAddress common.Address
@@ -181,65 +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.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
}
@@ -247,11 +245,11 @@ 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])
}
}
-// Directly maps to columns of database table "eth_tx_attempts".
+// Directly maps to columns of database table "evm.tx_attempts".
// This is exported, as tests and other external code still directly reads DB using this schema.
type DbEthTxAttempt struct {
ID int64
@@ -268,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 {
@@ -300,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
}
@@ -342,7 +336,7 @@ func NewTxStore(
}
const insertIntoEthTxAttemptsQuery = `
-INSERT INTO eth_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)
+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)
RETURNING *;
`
@@ -363,7 +357,7 @@ func (o *evmTxStore) preloadTxAttempts(txs []Tx) error {
return nil
}
var dbAttempts []DbEthTxAttempt
- sql := `SELECT * FROM eth_tx_attempts WHERE eth_tx_id IN (?) ORDER BY id desc;`
+ sql := `SELECT * FROM evm.tx_attempts WHERE eth_tx_id IN (?) ORDER BY id desc;`
query, args, err := sqlx.In(sql, ids)
if err != nil {
return err
@@ -377,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)
}
}
@@ -398,12 +392,12 @@ func (o *evmTxStore) PreloadTxes(attempts []TxAttempt, qopts ...pg.QOpt) error {
}
dbEthTxs := make([]DbEthTx, len(ethTxIDs))
qq := o.q.WithOpts(qopts...)
- if err := qq.Select(&dbEthTxs, `SELECT * FROM eth_txes WHERE id = ANY($1)`, pq.Array(ethTxIDs)); err != nil {
+ if err := qq.Select(&dbEthTxs, `SELECT * FROM evm.txes WHERE id = ANY($1)`, pq.Array(ethTxIDs)); err != nil {
return pkgerrors.Wrap(err, "loadEthTxes failed")
}
for _, dbEtx := range dbEthTxs {
etx := ethTxM[dbEtx.ID]
- DbEthTxToEthTx(dbEtx, &etx)
+ dbEtx.ToTx(&etx)
ethTxM[etx.ID] = etx
}
for i, attempt := range attempts {
@@ -415,12 +409,12 @@ func (o *evmTxStore) PreloadTxes(attempts []TxAttempt, qopts ...pg.QOpt) error {
// Transactions returns all eth transactions without loaded relations
// limited by passed parameters.
func (o *evmTxStore) Transactions(offset, limit int) (txs []Tx, count int, err error) {
- sql := `SELECT count(*) FROM eth_txes WHERE id IN (SELECT DISTINCT eth_tx_id FROM eth_tx_attempts)`
+ sql := `SELECT count(*) FROM evm.txes WHERE id IN (SELECT DISTINCT eth_tx_id FROM evm.tx_attempts)`
if err = o.q.Get(&count, sql); err != nil {
return
}
- sql = `SELECT * FROM eth_txes WHERE id IN (SELECT DISTINCT eth_tx_id FROM eth_tx_attempts) ORDER BY id desc LIMIT $1 OFFSET $2`
+ sql = `SELECT * FROM evm.txes WHERE id IN (SELECT DISTINCT eth_tx_id FROM evm.tx_attempts) ORDER BY id desc LIMIT $1 OFFSET $2`
var dbEthTxs []DbEthTx
if err = o.q.Select(&dbEthTxs, sql, limit, offset); err != nil {
return
@@ -432,12 +426,12 @@ func (o *evmTxStore) Transactions(offset, limit int) (txs []Tx, count int, err e
// TransactionsWithAttempts returns all eth transactions with at least one attempt
// limited by passed parameters. Attempts are sorted by id.
func (o *evmTxStore) TransactionsWithAttempts(offset, limit int) (txs []Tx, count int, err error) {
- sql := `SELECT count(*) FROM eth_txes WHERE id IN (SELECT DISTINCT eth_tx_id FROM eth_tx_attempts)`
+ sql := `SELECT count(*) FROM evm.txes WHERE id IN (SELECT DISTINCT eth_tx_id FROM evm.tx_attempts)`
if err = o.q.Get(&count, sql); err != nil {
return
}
- sql = `SELECT * FROM eth_txes WHERE id IN (SELECT DISTINCT eth_tx_id FROM eth_tx_attempts) ORDER BY id desc LIMIT $1 OFFSET $2`
+ sql = `SELECT * FROM evm.txes WHERE id IN (SELECT DISTINCT eth_tx_id FROM evm.tx_attempts) ORDER BY id desc LIMIT $1 OFFSET $2`
var dbTxs []DbEthTx
if err = o.q.Select(&dbTxs, sql, limit, offset); err != nil {
return
@@ -449,12 +443,12 @@ func (o *evmTxStore) TransactionsWithAttempts(offset, limit int) (txs []Tx, coun
// TxAttempts returns the last tx attempts sorted by created_at descending.
func (o *evmTxStore) TxAttempts(offset, limit int) (txs []TxAttempt, count int, err error) {
- sql := `SELECT count(*) FROM eth_tx_attempts`
+ sql := `SELECT count(*) FROM evm.tx_attempts`
if err = o.q.Get(&count, sql); err != nil {
return
}
- sql = `SELECT * FROM eth_tx_attempts ORDER BY created_at DESC, id DESC LIMIT $1 OFFSET $2`
+ sql = `SELECT * FROM evm.tx_attempts ORDER BY created_at DESC, id DESC LIMIT $1 OFFSET $2`
var dbTxs []DbEthTxAttempt
if err = o.q.Select(&dbTxs, sql, limit, offset); err != nil {
return
@@ -467,13 +461,13 @@ func (o *evmTxStore) TxAttempts(offset, limit int) (txs []TxAttempt, count int,
// FindTxAttempt returns an individual TxAttempt
func (o *evmTxStore) FindTxAttempt(hash common.Hash) (*TxAttempt, error) {
dbTxAttempt := DbEthTxAttempt{}
- sql := `SELECT * FROM eth_tx_attempts WHERE hash = $1`
+ sql := `SELECT * FROM evm.tx_attempts WHERE hash = $1`
if err := o.q.Get(&dbTxAttempt, sql, hash); err != nil {
return nil, err
}
// reuse the preload
var attempt TxAttempt
- DbEthTxAttemptToEthTxAttempt(dbTxAttempt, &attempt)
+ dbTxAttempt.ToTxAttempt(&attempt)
attempts := []TxAttempt{attempt}
err := o.PreloadTxes(attempts)
return &attempts[0], err
@@ -481,7 +475,7 @@ func (o *evmTxStore) FindTxAttempt(hash common.Hash) (*TxAttempt, error) {
// FindTxAttemptsByTxIDs returns a list of attempts by ETH Tx IDs
func (o *evmTxStore) FindTxAttemptsByTxIDs(ids []int64) ([]TxAttempt, error) {
- sql := `SELECT * FROM eth_tx_attempts WHERE eth_tx_id = ANY($1)`
+ sql := `SELECT * FROM evm.tx_attempts WHERE eth_tx_id = ANY($1)`
var dbTxAttempts []DbEthTxAttempt
if err := o.q.Select(&dbTxAttempts, sql, ids); err != nil {
return nil, err
@@ -492,7 +486,7 @@ func (o *evmTxStore) FindTxAttemptsByTxIDs(ids []int64) ([]TxAttempt, error) {
func (o *evmTxStore) FindTxByHash(hash common.Hash) (*Tx, error) {
var dbEtx DbEthTx
err := o.q.Transaction(func(tx pg.Queryer) error {
- sql := `SELECT eth_txes.* FROM eth_txes WHERE id IN (SELECT DISTINCT eth_tx_id FROM eth_tx_attempts WHERE hash = $1)`
+ sql := `SELECT evm.txes.* FROM evm.txes WHERE id IN (SELECT DISTINCT eth_tx_id FROM evm.tx_attempts WHERE hash = $1)`
if err := tx.Get(&dbEtx, sql, hash); err != nil {
return pkgerrors.Wrapf(err, "failed to find eth_tx with hash %d", hash)
}
@@ -500,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")
}
@@ -509,20 +503,22 @@ func (o *evmTxStore) InsertTx(etx *Tx) error {
if etx.CreatedAt == (time.Time{}) {
etx.CreatedAt = time.Now()
}
- const insertEthTxSQL = `INSERT INTO eth_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 (
+ 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")
}
@@ -531,7 +527,7 @@ func (o *evmTxStore) InsertReceipt(receipt *evmtypes.Receipt) (int64, error) {
// convert to database representation
r := DbReceiptFromEvmReceipt(receipt)
- const insertEthReceiptSQL = `INSERT INTO eth_receipts (tx_hash, block_hash, block_number, transaction_index, receipt, created_at) VALUES (
+ const insertEthReceiptSQL = `INSERT INTO evm.receipts (tx_hash, block_hash, block_number, transaction_index, receipt, created_at) VALUES (
:tx_hash, :block_hash, :block_number, :transaction_index, :receipt, NOW()
) RETURNING *`
err := o.q.GetNamed(insertEthReceiptSQL, &r, &r)
@@ -543,15 +539,15 @@ func (o *evmTxStore) InsertReceipt(receipt *evmtypes.Receipt) (int64, error) {
func (o *evmTxStore) FindTxWithAttempts(etxID int64) (etx Tx, err error) {
err = o.q.Transaction(func(tx pg.Queryer) error {
var dbEtx DbEthTx
- if err = tx.Get(&dbEtx, `SELECT * FROM eth_txes WHERE id = $1 ORDER BY created_at ASC, id ASC`, etxID); err != nil {
+ 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 eth_tx_attempts for eth_tx with id %d", etxID)
+ return pkgerrors.Wrapf(err, "failed to load evm.tx_attempts for eth_tx with id %d", etxID)
}
if err = loadEthTxAttemptsReceipts(tx, &etx); err != nil {
- return pkgerrors.Wrapf(err, "failed to load eth_receipts for eth_tx with id %d", etxID)
+ return pkgerrors.Wrapf(err, "failed to load evm.receipts for eth_tx with id %d", etxID)
}
return nil
}, pg.OptReadOnlyTx())
@@ -563,8 +559,8 @@ func (o *evmTxStore) FindTxAttemptConfirmedByTxIDs(ids []int64) ([]TxAttempt, er
err := o.q.Transaction(func(tx pg.Queryer) error {
var dbAttempts []DbEthTxAttempt
if err := tx.Select(&dbAttempts, `SELECT eta.*
- FROM eth_tx_attempts eta
- join eth_receipts er on eta.hash = er.tx_hash where eta.eth_tx_id = ANY($1) ORDER BY eta.gas_price DESC, eta.gas_tip_cap DESC`, ids); err != nil {
+ FROM evm.tx_attempts eta
+ join evm.receipts er on eta.hash = er.tx_hash where eta.eth_tx_id = ANY($1) ORDER BY eta.gas_price DESC, eta.gas_tip_cap DESC`, ids); err != nil {
return err
}
txAttempts = dbEthTxAttemptsToEthTxAttempts(dbAttempts)
@@ -583,13 +579,13 @@ func (o *evmTxStore) LoadTxesAttempts(etxs []*Tx, qopts ...pg.QOpt) error {
ethTxesM[etx.ID] = etxs[i]
}
var dbTxAttempts []DbEthTxAttempt
- if err := qq.Select(&dbTxAttempts, `SELECT * FROM eth_tx_attempts WHERE eth_tx_id = ANY($1) ORDER BY eth_tx_attempts.gas_price DESC, eth_tx_attempts.gas_tip_cap DESC`, pq.Array(ethTxIDs)); err != nil {
- return pkgerrors.Wrap(err, "loadEthTxesAttempts failed to load eth_tx_attempts")
+ if err := qq.Select(&dbTxAttempts, `SELECT * FROM evm.tx_attempts WHERE eth_tx_id = ANY($1) ORDER BY evm.tx_attempts.gas_price DESC, evm.tx_attempts.gas_tip_cap DESC`, pq.Array(ethTxIDs)); err != nil {
+ return pkgerrors.Wrap(err, "loadEthTxesAttempts failed to load evm.tx_attempts")
}
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
@@ -616,8 +612,8 @@ func loadEthTxesAttemptsReceipts(q pg.Queryer, etxs []*Tx) (err error) {
}
}
var rs []dbReceipt
- if err = q.Select(&rs, `SELECT * FROM eth_receipts WHERE tx_hash = ANY($1)`, pq.Array(attemptHashes)); err != nil {
- return pkgerrors.Wrap(err, "loadEthTxesAttemptsReceipts failed to load eth_receipts")
+ if err = q.Select(&rs, `SELECT * FROM evm.receipts WHERE tx_hash = ANY($1)`, pq.Array(attemptHashes)); err != nil {
+ return pkgerrors.Wrap(err, "loadEthTxesAttemptsReceipts failed to load evm.receipts")
}
var receipts []*evmtypes.Receipt = fromDBReceipts(rs)
@@ -637,8 +633,8 @@ func loadConfirmedAttemptsReceipts(q pg.Queryer, attempts []TxAttempt) error {
hashes = append(hashes, attempt.Hash.Bytes())
}
var rs []dbReceipt
- if err := q.Select(&rs, `SELECT * FROM eth_receipts WHERE tx_hash = ANY($1)`, pq.Array(hashes)); err != nil {
- return pkgerrors.Wrap(err, "loadConfirmedAttemptsReceipts failed to load eth_receipts")
+ if err := q.Select(&rs, `SELECT * FROM evm.receipts WHERE tx_hash = ANY($1)`, pq.Array(hashes)); err != nil {
+ return pkgerrors.Wrap(err, "loadConfirmedAttemptsReceipts failed to load evm.receipts")
}
var receipts []*evmtypes.Receipt = fromDBReceipts(rs)
for _, receipt := range receipts {
@@ -656,19 +652,19 @@ func (o *evmTxStore) FindTxAttemptsRequiringResend(olderThan time.Time, maxInFli
limit = null.Uint32From(maxInFlightTransactions)
}
var dbAttempts []DbEthTxAttempt
- // this select distinct works because of unique index on eth_txes
+ // this select distinct works because of unique index on evm.txes
// (evm_chain_id, from_address, nonce)
err = o.q.Select(&dbAttempts, `
-SELECT DISTINCT ON (eth_txes.nonce) eth_tx_attempts.*
-FROM eth_tx_attempts
-JOIN eth_txes ON eth_txes.id = eth_tx_attempts.eth_tx_id AND eth_txes.state IN ('unconfirmed', 'confirmed_missing_receipt')
-WHERE eth_tx_attempts.state <> 'in_progress' AND eth_txes.broadcast_at <= $1 AND evm_chain_id = $2 AND from_address = $3
-ORDER BY eth_txes.nonce ASC, eth_tx_attempts.gas_price DESC, eth_tx_attempts.gas_tip_cap DESC
+SELECT DISTINCT ON (evm.txes.nonce) evm.tx_attempts.*
+FROM evm.tx_attempts
+JOIN evm.txes ON evm.txes.id = evm.tx_attempts.eth_tx_id AND evm.txes.state IN ('unconfirmed', 'confirmed_missing_receipt')
+WHERE evm.tx_attempts.state <> 'in_progress' AND evm.txes.broadcast_at <= $1 AND evm_chain_id = $2 AND from_address = $3
+ORDER BY evm.txes.nonce ASC, evm.tx_attempts.gas_price DESC, evm.tx_attempts.gas_tip_cap DESC
LIMIT $4
`, olderThan, chainID.String(), address, limit)
attempts = dbEthTxAttemptsToEthTxAttempts(dbAttempts)
- return attempts, pkgerrors.Wrap(err, "FindEthTxAttemptsRequiringResend failed to load eth_tx_attempts")
+ return attempts, pkgerrors.Wrap(err, "FindEthTxAttemptsRequiringResend failed to load evm.tx_attempts")
}
func (o *evmTxStore) UpdateBroadcastAts(now time.Time, etxIDs []int64) error {
@@ -679,8 +675,8 @@ func (o *evmTxStore) UpdateBroadcastAts(now time.Time, etxIDs []int64) error {
// Since EthConfirmer/EthResender can race (totally OK since highest
// priced transaction always wins) we only want to update broadcast_at if
// our version is later.
- _, err := o.q.Exec(`UPDATE eth_txes SET broadcast_at = $1 WHERE id = ANY($2) AND broadcast_at < $1`, now, pq.Array(etxIDs))
- return pkgerrors.Wrap(err, "updateBroadcastAts failed to update eth_txes")
+ _, err := o.q.Exec(`UPDATE evm.txes SET broadcast_at = $1 WHERE id = ANY($2) AND broadcast_at < $1`, now, pq.Array(etxIDs))
+ return pkgerrors.Wrap(err, "updateBroadcastAts failed to update evm.txes")
}
// SetBroadcastBeforeBlockNum updates already broadcast attempts with the
@@ -688,11 +684,11 @@ func (o *evmTxStore) UpdateBroadcastAts(now time.Time, etxIDs []int64) error {
// the attempt is already broadcast it _must_ have been before this head.
func (o *evmTxStore) SetBroadcastBeforeBlockNum(blockNum int64, chainID *big.Int) error {
_, err := o.q.Exec(
- `UPDATE eth_tx_attempts
+ `UPDATE evm.tx_attempts
SET broadcast_before_block_num = $1
-FROM eth_txes
-WHERE eth_tx_attempts.broadcast_before_block_num IS NULL AND eth_tx_attempts.state = 'broadcast'
-AND eth_txes.id = eth_tx_attempts.eth_tx_id AND eth_txes.evm_chain_id = $2`,
+FROM evm.txes
+WHERE evm.tx_attempts.broadcast_before_block_num IS NULL AND evm.tx_attempts.state = 'broadcast'
+AND evm.txes.id = evm.tx_attempts.eth_tx_id AND evm.txes.evm_chain_id = $2`,
blockNum, chainID.String(),
)
return pkgerrors.Wrap(err, "SetBroadcastBeforeBlockNum failed")
@@ -701,11 +697,11 @@ AND eth_txes.id = eth_tx_attempts.eth_tx_id AND eth_txes.evm_chain_id = $2`,
func (o *evmTxStore) FindTxAttemptsConfirmedMissingReceipt(chainID *big.Int) (attempts []TxAttempt, err error) {
var dbAttempts []DbEthTxAttempt
err = o.q.Select(&dbAttempts,
- `SELECT DISTINCT ON (eth_tx_attempts.eth_tx_id) eth_tx_attempts.*
- FROM eth_tx_attempts
- JOIN eth_txes ON eth_txes.id = eth_tx_attempts.eth_tx_id AND eth_txes.state = 'confirmed_missing_receipt'
+ `SELECT DISTINCT ON (evm.tx_attempts.eth_tx_id) evm.tx_attempts.*
+ FROM evm.tx_attempts
+ JOIN evm.txes ON evm.txes.id = evm.tx_attempts.eth_tx_id AND evm.txes.state = 'confirmed_missing_receipt'
WHERE evm_chain_id = $1
- ORDER BY eth_tx_attempts.eth_tx_id ASC, eth_tx_attempts.gas_price DESC, eth_tx_attempts.gas_tip_cap DESC`,
+ ORDER BY evm.tx_attempts.eth_tx_id ASC, evm.tx_attempts.gas_price DESC, evm.tx_attempts.gas_tip_cap DESC`,
chainID.String())
if err != nil {
err = pkgerrors.Wrap(err, "FindEtxAttemptsConfirmedMissingReceipt failed to query")
@@ -715,7 +711,7 @@ func (o *evmTxStore) FindTxAttemptsConfirmedMissingReceipt(chainID *big.Int) (at
}
func (o *evmTxStore) UpdateTxsUnconfirmed(ids []int64) error {
- _, err := o.q.Exec(`UPDATE eth_txes SET state='unconfirmed' WHERE id = ANY($1)`, pq.Array(ids))
+ _, err := o.q.Exec(`UPDATE evm.txes SET state='unconfirmed' WHERE id = ANY($1)`, pq.Array(ids))
if err != nil {
return pkgerrors.Wrap(err, "UpdateEthTxsUnconfirmed failed to execute")
@@ -727,17 +723,17 @@ func (o *evmTxStore) FindTxAttemptsRequiringReceiptFetch(chainID *big.Int) (atte
err = o.q.Transaction(func(tx pg.Queryer) error {
var dbAttempts []DbEthTxAttempt
err = tx.Select(&dbAttempts, `
-SELECT eth_tx_attempts.* FROM eth_tx_attempts
-JOIN eth_txes ON eth_txes.id = eth_tx_attempts.eth_tx_id AND eth_txes.state IN ('unconfirmed', 'confirmed_missing_receipt') AND eth_txes.evm_chain_id = $1
-WHERE eth_tx_attempts.state != 'insufficient_eth'
-ORDER BY eth_txes.nonce ASC, eth_tx_attempts.gas_price DESC, eth_tx_attempts.gas_tip_cap DESC
+SELECT evm.tx_attempts.* FROM evm.tx_attempts
+JOIN evm.txes ON evm.txes.id = evm.tx_attempts.eth_tx_id AND evm.txes.state IN ('unconfirmed', 'confirmed_missing_receipt') AND evm.txes.evm_chain_id = $1
+WHERE evm.tx_attempts.state != 'insufficient_eth'
+ORDER BY evm.txes.nonce ASC, evm.tx_attempts.gas_price DESC, evm.tx_attempts.gas_tip_cap DESC
`, chainID.String())
if err != nil {
- return pkgerrors.Wrap(err, "FindEthTxAttemptsRequiringReceiptFetch failed to load eth_tx_attempts")
+ return pkgerrors.Wrap(err, "FindEthTxAttemptsRequiringReceiptFetch failed to load evm.tx_attempts")
}
attempts = dbEthTxAttemptsToEthTxAttempts(dbAttempts)
err = o.PreloadTxes(attempts, pg.WithQueryer(tx))
- return pkgerrors.Wrap(err, "FindEthTxAttemptsRequiringReceiptFetch failed to load eth_txes")
+ return pkgerrors.Wrap(err, "FindEthTxAttemptsRequiringReceiptFetch failed to load evm.txes")
}, pg.OptReadOnlyTx())
return
}
@@ -791,27 +787,27 @@ func (o *evmTxStore) SaveFetchedReceipts(r []*evmtypes.Receipt, chainID *big.Int
/* #nosec G201 */
sql := `
WITH inserted_receipts AS (
- INSERT INTO eth_receipts (tx_hash, block_hash, block_number, transaction_index, receipt, created_at)
+ INSERT INTO evm.receipts (tx_hash, block_hash, block_number, transaction_index, receipt, created_at)
VALUES %s
ON CONFLICT (tx_hash, block_hash) DO UPDATE SET
block_number = EXCLUDED.block_number,
transaction_index = EXCLUDED.transaction_index,
receipt = EXCLUDED.receipt
- RETURNING eth_receipts.tx_hash, eth_receipts.block_number
+ RETURNING evm.receipts.tx_hash, evm.receipts.block_number
),
updated_eth_tx_attempts AS (
- UPDATE eth_tx_attempts
+ UPDATE evm.tx_attempts
SET
state = 'broadcast',
- broadcast_before_block_num = COALESCE(eth_tx_attempts.broadcast_before_block_num, inserted_receipts.block_number)
+ broadcast_before_block_num = COALESCE(evm.tx_attempts.broadcast_before_block_num, inserted_receipts.block_number)
FROM inserted_receipts
- WHERE inserted_receipts.tx_hash = eth_tx_attempts.hash
- RETURNING eth_tx_attempts.eth_tx_id
+ WHERE inserted_receipts.tx_hash = evm.tx_attempts.hash
+ RETURNING evm.tx_attempts.eth_tx_id
)
- UPDATE eth_txes
+ UPDATE evm.txes
SET state = 'confirmed'
FROM updated_eth_tx_attempts
- WHERE updated_eth_tx_attempts.eth_tx_id = eth_txes.id
+ WHERE updated_eth_tx_attempts.eth_tx_id = evm.txes.id
AND evm_chain_id = ?
`
@@ -824,7 +820,7 @@ func (o *evmTxStore) SaveFetchedReceipts(r []*evmtypes.Receipt, chainID *big.Int
}
// MarkAllConfirmedMissingReceipt
-// It is possible that we can fail to get a receipt for all eth_tx_attempts
+// It is possible that we can fail to get a receipt for all evm.tx_attempts
// even though a transaction with this nonce has long since been confirmed (we
// know this because transactions with higher nonces HAVE returned a receipt).
//
@@ -835,7 +831,7 @@ func (o *evmTxStore) SaveFetchedReceipts(r []*evmtypes.Receipt, chainID *big.Int
// In this case we mark these transactions as 'confirmed_missing_receipt' to
// prevent gas bumping.
//
-// NOTE: We continue to attempt to resend eth_txes in this state on
+// NOTE: We continue to attempt to resend evm.txes in this state on
// every head to guard against the extremely rare scenario of nonce gap due to
// reorg that excludes the transaction (from another wallet) that had this
// nonce (until finality depth is reached, after which we make the explicit
@@ -845,18 +841,18 @@ func (o *evmTxStore) SaveFetchedReceipts(r []*evmtypes.Receipt, chainID *big.Int
// attempts are below the finality depth from current head.
func (o *evmTxStore) MarkAllConfirmedMissingReceipt(chainID *big.Int) (err error) {
res, err := o.q.Exec(`
-UPDATE eth_txes
+UPDATE evm.txes
SET state = 'confirmed_missing_receipt'
FROM (
SELECT from_address, MAX(nonce) as max_nonce
- FROM eth_txes
+ FROM evm.txes
WHERE state = 'confirmed' AND evm_chain_id = $1
GROUP BY from_address
) AS max_table
WHERE state = 'unconfirmed'
AND evm_chain_id = $1
AND nonce < max_table.max_nonce
- AND eth_txes.from_address = max_table.from_address
+ AND evm.txes.from_address = max_table.from_address
`, chainID.String())
if err != nil {
return pkgerrors.Wrap(err, "markAllConfirmedMissingReceipt failed")
@@ -876,16 +872,16 @@ func (o *evmTxStore) GetInProgressTxAttempts(ctx context.Context, address common
err = qq.Transaction(func(tx pg.Queryer) error {
var dbAttempts []DbEthTxAttempt
err = tx.Select(&dbAttempts, `
-SELECT eth_tx_attempts.* FROM eth_tx_attempts
-INNER JOIN eth_txes ON eth_txes.id = eth_tx_attempts.eth_tx_id AND eth_txes.state in ('confirmed', 'confirmed_missing_receipt', 'unconfirmed')
-WHERE eth_tx_attempts.state = 'in_progress' AND eth_txes.from_address = $1 AND eth_txes.evm_chain_id = $2
+SELECT evm.tx_attempts.* FROM evm.tx_attempts
+INNER JOIN evm.txes ON evm.txes.id = evm.tx_attempts.eth_tx_id AND evm.txes.state in ('confirmed', 'confirmed_missing_receipt', 'unconfirmed')
+WHERE evm.tx_attempts.state = 'in_progress' AND evm.txes.from_address = $1 AND evm.txes.evm_chain_id = $2
`, address, chainID.String())
if err != nil {
- return pkgerrors.Wrap(err, "getInProgressEthTxAttempts failed to load eth_tx_attempts")
+ return pkgerrors.Wrap(err, "getInProgressEthTxAttempts failed to load evm.tx_attempts")
}
attempts = dbEthTxAttemptsToEthTxAttempts(dbAttempts)
err = o.PreloadTxes(attempts, pg.WithQueryer(tx))
- return pkgerrors.Wrap(err, "getInProgressEthTxAttempts failed to load eth_txes")
+ return pkgerrors.Wrap(err, "getInProgressEthTxAttempts failed to load evm.txes")
}, pg.OptReadOnlyTx())
return attempts, pkgerrors.Wrap(err, "getInProgressEthTxAttempts failed")
}
@@ -894,32 +890,47 @@ func (o *evmTxStore) FindReceiptsPendingConfirmation(ctx context.Context, blockN
var rs []dbReceiptPlus
err = o.q.SelectContext(ctx, &rs, `
- SELECT pipeline_task_runs.id, eth_receipts.receipt, COALESCE((eth_txes.meta->>'FailOnRevert')::boolean, false) "FailOnRevert" FROM pipeline_task_runs
+ SELECT pipeline_task_runs.id, evm.receipts.receipt, COALESCE((evm.txes.meta->>'FailOnRevert')::boolean, false) "FailOnRevert" FROM pipeline_task_runs
INNER JOIN pipeline_runs ON pipeline_runs.id = pipeline_task_runs.pipeline_run_id
- INNER JOIN eth_txes ON eth_txes.pipeline_task_run_id = pipeline_task_runs.id
- INNER JOIN eth_tx_attempts ON eth_txes.id = eth_tx_attempts.eth_tx_id
- INNER JOIN eth_receipts ON eth_tx_attempts.hash = eth_receipts.tx_hash
- WHERE pipeline_runs.state = 'suspended' AND eth_receipts.block_number <= ($1 - eth_txes.min_confirmations) AND eth_txes.evm_chain_id = $2
+ INNER JOIN evm.txes ON evm.txes.pipeline_task_run_id = pipeline_task_runs.id
+ INNER JOIN evm.tx_attempts ON evm.txes.id = evm.tx_attempts.eth_tx_id
+ INNER JOIN evm.receipts ON evm.tx_attempts.hash = evm.receipts.tx_hash
+ WHERE pipeline_runs.state = 'suspended' AND evm.receipts.block_number <= ($1 - evm.txes.min_confirmations) AND evm.txes.evm_chain_id = $2
`, blockNum, chainID.String())
receiptsPlus = fromDBReceiptsPlus(rs)
return
}
+// FindTxWithIdempotencyKey returns any broadcast ethtx with the given idempotencyKey and chainID
+func (o *evmTxStore) FindTxWithIdempotencyKey(idempotencyKey string, chainID *big.Int) (etx *Tx, err error) {
+ var dbEtx DbEthTx
+ err = o.q.Get(&dbEtx, `SELECT * FROM evm.txes WHERE idempotency_key = $1 and evm_chain_id = $2`, idempotencyKey, chainID.String())
+ if err != nil {
+ if errors.Is(err, sql.ErrNoRows) {
+ return nil, nil
+ }
+ return nil, pkgerrors.Wrap(err, "FindTxWithIdempotencyKey failed to load evm.txes")
+ }
+ etx = new(Tx)
+ dbEtx.ToTx(etx)
+ return
+}
+
// FindTxWithSequence returns any broadcast ethtx with the given nonce
func (o *evmTxStore) FindTxWithSequence(fromAddress common.Address, nonce evmtypes.Nonce) (etx *Tx, err error) {
etx = new(Tx)
err = o.q.Transaction(func(tx pg.Queryer) error {
var dbEtx DbEthTx
err = tx.Get(&dbEtx, `
-SELECT * FROM eth_txes WHERE from_address = $1 AND nonce = $2 AND state IN ('confirmed', 'confirmed_missing_receipt', 'unconfirmed')
+SELECT * FROM evm.txes WHERE from_address = $1 AND nonce = $2 AND state IN ('confirmed', 'confirmed_missing_receipt', 'unconfirmed')
`, fromAddress, nonce.Int64())
if err != nil {
- return pkgerrors.Wrap(err, "FindEthTxWithNonce failed to load eth_txes")
+ 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 eth_tx_attempts")
+ return pkgerrors.Wrap(err, "FindEthTxWithNonce failed to load evm.tx_attempts")
}, pg.OptReadOnlyTx())
if errors.Is(err, sql.ErrNoRows) {
return nil, nil
@@ -931,7 +942,7 @@ func updateEthTxAttemptUnbroadcast(q pg.Queryer, attempt TxAttempt) error {
if attempt.State != txmgrtypes.TxAttemptBroadcast {
return errors.New("expected eth_tx_attempt to be broadcast")
}
- _, err := q.Exec(`UPDATE eth_tx_attempts SET broadcast_before_block_num = NULL, state = 'in_progress' WHERE id = $1`, attempt.ID)
+ _, err := q.Exec(`UPDATE evm.tx_attempts SET broadcast_before_block_num = NULL, state = 'in_progress' WHERE id = $1`, attempt.ID)
return pkgerrors.Wrap(err, "updateEthTxAttemptUnbroadcast failed")
}
@@ -939,16 +950,16 @@ func updateEthTxUnconfirm(q pg.Queryer, etx Tx) error {
if etx.State != txmgr.TxConfirmed {
return errors.New("expected eth_tx state to be confirmed")
}
- _, err := q.Exec(`UPDATE eth_txes SET state = 'unconfirmed' WHERE id = $1`, etx.ID)
+ _, err := q.Exec(`UPDATE evm.txes SET state = 'unconfirmed' WHERE id = $1`, etx.ID)
return pkgerrors.Wrap(err, "updateEthTxUnconfirm failed")
}
func deleteEthReceipts(q pg.Queryer, etxID int64) (err error) {
_, err = q.Exec(`
-DELETE FROM eth_receipts
-USING eth_tx_attempts
-WHERE eth_receipts.tx_hash = eth_tx_attempts.hash
-AND eth_tx_attempts.eth_tx_id = $1
+DELETE FROM evm.receipts
+USING evm.tx_attempts
+WHERE evm.receipts.tx_hash = evm.tx_attempts.hash
+AND evm.tx_attempts.eth_tx_id = $1
`, etxID)
return pkgerrors.Wrap(err, "deleteEthReceipts failed")
}
@@ -969,39 +980,40 @@ func (o *evmTxStore) FindTransactionsConfirmedInBlockRange(highBlockNumber, lowB
err = o.q.Transaction(func(tx pg.Queryer) error {
var dbEtxs []DbEthTx
err = tx.Select(&dbEtxs, `
-SELECT DISTINCT eth_txes.* FROM eth_txes
-INNER JOIN eth_tx_attempts ON eth_txes.id = eth_tx_attempts.eth_tx_id AND eth_tx_attempts.state = 'broadcast'
-INNER JOIN eth_receipts ON eth_receipts.tx_hash = eth_tx_attempts.hash
-WHERE eth_txes.state IN ('confirmed', 'confirmed_missing_receipt') AND block_number BETWEEN $1 AND $2 AND evm_chain_id = $3
+SELECT DISTINCT evm.txes.* FROM evm.txes
+INNER JOIN evm.tx_attempts ON evm.txes.id = evm.tx_attempts.eth_tx_id AND evm.tx_attempts.state = 'broadcast'
+INNER JOIN evm.receipts ON evm.receipts.tx_hash = evm.tx_attempts.hash
+WHERE evm.txes.state IN ('confirmed', 'confirmed_missing_receipt') AND block_number BETWEEN $1 AND $2 AND evm_chain_id = $3
ORDER BY nonce ASC
`, lowBlockNumber, highBlockNumber, chainID.String())
if err != nil {
- return pkgerrors.Wrap(err, "FindTransactionsConfirmedInBlockRange failed to load eth_txes")
+ return pkgerrors.Wrap(err, "FindTransactionsConfirmedInBlockRange failed to load evm.txes")
}
etxs = make([]*Tx, len(dbEtxs))
dbEthTxsToEvmEthTxPtrs(dbEtxs, etxs)
if err = o.LoadTxesAttempts(etxs, pg.WithQueryer(tx)); err != nil {
- return pkgerrors.Wrap(err, "FindTransactionsConfirmedInBlockRange failed to load eth_tx_attempts")
+ return pkgerrors.Wrap(err, "FindTransactionsConfirmedInBlockRange failed to load evm.tx_attempts")
}
err = loadEthTxesAttemptsReceipts(tx, etxs)
- return pkgerrors.Wrap(err, "FindTransactionsConfirmedInBlockRange failed to load eth_receipts")
+ return pkgerrors.Wrap(err, "FindTransactionsConfirmedInBlockRange failed to load evm.receipts")
}, pg.OptReadOnlyTx())
return etxs, pkgerrors.Wrap(err, "FindTransactionsConfirmedInBlockRange failed")
}
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
// update anyway because it indicates a state where broadcast_at makes
// no sense e.g. fatal_error
- if _, err := tx.Exec(`UPDATE eth_txes SET broadcast_at = $1 WHERE id = $2 AND broadcast_at < $1`, broadcastAt, dbAttempt.EthTxID); err != nil {
- return pkgerrors.Wrap(err, "saveAttemptWithNewState failed to update eth_txes")
+ if _, err := tx.Exec(`UPDATE evm.txes SET broadcast_at = $1 WHERE id = $2 AND broadcast_at < $1`, broadcastAt, dbAttempt.EthTxID); err != nil {
+ return pkgerrors.Wrap(err, "saveAttemptWithNewState failed to update evm.txes")
}
- _, err := tx.Exec(`UPDATE eth_tx_attempts SET state=$1 WHERE id=$2`, dbAttempt.State, dbAttempt.ID)
- return pkgerrors.Wrap(err, "saveAttemptWithNewState failed to update eth_tx_attempts")
+ _, err := tx.Exec(`UPDATE evm.tx_attempts SET state=$1 WHERE id=$2`, dbAttempt.State, dbAttempt.ID)
+ return pkgerrors.Wrap(err, "saveAttemptWithNewState failed to update evm.tx_attempts")
})
}
@@ -1031,8 +1043,8 @@ func (o *evmTxStore) SaveConfirmedMissingReceiptAttempt(ctx context.Context, tim
if err := saveSentAttempt(tx, timeout, o.logger, attempt, broadcastAt); err != nil {
return err
}
- if _, err := tx.Exec(`UPDATE eth_txes SET state = 'confirmed_missing_receipt' WHERE id = $1`, attempt.TxID); err != nil {
- return pkgerrors.Wrap(err, "failed to update eth_txes")
+ if _, err := tx.Exec(`UPDATE evm.txes SET state = 'confirmed_missing_receipt' WHERE id = $1`, attempt.TxID); err != nil {
+ return pkgerrors.Wrap(err, "failed to update evm.txes")
}
return nil
@@ -1049,7 +1061,7 @@ func (o *evmTxStore) DeleteInProgressAttempt(ctx context.Context, attempt TxAtte
if attempt.ID == 0 {
return errors.New("DeleteInProgressAttempt: expected attempt to have an id")
}
- _, err := qq.Exec(`DELETE FROM eth_tx_attempts WHERE id = $1`, attempt.ID)
+ _, err := qq.Exec(`DELETE FROM evm.tx_attempts WHERE id = $1`, attempt.ID)
return pkgerrors.Wrap(err, "DeleteInProgressAttempt failed")
}
@@ -1058,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)
@@ -1066,20 +1079,20 @@ 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)
- return pkgerrors.Wrap(e, "SaveInProgressAttempt failed to insert into eth_tx_attempts")
+ 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
- res, err := o.q.Exec(`UPDATE eth_tx_attempts SET state=$1, broadcast_before_block_num=$2 WHERE id=$3`, dbAttempt.State, dbAttempt.BroadcastBeforeBlockNum, dbAttempt.ID)
+ res, err := o.q.Exec(`UPDATE evm.tx_attempts SET state=$1, broadcast_before_block_num=$2 WHERE id=$3`, dbAttempt.State, dbAttempt.BroadcastBeforeBlockNum, dbAttempt.ID)
if err != nil {
- return pkgerrors.Wrap(err, "SaveInProgressAttempt failed to update eth_tx_attempts")
+ return pkgerrors.Wrap(err, "SaveInProgressAttempt failed to update evm.tx_attempts")
}
rowsAffected, err := res.RowsAffected()
if err != nil {
return pkgerrors.Wrap(err, "SaveInProgressAttempt failed to get RowsAffected")
}
if rowsAffected == 0 {
- return pkgerrors.Wrapf(sql.ErrNoRows, "SaveInProgressAttempt tried to update eth_tx_attempts but no rows matched id %d", attempt.ID)
+ return pkgerrors.Wrapf(sql.ErrNoRows, "SaveInProgressAttempt tried to update evm.tx_attempts but no rows matched id %d", attempt.ID)
}
return nil
}
@@ -1088,7 +1101,7 @@ func (o *evmTxStore) SaveInProgressAttempt(attempt *TxAttempt) error {
// attempts which are unconfirmed for at least gasBumpThreshold blocks,
// limited by limit pending transactions
//
-// It also returns eth_txes that are unconfirmed with no eth_tx_attempts
+// It also returns evm.txes that are unconfirmed with no evm.tx_attempts
func (o *evmTxStore) FindTxsRequiringGasBump(ctx context.Context, address common.Address, blockNum, gasBumpThreshold, depth int64, chainID *big.Int) (etxs []*Tx, err error) {
if gasBumpThreshold == 0 {
return
@@ -1096,20 +1109,20 @@ func (o *evmTxStore) FindTxsRequiringGasBump(ctx context.Context, address common
qq := o.q.WithOpts(pg.WithParentCtx(ctx))
err = qq.Transaction(func(tx pg.Queryer) error {
stmt := `
-SELECT eth_txes.* FROM eth_txes
-LEFT JOIN eth_tx_attempts ON eth_txes.id = eth_tx_attempts.eth_tx_id AND (broadcast_before_block_num > $4 OR broadcast_before_block_num IS NULL OR eth_tx_attempts.state != 'broadcast')
-WHERE eth_txes.state = 'unconfirmed' AND eth_tx_attempts.id IS NULL AND eth_txes.from_address = $1 AND eth_txes.evm_chain_id = $2
- AND (($3 = 0) OR (eth_txes.id IN (SELECT id FROM eth_txes WHERE state = 'unconfirmed' AND from_address = $1 ORDER BY nonce ASC LIMIT $3)))
+SELECT evm.txes.* FROM evm.txes
+LEFT JOIN evm.tx_attempts ON evm.txes.id = evm.tx_attempts.eth_tx_id AND (broadcast_before_block_num > $4 OR broadcast_before_block_num IS NULL OR evm.tx_attempts.state != 'broadcast')
+WHERE evm.txes.state = 'unconfirmed' AND evm.tx_attempts.id IS NULL AND evm.txes.from_address = $1 AND evm.txes.evm_chain_id = $2
+ AND (($3 = 0) OR (evm.txes.id IN (SELECT id FROM evm.txes WHERE state = 'unconfirmed' AND from_address = $1 ORDER BY nonce ASC LIMIT $3)))
ORDER BY nonce ASC
`
var dbEtxs []DbEthTx
if err = tx.Select(&dbEtxs, stmt, address, chainID.String(), depth, blockNum-gasBumpThreshold); err != nil {
- return pkgerrors.Wrap(err, "FindEthTxsRequiringGasBump failed to load eth_txes")
+ return pkgerrors.Wrap(err, "FindEthTxsRequiringGasBump failed to load evm.txes")
}
etxs = make([]*Tx, len(dbEtxs))
dbEthTxsToEvmEthTxPtrs(dbEtxs, etxs)
err = o.LoadTxesAttempts(etxs, pg.WithQueryer(tx))
- return pkgerrors.Wrap(err, "FindEthTxsRequiringGasBump failed to load eth_tx_attempts")
+ return pkgerrors.Wrap(err, "FindEthTxsRequiringGasBump failed to load evm.tx_attempts")
}, pg.OptReadOnlyTx())
return
}
@@ -1122,18 +1135,18 @@ func (o *evmTxStore) FindTxsRequiringResubmissionDueToInsufficientFunds(address
err = qq.Transaction(func(tx pg.Queryer) error {
var dbEtxs []DbEthTx
err = tx.Select(&dbEtxs, `
-SELECT DISTINCT eth_txes.* FROM eth_txes
-INNER JOIN eth_tx_attempts ON eth_txes.id = eth_tx_attempts.eth_tx_id AND eth_tx_attempts.state = 'insufficient_eth'
-WHERE eth_txes.from_address = $1 AND eth_txes.state = 'unconfirmed' AND eth_txes.evm_chain_id = $2
+SELECT DISTINCT evm.txes.* FROM evm.txes
+INNER JOIN evm.tx_attempts ON evm.txes.id = evm.tx_attempts.eth_tx_id AND evm.tx_attempts.state = 'insufficient_eth'
+WHERE evm.txes.from_address = $1 AND evm.txes.state = 'unconfirmed' AND evm.txes.evm_chain_id = $2
ORDER BY nonce ASC
`, address, chainID.String())
if err != nil {
- return pkgerrors.Wrap(err, "FindEthTxsRequiringResubmissionDueToInsufficientEth failed to load eth_txes")
+ return pkgerrors.Wrap(err, "FindEthTxsRequiringResubmissionDueToInsufficientEth failed to load evm.txes")
}
etxs = make([]*Tx, len(dbEtxs))
dbEthTxsToEvmEthTxPtrs(dbEtxs, etxs)
err = o.LoadTxesAttempts(etxs, pg.WithQueryer(tx))
- return pkgerrors.Wrap(err, "FindEthTxsRequiringResubmissionDueToInsufficientEth failed to load eth_tx_attempts")
+ return pkgerrors.Wrap(err, "FindEthTxsRequiringResubmissionDueToInsufficientEth failed to load evm.tx_attempts")
}, pg.OptReadOnlyTx())
return
}
@@ -1165,20 +1178,20 @@ func (o *evmTxStore) MarkOldTxesMissingReceiptAsErrored(blockNum int64, finality
}
var data []etx
err := q.Select(&data, `
-UPDATE eth_txes
+UPDATE evm.txes
SET state='fatal_error', nonce=NULL, error=$1, broadcast_at=NULL, initial_broadcast_at=NULL
FROM (
- SELECT e1.id, e1.nonce, e1.from_address FROM eth_txes AS e1 WHERE id IN (
- SELECT e2.id FROM eth_txes AS e2
- INNER JOIN eth_tx_attempts ON e2.id = eth_tx_attempts.eth_tx_id
+ SELECT e1.id, e1.nonce, e1.from_address FROM evm.txes AS e1 WHERE id IN (
+ SELECT e2.id FROM evm.txes AS e2
+ INNER JOIN evm.tx_attempts ON e2.id = evm.tx_attempts.eth_tx_id
WHERE e2.state = 'confirmed_missing_receipt'
AND e2.evm_chain_id = $3
GROUP BY e2.id
- HAVING max(eth_tx_attempts.broadcast_before_block_num) < $2
+ HAVING max(evm.tx_attempts.broadcast_before_block_num) < $2
)
FOR UPDATE OF e1
) e0
-WHERE e0.id = eth_txes.id
+WHERE e0.id = evm.txes.id
RETURNING e0.id, e0.nonce`, ErrCouldNotGetReceipt, cutoff, chainID.String())
if err != nil {
@@ -1206,8 +1219,8 @@ RETURNING e0.id, e0.nonce`, ErrCouldNotGetReceipt, cutoff, chainID.String())
var results []result
err = q.Select(&results, `
SELECT e.id, e.from_address, max(a.broadcast_before_block_num) AS max_broadcast_before_block_num, array_agg(a.hash) AS tx_hashes
-FROM eth_txes e
-INNER JOIN eth_tx_attempts a ON e.id = a.eth_tx_id
+FROM evm.txes e
+INNER JOIN evm.tx_attempts a ON e.id = a.eth_tx_id
WHERE e.id = ANY($1)
GROUP BY e.id
`, etxIDs)
@@ -1245,16 +1258,17 @@ func (o *evmTxStore) SaveReplacementInProgressAttempt(oldAttempt TxAttempt, repl
return errors.New("expected oldAttempt to have an ID")
}
return qq.Transaction(func(tx pg.Queryer) error {
- if _, err := tx.Exec(`DELETE FROM eth_tx_attempts WHERE id=$1`, oldAttempt.ID); err != nil {
- return pkgerrors.Wrap(err, "saveReplacementInProgressAttempt failed to delete from eth_tx_attempts")
+ 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")
})
}
@@ -1263,8 +1277,8 @@ func (o *evmTxStore) SaveReplacementInProgressAttempt(oldAttempt TxAttempt, repl
func (o *evmTxStore) FindNextUnstartedTransactionFromAddress(etx *Tx, fromAddress common.Address, chainID *big.Int, qopts ...pg.QOpt) error {
qq := o.q.WithOpts(qopts...)
var dbEtx DbEthTx
- err := qq.Get(&dbEtx, `SELECT * FROM eth_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)
+ 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())
+ dbEtx.ToTx(etx)
return pkgerrors.Wrap(err, "failed to FindNextUnstartedTransactionFromAddress")
}
@@ -1282,12 +1296,13 @@ func (o *evmTxStore) UpdateTxFatalError(etx *Tx, qopts ...pg.QOpt) error {
etx.State = txmgr.TxFatalError
return qq.Transaction(func(tx pg.Queryer) error {
- if _, err := tx.Exec(`DELETE FROM eth_tx_attempts WHERE eth_tx_id = $1`, etx.ID); err != nil {
+ 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)
- err := pkgerrors.Wrap(tx.Get(&dbEtx, `UPDATE eth_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)
+ 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")
+ dbEtx.ToTx(etx)
return err
})
}
@@ -1319,13 +1334,15 @@ 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)
- if err := tx.Get(&dbEtx, `UPDATE eth_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 {
+ 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)
- if err := tx.Get(&dbAttempt, `UPDATE eth_tx_attempts SET state = $1 WHERE id = $2 RETURNING *`, dbAttempt.State, dbAttempt.ID); err != nil {
+ 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")
}
return nil
@@ -1347,13 +1364,13 @@ func (o *evmTxStore) UpdateTxUnstartedToInProgress(etx *Tx, attempt *TxAttempt,
etx.State = txmgr.TxInProgress
return qq.Transaction(func(tx pg.Queryer) error {
// If a replay was triggered while unconfirmed transactions were pending, they will be marked as fatal_error => abandoned.
- // In this case, we must remove the abandoned attempt from eth_tx_attempts before replacing it with a new one. In any other
+ // In this case, we must remove the abandoned attempt from evm.tx_attempts before replacing it with a new one. In any other
// case, we uphold the constraint, leaving the original tx attempt as-is and returning the constraint violation error.
//
- // Note: the record of the original abandoned transaction will remain in eth_txes, only the attempt is replaced. (Any receipt
+ // Note: the record of the original abandoned transaction will remain in evm.txes, only the attempt is replaced. (Any receipt
// associated with the abandoned attempt would also be lost, although this shouldn't happen since only unconfirmed transactions
// can be abandoned.)
- _, err := tx.Exec(`DELETE FROM eth_tx_attempts a USING eth_txes t
+ _, err := tx.Exec(`DELETE FROM evm.tx_attempts a USING evm.txes t
WHERE t.id = a.eth_tx_id AND a.hash = $1 AND t.state = $2 AND t.error = 'abandoned'`,
attempt.Hash, txmgr.TxFatalError,
)
@@ -1363,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")
@@ -1371,21 +1389,20 @@ func (o *evmTxStore) UpdateTxUnstartedToInProgress(etx *Tx, attempt *TxAttempt,
err = tx.Get(&dbAttempt, query, args...)
if err != nil {
var pqErr *pgconn.PgError
- if isPqErr := errors.As(err, &pqErr); isPqErr {
- switch pqErr.ConstraintName {
- case "eth_tx_attempts_eth_tx_id_fkey":
- return txmgr.ErrTxRemoved
- default:
- }
+ if isPqErr := errors.As(err, &pqErr); isPqErr &&
+ pqErr.SchemaName == "evm" &&
+ pqErr.ConstraintName == "eth_tx_attempts_eth_tx_id_fkey" {
+ return txmgr.ErrTxRemoved
}
if err != nil {
return pkgerrors.Wrap(err, "UpdateTxUnstartedToInProgress failed to create eth_tx_attempt")
}
}
- DbEthTxAttemptToEthTxAttempt(dbAttempt, attempt)
- dbEtx := DbEthTxFromEthTx(etx)
- err = tx.Get(&dbEtx, `UPDATE eth_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)
+ 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)
+ dbEtx.ToTx(etx)
return pkgerrors.Wrap(err, "UpdateTxUnstartedToInProgress failed to update eth_tx")
})
}
@@ -1402,14 +1419,14 @@ func (o *evmTxStore) GetTxInProgress(fromAddress common.Address, qopts ...pg.QOp
}
err = qq.Transaction(func(tx pg.Queryer) error {
var dbEtx DbEthTx
- err = tx.Get(&dbEtx, `SELECT * FROM eth_txes WHERE from_address = $1 and state = 'in_progress'`, fromAddress)
+ err = tx.Get(&dbEtx, `SELECT * FROM evm.txes WHERE from_address = $1 and state = 'in_progress'`, fromAddress)
if errors.Is(err, sql.ErrNoRows) {
etx = nil
return nil
} 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")
}
@@ -1425,7 +1442,7 @@ func (o *evmTxStore) GetTxInProgress(fromAddress common.Address, qopts ...pg.QOp
func (o *evmTxStore) HasInProgressTransaction(account common.Address, chainID *big.Int, qopts ...pg.QOpt) (exists bool, err error) {
qq := o.q.WithOpts(qopts...)
- err = qq.Get(&exists, `SELECT EXISTS(SELECT 1 FROM eth_txes WHERE state = 'in_progress' AND from_address = $1 AND evm_chain_id = $2)`, account, chainID.String())
+ err = qq.Get(&exists, `SELECT EXISTS(SELECT 1 FROM evm.txes WHERE state = 'in_progress' AND from_address = $1 AND evm_chain_id = $2)`, account, chainID.String())
return exists, pkgerrors.Wrap(err, "hasInProgressTransaction failed")
}
@@ -1434,7 +1451,7 @@ func (o *evmTxStore) UpdateKeyNextSequence(newNextNonce, currentNextNonce evmtyp
return qq.Transaction(func(tx pg.Queryer) error {
// We filter by next_nonce here as an optimistic lock to make sure it
// didn't get changed out from under us. Shouldn't happen but can't hurt.
- res, err := tx.Exec(`UPDATE evm_key_states SET next_nonce = $1, updated_at = $2 WHERE address = $3 AND next_nonce = $4 AND evm_chain_id = $5`, newNextNonce.Int64(), time.Now(), address, currentNextNonce.Int64(), chainID.String())
+ res, err := tx.Exec(`UPDATE evm.key_states SET next_nonce = $1, updated_at = $2 WHERE address = $3 AND next_nonce = $4 AND evm_chain_id = $5`, newNextNonce.Int64(), time.Now(), address, currentNextNonce.Int64(), chainID.String())
if err != nil {
return pkgerrors.Wrap(err, "NonceSyncer#fastForwardNonceIfNecessary failed to update keys.next_nonce")
}
@@ -1451,7 +1468,7 @@ func (o *evmTxStore) UpdateKeyNextSequence(newNextNonce, currentNextNonce evmtyp
func (o *evmTxStore) countTransactionsWithState(fromAddress common.Address, state txmgrtypes.TxState, chainID *big.Int, qopts ...pg.QOpt) (count uint32, err error) {
qq := o.q.WithOpts(qopts...)
- err = qq.Get(&count, `SELECT count(*) FROM eth_txes WHERE from_address = $1 AND state = $2 AND evm_chain_id = $3`,
+ err = qq.Get(&count, `SELECT count(*) FROM evm.txes WHERE from_address = $1 AND state = $2 AND evm_chain_id = $3`,
fromAddress, state, chainID.String())
return count, pkgerrors.Wrap(err, "failed to countTransactionsWithState")
}
@@ -1472,7 +1489,7 @@ func (o *evmTxStore) CheckTxQueueCapacity(fromAddress common.Address, maxQueuedT
return nil
}
var count uint64
- err = qq.Get(&count, `SELECT count(*) FROM eth_txes WHERE from_address = $1 AND state = 'unstarted' AND evm_chain_id = $2`, fromAddress, chainID.String())
+ err = qq.Get(&count, `SELECT count(*) FROM evm.txes WHERE from_address = $1 AND state = 'unstarted' AND evm_chain_id = $2`, fromAddress, chainID.String())
if err != nil {
err = pkgerrors.Wrap(err, "CheckTxQueueCapacity query failed")
return
@@ -1490,7 +1507,7 @@ func (o *evmTxStore) CreateTransaction(txRequest TxRequest, chainID *big.Int, qo
err = qq.Transaction(func(tx pg.Queryer) error {
if txRequest.PipelineTaskRunID != nil {
- err = tx.Get(&dbEtx, `SELECT * FROM eth_txes WHERE pipeline_task_run_id = $1 AND evm_chain_id = $2`, txRequest.PipelineTaskRunID, chainID.String())
+ err = tx.Get(&dbEtx, `SELECT * FROM evm.txes WHERE pipeline_task_run_id = $1 AND evm_chain_id = $2`, txRequest.PipelineTaskRunID, chainID.String())
// If no eth_tx matches (the common case) then continue
if !errors.Is(err, sql.ErrNoRows) {
if err != nil {
@@ -1501,19 +1518,19 @@ func (o *evmTxStore) CreateTransaction(txRequest TxRequest, chainID *big.Int, qo
}
}
err = tx.Get(&dbEtx, `
-INSERT INTO eth_txes (from_address, to_address, encoded_payload, value, gas_limit, state, created_at, meta, subject, evm_chain_id, min_confirmations, pipeline_task_run_id, transmit_checker)
+INSERT INTO evm.txes (from_address, to_address, encoded_payload, value, gas_limit, state, created_at, meta, subject, evm_chain_id, min_confirmations, pipeline_task_run_id, transmit_checker, idempotency_key)
VALUES (
-$1,$2,$3,$4,$5,'unstarted',NOW(),$6,$7,$8,$9,$10,$11
+$1,$2,$3,$4,$5,'unstarted',NOW(),$6,$7,$8,$9,$10,$11,$12
)
-RETURNING "eth_txes".*
-`, txRequest.FromAddress, txRequest.ToAddress, txRequest.EncodedPayload, assets.Eth(txRequest.Value), txRequest.FeeLimit, txRequest.Meta, txRequest.Strategy.Subject(), chainID.String(), txRequest.MinConfirmations, txRequest.PipelineTaskRunID, txRequest.Checker)
+RETURNING "txes".*
+`, txRequest.FromAddress, txRequest.ToAddress, txRequest.EncodedPayload, assets.Eth(txRequest.Value), txRequest.FeeLimit, txRequest.Meta, txRequest.Strategy.Subject(), chainID.String(), txRequest.MinConfirmations, txRequest.PipelineTaskRunID, txRequest.Checker, txRequest.IdempotencyKey)
if err != nil {
- return pkgerrors.Wrap(err, "CreateEthTransaction failed to insert eth_tx")
+ return pkgerrors.Wrap(err, "CreateEthTransaction failed to insert evm tx")
}
var pruned int64
pruned, err = txRequest.Strategy.PruneQueue(o, pg.WithQueryer(tx))
if err != nil {
- return pkgerrors.Wrap(err, "CreateEthTransaction failed to prune eth_txes")
+ return pkgerrors.Wrap(err, "CreateEthTransaction failed to prune evm.txes")
}
if pruned > 0 {
o.logger.Warnw(fmt.Sprintf("Dropped %d old transactions from transaction queue", pruned), "fromAddress", txRequest.FromAddress, "toAddress", txRequest.ToAddress, "meta", txRequest.Meta, "subject", txRequest.Strategy.Subject(), "replacementID", dbEtx.ID)
@@ -1521,7 +1538,7 @@ RETURNING "eth_txes".*
return nil
})
var etx Tx
- DbEthTxToEthTx(dbEtx, &etx)
+ dbEtx.ToTx(&etx)
return etx, err
}
@@ -1529,12 +1546,12 @@ func (o *evmTxStore) PruneUnstartedTxQueue(queueSize uint32, subject uuid.UUID,
qq := o.q.WithOpts(qopts...)
err = qq.Transaction(func(tx pg.Queryer) error {
res, err := qq.Exec(`
-DELETE FROM eth_txes
+DELETE FROM evm.txes
WHERE state = 'unstarted' AND subject = $1 AND
id < (
SELECT min(id) FROM (
SELECT id
- FROM eth_txes
+ FROM evm.txes
WHERE state = 'unstarted' AND subject = $2
ORDER BY id DESC
LIMIT $3
@@ -1550,26 +1567,26 @@ id < (
}
func (o *evmTxStore) ReapTxHistory(minBlockNumberToKeep int64, timeThreshold time.Time, chainID *big.Int) error {
- // Delete old confirmed eth_txes
+ // Delete old confirmed evm.txes
// NOTE that this relies on foreign key triggers automatically removing
- // the eth_tx_attempts and eth_receipts linked to every eth_tx
+ // the evm.tx_attempts and evm.receipts linked to every eth_tx
err := pg.Batch(func(_, limit uint) (count uint, err error) {
res, err := o.q.Exec(`
WITH old_enough_receipts AS (
- SELECT tx_hash FROM eth_receipts
+ SELECT tx_hash FROM evm.receipts
WHERE block_number < $1
ORDER BY block_number ASC, id ASC
LIMIT $2
)
-DELETE FROM eth_txes
-USING old_enough_receipts, eth_tx_attempts
-WHERE eth_tx_attempts.eth_tx_id = eth_txes.id
-AND eth_tx_attempts.hash = old_enough_receipts.tx_hash
-AND eth_txes.created_at < $3
-AND eth_txes.state = 'confirmed'
+DELETE FROM evm.txes
+USING old_enough_receipts, evm.tx_attempts
+WHERE evm.tx_attempts.eth_tx_id = evm.txes.id
+AND evm.tx_attempts.hash = old_enough_receipts.tx_hash
+AND evm.txes.created_at < $3
+AND evm.txes.state = 'confirmed'
AND evm_chain_id = $4`, minBlockNumberToKeep, limit, timeThreshold, chainID.String())
if err != nil {
- return count, pkgerrors.Wrap(err, "ReapTxes failed to delete old confirmed eth_txes")
+ return count, pkgerrors.Wrap(err, "ReapTxes failed to delete old confirmed evm.txes")
}
rowsAffected, err := res.RowsAffected()
if err != nil {
@@ -1578,17 +1595,17 @@ AND evm_chain_id = $4`, minBlockNumberToKeep, limit, timeThreshold, chainID.Stri
return uint(rowsAffected), err
})
if err != nil {
- return pkgerrors.Wrap(err, "TxmReaper#reapEthTxes batch delete of confirmed eth_txes failed")
+ return pkgerrors.Wrap(err, "TxmReaper#reapEthTxes batch delete of confirmed evm.txes failed")
}
- // Delete old 'fatal_error' eth_txes
+ // Delete old 'fatal_error' evm.txes
err = pg.Batch(func(_, limit uint) (count uint, err error) {
res, err := o.q.Exec(`
-DELETE FROM eth_txes
+DELETE FROM evm.txes
WHERE created_at < $1
AND state = 'fatal_error'
AND evm_chain_id = $2`, timeThreshold, chainID.String())
if err != nil {
- return count, pkgerrors.Wrap(err, "ReapTxes failed to delete old fatally errored eth_txes")
+ return count, pkgerrors.Wrap(err, "ReapTxes failed to delete old fatally errored evm.txes")
}
rowsAffected, err := res.RowsAffected()
if err != nil {
@@ -1597,13 +1614,13 @@ AND evm_chain_id = $2`, timeThreshold, chainID.String())
return uint(rowsAffected), err
})
if err != nil {
- return pkgerrors.Wrap(err, "TxmReaper#reapEthTxes batch delete of fatally errored eth_txes failed")
+ return pkgerrors.Wrap(err, "TxmReaper#reapEthTxes batch delete of fatally errored evm.txes failed")
}
return nil
}
func (o *evmTxStore) Abandon(chainID *big.Int, addr common.Address) error {
- _, err := o.q.Exec(`UPDATE eth_txes SET state='fatal_error', nonce = NULL, error = 'abandoned' WHERE state IN ('unconfirmed', 'in_progress', 'unstarted') AND evm_chain_id = $1 AND from_address = $2`, chainID.String(), addr)
+ _, err := o.q.Exec(`UPDATE evm.txes SET state='fatal_error', nonce = NULL, error = 'abandoned' WHERE state IN ('unconfirmed', 'in_progress', 'unstarted') AND evm_chain_id = $1 AND from_address = $2`, chainID.String(), addr)
return err
}
diff --git a/core/chains/evm/txmgr/evm_tx_store_test.go b/core/chains/evm/txmgr/evm_tx_store_test.go
index b4be30063b5..913652b7c8b 100644
--- a/core/chains/evm/txmgr/evm_tx_store_test.go
+++ b/core/chains/evm/txmgr/evm_tx_store_test.go
@@ -55,7 +55,7 @@ func TestORM_TransactionsWithAttempts(t *testing.T) {
cltest.MustCreateUnstartedGeneratedTx(t, txStore, from, &cltest.FixtureChainID)
var count int
- err := db.Get(&count, `SELECT count(*) FROM eth_txes`)
+ err := db.Get(&count, `SELECT count(*) FROM evm.txes`)
require.NoError(t, err)
require.Equal(t, 3, count)
@@ -100,7 +100,7 @@ func TestORM_Transactions(t *testing.T) {
cltest.MustCreateUnstartedGeneratedTx(t, txStore, from, &cltest.FixtureChainID)
var count int
- err := db.Get(&count, `SELECT count(*) FROM eth_txes`)
+ err := db.Get(&count, `SELECT count(*) FROM evm.txes`)
require.NoError(t, err)
require.Equal(t, 3, count)
@@ -130,7 +130,7 @@ func TestORM(t *testing.T) {
err = orm.InsertTx(&etx)
require.NoError(t, err)
assert.Greater(t, int(etx.ID), 0)
- cltest.AssertCount(t, db, "eth_txes", 1)
+ cltest.AssertCount(t, db, "evm.txes", 1)
})
var attemptL txmgr.TxAttempt
var attemptD txmgr.TxAttempt
@@ -139,7 +139,7 @@ func TestORM(t *testing.T) {
err = orm.InsertTxAttempt(&attemptD)
require.NoError(t, err)
assert.Greater(t, int(attemptD.ID), 0)
- cltest.AssertCount(t, db, "eth_tx_attempts", 1)
+ cltest.AssertCount(t, db, "evm.tx_attempts", 1)
attemptL = cltest.NewLegacyEthTxAttempt(t, etx.ID)
attemptL.State = txmgrtypes.TxAttemptBroadcast
@@ -147,7 +147,7 @@ func TestORM(t *testing.T) {
err = orm.InsertTxAttempt(&attemptL)
require.NoError(t, err)
assert.Greater(t, int(attemptL.ID), 0)
- cltest.AssertCount(t, db, "eth_tx_attempts", 2)
+ cltest.AssertCount(t, db, "evm.tx_attempts", 2)
})
var r txmgr.Receipt
t.Run("InsertReceipt", func(t *testing.T) {
@@ -156,7 +156,7 @@ func TestORM(t *testing.T) {
r.ID = id
require.NoError(t, err)
assert.Greater(t, int(r.ID), 0)
- cltest.AssertCount(t, db, "eth_receipts", 1)
+ cltest.AssertCount(t, db, "evm.receipts", 1)
})
t.Run("FindTxWithAttempts", func(t *testing.T) {
etx, err = orm.FindTxWithAttempts(etx.ID)
@@ -217,11 +217,11 @@ func TestORM_FindTxAttemptConfirmedByTxIDs(t *testing.T) {
cltest.MustInsertUnconfirmedEthTxWithBroadcastLegacyAttempt(t, orm, 4, from) // tx5
var count int
- err = db.Get(&count, `SELECT count(*) FROM eth_txes`)
+ err = db.Get(&count, `SELECT count(*) FROM evm.txes`)
require.NoError(t, err)
require.Equal(t, 5, count)
- err = db.Get(&count, `SELECT count(*) FROM eth_tx_attempts`)
+ err = db.Get(&count, `SELECT count(*) FROM evm.tx_attempts`)
require.NoError(t, err)
require.Equal(t, 4, count)
@@ -385,7 +385,7 @@ func TestORM_SetBroadcastBeforeBlockNum(t *testing.T) {
headNum := int64(9000)
var err error
- t.Run("saves block num to unconfirmed eth_tx_attempts without one", func(t *testing.T) {
+ t.Run("saves block num to unconfirmed evm.tx_attempts without one", func(t *testing.T) {
// Do the thing
require.NoError(t, txStore.SetBroadcastBeforeBlockNum(headNum, chainID))
@@ -397,7 +397,7 @@ func TestORM_SetBroadcastBeforeBlockNum(t *testing.T) {
assert.Equal(t, int64(9000), *attempt.BroadcastBeforeBlockNum)
})
- t.Run("does not change eth_tx_attempts that already have BroadcastBeforeBlockNum set", func(t *testing.T) {
+ t.Run("does not change evm.tx_attempts that already have BroadcastBeforeBlockNum set", func(t *testing.T) {
n := int64(42)
attempt := newBroadcastLegacyEthTxAttempt(t, etx.ID, 2)
attempt.BroadcastBeforeBlockNum = &n
@@ -414,10 +414,10 @@ func TestORM_SetBroadcastBeforeBlockNum(t *testing.T) {
assert.Equal(t, int64(42), *attempt.BroadcastBeforeBlockNum)
})
- t.Run("only updates eth_tx_attempts for the current chain", func(t *testing.T) {
+ t.Run("only updates evm.tx_attempts for the current chain", func(t *testing.T) {
require.NoError(t, ethKeyStore.Add(fromAddress, testutils.SimulatedChainID))
require.NoError(t, ethKeyStore.Enable(fromAddress, testutils.SimulatedChainID))
- etxThisChain := cltest.MustInsertUnconfirmedEthTxWithBroadcastLegacyAttempt(t, txStore, 1, fromAddress, cfg.DefaultChainID())
+ etxThisChain := cltest.MustInsertUnconfirmedEthTxWithBroadcastLegacyAttempt(t, txStore, 1, fromAddress, cfg.EVM().ChainID())
etxOtherChain := cltest.MustInsertUnconfirmedEthTxWithBroadcastLegacyAttempt(t, txStore, 0, fromAddress, testutils.SimulatedChainID)
require.NoError(t, txStore.SetBroadcastBeforeBlockNum(headNum, chainID))
@@ -654,11 +654,11 @@ func TestORM_FindReceiptsPendingConfirmation(t *testing.T) {
pgtest.MustExec(t, db, `UPDATE pipeline_runs SET state = 'suspended' WHERE id = $1`, run.ID)
etx := cltest.MustInsertConfirmedEthTxWithLegacyAttempt(t, txStore, 3, 1, fromAddress)
- pgtest.MustExec(t, db, `UPDATE eth_txes SET meta='{"FailOnRevert": true}'`)
+ pgtest.MustExec(t, db, `UPDATE evm.txes SET meta='{"FailOnRevert": true}'`)
attempt := etx.TxAttempts[0]
cltest.MustInsertEthReceipt(t, txStore, head.Number-minConfirmations, head.Hash, attempt.Hash)
- pgtest.MustExec(t, db, `UPDATE eth_txes SET pipeline_task_run_id = $1, min_confirmations = $2 WHERE id = $3`, &tr.ID, minConfirmations, etx.ID)
+ pgtest.MustExec(t, db, `UPDATE evm.txes SET pipeline_task_run_id = $1, min_confirmations = $2 WHERE id = $3`, &tr.ID, minConfirmations, etx.ID)
receiptsPlus, err := txStore.FindReceiptsPendingConfirmation(testutils.Context(t), head.Number, ethClient.ConfiguredChainID())
require.NoError(t, err)
@@ -666,6 +666,35 @@ func TestORM_FindReceiptsPendingConfirmation(t *testing.T) {
assert.Equal(t, tr.ID, receiptsPlus[0].ID)
}
+func Test_FindTxWithIdempotencyKey(t *testing.T) {
+ t.Parallel()
+ db := pgtest.NewSqlxDB(t)
+ cfg := newTestChainScopedConfig(t)
+ txStore := cltest.NewTestTxStore(t, db, cfg.Database())
+ ethKeyStore := cltest.NewKeyStore(t, db, cfg.Database()).Eth()
+ _, fromAddress := cltest.MustInsertRandomKeyReturningState(t, ethKeyStore, 0)
+
+ t.Run("returns nil if no results", func(t *testing.T) {
+ idempotencyKey := "777"
+ etx, err := txStore.FindTxWithIdempotencyKey(idempotencyKey, big.NewInt(0))
+ require.NoError(t, err)
+ assert.Nil(t, etx)
+ })
+
+ t.Run("returns transaction if it exists", func(t *testing.T) {
+ idempotencyKey := "777"
+ cfg.EVM().ChainID()
+ etx := cltest.MustCreateUnstartedGeneratedTx(t, txStore, fromAddress, big.NewInt(0),
+ cltest.EvmTxRequestWithIdempotencyKey(idempotencyKey))
+ require.Equal(t, idempotencyKey, *etx.IdempotencyKey)
+
+ res, err := txStore.FindTxWithIdempotencyKey(idempotencyKey, big.NewInt(0))
+ require.NoError(t, err)
+ assert.Equal(t, etx.Sequence, res.Sequence)
+ require.Equal(t, idempotencyKey, *res.IdempotencyKey)
+ })
+}
+
func TestORM_FindTxWithSequence(t *testing.T) {
t.Parallel()
@@ -992,8 +1021,8 @@ func TestEthConfirmer_FindTxsRequiringResubmissionDueToInsufficientEth(t *testin
})
t.Run("does not return confirmed or fatally errored eth_txes", func(t *testing.T) {
- pgtest.MustExec(t, db, `UPDATE eth_txes SET state='confirmed' WHERE id = $1`, etx1.ID)
- pgtest.MustExec(t, db, `UPDATE eth_txes SET state='fatal_error', nonce=NULL, error='foo', broadcast_at=NULL, initial_broadcast_at=NULL WHERE id = $1`, etx2.ID)
+ pgtest.MustExec(t, db, `UPDATE evm.txes SET state='confirmed' WHERE id = $1`, etx1.ID)
+ pgtest.MustExec(t, db, `UPDATE evm.txes SET state='fatal_error', nonce=NULL, error='foo', broadcast_at=NULL, initial_broadcast_at=NULL WHERE id = $1`, etx2.ID)
etxs, err := txStore.FindTxsRequiringResubmissionDueToInsufficientFunds(fromAddress, &cltest.FixtureChainID)
require.NoError(t, err)
@@ -1071,9 +1100,10 @@ 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 eth_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 (
+ 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
) RETURNING *`
_, err := tx.NamedExec(insertEthTxAttemptSQL, dbAttempt)
@@ -1233,7 +1263,7 @@ func TestORM_UpdateTxUnstartedToInProgress(t *testing.T) {
attempt := cltest.NewLegacyEthTxAttempt(t, etx.ID)
- err := q.ExecQ("DELETE FROM eth_txes WHERE id = $1", etx.ID)
+ err := q.ExecQ("DELETE FROM evm.txes WHERE id = $1", etx.ID)
require.NoError(t, err)
err = txStore.UpdateTxUnstartedToInProgress(&etx, &attempt)
@@ -1545,10 +1575,10 @@ func TestORM_CreateTransaction(t *testing.T) {
assert.Equal(t, big.Int(assets.NewEthValue(0)), etx.Value)
assert.Equal(t, subject, etx.Subject.UUID)
- cltest.AssertCount(t, db, "eth_txes", 1)
+ cltest.AssertCount(t, db, "evm.txes", 1)
var dbEthTx txmgr.DbEthTx
- require.NoError(t, db.Get(&dbEthTx, `SELECT * FROM eth_txes ORDER BY id ASC LIMIT 1`))
+ require.NoError(t, db.Get(&dbEthTx, `SELECT * FROM evm.txes ORDER BY id ASC LIMIT 1`))
assert.Equal(t, dbEthTx.State, txmgrcommon.TxUnstarted)
assert.Equal(t, gasLimit, dbEthTx.GasLimit)
diff --git a/core/chains/evm/txmgr/mocks/evm_tx_store.go b/core/chains/evm/txmgr/mocks/evm_tx_store.go
index a2cd12d3f21..4a06741a2f3 100644
--- a/core/chains/evm/txmgr/mocks/evm_tx_store.go
+++ b/core/chains/evm/txmgr/mocks/evm_tx_store.go
@@ -404,6 +404,56 @@ func (_m *EvmTxStore) FindTxByHash(hash common.Hash) (*types.Tx[*big.Int, common
return r0, r1
}
+// FindTxWithAttempts provides a mock function with given fields: etxID
+func (_m *EvmTxStore) FindTxWithAttempts(etxID int64) (types.Tx[*big.Int, common.Address, common.Hash, common.Hash, evmtypes.Nonce, gas.EvmFee], error) {
+ ret := _m.Called(etxID)
+
+ var r0 types.Tx[*big.Int, common.Address, common.Hash, common.Hash, evmtypes.Nonce, gas.EvmFee]
+ var r1 error
+ if rf, ok := ret.Get(0).(func(int64) (types.Tx[*big.Int, common.Address, common.Hash, common.Hash, evmtypes.Nonce, gas.EvmFee], error)); ok {
+ return rf(etxID)
+ }
+ if rf, ok := ret.Get(0).(func(int64) types.Tx[*big.Int, common.Address, common.Hash, common.Hash, evmtypes.Nonce, gas.EvmFee]); ok {
+ r0 = rf(etxID)
+ } else {
+ r0 = ret.Get(0).(types.Tx[*big.Int, common.Address, common.Hash, common.Hash, evmtypes.Nonce, gas.EvmFee])
+ }
+
+ if rf, ok := ret.Get(1).(func(int64) error); ok {
+ r1 = rf(etxID)
+ } else {
+ r1 = ret.Error(1)
+ }
+
+ return r0, r1
+}
+
+// FindTxWithIdempotencyKey provides a mock function with given fields: idempotencyKey, chainID
+func (_m *EvmTxStore) FindTxWithIdempotencyKey(idempotencyKey string, chainID *big.Int) (*types.Tx[*big.Int, common.Address, common.Hash, common.Hash, evmtypes.Nonce, gas.EvmFee], error) {
+ ret := _m.Called(idempotencyKey, chainID)
+
+ var r0 *types.Tx[*big.Int, common.Address, common.Hash, common.Hash, evmtypes.Nonce, gas.EvmFee]
+ var r1 error
+ if rf, ok := ret.Get(0).(func(string, *big.Int) (*types.Tx[*big.Int, common.Address, common.Hash, common.Hash, evmtypes.Nonce, gas.EvmFee], error)); ok {
+ return rf(idempotencyKey, chainID)
+ }
+ if rf, ok := ret.Get(0).(func(string, *big.Int) *types.Tx[*big.Int, common.Address, common.Hash, common.Hash, evmtypes.Nonce, gas.EvmFee]); ok {
+ r0 = rf(idempotencyKey, chainID)
+ } else {
+ if ret.Get(0) != nil {
+ r0 = ret.Get(0).(*types.Tx[*big.Int, common.Address, common.Hash, common.Hash, evmtypes.Nonce, gas.EvmFee])
+ }
+ }
+
+ if rf, ok := ret.Get(1).(func(string, *big.Int) error); ok {
+ r1 = rf(idempotencyKey, chainID)
+ } else {
+ r1 = ret.Error(1)
+ }
+
+ return r0, r1
+}
+
// FindTxWithSequence provides a mock function with given fields: fromAddress, seq
func (_m *EvmTxStore) FindTxWithSequence(fromAddress common.Address, seq evmtypes.Nonce) (*types.Tx[*big.Int, common.Address, common.Hash, common.Hash, evmtypes.Nonce, gas.EvmFee], error) {
ret := _m.Called(fromAddress, seq)
diff --git a/core/chains/evm/txmgr/nonce_syncer_test.go b/core/chains/evm/txmgr/nonce_syncer_test.go
index 88dc5e22022..05a6d4c8c7b 100644
--- a/core/chains/evm/txmgr/nonce_syncer_test.go
+++ b/core/chains/evm/txmgr/nonce_syncer_test.go
@@ -42,8 +42,8 @@ func Test_NonceSyncer_Sync(t *testing.T) {
require.Error(t, err)
assert.Contains(t, err.Error(), "something exploded")
- cltest.AssertCount(t, db, "eth_txes", 0)
- cltest.AssertCount(t, db, "eth_tx_attempts", 0)
+ cltest.AssertCount(t, db, "evm.txes", 0)
+ cltest.AssertCount(t, db, "evm.tx_attempts", 0)
assertDatabaseNonce(t, db, from, 0)
})
@@ -66,8 +66,8 @@ func Test_NonceSyncer_Sync(t *testing.T) {
sendingKeys := cltest.MustSendingKeyStates(t, ethKeyStore, testutils.FixtureChainID)
require.NoError(t, ns.Sync(testutils.Context(t), sendingKeys[0].Address.Address()))
- cltest.AssertCount(t, db, "eth_txes", 0)
- cltest.AssertCount(t, db, "eth_tx_attempts", 0)
+ cltest.AssertCount(t, db, "evm.txes", 0)
+ cltest.AssertCount(t, db, "evm.tx_attempts", 0)
assertDatabaseNonce(t, db, from, 0)
})
@@ -91,8 +91,8 @@ func Test_NonceSyncer_Sync(t *testing.T) {
sendingKeys := cltest.MustSendingKeyStates(t, ethKeyStore, testutils.FixtureChainID)
require.NoError(t, ns.Sync(testutils.Context(t), sendingKeys[0].Address.Address()))
- cltest.AssertCount(t, db, "eth_txes", 0)
- cltest.AssertCount(t, db, "eth_tx_attempts", 0)
+ cltest.AssertCount(t, db, "evm.txes", 0)
+ cltest.AssertCount(t, db, "evm.tx_attempts", 0)
assertDatabaseNonce(t, db, k1.Address, 32)
})
@@ -166,7 +166,7 @@ func assertDatabaseNonce(t *testing.T, db *sqlx.DB, address common.Address, nonc
t.Helper()
var nextNonce int64
- err := db.Get(&nextNonce, `SELECT next_nonce FROM evm_key_states WHERE address = $1`, address)
+ err := db.Get(&nextNonce, `SELECT next_nonce FROM evm.key_states WHERE address = $1`, address)
require.NoError(t, err)
assert.Equal(t, nonce, nextNonce)
}
diff --git a/core/chains/evm/txmgr/reaper_test.go b/core/chains/evm/txmgr/reaper_test.go
index 7f32761fa42..11843222999 100644
--- a/core/chains/evm/txmgr/reaper_test.go
+++ b/core/chains/evm/txmgr/reaper_test.go
@@ -76,7 +76,7 @@ func TestReaper_ReapTxes(t *testing.T) {
err := r.ReapTxes(42)
assert.NoError(t, err)
- cltest.AssertCount(t, db, "eth_txes", 1)
+ cltest.AssertCount(t, db, "evm.txes", 1)
})
t.Run("doesn't touch ethtxes with different chain ID", func(t *testing.T) {
@@ -90,10 +90,10 @@ func TestReaper_ReapTxes(t *testing.T) {
err := r.ReapTxes(42)
assert.NoError(t, err)
// Didn't delete because eth_tx has chain ID of 0
- cltest.AssertCount(t, db, "eth_txes", 1)
+ cltest.AssertCount(t, db, "evm.txes", 1)
})
- t.Run("deletes confirmed eth_txes that exceed the age threshold with at least EVM.FinalityDepth blocks above their receipt", func(t *testing.T) {
+ t.Run("deletes confirmed evm.txes that exceed the age threshold with at least EVM.FinalityDepth blocks above their receipt", func(t *testing.T) {
config := txmgrmocks.NewReaperConfig(t)
config.On("FinalityDepth").Return(uint32(10))
@@ -104,24 +104,24 @@ func TestReaper_ReapTxes(t *testing.T) {
err := r.ReapTxes(42)
assert.NoError(t, err)
// Didn't delete because eth_tx was not old enough
- cltest.AssertCount(t, db, "eth_txes", 1)
+ cltest.AssertCount(t, db, "evm.txes", 1)
- pgtest.MustExec(t, db, `UPDATE eth_txes SET created_at=$1`, oneDayAgo)
+ pgtest.MustExec(t, db, `UPDATE evm.txes SET created_at=$1`, oneDayAgo)
err = r.ReapTxes(12)
assert.NoError(t, err)
// Didn't delete because eth_tx although old enough, was still within EVM.FinalityDepth of the current head
- cltest.AssertCount(t, db, "eth_txes", 1)
+ cltest.AssertCount(t, db, "evm.txes", 1)
err = r.ReapTxes(42)
assert.NoError(t, err)
// Now it deleted because the eth_tx was past EVM.FinalityDepth
- cltest.AssertCount(t, db, "eth_txes", 0)
+ cltest.AssertCount(t, db, "evm.txes", 0)
})
cltest.MustInsertFatalErrorEthTx(t, txStore, from)
- t.Run("deletes errored eth_txes that exceed the age threshold", func(t *testing.T) {
+ t.Run("deletes errored evm.txes that exceed the age threshold", func(t *testing.T) {
config := txmgrmocks.NewReaperConfig(t)
config.On("FinalityDepth").Return(uint32(10))
@@ -132,13 +132,13 @@ func TestReaper_ReapTxes(t *testing.T) {
err := r.ReapTxes(42)
assert.NoError(t, err)
// Didn't delete because eth_tx was not old enough
- cltest.AssertCount(t, db, "eth_txes", 1)
+ cltest.AssertCount(t, db, "evm.txes", 1)
- require.NoError(t, utils.JustError(db.Exec(`UPDATE eth_txes SET created_at=$1`, oneDayAgo)))
+ require.NoError(t, utils.JustError(db.Exec(`UPDATE evm.txes SET created_at=$1`, oneDayAgo)))
err = r.ReapTxes(42)
assert.NoError(t, err)
// Deleted because it is old enough now
- cltest.AssertCount(t, db, "eth_txes", 0)
+ cltest.AssertCount(t, db, "evm.txes", 0)
})
}
diff --git a/core/chains/evm/txmgr/resender_test.go b/core/chains/evm/txmgr/resender_test.go
index 60b6bcdce20..d17156f4525 100644
--- a/core/chains/evm/txmgr/resender_test.go
+++ b/core/chains/evm/txmgr/resender_test.go
@@ -187,10 +187,10 @@ func Test_EthResender_Start(t *testing.T) {
}()
var dbEtx txmgr.DbEthTx
- err := db.Get(&dbEtx, `SELECT * FROM eth_txes WHERE id = $1`, etx.ID)
+ err := db.Get(&dbEtx, `SELECT * FROM evm.txes WHERE id = $1`, etx.ID)
require.NoError(t, err)
var dbEtx2 txmgr.DbEthTx
- err = db.Get(&dbEtx2, `SELECT * FROM eth_txes WHERE id = $1`, etx2.ID)
+ err = db.Get(&dbEtx2, `SELECT * FROM evm.txes WHERE id = $1`, etx2.ID)
require.NoError(t, err)
assert.Greater(t, dbEtx.BroadcastAt.Unix(), originalBroadcastAt.Unix())
diff --git a/core/chains/evm/txmgr/transmitchecker.go b/core/chains/evm/txmgr/transmitchecker.go
index 4569063d63d..969e789031c 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/chains/evm/txmgr/txmgr_test.go b/core/chains/evm/txmgr/txmgr_test.go
index d127304c408..79fcf101d5f 100644
--- a/core/chains/evm/txmgr/txmgr_test.go
+++ b/core/chains/evm/txmgr/txmgr_test.go
@@ -137,10 +137,10 @@ func TestTxm_CreateTransaction(t *testing.T) {
assert.Equal(t, big.Int(assets.NewEthValue(0)), etx.Value)
assert.Equal(t, subject, etx.Subject.UUID)
- cltest.AssertCount(t, db, "eth_txes", 1)
+ cltest.AssertCount(t, db, "evm.txes", 1)
var dbEtx txmgr.DbEthTx
- require.NoError(t, db.Get(&dbEtx, `SELECT * FROM eth_txes ORDER BY id ASC LIMIT 1`))
+ require.NoError(t, db.Get(&dbEtx, `SELECT * FROM evm.txes ORDER BY id ASC LIMIT 1`))
assert.Equal(t, etx.State, txmgrcommon.TxUnstarted)
assert.Equal(t, gasLimit, etx.FeeLimit)
@@ -219,7 +219,7 @@ func TestTxm_CreateTransaction(t *testing.T) {
})
t.Run("simulate transmit checker", func(t *testing.T) {
- pgtest.MustExec(t, db, `DELETE FROM eth_txes`)
+ pgtest.MustExec(t, db, `DELETE FROM evm.txes`)
checker := txmgr.TransmitCheckerSpec{
CheckerType: txmgr.TransmitCheckerTypeSimulate,
@@ -234,9 +234,9 @@ func TestTxm_CreateTransaction(t *testing.T) {
Checker: checker,
})
assert.NoError(t, err)
- cltest.AssertCount(t, db, "eth_txes", 1)
+ cltest.AssertCount(t, db, "evm.txes", 1)
var dbEtx txmgr.DbEthTx
- require.NoError(t, db.Get(&dbEtx, `SELECT * FROM eth_txes ORDER BY id ASC LIMIT 1`))
+ require.NoError(t, db.Get(&dbEtx, `SELECT * FROM evm.txes ORDER BY id ASC LIMIT 1`))
var c txmgr.TransmitCheckerSpec
require.NotNil(t, etx.TransmitChecker)
@@ -245,7 +245,7 @@ func TestTxm_CreateTransaction(t *testing.T) {
})
t.Run("meta and vrf checker", func(t *testing.T) {
- pgtest.MustExec(t, db, `DELETE FROM eth_txes`)
+ pgtest.MustExec(t, db, `DELETE FROM evm.txes`)
testDefaultSubID := uint64(2)
testDefaultMaxLink := "1000000000000000000"
testDefaultMaxEth := "2000000000000000000"
@@ -278,9 +278,9 @@ func TestTxm_CreateTransaction(t *testing.T) {
Checker: checker,
})
assert.NoError(t, err)
- cltest.AssertCount(t, db, "eth_txes", 1)
+ cltest.AssertCount(t, db, "evm.txes", 1)
var dbEtx txmgr.DbEthTx
- require.NoError(t, db.Get(&dbEtx, `SELECT * FROM eth_txes ORDER BY id ASC LIMIT 1`))
+ require.NoError(t, db.Get(&dbEtx, `SELECT * FROM evm.txes ORDER BY id ASC LIMIT 1`))
m, err := etx.GetMeta()
require.NoError(t, err)
@@ -293,8 +293,8 @@ func TestTxm_CreateTransaction(t *testing.T) {
})
t.Run("forwards tx when a proper forwarder is set up", func(t *testing.T) {
- pgtest.MustExec(t, db, `DELETE FROM eth_txes`)
- pgtest.MustExec(t, db, `DELETE FROM evm_forwarders`)
+ pgtest.MustExec(t, db, `DELETE FROM evm.txes`)
+ pgtest.MustExec(t, db, `DELETE FROM evm.forwarders`)
evmConfig.maxQueued = uint64(1)
// Create mock forwarder, mock authorizedsenders call.
@@ -313,16 +313,61 @@ func TestTxm_CreateTransaction(t *testing.T) {
Strategy: txmgrcommon.NewSendEveryStrategy(),
})
assert.NoError(t, err)
- cltest.AssertCount(t, db, "eth_txes", 1)
+ cltest.AssertCount(t, db, "evm.txes", 1)
var dbEtx txmgr.DbEthTx
- require.NoError(t, db.Get(&dbEtx, `SELECT * FROM eth_txes ORDER BY id ASC LIMIT 1`))
+ require.NoError(t, db.Get(&dbEtx, `SELECT * FROM evm.txes ORDER BY id ASC LIMIT 1`))
m, err := etx.GetMeta()
require.NoError(t, err)
require.NotNil(t, m.FwdrDestAddress)
require.Equal(t, etx.ToAddress.String(), fwdrAddr.String())
})
+
+ t.Run("insert Tx successfully with a IdempotencyKey", func(t *testing.T) {
+ evmConfig.maxQueued = uint64(3)
+ id := uuid.New()
+ idempotencyKey := "1"
+ _, err := txm.CreateTransaction(txmgr.TxRequest{
+ IdempotencyKey: &idempotencyKey,
+ FromAddress: fromAddress,
+ ToAddress: testutils.NewAddress(),
+ EncodedPayload: []byte{1, 2, 3},
+ FeeLimit: 21000,
+ PipelineTaskRunID: &id,
+ Strategy: txmgrcommon.NewSendEveryStrategy(),
+ })
+ assert.NoError(t, err)
+ })
+
+ t.Run("doesn't insert eth_tx if a matching tx already exists for that IdempotencyKey", func(t *testing.T) {
+ evmConfig.maxQueued = uint64(3)
+ id := uuid.New()
+ idempotencyKey := "2"
+ tx1, err := txm.CreateTransaction(txmgr.TxRequest{
+ IdempotencyKey: &idempotencyKey,
+ FromAddress: fromAddress,
+ ToAddress: testutils.NewAddress(),
+ EncodedPayload: []byte{1, 2, 3},
+ FeeLimit: 21000,
+ PipelineTaskRunID: &id,
+ Strategy: txmgrcommon.NewSendEveryStrategy(),
+ })
+ assert.NoError(t, err)
+
+ tx2, err := txm.CreateTransaction(txmgr.TxRequest{
+ IdempotencyKey: &idempotencyKey,
+ FromAddress: fromAddress,
+ ToAddress: testutils.NewAddress(),
+ EncodedPayload: []byte{1, 2, 3},
+ FeeLimit: 21000,
+ PipelineTaskRunID: &id,
+ Strategy: txmgrcommon.NewSendEveryStrategy(),
+ })
+ assert.NoError(t, err)
+
+ assert.Equal(t, tx1.GetID(), tx2.GetID())
+ })
}
func newMockTxStrategy(t *testing.T) *commontxmmocks.TxStrategy {
@@ -401,7 +446,7 @@ func (g *gasEstimatorConfig) PriceMax() *assets.Wei { return asse
func (g *gasEstimatorConfig) PriceMin() *assets.Wei { return assets.NewWeiI(42) }
func (g *gasEstimatorConfig) Mode() string { return "FixedPrice" }
func (g *gasEstimatorConfig) LimitJobType() evmconfig.LimitJobType { return &limitJobTypeConfig{} }
-func (e *gasEstimatorConfig) PriceMaxKey(addr common.Address) *assets.Wei {
+func (g *gasEstimatorConfig) PriceMaxKey(addr common.Address) *assets.Wei {
return assets.NewWeiI(42)
}
@@ -505,7 +550,7 @@ func TestTxm_CreateTransaction_OutOfEth(t *testing.T) {
require.Equal(t, payload, etx.EncodedPayload)
})
- require.NoError(t, utils.JustError(db.Exec(`DELETE FROM eth_txes WHERE from_address = $1`, thisKey.Address)))
+ require.NoError(t, utils.JustError(db.Exec(`DELETE FROM evm.txes WHERE from_address = $1`, thisKey.Address)))
t.Run("if this key has any transactions with insufficient eth errors, inserts it anyway", func(t *testing.T) {
payload := cltest.MustRandomBytes(t, 100)
@@ -528,7 +573,7 @@ func TestTxm_CreateTransaction_OutOfEth(t *testing.T) {
require.Equal(t, payload, etx.EncodedPayload)
})
- require.NoError(t, utils.JustError(db.Exec(`DELETE FROM eth_txes WHERE from_address = $1`, thisKey.Address)))
+ require.NoError(t, utils.JustError(db.Exec(`DELETE FROM evm.txes WHERE from_address = $1`, thisKey.Address)))
t.Run("if this key has transactions but no insufficient eth errors, transmits as normal", func(t *testing.T) {
payload := cltest.MustRandomBytes(t, 100)
@@ -581,7 +626,7 @@ func TestTxm_Lifecycle(t *testing.T) {
sub := pgmocks.NewSubscription(t)
sub.On("Events").Return(make(<-chan pg.Event))
- eventBroadcaster.On("Subscribe", "insert_on_eth_txes", "").Return(sub, nil)
+ eventBroadcaster.On("Subscribe", "evm.insert_on_txes", "").Return(sub, nil)
evmConfig.bumpThreshold = uint64(1)
require.NoError(t, txm.Start(testutils.Context(t)))
@@ -650,7 +695,7 @@ func TestTxm_Reset(t *testing.T) {
sub := pgmocks.NewSubscription(t)
sub.On("Events").Return(make(<-chan pg.Event))
sub.On("Close")
- eventBroadcaster.On("Subscribe", "insert_on_eth_txes", "").Return(sub, nil)
+ eventBroadcaster.On("Subscribe", "evm.insert_on_txes", "").Return(sub, nil)
estimator := gas.NewEstimator(logger.TestLogger(t), ethClient, cfg.EVM(), cfg.EVM().GasEstimator())
txm, err := makeTestEvmTxm(t, db, ethClient, estimator, cfg.EVM(), cfg.EVM().GasEstimator(), cfg.EVM().Transactions(), cfg.Database(), cfg.Database().Listener(), kst.Eth(), eventBroadcaster)
@@ -683,7 +728,7 @@ func TestTxm_Reset(t *testing.T) {
f.AssertCalled(t)
})
- t.Run("calls function and deletes relevant eth_txes if abandon=true", func(t *testing.T) {
+ t.Run("calls function and deletes relevant evm.txes if abandon=true", func(t *testing.T) {
f := new(fnMock)
err := txm.Reset(f.Fn, addr, true)
@@ -692,13 +737,13 @@ func TestTxm_Reset(t *testing.T) {
f.AssertCalled(t)
var s string
- err = db.Get(&s, `SELECT error FROM eth_txes WHERE from_address = $1 AND state = 'fatal_error'`, addr)
+ err = db.Get(&s, `SELECT error FROM evm.txes WHERE from_address = $1 AND state = 'fatal_error'`, addr)
require.NoError(t, err)
assert.Equal(t, "abandoned", s)
// the other address didn't get touched
var count int
- err = db.Get(&count, `SELECT count(*) FROM eth_txes WHERE from_address = $1 AND state = 'fatal_error'`, addr2)
+ err = db.Get(&count, `SELECT count(*) FROM evm.txes WHERE from_address = $1 AND state = 'fatal_error'`, addr2)
require.NoError(t, err)
assert.Equal(t, 0, count)
})
diff --git a/core/chains/evm/types/types.go b/core/chains/evm/types/types.go
index dea4f9771fd..7d756485d00 100644
--- a/core/chains/evm/types/types.go
+++ b/core/chains/evm/types/types.go
@@ -12,13 +12,16 @@ import (
"github.com/pkg/errors"
"gopkg.in/guregu/null.v4"
- "github.com/smartcontractkit/chainlink/v2/core/chains"
+ "github.com/smartcontractkit/chainlink-relay/pkg/types"
+ "github.com/smartcontractkit/chainlink/v2/core/services/relay"
"github.com/smartcontractkit/chainlink/v2/core/utils"
)
type Configs interface {
- chains.ChainConfigs
- chains.NodeConfigs[utils.Big, Node]
+ Chains(ids ...relay.ChainID) ([]types.ChainStatus, int, error)
+ Node(name string) (Node, error)
+ Nodes(chainID relay.ChainID) (nodes []Node, err error)
+ NodeStatus(name string) (types.NodeStatus, error)
}
type Node struct {
diff --git a/core/chains/internal/utils.go b/core/chains/internal/utils.go
new file mode 100644
index 00000000000..0932f12209c
--- /dev/null
+++ b/core/chains/internal/utils.go
@@ -0,0 +1,109 @@
+package internal
+
+import (
+ "encoding/base64"
+ "errors"
+ "fmt"
+ "net/url"
+ "strconv"
+
+ "github.com/smartcontractkit/chainlink-relay/pkg/types"
+)
+
+// PageToken is simple internal representation for coordination requests and responses in a paginated API
+// It is inspired by the Google API Design patterns
+// https://cloud.google.com/apis/design/design_patterns#list_pagination
+// https://google.aip.dev/158
+type PageToken struct {
+ Page int
+ Size int
+}
+
+var (
+ ErrInvalidToken = errors.New("invalid page token")
+ ErrOutOfRange = errors.New("out of range")
+ defaultSize = 100
+)
+
+// Encode the token in base64 for transmission for the wire
+func (pr *PageToken) Encode() string {
+ if pr.Size == 0 {
+ pr.Size = defaultSize
+ }
+ // this is a simple minded implementation and may benefit from something fancier
+ // note that this is a valid url.Query string, which we leverage in decoding
+ s := fmt.Sprintf("page=%d&size=%d", pr.Page, pr.Size)
+ return base64.RawStdEncoding.EncodeToString([]byte(s))
+}
+
+// b64enc must be the base64 encoded token string, corresponding to [PageToken.Encode()]
+func NewPageToken(b64enc string) (*PageToken, error) {
+ // empty is valid
+ if b64enc == "" {
+ return &PageToken{Page: 0, Size: defaultSize}, nil
+ }
+
+ b, err := base64.RawStdEncoding.DecodeString(b64enc)
+ if err != nil {
+ return nil, err
+ }
+ // here too, this is simple minded and could be fancier
+
+ vals, err := url.ParseQuery(string(b))
+ if err != nil {
+ return nil, err
+ }
+ if !(vals.Has("page") && vals.Has("size")) {
+ return nil, ErrInvalidToken
+ }
+ page, err := strconv.Atoi(vals.Get("page"))
+ if err != nil {
+ return nil, fmt.Errorf("%w: bad page", ErrInvalidToken)
+ }
+ size, err := strconv.Atoi(vals.Get("size"))
+ if err != nil {
+ return nil, fmt.Errorf("%w: bad size", ErrInvalidToken)
+ }
+ return &PageToken{
+ Page: page,
+ Size: size,
+ }, err
+}
+
+func ValidatePageToken(pageSize int, token string) (page int, err error) {
+
+ if token == "" {
+ return 0, nil
+ }
+ t, err := NewPageToken(token)
+ if err != nil {
+ return -1, err
+ }
+ return t.Page, nil
+}
+
+// if start is out of range, must return ErrOutOfRange
+type ListNodeStatusFn = func(start, end int) (stats []types.NodeStatus, total int, err error)
+
+func ListNodeStatuses(pageSize int, pageToken string, listFn ListNodeStatusFn) (stats []types.NodeStatus, nextPageToken string, total int, err error) {
+ if pageSize == 0 {
+ pageSize = defaultSize
+ }
+ t := &PageToken{Page: 0, Size: pageSize}
+ if pageToken != "" {
+ t, err = NewPageToken(pageToken)
+ if err != nil {
+ return nil, "", -1, err
+ }
+ }
+ start, end := t.Page*t.Size, (t.Page+1)*t.Size
+ stats, total, err = listFn(start, end)
+ if err != nil {
+ return stats, "", -1, err
+ }
+ if total > end {
+ next_token := &PageToken{Page: t.Page + 1, Size: t.Size}
+ nextPageToken = next_token.Encode()
+ }
+ return stats, nextPageToken, total, nil
+}
diff --git a/core/chains/internal/utils_test.go b/core/chains/internal/utils_test.go
new file mode 100644
index 00000000000..5a47ed3d8ff
--- /dev/null
+++ b/core/chains/internal/utils_test.go
@@ -0,0 +1,166 @@
+package internal
+
+import (
+ "encoding/base64"
+ "fmt"
+ "reflect"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+
+ "github.com/smartcontractkit/chainlink-relay/pkg/types"
+)
+
+func TestNewPageToken(t *testing.T) {
+ type args struct {
+ t *PageToken
+ }
+ tests := []struct {
+ name string
+ args args
+ want *PageToken
+ wantErr bool
+ }{
+ {
+ name: "empty",
+ args: args{t: &PageToken{}},
+ want: &PageToken{Page: 0, Size: defaultSize},
+ },
+ {
+ name: "page set, size unset",
+ args: args{t: &PageToken{Page: 1}},
+ want: &PageToken{Page: 1, Size: defaultSize},
+ },
+ {
+ name: "page set, size set",
+ args: args{t: &PageToken{Page: 3, Size: 10}},
+ want: &PageToken{Page: 3, Size: 10},
+ },
+ {
+ name: "page unset, size set",
+ args: args{t: &PageToken{Size: 17}},
+ want: &PageToken{Page: 0, Size: 17},
+ },
+ }
+ for _, tt := range tests {
+ enc := tt.args.t.Encode()
+ t.Run(tt.name, func(t *testing.T) {
+ got, err := NewPageToken(enc)
+ if (err != nil) != tt.wantErr {
+ t.Errorf("NewPageToken() error = %v, wantErr %v", err, tt.wantErr)
+ return
+ }
+ if !reflect.DeepEqual(got, tt.want) {
+ t.Errorf("NewPageToken() = %v, want %v", got, tt.want)
+ }
+ })
+ }
+}
+
+func TestListNodeStatuses(t *testing.T) {
+ testStats := []types.NodeStatus{
+ types.NodeStatus{
+ ChainID: "chain-1",
+ Name: "name-1",
+ },
+ types.NodeStatus{
+ ChainID: "chain-2",
+ Name: "name-2",
+ },
+ types.NodeStatus{
+ ChainID: "chain-3",
+ Name: "name-3",
+ },
+ }
+
+ type args struct {
+ pageSize int
+ pageToken string
+ listFn ListNodeStatusFn
+ }
+ tests := []struct {
+ name string
+ args args
+ wantStats []types.NodeStatus
+ wantNext_pageToken string
+ wantTotal int
+ wantErr bool
+ }{
+ {
+ name: "all on first page",
+ args: args{
+ pageSize: 10, // > length of test stats
+ pageToken: "",
+ listFn: func(start, end int) ([]types.NodeStatus, int, error) {
+ return testStats, len(testStats), nil
+ },
+ },
+ wantNext_pageToken: "",
+ wantTotal: len(testStats),
+ wantStats: testStats,
+ },
+ {
+ name: "small first page",
+ args: args{
+ pageSize: len(testStats) - 1,
+ pageToken: "",
+ listFn: func(start, end int) ([]types.NodeStatus, int, error) {
+ return testStats[start:end], len(testStats), nil
+ },
+ },
+ wantNext_pageToken: base64.RawStdEncoding.EncodeToString([]byte("page=1&size=2")), // hard coded 2 is len(testStats)-1
+ wantTotal: len(testStats),
+ wantStats: testStats[0 : len(testStats)-1],
+ },
+ {
+ name: "second page",
+ args: args{
+ pageSize: len(testStats) - 1,
+ pageToken: base64.RawStdEncoding.EncodeToString([]byte("page=1&size=2")), // hard coded 2 is len(testStats)-1
+ listFn: func(start, end int) ([]types.NodeStatus, int, error) {
+ // note list function must do the start, end bound checking. here we are making it simple
+ if end > len(testStats) {
+ end = len(testStats)
+ }
+ return testStats[start:end], len(testStats), nil
+ },
+ },
+ wantNext_pageToken: "",
+ wantTotal: len(testStats),
+ wantStats: testStats[len(testStats)-1:],
+ },
+ {
+ name: "bad list fn",
+ args: args{
+ listFn: func(start, end int) ([]types.NodeStatus, int, error) {
+ return nil, 0, fmt.Errorf("i'm a bad list fn")
+ },
+ },
+ wantTotal: -1,
+ wantErr: true,
+ },
+ {
+ name: "invalid token",
+ args: args{
+ pageToken: "invalid token",
+ listFn: func(start, end int) ([]types.NodeStatus, int, error) {
+ return testStats[start:end], len(testStats), nil
+ },
+ },
+ wantTotal: -1,
+ wantErr: true,
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ gotStats, gotNext_pageToken, gotTotal, err := ListNodeStatuses(tt.args.pageSize, tt.args.pageToken, tt.args.listFn)
+ if (err != nil) != tt.wantErr {
+ t.Errorf("ListNodeStatuses() error = %v, wantErr %v", err, tt.wantErr)
+ return
+ }
+ assert.Equal(t, tt.wantStats, gotStats)
+ assert.Equal(t, tt.wantNext_pageToken, gotNext_pageToken)
+ assert.Equal(t, tt.wantTotal, gotTotal)
+ })
+ }
+}
diff --git a/core/chains/solana/chain.go b/core/chains/solana/chain.go
index a11c0998a1c..682fb23f9f2 100644
--- a/core/chains/solana/chain.go
+++ b/core/chains/solana/chain.go
@@ -18,6 +18,7 @@ import (
"github.com/smartcontractkit/chainlink-relay/pkg/logger"
"github.com/smartcontractkit/chainlink-relay/pkg/loop"
+ relaytypes "github.com/smartcontractkit/chainlink-relay/pkg/types"
"github.com/smartcontractkit/chainlink-solana/pkg/solana"
"github.com/smartcontractkit/chainlink-solana/pkg/solana/client"
@@ -25,23 +26,59 @@ import (
"github.com/smartcontractkit/chainlink-solana/pkg/solana/db"
"github.com/smartcontractkit/chainlink-solana/pkg/solana/txm"
+ "github.com/smartcontractkit/chainlink/v2/core/chains"
+ "github.com/smartcontractkit/chainlink/v2/core/chains/internal"
"github.com/smartcontractkit/chainlink/v2/core/chains/solana/monitor"
"github.com/smartcontractkit/chainlink/v2/core/services"
+ "github.com/smartcontractkit/chainlink/v2/core/services/relay"
"github.com/smartcontractkit/chainlink/v2/core/utils"
)
// DefaultRequestTimeout is the default Solana client timeout.
const DefaultRequestTimeout = 30 * time.Second
+// ChainOpts holds options for configuring a Chain.
+type ChainOpts struct {
+ Logger logger.Logger
+ KeyStore loop.Keystore
+}
+
+func (o *ChainOpts) Validate() (err error) {
+ required := func(s string) error {
+ return errors.Errorf("%s is required", s)
+ }
+ if o.Logger == nil {
+ err = multierr.Append(err, required("Logger"))
+ }
+ if o.KeyStore == nil {
+ err = multierr.Append(err, required("KeyStore"))
+ }
+ return
+}
+
+func (o *ChainOpts) GetLogger() logger.Logger {
+ return o.Logger
+}
+
+func NewChain(cfg *SolanaConfig, opts ChainOpts) (solana.Chain, error) {
+ if !cfg.IsEnabled() {
+ return nil, fmt.Errorf("cannot create new chain with ID %s: %w", *cfg.ChainID, chains.ErrChainDisabled)
+ }
+ c, err := newChain(*cfg.ChainID, cfg, opts.KeyStore, opts.Logger)
+ if err != nil {
+ return nil, err
+ }
+ return c, nil
+}
+
var _ solana.Chain = (*chain)(nil)
type chain struct {
utils.StartStopOnce
id string
- cfg config.Config
+ cfg *SolanaConfig
txm *txm.Txm
balanceMonitor services.ServiceCtx
- nodes func(chainID string) (nodes []db.Node, err error)
lggr logger.Logger
// tracking node chain id for verification
@@ -172,12 +209,11 @@ func (v *verifiedCachedClient) GetAccountInfoWithOpts(ctx context.Context, addr
return v.ReaderWriter.GetAccountInfoWithOpts(ctx, addr, opts)
}
-func newChain(id string, cfg config.Config, ks loop.Keystore, cfgs Configs, lggr logger.Logger) (*chain, error) {
- lggr = logger.With(lggr, "chainID", id, "chainSet", "solana")
+func newChain(id string, cfg *SolanaConfig, ks loop.Keystore, lggr logger.Logger) (*chain, error) {
+ lggr = logger.With(lggr, "chainID", id, "chain", "solana")
var ch = chain{
id: id,
cfg: cfg,
- nodes: cfgs.Nodes,
lggr: logger.Named(lggr, "Chain"),
clientCache: map[string]*verifiedCachedClient{},
}
@@ -189,6 +225,47 @@ func newChain(id string, cfg config.Config, ks loop.Keystore, cfgs Configs, lggr
return &ch, nil
}
+// ChainService interface
+func (c *chain) GetChainStatus(ctx context.Context) (relaytypes.ChainStatus, error) {
+ toml, err := c.cfg.TOMLString()
+ if err != nil {
+ return relaytypes.ChainStatus{}, err
+ }
+ return relaytypes.ChainStatus{
+ ID: c.id,
+ Enabled: c.cfg.IsEnabled(),
+ Config: toml,
+ }, nil
+}
+
+func (c *chain) ListNodeStatuses(ctx context.Context, pageSize int32, pageToken string) (stats []relaytypes.NodeStatus, nextPageToken string, total int, err error) {
+ return internal.ListNodeStatuses(int(pageSize), pageToken, c.listNodeStatuses)
+}
+
+func (c *chain) Transact(ctx context.Context, from, to string, amount *big.Int, balanceCheck bool) error {
+ return c.sendTx(ctx, from, to, amount, balanceCheck)
+}
+
+func (c *chain) listNodeStatuses(start, end int) ([]relaytypes.NodeStatus, int, error) {
+ stats := make([]relaytypes.NodeStatus, 0)
+ total := len(c.cfg.Nodes)
+ if start >= total {
+ return stats, total, internal.ErrOutOfRange
+ }
+ if end > total {
+ end = total
+ }
+ nodes := c.cfg.Nodes[start:end]
+ for _, node := range nodes {
+ stat, err := nodeStatus(node, c.ChainID())
+ if err != nil {
+ return stats, total, err
+ }
+ stats = append(stats, stat)
+ }
+ return stats, total, nil
+}
+
func (c *chain) Name() string {
return c.lggr.Name()
}
@@ -209,11 +286,15 @@ func (c *chain) Reader() (client.Reader, error) {
return c.getClient()
}
+func (c *chain) ChainID() relay.ChainID {
+ return relay.ChainID(c.id)
+}
+
// getClient returns a client, randomly selecting one from available and valid nodes
func (c *chain) getClient() (client.ReaderWriter, error) {
var node db.Node
var client client.ReaderWriter
- nodes, err := c.nodes(c.id) // opt: pass static nodes set to constructor
+ nodes, err := c.cfg.ListNodes()
if err != nil {
return nil, errors.Wrap(err, "failed to get nodes")
}
@@ -260,7 +341,7 @@ func (c *chain) verifiedClient(node db.Node) (client.ReaderWriter, error) {
expectedChainID: c.id,
}
// create client
- cl.ReaderWriter, err = client.NewClient(url, c.cfg, DefaultRequestTimeout, logger.Named(c.lggr, "Client-"+node.Name))
+ cl.ReaderWriter, err = client.NewClient(url, c.cfg, DefaultRequestTimeout, logger.Named(c.lggr, "Client."+node.Name))
if err != nil {
return nil, errors.Wrap(err, "failed to create client")
}
@@ -310,7 +391,7 @@ func (c *chain) HealthReport() map[string]error {
return report
}
-func (c *chain) SendTx(ctx context.Context, from, to string, amount *big.Int, balanceCheck bool) error {
+func (c *chain) sendTx(ctx context.Context, from, to string, amount *big.Int, balanceCheck bool) error {
reader, err := c.Reader()
if err != nil {
return fmt.Errorf("chain unreachable: %w", err)
diff --git a/core/chains/solana/chain_set.go b/core/chains/solana/chain_set.go
deleted file mode 100644
index 56a8a6e189f..00000000000
--- a/core/chains/solana/chain_set.go
+++ /dev/null
@@ -1,71 +0,0 @@
-package solana
-
-import (
- "github.com/pkg/errors"
- "go.uber.org/multierr"
-
- "github.com/smartcontractkit/chainlink-relay/pkg/logger"
- "github.com/smartcontractkit/chainlink-relay/pkg/loop"
- "github.com/smartcontractkit/chainlink-solana/pkg/solana"
- "github.com/smartcontractkit/chainlink-solana/pkg/solana/db"
-
- "github.com/smartcontractkit/chainlink/v2/core/chains"
-)
-
-// ChainSetOpts holds options for configuring a ChainSet.
-type ChainSetOpts struct {
- Logger logger.Logger
- KeyStore loop.Keystore
- Configs Configs
-}
-
-func (o *ChainSetOpts) Validate() (err error) {
- required := func(s string) error {
- return errors.Errorf("%s is required", s)
- }
- if o.Logger == nil {
- err = multierr.Append(err, required("Logger"))
- }
- if o.KeyStore == nil {
- err = multierr.Append(err, required("KeyStore"))
- }
- if o.Configs == nil {
- err = multierr.Append(err, required("Configs"))
- }
- return
-}
-
-func (o *ChainSetOpts) ConfigsAndLogger() (chains.Configs[string, db.Node], logger.Logger) {
- return o.Configs, o.Logger
-}
-
-func (o *ChainSetOpts) NewTOMLChain(cfg *SolanaConfig) (solana.Chain, error) {
- if !cfg.IsEnabled() {
- return nil, errors.Errorf("cannot create new chain with ID %s, the chain is disabled", *cfg.ChainID)
- }
- c, err := newChain(*cfg.ChainID, cfg, o.KeyStore, o.Configs, o.Logger)
- if err != nil {
- return nil, err
- }
- return c, nil
-}
-
-func NewChainSet(opts ChainSetOpts, cfgs SolanaConfigs) (solana.ChainSet, error) {
- solChains := map[string]solana.Chain{}
- var err error
- for _, chain := range cfgs {
- if !chain.IsEnabled() {
- continue
- }
- var err2 error
- solChains[*chain.ChainID], err2 = opts.NewTOMLChain(chain)
- if err2 != nil {
- err = multierr.Combine(err, err2)
- continue
- }
- }
- if err != nil {
- return nil, errors.Wrap(err, "failed to load some Solana chains")
- }
- return chains.NewChainSet[db.Node, solana.Chain](solChains, &opts)
-}
diff --git a/core/chains/solana/chain_test.go b/core/chains/solana/chain_test.go
index 176cc1d15d8..c8dfcf8501e 100644
--- a/core/chains/solana/chain_test.go
+++ b/core/chains/solana/chain_test.go
@@ -13,9 +13,9 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
- "github.com/smartcontractkit/chainlink-relay/pkg/types"
+ "github.com/smartcontractkit/chainlink-relay/pkg/utils"
"github.com/smartcontractkit/chainlink-solana/pkg/solana/client"
- "github.com/smartcontractkit/chainlink-solana/pkg/solana/config"
+ solcfg "github.com/smartcontractkit/chainlink-solana/pkg/solana/config"
"github.com/smartcontractkit/chainlink-solana/pkg/solana/db"
"github.com/smartcontractkit/chainlink/v2/core/logger"
@@ -44,72 +44,74 @@ func TestSolanaChain_GetClient(t *testing.T) {
}))
defer mockServer.Close()
- solORM := &mockConfigs{}
- lggr := logger.TestLogger(t)
+ ch := solcfg.Chain{}
+ ch.SetDefaults()
+ cfg := &SolanaConfig{
+ ChainID: ptr("devnet"),
+ Chain: ch,
+ }
testChain := chain{
id: "devnet",
- nodes: solORM.Nodes,
- cfg: config.NewConfig(db.ChainCfg{}, lggr),
+ cfg: cfg,
lggr: logger.TestLogger(t),
clientCache: map[string]*verifiedCachedClient{},
}
- // random nodes (happy path, all valid)
- solORM.nodesForChain = []db.Node{
- {
- SolanaChainID: "devnet",
- SolanaURL: mockServer.URL + "/1",
+ cfg.Nodes = SolanaNodes([]*solcfg.Node{
+ &solcfg.Node{
+ Name: ptr("devnet"),
+ URL: utils.MustParseURL(mockServer.URL + "/1"),
},
- {
- SolanaChainID: "devnet",
- SolanaURL: mockServer.URL + "/2",
+ &solcfg.Node{
+ Name: ptr("devnet"),
+ URL: utils.MustParseURL(mockServer.URL + "/2"),
},
- }
+ })
_, err := testChain.getClient()
assert.NoError(t, err)
// random nodes (happy path, 1 valid + multiple invalid)
- solORM.nodesForChain = []db.Node{
- {
- SolanaChainID: "devnet",
- SolanaURL: mockServer.URL + "/1",
+ cfg.Nodes = SolanaNodes([]*solcfg.Node{
+ &solcfg.Node{
+ Name: ptr("devnet"),
+ URL: utils.MustParseURL(mockServer.URL + "/1"),
},
- {
- SolanaChainID: "devnet",
- SolanaURL: mockServer.URL + "/mismatch/1",
+ &solcfg.Node{
+ Name: ptr("devnet"),
+ URL: utils.MustParseURL(mockServer.URL + "/mismatch/1"),
},
- {
- SolanaChainID: "devnet",
- SolanaURL: mockServer.URL + "/mismatch/2",
+ &solcfg.Node{
+ Name: ptr("devnet"),
+ URL: utils.MustParseURL(mockServer.URL + "/mismatch/2"),
},
- {
- SolanaChainID: "devnet",
- SolanaURL: mockServer.URL + "/mismatch/3",
+ &solcfg.Node{
+ Name: ptr("devnet"),
+ URL: utils.MustParseURL(mockServer.URL + "/mismatch/3"),
},
- {
- SolanaChainID: "devnet",
- SolanaURL: mockServer.URL + "/mismatch/4",
+ &solcfg.Node{
+ Name: ptr("devnet"),
+ URL: utils.MustParseURL(mockServer.URL + "/mismatch/4"),
},
- }
+ })
_, err = testChain.getClient()
assert.NoError(t, err)
// empty nodes response
- solORM.nodesForChain = nil
+ cfg.Nodes = nil
_, err = testChain.getClient()
assert.Error(t, err)
// no valid nodes to select from
- solORM.nodesForChain = []db.Node{
- {
- SolanaChainID: "devnet",
- SolanaURL: mockServer.URL + "/mismatch/1",
+ cfg.Nodes = SolanaNodes([]*solcfg.Node{
+ &solcfg.Node{
+ Name: ptr("devnet"),
+ URL: utils.MustParseURL(mockServer.URL + "/mismatch/1"),
},
- {
- SolanaChainID: "devnet",
- SolanaURL: mockServer.URL + "/mismatch/2",
+ &solcfg.Node{
+ Name: ptr("devnet"),
+ URL: utils.MustParseURL(mockServer.URL + "/mismatch/2"),
},
- }
+ })
_, err = testChain.getClient()
assert.NoError(t, err)
}
@@ -139,9 +141,14 @@ func TestSolanaChain_VerifiedClient(t *testing.T) {
}))
defer mockServer.Close()
- lggr := logger.TestLogger(t)
+ ch := solcfg.Chain{}
+ ch.SetDefaults()
+ cfg := &SolanaConfig{
+ ChainID: ptr("devnet"),
+ Chain: ch,
+ }
testChain := chain{
- cfg: config.NewConfig(db.ChainCfg{}, lggr),
+ cfg: cfg,
lggr: logger.TestLogger(t),
clientCache: map[string]*verifiedCachedClient{},
}
@@ -177,10 +184,16 @@ func TestSolanaChain_VerifiedClient_ParallelClients(t *testing.T) {
}))
defer mockServer.Close()
- lggr := logger.TestLogger(t)
+ ch := solcfg.Chain{}
+ ch.SetDefaults()
+ cfg := &SolanaConfig{
+ ChainID: ptr("devnet"),
+ Enabled: ptr(true),
+ Chain: ch,
+ }
testChain := chain{
id: "devnet",
- cfg: config.NewConfig(db.ChainCfg{}, lggr),
+ cfg: cfg,
lggr: logger.TestLogger(t),
clientCache: map[string]*verifiedCachedClient{},
}
@@ -213,24 +226,6 @@ func TestSolanaChain_VerifiedClient_ParallelClients(t *testing.T) {
assert.Equal(t, testChain.clientCache[mockServer.URL], client1)
}
-var _ Configs = &mockConfigs{}
-
-type mockConfigs struct {
- nodesForChain []db.Node
-}
-
-func (m *mockConfigs) Nodes(chainID string) (nodes []db.Node, err error) {
- return m.nodesForChain, nil
-}
-
-func (m *mockConfigs) Chains(offset, limit int, ids ...string) ([]types.ChainStatus, int, error) {
- panic("unimplemented")
-}
-
-func (m *mockConfigs) Node(s string) (db.Node, error) { panic("unimplemented") }
-
-func (m *mockConfigs) NodeStatus(s string) (types.NodeStatus, error) { panic("unimplemented") }
-
-func (m *mockConfigs) NodeStatusesPaged(offset, limit int, chainIDs ...string) (nodes []types.NodeStatus, count int, err error) {
- panic("unimplemented")
+func ptr[T any](t T) *T {
+ return &t
}
diff --git a/core/chains/solana/config.go b/core/chains/solana/config.go
index e654a9029b1..b6e4a077f9e 100644
--- a/core/chains/solana/config.go
+++ b/core/chains/solana/config.go
@@ -10,12 +10,12 @@ import (
"go.uber.org/multierr"
"golang.org/x/exp/slices"
- "github.com/smartcontractkit/chainlink-relay/pkg/types"
+ relaytypes "github.com/smartcontractkit/chainlink-relay/pkg/types"
solcfg "github.com/smartcontractkit/chainlink-solana/pkg/solana/config"
soldb "github.com/smartcontractkit/chainlink-solana/pkg/solana/db"
- "github.com/smartcontractkit/chainlink/v2/core/chains"
+ "github.com/smartcontractkit/chainlink/v2/core/services/relay"
"github.com/smartcontractkit/chainlink/v2/core/utils/config"
)
@@ -75,120 +75,13 @@ func (cs *SolanaConfigs) SetFrom(fs *SolanaConfigs) (err error) {
return
}
-func (cs SolanaConfigs) Chains(ids ...string) (r []types.ChainStatus, err error) {
- for _, ch := range cs {
- if ch == nil {
- continue
- }
- if len(ids) > 0 {
- var match bool
- for _, id := range ids {
- if id == *ch.ChainID {
- match = true
- break
- }
- }
- if !match {
- continue
- }
- }
- ch2 := types.ChainStatus{
- ID: *ch.ChainID,
- Enabled: ch.IsEnabled(),
- }
- ch2.Config, err = ch.TOMLString()
- if err != nil {
- return
- }
- r = append(r, ch2)
- }
- return
-}
-
-func (cs SolanaConfigs) Node(name string) (soldb.Node, error) {
- for i := range cs {
- for _, n := range cs[i].Nodes {
- if n.Name != nil && *n.Name == name {
- return legacySolNode(n, *cs[i].ChainID), nil
- }
- }
- }
- return soldb.Node{}, fmt.Errorf("node %s: %w", name, chains.ErrNotFound)
-}
-
-func (cs SolanaConfigs) nodes(chainID string) (ns SolanaNodes) {
- for _, c := range cs {
- if *c.ChainID == chainID {
- return c.Nodes
- }
- }
- return nil
-}
-
-func (cs SolanaConfigs) Nodes(chainID string) (ns []soldb.Node, err error) {
- nodes := cs.nodes(chainID)
- if nodes == nil {
- err = fmt.Errorf("no nodes: chain %s: %w", chainID, chains.ErrNotFound)
- return
- }
- for _, n := range nodes {
- if n == nil {
- continue
- }
- ns = append(ns, legacySolNode(n, chainID))
- }
- return
-}
-
-func (cs SolanaConfigs) NodeStatus(name string) (types.NodeStatus, error) {
- for i := range cs {
- for _, n := range cs[i].Nodes {
- if n.Name != nil && *n.Name == name {
- return nodeStatus(n, *cs[i].ChainID)
- }
- }
- }
- return types.NodeStatus{}, fmt.Errorf("node %s: %w", name, chains.ErrNotFound)
-}
-
-func (cs SolanaConfigs) NodeStatuses(chainIDs ...string) (ns []types.NodeStatus, err error) {
- if len(chainIDs) == 0 {
- for i := range cs {
- for _, n := range cs[i].Nodes {
- if n == nil {
- continue
- }
- n2, err := nodeStatus(n, *cs[i].ChainID)
- if err != nil {
- return nil, err
- }
- ns = append(ns, n2)
- }
- }
- return
- }
- for _, id := range chainIDs {
- for _, n := range cs.nodes(id) {
- if n == nil {
- continue
- }
- n2, err := nodeStatus(n, id)
- if err != nil {
- return nil, err
- }
- ns = append(ns, n2)
- }
- }
- return
-}
-
-func nodeStatus(n *solcfg.Node, chainID string) (types.NodeStatus, error) {
- var s types.NodeStatus
- s.ChainID = chainID
+func nodeStatus(n *solcfg.Node, id relay.ChainID) (relaytypes.NodeStatus, error) {
+ var s relaytypes.NodeStatus
+ s.ChainID = id
s.Name = *n.Name
b, err := toml.Marshal(n)
if err != nil {
- return types.NodeStatus{}, err
+ return relaytypes.NodeStatus{}, err
}
s.Config = string(b)
return s, nil
@@ -219,16 +112,17 @@ func setFromNode(n, f *solcfg.Node) {
}
}
-func legacySolNode(n *solcfg.Node, chainID string) soldb.Node {
+func legacySolNode(n *solcfg.Node, id relay.ChainID) soldb.Node {
return soldb.Node{
Name: *n.Name,
- SolanaChainID: chainID,
+ SolanaChainID: id,
SolanaURL: (*url.URL)(n.URL).String(),
}
}
type SolanaConfig struct {
ChainID *string
+ // Do not access directly, use [IsEnabled]
Enabled *bool
solcfg.Chain
Nodes SolanaNodes
@@ -369,14 +263,10 @@ func (c *SolanaConfig) FeeBumpPeriod() time.Duration {
return c.Chain.FeeBumpPeriod.Duration()
}
-// Configs manages solana chains and nodes.
-type Configs interface {
- chains.ChainConfigs
- chains.NodeConfigs[string, soldb.Node]
-}
-
-var _ chains.Configs[string, soldb.Node] = (Configs)(nil)
-
-func NewConfigs(cfgs chains.ConfigsV2[string, soldb.Node]) Configs {
- return chains.NewConfigs(cfgs)
+func (c *SolanaConfig) ListNodes() ([]soldb.Node, error) {
+ var allNodes []soldb.Node
+ for _, n := range c.Nodes {
+ allNodes = append(allNodes, legacySolNode(n, *c.ChainID))
+ }
+ return allNodes, nil
}
diff --git a/core/chains/starknet/chain.go b/core/chains/starknet/chain.go
index 9dfed44e57d..fead94cda60 100644
--- a/core/chains/starknet/chain.go
+++ b/core/chains/starknet/chain.go
@@ -2,42 +2,80 @@ package starknet
import (
"context"
+ "fmt"
"math/big"
"math/rand"
"github.com/pkg/errors"
+ "go.uber.org/multierr"
"golang.org/x/exp/maps"
"github.com/smartcontractkit/chainlink-relay/pkg/logger"
"github.com/smartcontractkit/chainlink-relay/pkg/loop"
+ relaytypes "github.com/smartcontractkit/chainlink-relay/pkg/types"
+
starkChain "github.com/smartcontractkit/chainlink-starknet/relayer/pkg/chainlink/chain"
+ starkchain "github.com/smartcontractkit/chainlink-starknet/relayer/pkg/chainlink/chain"
"github.com/smartcontractkit/chainlink-starknet/relayer/pkg/chainlink/config"
"github.com/smartcontractkit/chainlink-starknet/relayer/pkg/chainlink/db"
"github.com/smartcontractkit/chainlink-starknet/relayer/pkg/chainlink/txm"
"github.com/smartcontractkit/chainlink-starknet/relayer/pkg/starknet"
"github.com/smartcontractkit/chainlink/v2/core/chains"
- "github.com/smartcontractkit/chainlink/v2/core/chains/starknet/types"
+ "github.com/smartcontractkit/chainlink/v2/core/chains/internal"
+ "github.com/smartcontractkit/chainlink/v2/core/services/relay"
"github.com/smartcontractkit/chainlink/v2/core/utils"
)
+type ChainOpts struct {
+ Logger logger.Logger
+ // the implementation used here needs to be co-ordinated with the starknet transaction manager keystore adapter
+ KeyStore loop.Keystore
+}
+
+func (o *ChainOpts) Name() string {
+ return o.Logger.Name()
+}
+
+func (o *ChainOpts) Validate() (err error) {
+ required := func(s string) error {
+ return errors.Errorf("%s is required", s)
+ }
+ if o.Logger == nil {
+ err = multierr.Append(err, required("Logger'"))
+ }
+ if o.KeyStore == nil {
+ err = multierr.Append(err, required("KeyStore"))
+ }
+ return
+}
+
var _ starkChain.Chain = (*chain)(nil)
type chain struct {
utils.StartStopOnce
id string
- cfg config.Config
- cfgs types.Configs
+ cfg *StarknetConfig
lggr logger.Logger
txm txm.StarkTXM
}
-func newChain(id string, cfg config.Config, loopKs loop.Keystore, cfgs types.Configs, lggr logger.Logger) (*chain, error) {
+func NewChain(cfg *StarknetConfig, opts ChainOpts) (starkchain.Chain, error) {
+ if !cfg.IsEnabled() {
+ return nil, fmt.Errorf("cannot create new chain with ID %s: %w", *cfg.ChainID, chains.ErrChainDisabled)
+ }
+ c, err := newChain(*cfg.ChainID, cfg, opts.KeyStore, opts.Logger)
+ if err != nil {
+ return nil, err
+ }
+ return c, nil
+}
+
+func newChain(id string, cfg *StarknetConfig, loopKs loop.Keystore, lggr logger.Logger) (*chain, error) {
lggr = logger.With(lggr, "starknetChainID", id)
ch := &chain{
id: id,
cfg: cfg,
- cfgs: cfgs,
lggr: logger.Named(lggr, "Chain"),
}
@@ -70,11 +108,15 @@ func (c *chain) Reader() (starknet.Reader, error) {
return c.getClient()
}
+func (c *chain) ChainID() relay.ChainID {
+ return relay.ChainID(c.id)
+}
+
// getClient returns a client, randomly selecting one from available and valid nodes
func (c *chain) getClient() (*starknet.Client, error) {
var node db.Node
var client *starknet.Client
- nodes, err := c.cfgs.Nodes(c.id)
+ nodes, err := c.cfg.ListNodes()
if err != nil {
return nil, errors.Wrap(err, "failed to get nodes")
}
@@ -126,6 +168,52 @@ func (c *chain) HealthReport() map[string]error {
return report
}
-func (c *chain) SendTx(ctx context.Context, from, to string, amount *big.Int, balanceCheck bool) error {
+func (c *chain) ID() string {
+ return c.id
+}
+
+// ChainService interface
+func (c *chain) GetChainStatus(ctx context.Context) (relaytypes.ChainStatus, error) {
+ toml, err := c.cfg.TOMLString()
+ if err != nil {
+ return relaytypes.ChainStatus{}, err
+ }
+ return relaytypes.ChainStatus{
+ ID: c.id,
+ Enabled: c.cfg.IsEnabled(),
+ Config: toml,
+ }, nil
+}
+
+func (c *chain) ListNodeStatuses(ctx context.Context, pageSize int32, pageToken string) (stats []relaytypes.NodeStatus, nextPageToken string, total int, err error) {
+ return internal.ListNodeStatuses(int(pageSize), pageToken, c.listNodeStatuses)
+}
+
+func (c *chain) Transact(ctx context.Context, from, to string, amount *big.Int, balanceCheck bool) error {
return chains.ErrLOOPPUnsupported
}
+
+func (c *chain) SendTx(ctx context.Context, from, to string, amount *big.Int, balanceCheck bool) error {
+ return c.Transact(ctx, from, to, amount, balanceCheck)
+}
+
+// TODO BCF-2602 statuses are static for non-evm chain and should be dynamic
+func (c *chain) listNodeStatuses(start, end int) ([]relaytypes.NodeStatus, int, error) {
+ stats := make([]relaytypes.NodeStatus, 0)
+ total := len(c.cfg.Nodes)
+ if start >= total {
+ return stats, total, internal.ErrOutOfRange
+ }
+ if end <= 0 || end > total {
+ end = total
+ }
+ nodes := c.cfg.Nodes[start:end]
+ for _, node := range nodes {
+ stat, err := nodeStatus(node, c.ChainID())
+ if err != nil {
+ return stats, total, err
+ }
+ stats = append(stats, stat)
+ }
+ return stats, total, nil
+}
diff --git a/core/chains/starknet/chain_set.go b/core/chains/starknet/chain_set.go
deleted file mode 100644
index ab2b5982e9b..00000000000
--- a/core/chains/starknet/chain_set.go
+++ /dev/null
@@ -1,76 +0,0 @@
-package starknet
-
-import (
- "github.com/pkg/errors"
- "go.uber.org/multierr"
-
- "github.com/smartcontractkit/chainlink-relay/pkg/logger"
- "github.com/smartcontractkit/chainlink-relay/pkg/loop"
- starkchain "github.com/smartcontractkit/chainlink-starknet/relayer/pkg/chainlink/chain"
- "github.com/smartcontractkit/chainlink-starknet/relayer/pkg/chainlink/db"
-
- "github.com/smartcontractkit/chainlink/v2/core/chains"
- "github.com/smartcontractkit/chainlink/v2/core/chains/starknet/types"
-)
-
-type ChainSetOpts struct {
- Logger logger.Logger
- // the implementation used here needs to be co-ordinated with the starknet transaction manager keystore adapter
- KeyStore loop.Keystore
- Configs types.Configs
-}
-
-func (o *ChainSetOpts) Name() string {
- return o.Logger.Name()
-}
-
-func (o *ChainSetOpts) Validate() (err error) {
- required := func(s string) error {
- return errors.Errorf("%s is required", s)
- }
- if o.Logger == nil {
- err = multierr.Append(err, required("Logger'"))
- }
- if o.KeyStore == nil {
- err = multierr.Append(err, required("KeyStore"))
- }
- if o.Configs == nil {
- err = multierr.Append(err, required("Configs"))
- }
- return
-}
-
-func (o *ChainSetOpts) ConfigsAndLogger() (chains.Configs[string, db.Node], logger.Logger) {
- return o.Configs, o.Logger
-}
-
-func (o *ChainSetOpts) NewTOMLChain(cfg *StarknetConfig) (starkchain.Chain, error) {
- if !cfg.IsEnabled() {
- return nil, errors.Errorf("cannot create new chain with ID %s, the chain is disabled", *cfg.ChainID)
- }
- c, err := newChain(*cfg.ChainID, cfg, o.KeyStore, o.Configs, o.Logger)
- if err != nil {
- return nil, err
- }
- return c, nil
-}
-
-func NewChainSet(opts ChainSetOpts, cfgs StarknetConfigs) (starkchain.ChainSet, error) {
- stkChains := map[string]starkchain.Chain{}
- var err error
- for _, chain := range cfgs {
- if !chain.IsEnabled() {
- continue
- }
- var err2 error
- stkChains[*chain.ChainID], err2 = opts.NewTOMLChain(chain)
- if err2 != nil {
- err = multierr.Combine(err, err2)
- continue
- }
- }
- if err != nil {
- return nil, errors.Wrap(err, "failed to load some Solana chains")
- }
- return chains.NewChainSet[db.Node, starkchain.Chain](stkChains, &opts)
-}
diff --git a/core/chains/starknet/config.go b/core/chains/starknet/config.go
index c555028c6fb..33b2a8d257a 100644
--- a/core/chains/starknet/config.go
+++ b/core/chains/starknet/config.go
@@ -14,7 +14,7 @@ import (
stkcfg "github.com/smartcontractkit/chainlink-starknet/relayer/pkg/chainlink/config"
"github.com/smartcontractkit/chainlink-starknet/relayer/pkg/chainlink/db"
- "github.com/smartcontractkit/chainlink/v2/core/chains"
+ "github.com/smartcontractkit/chainlink/v2/core/services/relay"
"github.com/smartcontractkit/chainlink/v2/core/utils/config"
)
@@ -74,118 +74,9 @@ func (cs *StarknetConfigs) SetFrom(fs *StarknetConfigs) (err error) {
return
}
-func (cs StarknetConfigs) Chains(ids ...string) (r []types.ChainStatus, err error) {
- for _, ch := range cs {
- if ch == nil {
- continue
- }
- if len(ids) > 0 {
- var match bool
- for _, id := range ids {
- if id == *ch.ChainID {
- match = true
- break
- }
- }
- if !match {
- continue
- }
- }
- ch2 := types.ChainStatus{
- ID: *ch.ChainID,
- Enabled: ch.IsEnabled(),
- }
- ch2.Config, err = ch.TOMLString()
- if err != nil {
- return
- }
- r = append(r, ch2)
- }
- return
-}
-
-func (cs StarknetConfigs) Node(name string) (n db.Node, err error) {
- for i := range cs {
- for _, n := range cs[i].Nodes {
- if n.Name != nil && *n.Name == name {
- return legacyNode(n, *cs[i].ChainID), nil
- }
- }
- }
- err = fmt.Errorf("node %s: %w", name, chains.ErrNotFound)
- return
-}
-
-func (cs StarknetConfigs) nodes(chainID string) (ns StarknetNodes) {
- for _, c := range cs {
- if *c.ChainID == chainID {
- return c.Nodes
- }
- }
- return nil
-}
-
-func (cs StarknetConfigs) Nodes(chainID string) (ns []db.Node, err error) {
- nodes := cs.nodes(chainID)
- if nodes == nil {
- err = fmt.Errorf("no nodes: chain %s: %w", chainID, chains.ErrNotFound)
- return
- }
- for _, n := range nodes {
- if n == nil {
- continue
- }
- ns = append(ns, legacyNode(n, chainID))
- }
- return
-}
-
-func (cs StarknetConfigs) NodeStatus(name string) (n types.NodeStatus, err error) {
- for i := range cs {
- for _, n := range cs[i].Nodes {
- if n.Name != nil && *n.Name == name {
- return nodeStatus(n, *cs[i].ChainID)
- }
- }
- }
- err = fmt.Errorf("node %s: %w", name, chains.ErrNotFound)
- return
-}
-
-func (cs StarknetConfigs) NodeStatuses(chainIDs ...string) (ns []types.NodeStatus, err error) {
- if len(chainIDs) == 0 {
- for i := range cs {
- for _, n := range cs[i].Nodes {
- if n == nil {
- continue
- }
- n2, err := nodeStatus(n, *cs[i].ChainID)
- if err != nil {
- return nil, err
- }
- ns = append(ns, n2)
- }
- }
- return
- }
- for _, id := range chainIDs {
- for _, n := range cs.nodes(id) {
- if n == nil {
- continue
- }
- n2, err := nodeStatus(n, id)
- if err != nil {
- return nil, err
- }
- ns = append(ns, n2)
- }
- }
- return
-}
-
-func nodeStatus(n *stkcfg.Node, chainID string) (types.NodeStatus, error) {
+func nodeStatus(n *stkcfg.Node, id relay.ChainID) (types.NodeStatus, error) {
var s types.NodeStatus
- s.ChainID = chainID
+ s.ChainID = id
s.Name = *n.Name
b, err := toml.Marshal(n)
if err != nil {
@@ -197,6 +88,7 @@ func nodeStatus(n *stkcfg.Node, chainID string) (types.NodeStatus, error) {
type StarknetConfig struct {
ChainID *string
+ // Do not access directly. Use [IsEnabled]
Enabled *bool
stkcfg.Chain
Nodes StarknetNodes
@@ -282,7 +174,7 @@ func setFromNode(n, f *stkcfg.Node) {
}
}
-func legacyNode(n *stkcfg.Node, id string) db.Node {
+func legacyNode(n *stkcfg.Node, id relay.ChainID) db.Node {
return db.Node{
Name: *n.Name,
ChainID: id,
@@ -311,3 +203,11 @@ func (c *StarknetConfig) OCR2CacheTTL() time.Duration {
func (c *StarknetConfig) RequestTimeout() time.Duration {
return c.Chain.RequestTimeout.Duration()
}
+
+func (c *StarknetConfig) ListNodes() ([]db.Node, error) {
+ var allNodes []db.Node
+ for _, n := range c.Nodes {
+ allNodes = append(allNodes, legacyNode(n, *c.ChainID))
+ }
+ return allNodes, nil
+}
diff --git a/core/chains/starknet/orm.go b/core/chains/starknet/orm.go
deleted file mode 100644
index 9d7109d150e..00000000000
--- a/core/chains/starknet/orm.go
+++ /dev/null
@@ -1,12 +0,0 @@
-package starknet
-
-import (
- starknetdb "github.com/smartcontractkit/chainlink-starknet/relayer/pkg/chainlink/db"
-
- "github.com/smartcontractkit/chainlink/v2/core/chains"
- "github.com/smartcontractkit/chainlink/v2/core/chains/starknet/types"
-)
-
-func NewConfigs(cfgs chains.ConfigsV2[string, starknetdb.Node]) types.Configs {
- return chains.NewConfigs(cfgs)
-}
diff --git a/core/chains/starknet/types/types.go b/core/chains/starknet/types/types.go
deleted file mode 100644
index 2158d80fbb9..00000000000
--- a/core/chains/starknet/types/types.go
+++ /dev/null
@@ -1,12 +0,0 @@
-package types
-
-import (
- "github.com/smartcontractkit/chainlink-starknet/relayer/pkg/chainlink/db"
-
- "github.com/smartcontractkit/chainlink/v2/core/chains"
-)
-
-type Configs interface {
- chains.ChainConfigs
- chains.NodeConfigs[string, db.Node]
-}
diff --git a/core/cmd/app.go b/core/cmd/app.go
index a37b75e2b24..17a4da85002 100644
--- a/core/cmd/app.go
+++ b/core/cmd/app.go
@@ -209,17 +209,15 @@ func NewApp(s *Shell) *cli.App {
if c.IsSet("config") {
if s.configFilesIsSet || s.secretsFileIsSet {
return errNoDuplicateFlags
- } else {
- s.configFiles = c.StringSlice("config")
}
+ s.configFiles = c.StringSlice("config")
}
if c.IsSet("secrets") {
if s.configFilesIsSet || s.secretsFileIsSet {
return errNoDuplicateFlags
- } else {
- s.secretsFiles = c.StringSlice("secrets")
}
+ s.secretsFiles = c.StringSlice("secrets")
}
// flags here, or ENV VAR only
diff --git a/core/cmd/app_test.go b/core/cmd/app_test.go
index d99f941fded..78331bf7063 100644
--- a/core/cmd/app_test.go
+++ b/core/cmd/app_test.go
@@ -145,7 +145,6 @@ func Test_initServerConfig(t *testing.T) {
fileNames: []string{testtomlutils.WriteTOMLFile(t, testConfigFileContents, "test.toml")},
secretsFiles: []string{
"../services/chainlink/testdata/mergingsecretsdata/secrets-database.toml",
- "../services/chainlink/testdata/mergingsecretsdata/secrets-explorer.toml",
"../services/chainlink/testdata/mergingsecretsdata/secrets-password.toml",
"../services/chainlink/testdata/mergingsecretsdata/secrets-pyroscope.toml",
"../services/chainlink/testdata/mergingsecretsdata/secrets-prometheus.toml",
@@ -168,18 +167,6 @@ func Test_initServerConfig(t *testing.T) {
},
wantErr: true,
},
- {
- name: "reading multiple secrets with overrides: Explorer",
- args: args{
- opts: new(chainlink.GeneralConfigOpts),
- fileNames: []string{testtomlutils.WriteTOMLFile(t, testConfigFileContents, "test.toml")},
- secretsFiles: []string{
- "../testdata/mergingsecretsdata/secrets-explorer.toml",
- "../testdata/mergingsecretsdata/secrets-explorer.toml",
- },
- },
- wantErr: true,
- },
{
name: "reading multiple secrets with overrides: Password",
args: args{
diff --git a/core/cmd/cosmos_node_commands_test.go b/core/cmd/cosmos_node_commands_test.go
index e4331ab4576..93364b74e0b 100644
--- a/core/cmd/cosmos_node_commands_test.go
+++ b/core/cmd/cosmos_node_commands_test.go
@@ -60,7 +60,7 @@ func TestShell_IndexCosmosNodes(t *testing.T) {
//Render table and check the fields order
b := new(bytes.Buffer)
rt := cmd.RendererTable{b}
- nodes.RenderTable(rt)
+ require.NoError(t, nodes.RenderTable(rt))
renderLines := strings.Split(b.String(), "\n")
assert.Equal(t, 10, len(renderLines))
assert.Contains(t, renderLines[2], "Name")
diff --git a/core/cmd/cosmos_transaction_commands_test.go b/core/cmd/cosmos_transaction_commands_test.go
index 11b89c5232a..04858d2956a 100644
--- a/core/cmd/cosmos_transaction_commands_test.go
+++ b/core/cmd/cosmos_transaction_commands_test.go
@@ -50,7 +50,7 @@ func TestShell_SendCosmosCoins(t *testing.T) {
chainID := cosmostest.RandomChainID()
cosmosChain := coscfg.Chain{}
cosmosChain.SetDefaults()
- accounts, _, url := cosmosclient.SetupLocalCosmosNode(t, chainID, *cosmosChain.FeeToken)
+ accounts, _, url := cosmosclient.SetupLocalCosmosNode(t, chainID, *cosmosChain.GasToken)
require.Greater(t, len(accounts), 1)
nodes := cosmos.CosmosNodes{
&coscfg.Node{
@@ -71,7 +71,7 @@ func TestShell_SendCosmosCoins(t *testing.T) {
require.NoError(t, err)
require.Eventually(t, func() bool {
- coin, err := reader.Balance(from.Address, *cosmosChain.FeeToken)
+ coin, err := reader.Balance(from.Address, *cosmosChain.GasToken)
if !assert.NoError(t, err) {
return false
}
@@ -97,7 +97,7 @@ func TestShell_SendCosmosCoins(t *testing.T) {
} {
tt := tt
t.Run(tt.amount, func(t *testing.T) {
- startBal, err := reader.Balance(from.Address, *cosmosChain.FeeToken)
+ startBal, err := reader.Balance(from.Address, *cosmosChain.GasToken)
require.NoError(t, err)
set := flag.NewFlagSet("sendcosmoscoins", 0)
@@ -156,11 +156,11 @@ func TestShell_SendCosmosCoins(t *testing.T) {
}
// Check balance
- endBal, err := reader.Balance(from.Address, *cosmosChain.FeeToken)
+ endBal, err := reader.Balance(from.Address, *cosmosChain.GasToken)
require.NoError(t, err)
if assert.NotNil(t, startBal) && assert.NotNil(t, endBal) {
diff := startBal.Sub(*endBal).Amount
- sent, err := denom.ConvertDecCoinToDenom(sdk.NewDecCoinFromDec(nativeToken, sdk.MustNewDecFromStr(tt.amount)), *cosmosChain.FeeToken)
+ sent, err := denom.ConvertDecCoinToDenom(sdk.NewDecCoinFromDec(nativeToken, sdk.MustNewDecFromStr(tt.amount)), *cosmosChain.GasToken)
require.NoError(t, err)
if assert.True(t, diff.IsInt64()) && assert.True(t, sent.Amount.IsInt64()) {
require.Greater(t, diff.Int64(), sent.Amount.Int64())
diff --git a/core/cmd/eth_keys_commands_test.go b/core/cmd/eth_keys_commands_test.go
index 71dee517b27..30e115e9482 100644
--- a/core/cmd/eth_keys_commands_test.go
+++ b/core/cmd/eth_keys_commands_test.go
@@ -15,6 +15,7 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/assets"
"github.com/smartcontractkit/chainlink/v2/core/cmd"
"github.com/smartcontractkit/chainlink/v2/core/internal/cltest"
+ "github.com/smartcontractkit/chainlink/v2/core/internal/testutils"
"github.com/smartcontractkit/chainlink/v2/core/services/chainlink"
"github.com/smartcontractkit/chainlink/v2/core/utils"
"github.com/smartcontractkit/chainlink/v2/core/web/presenters"
@@ -177,33 +178,26 @@ func TestShell_CreateETHKey(t *testing.T) {
db := app.GetSqlxDB()
client, _ := app.NewShellAndRenderer()
- cltest.AssertCount(t, db, "evm_key_states", 1) // The initial funding key
+ cltest.AssertCount(t, db, "evm.key_states", 1) // The initial funding key
keys, err := app.KeyStore.Eth().GetAll()
require.NoError(t, err)
require.Equal(t, 1, len(keys))
- // create a key on the default chain
- set := flag.NewFlagSet("test", 0)
- cltest.FlagSetApplyFromAction(client.CreateETHKey, set, "")
- c := cli.NewContext(nil, set, nil)
- assert.NoError(t, client.CreateETHKey(c))
-
- // create the key on a specific chainID
id := big.NewInt(0)
- set = flag.NewFlagSet("test", 0)
+ set := flag.NewFlagSet("test", 0)
cltest.FlagSetApplyFromAction(client.CreateETHKey, set, "")
- require.NoError(t, set.Set("evmChainID", ""))
+ require.NoError(t, set.Set("evm-chain-id", testutils.FixtureChainID.String()))
- c = cli.NewContext(nil, set, nil)
- require.NoError(t, set.Parse([]string{"-evmChainID", id.String()}))
+ c := cli.NewContext(nil, set, nil)
+ require.NoError(t, set.Parse([]string{"-evm-chain-id", id.String()}))
assert.NoError(t, client.CreateETHKey(c))
- cltest.AssertCount(t, db, "evm_key_states", 3)
+ cltest.AssertCount(t, db, "evm.key_states", 2)
keys, err = app.KeyStore.Eth().GetAll()
require.NoError(t, err)
- require.Equal(t, 3, len(keys))
+ require.Equal(t, 2, len(keys))
}
func TestShell_DeleteETHKey(t *testing.T) {
@@ -304,13 +298,16 @@ func TestShell_ImportExportETHKey_NoChains(t *testing.T) {
_, err = ethKeyStore.Get(address)
require.Error(t, err)
- cltest.AssertCount(t, app.GetSqlxDB(), "evm_key_states", 0)
+ cltest.AssertCount(t, app.GetSqlxDB(), "evm.key_states", 0)
// Import the key
set = flag.NewFlagSet("test", 0)
- set.String("old-password", "../internal/fixtures/incorrect_password.txt", "")
- err = set.Parse([]string{keyfilepath})
- require.NoError(t, err)
+ cltest.FlagSetApplyFromAction(client.ImportETHKey, set, "")
+
+ require.NoError(t, set.Set("evmChainID", testutils.FixtureChainID.String()))
+ require.NoError(t, set.Set("old-password", "../internal/fixtures/incorrect_password.txt"))
+ require.NoError(t, set.Parse([]string{keyfilepath}))
+
c = cli.NewContext(nil, set, nil)
err = client.ImportETHKey(c)
require.NoError(t, err)
@@ -412,6 +409,8 @@ func TestShell_ImportExportETHKey_WithChains(t *testing.T) {
set = flag.NewFlagSet("test", 0)
cltest.FlagSetApplyFromAction(client.ImportETHKey, set, "")
+ require.NoError(t, set.Set("evmChainID", testutils.FixtureChainID.String()))
+ require.NoError(t, set.Set("evmChainID", testutils.FixtureChainID.String()))
require.NoError(t, set.Set("old-password", "../internal/fixtures/incorrect_password.txt"))
require.NoError(t, set.Parse([]string{keyfilepath}))
diff --git a/core/cmd/evm_node_commands_test.go b/core/cmd/evm_node_commands_test.go
index 3ad4103b0f1..869ef1b9b3e 100644
--- a/core/cmd/evm_node_commands_test.go
+++ b/core/cmd/evm_node_commands_test.go
@@ -76,7 +76,7 @@ func TestShell_IndexEVMNodes(t *testing.T) {
//Render table and check the fields order
b := new(bytes.Buffer)
rt := cmd.RendererTable{b}
- nodes.RenderTable(rt)
+ require.NoError(t, nodes.RenderTable(rt))
renderLines := strings.Split(b.String(), "\n")
assert.Equal(t, 23, len(renderLines))
assert.Contains(t, renderLines[2], "Name")
diff --git a/core/cmd/evm_transaction_commands.go b/core/cmd/evm_transaction_commands.go
index 8239ff34569..68fffde303e 100644
--- a/core/cmd/evm_transaction_commands.go
+++ b/core/cmd/evm_transaction_commands.go
@@ -133,7 +133,7 @@ func (s *Shell) ShowTransaction(c *cli.Context) (err error) {
// SendEther transfers ETH from the node's account to a specified address.
func (s *Shell) SendEther(c *cli.Context) (err error) {
if c.NArg() < 3 {
- return s.errorOut(errors.New("three arguments expected: amount, fromAddress and toAddress"))
+ return s.errorOut(errors.New("the following arguments expected: (chain) id (in multi-chain setup), amount, fromAddress and toAddress"))
}
var amount assets.Eth
diff --git a/core/cmd/evm_transaction_commands_test.go b/core/cmd/evm_transaction_commands_test.go
index 931942c6093..eb421b03968 100644
--- a/core/cmd/evm_transaction_commands_test.go
+++ b/core/cmd/evm_transaction_commands_test.go
@@ -2,8 +2,10 @@ package cmd_test
import (
"flag"
+ "fmt"
"math/big"
"testing"
+ "time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
@@ -12,9 +14,13 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/assets"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr"
+ evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types"
"github.com/smartcontractkit/chainlink/v2/core/cmd"
"github.com/smartcontractkit/chainlink/v2/core/internal/cltest"
+ "github.com/smartcontractkit/chainlink/v2/core/internal/testutils"
+ "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/evmtest"
"github.com/smartcontractkit/chainlink/v2/core/services/chainlink"
+ "github.com/smartcontractkit/chainlink/v2/core/store/models"
)
func TestShell_IndexTransactions(t *testing.T) {
@@ -133,11 +139,16 @@ func TestShell_SendEther_From_Txm(t *testing.T) {
ethMock := newEthMockWithTransactionsOnBlocksAssertions(t)
ethMock.On("BalanceAt", mock.Anything, key.Address, (*big.Int)(nil)).Return(balance.ToInt(), nil)
+ ethMock.On("SequenceAt", mock.Anything, mock.Anything, mock.Anything).Return(evmtypes.Nonce(0), nil).Maybe()
app := startNewApplicationV2(t, func(c *chainlink.Config, s *chainlink.Secrets) {
c.EVM[0].Enabled = ptr(true)
c.EVM[0].NonceAutoSync = ptr(false)
c.EVM[0].BalanceMonitor.Enabled = ptr(false)
+
+ // NOTE: FallbackPollInterval is used in this test to quickly create TxAttempts
+ // Testing triggers requires committing transactions and does not work with transactional tests
+ c.Database.Listener.FallbackPollInterval = models.MustNewDuration(time.Second)
},
withKey(),
withMocks(ethMock, key),
@@ -151,6 +162,7 @@ func TestShell_SendEther_From_Txm(t *testing.T) {
amount := "100.5"
to := "0x342156c8d3bA54Abc67920d35ba1d1e67201aC9C"
require.NoError(t, set.Parse([]string{amount, fromAddress.Hex(), to}))
+ require.NoError(t, set.Set("id", evmtest.MustGetDefaultChainID(t, app.Config.EVMConfigs()).String()))
cliapp := cli.NewApp()
c := cli.NewContext(cliapp, set, nil)
@@ -158,7 +170,7 @@ func TestShell_SendEther_From_Txm(t *testing.T) {
assert.NoError(t, client.SendEther(c))
dbEvmTx := txmgr.DbEthTx{}
- require.NoError(t, db.Get(&dbEvmTx, `SELECT * FROM eth_txes`))
+ require.NoError(t, db.Get(&dbEvmTx, `SELECT * FROM evm.txes`))
require.Equal(t, "100.500000000000000000", dbEvmTx.Value.String())
require.Equal(t, fromAddress, dbEvmTx.FromAddress)
require.Equal(t, to, dbEvmTx.ToAddress.String())
@@ -167,6 +179,11 @@ func TestShell_SendEther_From_Txm(t *testing.T) {
assert.Equal(t, &dbEvmTx.FromAddress, output.From)
assert.Equal(t, &dbEvmTx.ToAddress, output.To)
assert.Equal(t, dbEvmTx.Value.String(), output.Value)
+ assert.Equal(t, fmt.Sprintf("%d", *dbEvmTx.Nonce), output.Nonce)
+
+ var dbEvmTxAttempt txmgr.DbEthTxAttempt
+ require.NoError(t, db.Get(&dbEvmTxAttempt, `SELECT * FROM evm.tx_attempts`))
+ assert.Equal(t, dbEvmTxAttempt.Hash, output.Hash)
}
func TestShell_SendEther_From_Txm_WEI(t *testing.T) {
@@ -181,11 +198,16 @@ func TestShell_SendEther_From_Txm_WEI(t *testing.T) {
ethMock := newEthMockWithTransactionsOnBlocksAssertions(t)
ethMock.On("BalanceAt", mock.Anything, key.Address, (*big.Int)(nil)).Return(balance.ToInt(), nil)
+ ethMock.On("SequenceAt", mock.Anything, mock.Anything, mock.Anything).Return(evmtypes.Nonce(0), nil).Maybe()
app := startNewApplicationV2(t, func(c *chainlink.Config, s *chainlink.Secrets) {
c.EVM[0].Enabled = ptr(true)
c.EVM[0].NonceAutoSync = ptr(false)
c.EVM[0].BalanceMonitor.Enabled = ptr(false)
+
+ // NOTE: FallbackPollInterval is used in this test to quickly create TxAttempts
+ // Testing triggers requires committing transactions and does not work with transactional tests
+ c.Database.Listener.FallbackPollInterval = models.MustNewDuration(time.Second)
},
withKey(),
withMocks(ethMock, key),
@@ -196,6 +218,7 @@ func TestShell_SendEther_From_Txm_WEI(t *testing.T) {
set := flag.NewFlagSet("sendether", 0)
cltest.FlagSetApplyFromAction(client.SendEther, set, "")
+ require.NoError(t, set.Set("id", testutils.FixtureChainID.String()))
require.NoError(t, set.Set("wei", "false"))
amount := "1000000000000000000"
@@ -212,7 +235,7 @@ func TestShell_SendEther_From_Txm_WEI(t *testing.T) {
assert.NoError(t, client.SendEther(c))
dbEvmTx := txmgr.DbEthTx{}
- require.NoError(t, db.Get(&dbEvmTx, `SELECT * FROM eth_txes`))
+ require.NoError(t, db.Get(&dbEvmTx, `SELECT * FROM evm.txes`))
require.Equal(t, "1.000000000000000000", dbEvmTx.Value.String())
require.Equal(t, fromAddress, dbEvmTx.FromAddress)
require.Equal(t, to, dbEvmTx.ToAddress.String())
@@ -221,4 +244,9 @@ func TestShell_SendEther_From_Txm_WEI(t *testing.T) {
assert.Equal(t, &dbEvmTx.FromAddress, output.From)
assert.Equal(t, &dbEvmTx.ToAddress, output.To)
assert.Equal(t, dbEvmTx.Value.String(), output.Value)
+ assert.Equal(t, fmt.Sprintf("%d", *dbEvmTx.Nonce), output.Nonce)
+
+ 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/forwarders_commands_test.go b/core/cmd/forwarders_commands_test.go
index 7d519917d5a..4381b5ca683 100644
--- a/core/cmd/forwarders_commands_test.go
+++ b/core/cmd/forwarders_commands_test.go
@@ -77,7 +77,7 @@ func TestShell_TrackEVMForwarder(t *testing.T) {
cltest.FlagSetApplyFromAction(client.TrackForwarder, set, "")
require.NoError(t, set.Set("address", "0x5431F5F973781809D18643b87B44921b11355d81"))
- require.NoError(t, set.Set("evmChainID", id.String()))
+ require.NoError(t, set.Set("evm-chain-id", id.String()))
err := client.TrackForwarder(cli.NewContext(nil, set, nil))
require.NoError(t, err)
@@ -122,7 +122,7 @@ func TestShell_TrackEVMForwarder_BadAddress(t *testing.T) {
cltest.FlagSetApplyFromAction(client.TrackForwarder, set, "")
require.NoError(t, set.Set("address", "0xWrongFormatAddress"))
- require.NoError(t, set.Set("evmChainID", id.String()))
+ require.NoError(t, set.Set("evm-chain-id", id.String()))
err := client.TrackForwarder(cli.NewContext(nil, set, nil))
require.Contains(t, err.Error(), "could not decode address: invalid hex string")
diff --git a/core/cmd/renderer_test.go b/core/cmd/renderer_test.go
index 78de49ffed4..f617747953c 100644
--- a/core/cmd/renderer_test.go
+++ b/core/cmd/renderer_test.go
@@ -37,7 +37,7 @@ func TestRendererTable_RenderConfigurationV2(t *testing.T) {
app := cltest.NewApplicationEVMDisabled(t)
wantUser, wantEffective := app.Config.ConfigTOML()
require.NoError(t, app.Start(testutils.Context(t)))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
t.Run("effective", func(t *testing.T) {
resp, cleanup := client.Get("/v2/config/v2")
diff --git a/core/cmd/shell.go b/core/cmd/shell.go
index 4215e36b496..8532f2f5431 100644
--- a/core/cmd/shell.go
+++ b/core/cmd/shell.go
@@ -109,15 +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"))
- } else {
- fmt.Printf("Notification for upcoming configuration change: %v\n", err)
- fmt.Println("This configuration will be disallowed in future production releases.")
- fmt.Println()
- }
+ fmt.Println("Invalid configuration:", err)
+ fmt.Println()
+ return s.errorOut(errors.New("invalid configuration"))
}
return nil
}
@@ -134,6 +128,11 @@ 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())
+ err = migrate.SetMigrationENVVars(cfg)
+ if err != nil {
+ return nil, err
+ }
+
err = handleNodeVersioning(db, appLggr, cfg.RootDir(), cfg.Database(), cfg.WebServer().HTTPPort())
if err != nil {
return nil, err
@@ -144,20 +143,18 @@ func (n ChainlinkAppFactory) NewApplication(ctx context.Context, cfg chainlink.G
dbListener := cfg.Database().Listener()
eventBroadcaster := pg.NewEventBroadcaster(cfg.Database().URL(), dbListener.MinReconnectInterval(), dbListener.MaxReconnectDuration(), appLggr, cfg.AppID())
- loopRegistry := plugins.NewLoopRegistry(appLggr.Named("LoopRegistry"))
+ loopRegistry := plugins.NewLoopRegistry(appLggr)
// 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
diff --git a/core/cmd/shell_local.go b/core/cmd/shell_local.go
index cd4f170523b..372aad01384 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)
@@ -375,22 +372,7 @@ func (s *Shell) runNode(c *cli.Context) error {
legacyEVMChains := app.GetRelayers().LegacyEVMChains()
- // By passing in a function we can be lazy trying to look up a default
- // chain - if there are no existing keys, there is no need to check for
- // a chain ID
- DefaultEVMChainIDFunc := func() (*big.Int, error) {
- def, err2 := legacyEVMChains.Default()
- if err2 != nil {
- return nil, errors.Wrap(err2, "cannot get default EVM chain ID; no default EVM chain available")
- }
- return def.ID(), nil
- }
- err = keyStore.Migrate(s.Config.Password().VRF(), DefaultEVMChainIDFunc)
-
if s.Config.EVMEnabled() {
- if err != nil {
- return errors.Wrap(err, "error migrating keystore")
- }
chainList, err := legacyEVMChains.List()
if err != nil {
return fmt.Errorf("error listing legacy evm chains: %w", err)
@@ -637,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())
@@ -727,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()
@@ -834,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 {
@@ -855,6 +834,11 @@ func (s *Shell) MigrateDatabase(_ *cli.Context) error {
return s.errorOut(errDBURLMissing)
}
+ err := migrate.SetMigrationENVVars(s.Config)
+ if err != nil {
+ return err
+ }
+
s.Logger.Infof("Migrating database: %#v", parsed.String())
if err := migrateDB(cfg, s.Logger); err != nil {
return s.errorOut(err)
@@ -862,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() {
@@ -1038,6 +1022,7 @@ func migrateDB(config dbConfig, lggr logger.Logger) error {
if err != nil {
return fmt.Errorf("failed to initialize orm: %v", err)
}
+
if err = migrate.Migrate(db.DB, lggr); err != nil {
return fmt.Errorf("migrateDB failed: %v", err)
}
diff --git a/core/cmd/shell_local_test.go b/core/cmd/shell_local_test.go
index db170d267d5..691e5faa923 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)
@@ -136,10 +134,7 @@ func TestShell_RunNodeWithPasswords(t *testing.T) {
if err := cli.Before(c); err != nil {
return err
}
- if err := client.RunNode(c); err != nil {
- return err
- }
- return nil
+ return client.RunNode(c)
}
if test.wantUnlocked {
@@ -194,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)
@@ -326,6 +320,7 @@ func TestShell_RebroadcastTransactions_Txm(t *testing.T) {
set := flag.NewFlagSet("test", 0)
cltest.FlagSetApplyFromAction(client.RebroadcastTransactions, set, "")
+ require.NoError(t, set.Set("evmChainID", testutils.FixtureChainID.String()))
require.NoError(t, set.Set("beginningNonce", strconv.FormatUint(beginningNonce, 10)))
require.NoError(t, set.Set("endingNonce", strconv.FormatUint(endingNonce, 10)))
require.NoError(t, set.Set("gasPriceWei", "100000000000"))
@@ -405,6 +400,7 @@ func TestShell_RebroadcastTransactions_OutsideRange_Txm(t *testing.T) {
set := flag.NewFlagSet("test", 0)
cltest.FlagSetApplyFromAction(client.RebroadcastTransactions, set, "")
+ require.NoError(t, set.Set("evmChainID", testutils.FixtureChainID.String()))
require.NoError(t, set.Set("beginningNonce", strconv.FormatUint(uint64(beginningNonce), 10)))
require.NoError(t, set.Set("endingNonce", strconv.FormatUint(uint64(endingNonce), 10)))
require.NoError(t, set.Set("gasPriceWei", gasPrice.String()))
@@ -483,9 +479,9 @@ func TestShell_RebroadcastTransactions_AddressCheck(t *testing.T) {
}
set := flag.NewFlagSet("test", 0)
- set.Set("evmChainID", testutils.SimulatedChainID.String())
cltest.FlagSetApplyFromAction(client.RebroadcastTransactions, set, "")
+ require.NoError(t, set.Set("evmChainID", testutils.FixtureChainID.String()))
require.NoError(t, set.Set("address", fromAddress.Hex()))
require.NoError(t, set.Set("password", "../internal/fixtures/correct_password.txt"))
c := cli.NewContext(nil, set, nil)
diff --git a/core/cmd/shell_remote_test.go b/core/cmd/shell_remote_test.go
index 69fa5924828..83686443faa 100644
--- a/core/cmd/shell_remote_test.go
+++ b/core/cmd/shell_remote_test.go
@@ -125,13 +125,9 @@ func TestShell_ReplayBlocks(t *testing.T) {
cltest.FlagSetApplyFromAction(client.ReplayFromBlock, set, "")
require.NoError(t, set.Set("block-number", "42"))
-
- c := cli.NewContext(nil, set, nil)
- assert.NoError(t, client.ReplayFromBlock(c))
-
require.NoError(t, set.Set("evm-chain-id", "12345678"))
- c = cli.NewContext(nil, set, nil)
- assert.ErrorContains(t, client.ReplayFromBlock(c), "evmChainID does not match any local chains")
+ c := cli.NewContext(nil, set, nil)
+ assert.ErrorContains(t, client.ReplayFromBlock(c), "chain id does not match any local chains")
require.NoError(t, set.Set("evm-chain-id", "0"))
c = cli.NewContext(nil, set, nil)
diff --git a/core/cmd/shell_test.go b/core/cmd/shell_test.go
index 733c0058f37..c74a0067a68 100644
--- a/core/cmd/shell_test.go
+++ b/core/cmd/shell_test.go
@@ -342,11 +342,26 @@ func TestSetupSolanaRelayer(t *testing.T) {
lggr := logger.TestLogger(t)
reg := plugins.NewLoopRegistry(lggr)
ks := mocks.NewSolana(t)
+
+ // config 3 chains but only enable 2 => should only be 2 relayer
+ nEnabledChains := 2
tConfig := configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) {
c.Solana = solana.SolanaConfigs{
&solana.SolanaConfig{
ChainID: ptr[string]("solana-id-1"),
- Enabled: new(bool),
+ Enabled: ptr(true),
+ Chain: solcfg.Chain{},
+ Nodes: []*solcfg.Node{},
+ },
+ &solana.SolanaConfig{
+ ChainID: ptr[string]("solana-id-2"),
+ Enabled: ptr(true),
+ Chain: solcfg.Chain{},
+ Nodes: []*solcfg.Node{},
+ },
+ &solana.SolanaConfig{
+ ChainID: ptr[string]("disabled-solana-id-1"),
+ Enabled: ptr(false),
Chain: solcfg.Chain{},
Nodes: []*solcfg.Node{},
},
@@ -355,8 +370,6 @@ func TestSetupSolanaRelayer(t *testing.T) {
rf := chainlink.RelayerFactory{
Logger: lggr,
- DB: pgtest.NewSqlxDB(t),
- QConfig: tConfig.Database(),
LoopRegistry: reg,
}
@@ -365,7 +378,7 @@ func TestSetupSolanaRelayer(t *testing.T) {
relayers, err := rf.NewSolana(ks, tConfig.SolanaConfigs())
require.NoError(t, err)
require.NotNil(t, relayers)
- require.Len(t, relayers, 1)
+ require.Len(t, relayers, nEnabledChains)
// no using plugin, so registry should be empty
require.Len(t, reg.List(), 0)
})
@@ -376,22 +389,65 @@ func TestSetupSolanaRelayer(t *testing.T) {
relayers, err := rf.NewSolana(ks, tConfig.SolanaConfigs())
require.NoError(t, err)
require.NotNil(t, relayers)
- require.Len(t, relayers, 1)
+ require.Len(t, relayers, nEnabledChains)
// make sure registry has the plugin
- require.Len(t, reg.List(), 1)
+ require.Len(t, reg.List(), nEnabledChains)
+ })
+
+ // test that duplicate enabled chains is an error when
+ duplicateConfig := configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) {
+ c.Solana = solana.SolanaConfigs{
+ &solana.SolanaConfig{
+ ChainID: ptr[string]("dupe"),
+ Enabled: ptr(true),
+ Chain: solcfg.Chain{},
+ Nodes: []*solcfg.Node{},
+ },
+ &solana.SolanaConfig{
+ ChainID: ptr[string]("dupe"),
+ Enabled: ptr(true),
+ Chain: solcfg.Chain{},
+ Nodes: []*solcfg.Node{},
+ },
+ }
+ })
+
+ // not parallel; shared state
+ t.Run("no plugin, duplicate chains", func(t *testing.T) {
+ _, err := rf.NewSolana(ks, duplicateConfig.SolanaConfigs())
+ require.Error(t, err)
})
+ t.Run("plugin, duplicate chains", func(t *testing.T) {
+ t.Setenv("CL_SOLANA_CMD", "phony_solana_cmd")
+ _, err := rf.NewSolana(ks, duplicateConfig.SolanaConfigs())
+ require.Error(t, err)
+ })
}
func TestSetupStarkNetRelayer(t *testing.T) {
lggr := logger.TestLogger(t)
reg := plugins.NewLoopRegistry(lggr)
ks := mocks.NewStarkNet(t)
+ // config 3 chains but only enable 2 => should only be 2 relayer
+ nEnabledChains := 2
tConfig := configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) {
c.Starknet = starknet.StarknetConfigs{
&starknet.StarknetConfig{
ChainID: ptr[string]("starknet-id-1"),
- Enabled: new(bool),
+ Enabled: ptr(true),
+ Chain: stkcfg.Chain{},
+ Nodes: []*config.Node{},
+ },
+ &starknet.StarknetConfig{
+ ChainID: ptr[string]("starknet-id-2"),
+ Enabled: ptr(true),
+ Chain: stkcfg.Chain{},
+ Nodes: []*config.Node{},
+ },
+ &starknet.StarknetConfig{
+ ChainID: ptr[string]("disabled-starknet-id-1"),
+ Enabled: ptr(false),
Chain: stkcfg.Chain{},
Nodes: []*config.Node{},
},
@@ -399,8 +455,6 @@ func TestSetupStarkNetRelayer(t *testing.T) {
})
rf := chainlink.RelayerFactory{
Logger: lggr,
- DB: pgtest.NewSqlxDB(t),
- QConfig: tConfig.Database(),
LoopRegistry: reg,
}
@@ -409,7 +463,7 @@ func TestSetupStarkNetRelayer(t *testing.T) {
relayers, err := rf.NewStarkNet(ks, tConfig.StarknetConfigs())
require.NoError(t, err)
require.NotNil(t, relayers)
- require.Len(t, relayers, 1)
+ require.Len(t, relayers, nEnabledChains)
// no using plugin, so registry should be empty
require.Len(t, reg.List(), 0)
})
@@ -420,9 +474,38 @@ func TestSetupStarkNetRelayer(t *testing.T) {
relayers, err := rf.NewStarkNet(ks, tConfig.StarknetConfigs())
require.NoError(t, err)
require.NotNil(t, relayers)
- require.Len(t, relayers, 1)
+ require.Len(t, relayers, nEnabledChains)
// make sure registry has the plugin
- require.Len(t, reg.List(), 1)
+ require.Len(t, reg.List(), nEnabledChains)
})
+ // test that duplicate enabled chains is an error when
+ duplicateConfig := configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) {
+ c.Starknet = starknet.StarknetConfigs{
+ &starknet.StarknetConfig{
+ ChainID: ptr[string]("dupe"),
+ Enabled: ptr(true),
+ Chain: stkcfg.Chain{},
+ Nodes: []*config.Node{},
+ },
+ &starknet.StarknetConfig{
+ ChainID: ptr[string]("dupe"),
+ Enabled: ptr(true),
+ Chain: stkcfg.Chain{},
+ Nodes: []*config.Node{},
+ },
+ }
+ })
+
+ // not parallel; shared state
+ t.Run("no plugin, duplicate chains", func(t *testing.T) {
+ _, err := rf.NewStarkNet(ks, duplicateConfig.StarknetConfigs())
+ require.Error(t, err)
+ })
+
+ t.Run("plugin, duplicate chains", func(t *testing.T) {
+ t.Setenv("CL_STARKNET_CMD", "phony_starknet_cmd")
+ _, err := rf.NewStarkNet(ks, duplicateConfig.StarknetConfigs())
+ require.Error(t, err)
+ })
}
diff --git a/core/cmd/solana_chains_commands_test.go b/core/cmd/solana_chains_commands_test.go
index 7e8c2373be1..ac80b307d0a 100644
--- a/core/cmd/solana_chains_commands_test.go
+++ b/core/cmd/solana_chains_commands_test.go
@@ -16,8 +16,11 @@ func TestShell_IndexSolanaChains(t *testing.T) {
t.Parallel()
id := solanatest.RandomChainID()
- chain := solana.SolanaConfig{ChainID: &id}
- app := solanaStartNewApplication(t, &chain)
+ cfg := solana.SolanaConfig{
+ ChainID: &id,
+ Enabled: ptr(true),
+ }
+ app := solanaStartNewApplication(t, &cfg)
client, r := app.NewShellAndRenderer()
require.Nil(t, cmd.SolanaChainClient(client).IndexChains(cltest.EmptyCLIContext()))
diff --git a/core/cmd/solana_node_commands_test.go b/core/cmd/solana_node_commands_test.go
index 4d6d585b260..48a889c0adf 100644
--- a/core/cmd/solana_node_commands_test.go
+++ b/core/cmd/solana_node_commands_test.go
@@ -29,7 +29,6 @@ func solanaStartNewApplication(t *testing.T, cfgs ...*solana.SolanaConfig) *clte
})
}
-// TODO fix https://smartcontract-it.atlassian.net/browse/BCF-2114
func TestShell_IndexSolanaNodes(t *testing.T) {
t.Parallel()
@@ -72,7 +71,7 @@ func TestShell_IndexSolanaNodes(t *testing.T) {
//Render table and check the fields order
b := new(bytes.Buffer)
rt := cmd.RendererTable{b}
- nodes.RenderTable(rt)
+ require.NoError(t, nodes.RenderTable(rt))
renderLines := strings.Split(b.String(), "\n")
assert.Equal(t, 17, len(renderLines))
assert.Contains(t, renderLines[2], "Name")
diff --git a/core/cmd/solana_transaction_commands_test.go b/core/cmd/solana_transaction_commands_test.go
index 4fcb8ad84e0..a23a3dce5c2 100644
--- a/core/cmd/solana_transaction_commands_test.go
+++ b/core/cmd/solana_transaction_commands_test.go
@@ -34,6 +34,7 @@ func TestShell_SolanaSendSol(t *testing.T) {
cfg := solana.SolanaConfig{
ChainID: &chainID,
Nodes: solana.SolanaNodes{&node},
+ Enabled: ptr(true),
}
app := solanaStartNewApplication(t, &cfg)
from, err := app.GetKeyStore().Solana().Create()
diff --git a/core/cmd/starknet_node_commands_test.go b/core/cmd/starknet_node_commands_test.go
index 92490df2d18..7df7af429b5 100644
--- a/core/cmd/starknet_node_commands_test.go
+++ b/core/cmd/starknet_node_commands_test.go
@@ -6,11 +6,12 @@ import (
"testing"
"github.com/pelletier/go-toml/v2"
- "github.com/smartcontractkit/chainlink-relay/pkg/utils"
- "github.com/smartcontractkit/chainlink-starknet/relayer/pkg/chainlink/config"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
+ "github.com/smartcontractkit/chainlink-relay/pkg/utils"
+ "github.com/smartcontractkit/chainlink-starknet/relayer/pkg/chainlink/config"
+
"github.com/smartcontractkit/chainlink/v2/core/chains/starknet"
"github.com/smartcontractkit/chainlink/v2/core/cmd"
"github.com/smartcontractkit/chainlink/v2/core/internal/cltest"
@@ -70,7 +71,7 @@ func TestShell_IndexStarkNetNodes(t *testing.T) {
//Render table and check the fields order
b := new(bytes.Buffer)
rt := cmd.RendererTable{b}
- nodes.RenderTable(rt)
+ require.NoError(t, nodes.RenderTable(rt))
renderLines := strings.Split(b.String(), "\n")
assert.Equal(t, 17, len(renderLines))
assert.Contains(t, renderLines[2], "Name")
diff --git a/core/config/app_config.go b/core/config/app_config.go
index 82652d3c8ce..20e877e6ec1 100644
--- a/core/config/app_config.go
+++ b/core/config/app_config.go
@@ -1,7 +1,6 @@
package config
import (
- "math/big"
"time"
"github.com/google/uuid"
@@ -21,7 +20,6 @@ type AppConfig interface {
RootDir() string
ShutdownGracePeriod() time.Duration
InsecureFastScrypt() bool
- DefaultChainID() *big.Int
EVMEnabled() bool
EVMRPCEnabled() bool
CosmosEnabled() bool
@@ -38,7 +36,6 @@ type AppConfig interface {
AuditLogger() AuditLogger
AutoPprof() AutoPprof
Database() Database
- Explorer() Explorer
Feature() Feature
FluxMonitor() FluxMonitor
Insecure() Insecure
diff --git a/core/config/docs/chains-cosmos.toml b/core/config/docs/chains-cosmos.toml
index 3281c6c27a6..bcdb040a680 100644
--- a/core/config/docs/chains-cosmos.toml
+++ b/core/config/docs/chains-cosmos.toml
@@ -13,8 +13,8 @@ BlocksUntilTxTimeout = 30 # Default
ConfirmPollPeriod = '1s' # Default
# FallbackGasPrice sets a fallback gas price to use when the estimator is not available.
FallbackGasPrice = '0.015' # Default
-# FeeToken is the token denomination which is being used to pay gas fees on this chain.
-FeeToken = 'ucosm' # Default
+# GasToken is the token denomination which is being used to pay gas fees on this chain.
+GasToken = 'ucosm' # Default
# GasLimitMultiplier scales the estimated gas limit.
GasLimitMultiplier = '1.5' # Default
# MaxMsgsPerBatch limits the numbers of mesages per transaction batch.
diff --git a/core/config/docs/core.toml b/core/config/docs/core.toml
index 7253cbd1aad..b9c1063c12a 100644
--- a/core/config/docs/core.toml
+++ b/core/config/docs/core.toml
@@ -1,5 +1,3 @@
-# ExplorerURL is the websocket URL used by the node to push stats. This variable is required to deliver telemetry.
-ExplorerURL = 'ws://explorer.url' # Example
# **ADVANCED**
# InsecureFastScrypt causes all key stores to encrypt using "fast" scrypt params instead. This is insecure and only useful for local testing. DO NOT ENABLE THIS IN PRODUCTION.
InsecureFastScrypt = false # Default
diff --git a/core/config/docs/secrets.toml b/core/config/docs/secrets.toml
index de097e50a0e..2b491a77497 100644
--- a/core/config/docs/secrets.toml
+++ b/core/config/docs/secrets.toml
@@ -14,16 +14,6 @@ BackupURL = "postgresql://user:pass@read-replica.example.com:5432/dbname?sslmode
# Environment variable: `CL_DATABASE_ALLOW_SIMPLE_PASSWORDS`
AllowSimplePasswords = false # Default
-[Explorer]
-# AccessKey is the access key for authenticating with the Explorer.
-#
-# Environment variable: `CL_EXPLORER_ACCESS_KEY`
-AccessKey = "access_key" # Example
-# Secret is the secret for authenticating with the Explorer.
-#
-# Environment variable: `CL_EXPLORER_SECRET`
-Secret = "secret" # Example
-
[Password]
# Keystore is the password for the node's account.
#
@@ -51,8 +41,10 @@ AuthToken = "prometheus-token" # Example
Username = "A-Mercury-Username" # Example
# Password is used for basic auth of the Mercury endpoint
Password = "A-Mercury-Password" # Example
-# URL is the Mercury endpoint URL which is used by OCR2 Automation to access Mercury price feed
+# URL is the Mercury endpoint base URL used to access Mercury price feed
URL = "https://example.com" # Example
+# LegacyURL is the Mercury legacy endpoint base URL used to access Mercury v0.2 price feed
+LegacyURL = "https://example.v1.com" # Example
[Threshold]
# ThresholdKeyShare used by the threshold decryption OCR plugin
diff --git a/core/config/env/env.go b/core/config/env/env.go
index 160aae65f6d..ea84a50b754 100644
--- a/core/config/env/env.go
+++ b/core/config/env/env.go
@@ -31,13 +31,13 @@ var (
DatabaseAllowSimplePasswords = Var("CL_DATABASE_ALLOW_SIMPLE_PASSWORDS")
DatabaseURL = Secret("CL_DATABASE_URL")
DatabaseBackupURL = Secret("CL_DATABASE_BACKUP_URL")
- ExplorerAccessKey = Secret("CL_EXPLORER_ACCESS_KEY")
- ExplorerSecret = Secret("CL_EXPLORER_SECRET")
PasswordKeystore = Secret("CL_PASSWORD_KEYSTORE")
PasswordVRF = Secret("CL_PASSWORD_VRF")
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/config/ethereum_config.go b/core/config/ethereum_config.go
deleted file mode 100644
index de3ccf28047..00000000000
--- a/core/config/ethereum_config.go
+++ /dev/null
@@ -1,9 +0,0 @@
-package config
-
-import (
- "math/big"
-)
-
-type Ethereum interface {
- DefaultChainID() *big.Int
-}
diff --git a/core/config/explorer_config.go b/core/config/explorer_config.go
deleted file mode 100644
index dcb201d616d..00000000000
--- a/core/config/explorer_config.go
+++ /dev/null
@@ -1,9 +0,0 @@
-package config
-
-import "net/url"
-
-type Explorer interface {
- AccessKey() string
- Secret() string
- URL() *url.URL
-}
diff --git a/core/config/toml/types.go b/core/config/toml/types.go
index 5aedcf4deb6..5fba0c7ea5e 100644
--- a/core/config/toml/types.go
+++ b/core/config/toml/types.go
@@ -32,7 +32,6 @@ var ErrUnsupported = errors.New("unsupported with config v2")
type Core struct {
// General/misc
AppID uuid.UUID `toml:"-"` // random or test
- ExplorerURL *models.URL
InsecureFastScrypt *bool
RootDir *string
ShutdownGracePeriod *models.Duration
@@ -57,9 +56,6 @@ type Core struct {
// SetFrom updates c with any non-nil values from f. (currently TOML field only!)
func (c *Core) SetFrom(f *Core) {
- if v := f.ExplorerURL; v != nil {
- c.ExplorerURL = v
- }
if v := f.InsecureFastScrypt; v != nil {
c.InsecureFastScrypt = v
}
@@ -102,7 +98,6 @@ func (c *Core) ValidateConfig() (err error) {
type Secrets struct {
Database DatabaseSecrets `toml:",omitempty"`
- Explorer ExplorerSecrets `toml:",omitempty"`
Password Passwords `toml:",omitempty"`
Pyroscope PyroscopeSecrets `toml:",omitempty"`
Prometheus PrometheusSecrets `toml:",omitempty"`
@@ -197,39 +192,6 @@ func (d *DatabaseSecrets) validateMerge(f *DatabaseSecrets) (err error) {
return err
}
-type ExplorerSecrets struct {
- AccessKey *models.Secret
- Secret *models.Secret
-}
-
-func (e *ExplorerSecrets) SetFrom(f *ExplorerSecrets) (err error) {
- err = e.validateMerge(f)
- if err != nil {
- return err
- }
-
- if v := f.AccessKey; v != nil {
- e.AccessKey = v
- }
- if v := f.Secret; v != nil {
- e.Secret = v
- }
-
- return nil
-}
-
-func (e *ExplorerSecrets) validateMerge(f *ExplorerSecrets) (err error) {
- if e.AccessKey != nil && f.AccessKey != nil {
- err = multierr.Append(err, configutils.ErrOverride{Name: "AccessKey"})
- }
-
- if e.Secret != nil && f.Secret != nil {
- err = multierr.Append(err, configutils.ErrOverride{Name: "Secret"})
- }
-
- return err
-}
-
type Passwords struct {
Keystore *models.Secret
VRF *models.Secret
@@ -1215,8 +1177,13 @@ func (ins *Insecure) setFrom(f *Insecure) {
}
type MercuryCredentials struct {
- URL *models.SecretURL
+ // LegacyURL is the legacy base URL for mercury v0.2 API
+ LegacyURL *models.SecretURL
+ // URL is the base URL for mercury v0.3 API
+ URL *models.SecretURL
+ // Username is the user id for mercury credential
Username *models.Secret
+ // Password is the user secret key for mercury credential
Password *models.Secret
}
@@ -1263,6 +1230,10 @@ func (m *MercurySecrets) ValidateConfig() (err error) {
err = multierr.Append(err, configutils.ErrMissing{Name: "URL", Msg: "must be provided and non-empty"})
continue
}
+ if creds.LegacyURL != nil && creds.LegacyURL.URL() == nil {
+ err = multierr.Append(err, configutils.ErrMissing{Name: "Legacy URL", Msg: "must be a valid URL"})
+ continue
+ }
s := creds.URL.URL().String()
if _, exists := urls[s]; exists {
err = multierr.Append(err, configutils.NewErrDuplicate("URL", s))
diff --git a/core/config/toml/types_test.go b/core/config/toml/types_test.go
index e2eb5eed815..2ab3f0fb86b 100644
--- a/core/config/toml/types_test.go
+++ b/core/config/toml/types_test.go
@@ -27,6 +27,12 @@ func TestMercurySecrets_valid(t *testing.T) {
Username: models.NewSecret("new user1"),
Password: models.NewSecret("new password2"),
},
+ "cred3": {
+ LegacyURL: models.MustSecretURL("https://abc.com"),
+ URL: models.MustSecretURL("HTTPS://GOOGLE1.COM"),
+ Username: models.NewSecret("new user1"),
+ Password: models.NewSecret("new password2"),
+ },
},
}
diff --git a/core/gethwrappers/OffchainAggregator/OffchainAggregator.abi b/core/gethwrappers/OffchainAggregator/OffchainAggregator.abi
index e33ed2b8f3f..d83251ac189 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/functions/generated/functions_client_example/functions_client_example.go b/core/gethwrappers/functions/generated/functions_client_example/functions_client_example.go
index 6dc02520146..6ae90b45edb 100644
--- a/core/gethwrappers/functions/generated/functions_client_example/functions_client_example.go
+++ b/core/gethwrappers/functions/generated/functions_client_example/functions_client_example.go
@@ -32,7 +32,7 @@ var (
var FunctionsClientExampleMetaData = &bind.MetaData{
ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"EmptyArgs\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptySecrets\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptySource\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoInlineSecrets\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyRouterCanFulfill\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"}],\"name\":\"UnexpectedRequestID\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"RequestFulfilled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"RequestSent\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MAX_CALLBACK_GAS\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"handleOracleFulfillment\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_lastError\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_lastErrorLength\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_lastRequestId\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_lastResponse\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_lastResponseLength\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"source\",\"type\":\"string\"},{\"internalType\":\"bytes\",\"name\":\"encryptedSecretsReferences\",\"type\":\"bytes\"},{\"internalType\":\"string[]\",\"name\":\"args\",\"type\":\"string[]\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"jobId\",\"type\":\"bytes32\"}],\"name\":\"sendRequest\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]",
- Bin: "0x60a06040523480156200001157600080fd5b5060405162001a7638038062001a76833981016040819052620000349162000180565b6001600160a01b0381166080523380600081620000985760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000cb57620000cb81620000d5565b50505050620001b2565b336001600160a01b038216036200012f5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200008f565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000602082840312156200019357600080fd5b81516001600160a01b0381168114620001ab57600080fd5b9392505050565b6080516118a1620001d5600039600081816101c60152610a2a01526118a16000f3fe608060405234801561001057600080fd5b50600436106100c95760003560e01c80636d9809a011610081578063b1e217491161005b578063b1e2174914610182578063f2fde38b1461018b578063f7b4c06f1461019e57600080fd5b80636d9809a01461014857806379ba5097146101525780638da5cb5b1461015a57600080fd5b806342748b2a116100b257806342748b2a146100ff5780634b0795a81461012c5780635fa353e71461013557600080fd5b80630ca76175146100ce5780633944ea3a146100e3575b600080fd5b6100e16100dc3660046112ed565b6101ae565b005b6100ec60035481565b6040519081526020015b60405180910390f35b60055461011790640100000000900463ffffffff1681565b60405163ffffffff90911681526020016100f6565b6100ec60045481565b6100e16101433660046113c0565b61022d565b6101176201117081565b6100e1610347565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100f6565b6100ec60025481565b6100e16101993660046114a4565b610449565b6005546101179063ffffffff1681565b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161461021d576040517fc6829f8300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61022883838361045d565b505050565b61023561052b565b61027e6040805161010081019091528060008152602001600081526020016000815260200160608152602001606081526020016060815260200160608152602001606081525090565b6102c089898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525085939250506105ae9050565b85156103085761030887878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525085939250506105bf9050565b83156103225761032261031b85876114da565b8290610609565b61033961032e8261064c565b846201117085610a25565b600255505050505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146103cd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b61045161052b565b61045a81610b04565b50565b826002541461049b576040517fd068bf5b000000000000000000000000000000000000000000000000000000008152600481018490526024016103c4565b6104a482610bf9565b6003558151600580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff9092169190911790556104e681610bf9565b600455516005805463ffffffff909216640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff9092169190911790555050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146105ac576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016103c4565b565b6105bb8260008084610c7b565b5050565b80516000036105fa576040517fe889636f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60016020830152608090910152565b8051600003610644576040517ffe936cb700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c090910152565b6060600061065b610100610d12565b90506106a56040518060400160405280600c81526020017f636f64654c6f636174696f6e000000000000000000000000000000000000000081525082610d3390919063ffffffff16565b82516106c39060028111156106bc576106bc611572565b8290610d4c565b60408051808201909152600881527f6c616e67756167650000000000000000000000000000000000000000000000006020820152610702908290610d33565b60408301516107199080156106bc576106bc611572565b60408051808201909152600681527f736f7572636500000000000000000000000000000000000000000000000000006020820152610758908290610d33565b6060830151610768908290610d33565b60a083015151156107c25760408051808201909152601081527f726571756573745369676e61747572650000000000000000000000000000000060208201526107b2908290610d33565b60a08301516107c2908290610d81565b60c0830151511561086f5760408051808201909152600481527f6172677300000000000000000000000000000000000000000000000000000000602082015261080c908290610d33565b61081581610d8e565b60005b8360c0015151811015610865576108558460c00151828151811061083e5761083e6115a1565b602002602001015183610d3390919063ffffffff16565b61085e816115ff565b9050610818565b5061086f81610db2565b608083015151156109705760008360200151600281111561089257610892611572565b036108c9576040517fa80d31f700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051808201909152600f81527f736563726574734c6f636174696f6e00000000000000000000000000000000006020820152610908908290610d33565b610921836020015160028111156106bc576106bc611572565b60408051808201909152600781527f73656372657473000000000000000000000000000000000000000000000000006020820152610960908290610d33565b6080830151610970908290610d81565b60e08301515115610a1d5760408051808201909152600981527f627974657341726773000000000000000000000000000000000000000000000060208201526109ba908290610d33565b6109c381610d8e565b60005b8360e0015151811015610a1357610a038460e0015182815181106109ec576109ec6115a1565b602002602001015183610d8190919063ffffffff16565b610a0c816115ff565b90506109c6565b50610a1d81610db2565b515192915050565b6000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663461d27628688600188886040518663ffffffff1660e01b8152600401610a8a959493929190611637565b6020604051808303816000875af1158015610aa9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610acd91906116d7565b60405190915081907f1131472297a800fee664d1d89cfa8f7676ff07189ecc53f80bbb5f4969099db890600090a295945050505050565b3373ffffffffffffffffffffffffffffffffffffffff821603610b83576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016103c4565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008060209050602083511015610c0e575081515b60005b81811015610c7457610c248160086116f0565b848281518110610c3657610c366115a1565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016901c9290921791610c6d816115ff565b9050610c11565b5050919050565b8051600003610cb6576040517f22ce3edd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83836002811115610cc957610cc9611572565b90816002811115610cdc57610cdc611572565b90525060408401828015610cf257610cf2611572565b90818015610d0257610d02611572565b9052506060909301929092525050565b610d1a6111a4565b8051610d269083610dd0565b5060006020820152919050565b610d408260038351610e4a565b81516102289082610f71565b8151610d599060c2610f99565b506105bb8282604051602001610d7191815260200190565b6040516020818303038152906040525b610d408260028351610e4a565b610d99816004611002565b600181602001818151610dac9190611707565b90525050565b610dbd816007611002565b600181602001818151610dac919061171a565b604080518082019091526060815260006020820152610df060208361172d565b15610e1857610e0060208361172d565b610e0b90602061171a565b610e159083611707565b91505b602080840183905260405180855260008152908184010181811015610e3c57600080fd5b604052508290505b92915050565b60178167ffffffffffffffff1611610e77578251610e719060e0600585901b168317610f99565b50505050565b60ff8167ffffffffffffffff1611610eb9578251610ea0906018611fe0600586901b1617610f99565b508251610e719067ffffffffffffffff83166001611019565b61ffff8167ffffffffffffffff1611610efc578251610ee3906019611fe0600586901b1617610f99565b508251610e719067ffffffffffffffff83166002611019565b63ffffffff8167ffffffffffffffff1611610f41578251610f2890601a611fe0600586901b1617610f99565b508251610e719067ffffffffffffffff83166004611019565b8251610f5890601b611fe0600586901b1617610f99565b508251610e719067ffffffffffffffff83166008611019565b604080518082019091526060815260006020820152610f928383845161109e565b9392505050565b6040805180820190915260608152600060208201528251516000610fbe826001611707565b905084602001518210610fdf57610fdf85610fda8360026116f0565b61118d565b8451602083820101858153508051821115610ff8578181525b5093949350505050565b815161022890601f611fe0600585901b1617610f99565b604080518082019091526060815260006020820152835151600061103d8285611707565b9050856020015181111561105a5761105a86610fda8360026116f0565b6000600161106a86610100611888565b611074919061171a565b90508651828101878319825116178152508051831115611092578281525b50959695505050505050565b60408051808201909152606081526000602082015282518211156110c157600080fd5b83515160006110d08483611707565b905085602001518111156110ed576110ed86610fda8360026116f0565b855180518382016020019160009180851115611107578482525b505050602086015b602086106111475780518252611126602083611707565b9150611133602082611707565b905061114060208761171a565b955061110f565b5181517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60208890036101000a0190811690199190911617905250849150509392505050565b81516111998383610dd0565b50610e718382610f71565b60405180604001604052806111cc604051806040016040528060608152602001600081525090565b8152602001600081525090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561124f5761124f6111d9565b604052919050565b600067ffffffffffffffff831115611271576112716111d9565b6112a260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f86011601611208565b90508281528383830111156112b657600080fd5b828260208301376000602084830101529392505050565b600082601f8301126112de57600080fd5b610f9283833560208501611257565b60008060006060848603121561130257600080fd5b83359250602084013567ffffffffffffffff8082111561132157600080fd5b61132d878388016112cd565b9350604086013591508082111561134357600080fd5b50611350868287016112cd565b9150509250925092565b60008083601f84011261136c57600080fd5b50813567ffffffffffffffff81111561138457600080fd5b60208301915083602082850101111561139c57600080fd5b9250929050565b803567ffffffffffffffff811681146113bb57600080fd5b919050565b60008060008060008060008060a0898b0312156113dc57600080fd5b883567ffffffffffffffff808211156113f457600080fd5b6114008c838d0161135a565b909a50985060208b013591508082111561141957600080fd5b6114258c838d0161135a565b909850965060408b013591508082111561143e57600080fd5b818b0191508b601f83011261145257600080fd5b81358181111561146157600080fd5b8c60208260051b850101111561147657600080fd5b60208301965080955050505061148e60608a016113a3565b9150608089013590509295985092959890939650565b6000602082840312156114b657600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610f9257600080fd5b600067ffffffffffffffff808411156114f5576114f56111d9565b8360051b6020611506818301611208565b86815291850191818101903684111561151e57600080fd5b865b84811015611566578035868111156115385760008081fd5b880136601f82011261154a5760008081fd5b611558368235878401611257565b845250918301918301611520565b50979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611630576116306115d0565b5060010190565b67ffffffffffffffff861681526000602060a08184015286518060a085015260005b818110156116755788810183015185820160c001528201611659565b50600060c0828601015260c07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f830116850101925050506116be604083018661ffff169052565b63ffffffff939093166060820152608001529392505050565b6000602082840312156116e957600080fd5b5051919050565b8082028115828204841417610e4457610e446115d0565b80820180821115610e4457610e446115d0565b81810381811115610e4457610e446115d0565b600082611763577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500690565b600181815b808511156117c157817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156117a7576117a76115d0565b808516156117b457918102915b93841c939080029061176d565b509250929050565b6000826117d857506001610e44565b816117e557506000610e44565b81600181146117fb576002811461180557611821565b6001915050610e44565b60ff841115611816576118166115d0565b50506001821b610e44565b5060208310610133831016604e8410600b8410161715611844575081810a610e44565b61184e8383611768565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115611880576118806115d0565b029392505050565b6000610f9283836117c956fea164736f6c6343000813000a",
+ Bin: "0x60a06040523480156200001157600080fd5b5060405162001a4838038062001a48833981016040819052620000349162000180565b6001600160a01b0381166080523380600081620000985760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000cb57620000cb81620000d5565b50505050620001b2565b336001600160a01b038216036200012f5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200008f565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000602082840312156200019357600080fd5b81516001600160a01b0381168114620001ab57600080fd5b9392505050565b608051611873620001d5600039600081816101c601526109f301526118736000f3fe608060405234801561001057600080fd5b50600436106100c95760003560e01c80636d9809a011610081578063b1e217491161005b578063b1e2174914610182578063f2fde38b1461018b578063f7b4c06f1461019e57600080fd5b80636d9809a01461014857806379ba5097146101525780638da5cb5b1461015a57600080fd5b806342748b2a116100b257806342748b2a146100ff5780634b0795a81461012c5780635fa353e71461013557600080fd5b80630ca76175146100ce5780633944ea3a146100e3575b600080fd5b6100e16100dc3660046112bf565b6101ae565b005b6100ec60035481565b6040519081526020015b60405180910390f35b60055461011790640100000000900463ffffffff1681565b60405163ffffffff90911681526020016100f6565b6100ec60045481565b6100e1610143366004611392565b610258565b6101176201117081565b6100e161036a565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100f6565b6100ec60025481565b6100e1610199366004611476565b61046c565b6005546101179063ffffffff1681565b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161461021d576040517fc6829f8300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610228838383610480565b60405183907f85e1543bf2f84fe80c6badbce3648c8539ad1df4d2b3d822938ca0538be727e690600090a2505050565b61026061054e565b6102a16040805160e0810190915280600081526020016000815260200160008152602001606081526020016060815260200160608152602001606081525090565b6102e389898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525085939250506105d19050565b851561032b5761032b87878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525085939250506105e29050565b83156103455761034561033e85876114ac565b829061062c565b61035c6103518261066f565b8462011170856109ee565b600255505050505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146103f0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b61047461054e565b61047d81610acd565b50565b82600254146104be576040517fd068bf5b000000000000000000000000000000000000000000000000000000008152600481018490526024016103e7565b6104c782610bc2565b6003558151600580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff90921691909117905561050981610bc2565b600455516005805463ffffffff909216640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff9092169190911790555050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146105cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016103e7565b565b6105de8260008084610c44565b5050565b805160000361061d576040517fe889636f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60016020830152608090910152565b8051600003610667576040517ffe936cb700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60a090910152565b6060600061067e610100610cdb565b90506106c86040518060400160405280600c81526020017f636f64654c6f636174696f6e000000000000000000000000000000000000000081525082610cfc90919063ffffffff16565b82516106e69060028111156106df576106df611544565b8290610d1a565b60408051808201909152600881527f6c616e67756167650000000000000000000000000000000000000000000000006020820152610725908290610cfc565b604083015161073c9080156106df576106df611544565b60408051808201909152600681527f736f757263650000000000000000000000000000000000000000000000000000602082015261077b908290610cfc565b606083015161078b908290610cfc565b60a083015151156108385760408051808201909152600481527f617267730000000000000000000000000000000000000000000000000000000060208201526107d5908290610cfc565b6107de81610d53565b60005b8360a001515181101561082e5761081e8460a00151828151811061080757610807611573565b602002602001015183610cfc90919063ffffffff16565b610827816115d1565b90506107e1565b5061083881610d77565b608083015151156109395760008360200151600281111561085b5761085b611544565b03610892576040517fa80d31f700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051808201909152600f81527f736563726574734c6f636174696f6e000000000000000000000000000000000060208201526108d1908290610cfc565b6108ea836020015160028111156106df576106df611544565b60408051808201909152600781527f73656372657473000000000000000000000000000000000000000000000000006020820152610929908290610cfc565b6080830151610939908290610d95565b60c083015151156109e65760408051808201909152600981527f62797465734172677300000000000000000000000000000000000000000000006020820152610983908290610cfc565b61098c81610d53565b60005b8360c00151518110156109dc576109cc8460c0015182815181106109b5576109b5611573565b602002602001015183610d9590919063ffffffff16565b6109d5816115d1565b905061098f565b506109e681610d77565b515192915050565b6000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663461d27628688600188886040518663ffffffff1660e01b8152600401610a53959493929190611609565b6020604051808303816000875af1158015610a72573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a9691906116a9565b60405190915081907f1131472297a800fee664d1d89cfa8f7676ff07189ecc53f80bbb5f4969099db890600090a295945050505050565b3373ffffffffffffffffffffffffffffffffffffffff821603610b4c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016103e7565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008060209050602083511015610bd7575081515b60005b81811015610c3d57610bed8160086116c2565b848281518110610bff57610bff611573565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016901c9290921791610c36816115d1565b9050610bda565b5050919050565b8051600003610c7f576040517f22ce3edd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83836002811115610c9257610c92611544565b90816002811115610ca557610ca5611544565b90525060408401828015610cbb57610cbb611544565b90818015610ccb57610ccb611544565b9052506060909301929092525050565b610ce3611176565b8051610cef9083610da2565b5060006020820152919050565b610d098260038351610e1c565b8151610d159082610f43565b505050565b8151610d279060c2610f6b565b506105de8282604051602001610d3f91815260200190565b604051602081830303815290604052610d95565b610d5e816004610fd4565b600181602001818151610d7191906116d9565b90525050565b610d82816007610fd4565b600181602001818151610d7191906116ec565b610d098260028351610e1c565b604080518082019091526060815260006020820152610dc26020836116ff565b15610dea57610dd26020836116ff565b610ddd9060206116ec565b610de790836116d9565b91505b602080840183905260405180855260008152908184010181811015610e0e57600080fd5b604052508290505b92915050565b60178167ffffffffffffffff1611610e49578251610e439060e0600585901b168317610f6b565b50505050565b60ff8167ffffffffffffffff1611610e8b578251610e72906018611fe0600586901b1617610f6b565b508251610e439067ffffffffffffffff83166001610feb565b61ffff8167ffffffffffffffff1611610ece578251610eb5906019611fe0600586901b1617610f6b565b508251610e439067ffffffffffffffff83166002610feb565b63ffffffff8167ffffffffffffffff1611610f13578251610efa90601a611fe0600586901b1617610f6b565b508251610e439067ffffffffffffffff83166004610feb565b8251610f2a90601b611fe0600586901b1617610f6b565b508251610e439067ffffffffffffffff83166008610feb565b604080518082019091526060815260006020820152610f6483838451611070565b9392505050565b6040805180820190915260608152600060208201528251516000610f908260016116d9565b905084602001518210610fb157610fb185610fac8360026116c2565b61115f565b8451602083820101858153508051821115610fca578181525b5093949350505050565b8151610d1590601f611fe0600585901b1617610f6b565b604080518082019091526060815260006020820152835151600061100f82856116d9565b9050856020015181111561102c5761102c86610fac8360026116c2565b6000600161103c8661010061185a565b61104691906116ec565b90508651828101878319825116178152508051831115611064578281525b50959695505050505050565b604080518082019091526060815260006020820152825182111561109357600080fd5b83515160006110a284836116d9565b905085602001518111156110bf576110bf86610fac8360026116c2565b8551805183820160200191600091808511156110d9578482525b505050602086015b6020861061111957805182526110f86020836116d9565b91506111056020826116d9565b90506111126020876116ec565b95506110e1565b5181517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60208890036101000a0190811690199190911617905250849150509392505050565b815161116b8383610da2565b50610e438382610f43565b604051806040016040528061119e604051806040016040528060608152602001600081525090565b8152602001600081525090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611221576112216111ab565b604052919050565b600067ffffffffffffffff831115611243576112436111ab565b61127460207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116016111da565b905082815283838301111561128857600080fd5b828260208301376000602084830101529392505050565b600082601f8301126112b057600080fd5b610f6483833560208501611229565b6000806000606084860312156112d457600080fd5b83359250602084013567ffffffffffffffff808211156112f357600080fd5b6112ff8783880161129f565b9350604086013591508082111561131557600080fd5b506113228682870161129f565b9150509250925092565b60008083601f84011261133e57600080fd5b50813567ffffffffffffffff81111561135657600080fd5b60208301915083602082850101111561136e57600080fd5b9250929050565b803567ffffffffffffffff8116811461138d57600080fd5b919050565b60008060008060008060008060a0898b0312156113ae57600080fd5b883567ffffffffffffffff808211156113c657600080fd5b6113d28c838d0161132c565b909a50985060208b01359150808211156113eb57600080fd5b6113f78c838d0161132c565b909850965060408b013591508082111561141057600080fd5b818b0191508b601f83011261142457600080fd5b81358181111561143357600080fd5b8c60208260051b850101111561144857600080fd5b60208301965080955050505061146060608a01611375565b9150608089013590509295985092959890939650565b60006020828403121561148857600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610f6457600080fd5b600067ffffffffffffffff808411156114c7576114c76111ab565b8360051b60206114d88183016111da565b8681529185019181810190368411156114f057600080fd5b865b848110156115385780358681111561150a5760008081fd5b880136601f82011261151c5760008081fd5b61152a368235878401611229565b8452509183019183016114f2565b50979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611602576116026115a2565b5060010190565b67ffffffffffffffff861681526000602060a08184015286518060a085015260005b818110156116475788810183015185820160c00152820161162b565b50600060c0828601015260c07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010192505050611690604083018661ffff169052565b63ffffffff939093166060820152608001529392505050565b6000602082840312156116bb57600080fd5b5051919050565b8082028115828204841417610e1657610e166115a2565b80820180821115610e1657610e166115a2565b81810381811115610e1657610e166115a2565b600082611735577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500690565b600181815b8085111561179357817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115611779576117796115a2565b8085161561178657918102915b93841c939080029061173f565b509250929050565b6000826117aa57506001610e16565b816117b757506000610e16565b81600181146117cd57600281146117d7576117f3565b6001915050610e16565b60ff8411156117e8576117e86115a2565b50506001821b610e16565b5060208310610133831016604e8410600b8410161715611816575081810a610e16565b611820838361173a565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115611852576118526115a2565b029392505050565b6000610f64838361179b56fea164736f6c6343000813000a",
}
var FunctionsClientExampleABI = FunctionsClientExampleMetaData.ABI
diff --git a/core/gethwrappers/functions/generated/functions_coordinator/functions_coordinator.go b/core/gethwrappers/functions/generated/functions_coordinator/functions_coordinator.go
index 3de584ddb22..94f1efd2d6a 100644
--- a/core/gethwrappers/functions/generated/functions_coordinator/functions_coordinator.go
+++ b/core/gethwrappers/functions/generated/functions_coordinator/functions_coordinator.go
@@ -31,14 +31,13 @@ var (
)
type FunctionsBillingConfig struct {
- MaxCallbackGasLimit uint32
+ FulfillmentGasPriceOverEstimationBP uint32
FeedStalenessSeconds uint32
GasOverheadBeforeCallback uint32
GasOverheadAfterCallback uint32
RequestTimeoutSeconds uint32
DonFee *big.Int
MaxSupportedRequestDataVersion uint16
- FulfillmentGasPriceOverEstimationBP uint32
FallbackNativePerUnitLink *big.Int
}
@@ -71,8 +70,8 @@ type FunctionsResponseRequestMeta struct {
}
var FunctionsCoordinatorMetaData = &bind.MetaData{
- ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxCallbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"feedStalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"requestTimeoutSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint72\",\"name\":\"donFee\",\"type\":\"uint72\"},{\"internalType\":\"uint16\",\"name\":\"maxSupportedRequestDataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentGasPriceOverEstimationBP\",\"type\":\"uint32\"},{\"internalType\":\"uint224\",\"name\":\"fallbackNativePerUnitLink\",\"type\":\"uint224\"}],\"internalType\":\"structFunctionsBilling.Config\",\"name\":\"config\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"linkToNativeFeed\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"EmptyPublicKey\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InconsistentReportData\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidCalldata\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"linkWei\",\"type\":\"int256\"}],\"name\":\"InvalidLinkWeiPrice\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSubscription\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"MustBeSubOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoTransmittersSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByRouterOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PaymentTooLarge\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReportInvalid\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RouterMustBeSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedPublicKeyChange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedSender\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnsupportedRequestDataVersion\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"}],\"name\":\"CommitmentDeleted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxCallbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"feedStalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"requestTimeoutSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint72\",\"name\":\"donFee\",\"type\":\"uint72\"},{\"internalType\":\"uint16\",\"name\":\"maxSupportedRequestDataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentGasPriceOverEstimationBP\",\"type\":\"uint32\"},{\"internalType\":\"uint224\",\"name\":\"fallbackNativePerUnitLink\",\"type\":\"uint224\"}],\"indexed\":false,\"internalType\":\"structFunctionsBilling.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"requestingContract\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"requestInitiator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"subscriptionOwner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"dataVersion\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"flags\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"callbackGasLimit\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"estimatedTotalCostJuels\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"client\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint72\",\"name\":\"adminFee\",\"type\":\"uint72\"},{\"internalType\":\"uint72\",\"name\":\"donFee\",\"type\":\"uint72\"},{\"internalType\":\"uint40\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint40\"},{\"internalType\":\"uint32\",\"name\":\"timeoutTimestamp\",\"type\":\"uint32\"}],\"indexed\":false,\"internalType\":\"structFunctionsResponse.Commitment\",\"name\":\"commitment\",\"type\":\"tuple\"}],\"name\":\"OracleRequest\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"}],\"name\":\"OracleResponse\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"}],\"name\":\"deleteCommitment\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"node\",\"type\":\"address\"}],\"name\":\"deleteNodePublicKey\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"gasPriceGwei\",\"type\":\"uint256\"}],\"name\":\"estimateCost\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAdminFee\",\"outputs\":[{\"internalType\":\"uint72\",\"name\":\"\",\"type\":\"uint72\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllNodePublicKeys\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"},{\"internalType\":\"bytes[]\",\"name\":\"\",\"type\":\"bytes[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxCallbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"feedStalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"requestTimeoutSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint72\",\"name\":\"donFee\",\"type\":\"uint72\"},{\"internalType\":\"uint16\",\"name\":\"maxSupportedRequestDataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentGasPriceOverEstimationBP\",\"type\":\"uint32\"},{\"internalType\":\"uint224\",\"name\":\"fallbackNativePerUnitLink\",\"type\":\"uint224\"}],\"internalType\":\"structFunctionsBilling.Config\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"getDONFee\",\"outputs\":[{\"internalType\":\"uint72\",\"name\":\"\",\"type\":\"uint72\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDONPublicKey\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getThresholdPublicKey\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getWeiPerUnitLink\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"oracleWithdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"oracleWithdrawAll\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"_transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"_f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"_onchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"_offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"_offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"donPublicKey\",\"type\":\"bytes\"}],\"name\":\"setDONPublicKey\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"node\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"publicKey\",\"type\":\"bytes\"}],\"name\":\"setNodePublicKey\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"thresholdPublicKey\",\"type\":\"bytes\"}],\"name\":\"setThresholdPublicKey\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bytes32\",\"name\":\"flags\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"requestingContract\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"availableBalance\",\"type\":\"uint96\"},{\"internalType\":\"uint72\",\"name\":\"adminFee\",\"type\":\"uint72\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"initiatedRequests\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"dataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint64\",\"name\":\"completedRequests\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"subscriptionOwner\",\"type\":\"address\"}],\"internalType\":\"structFunctionsResponse.RequestMeta\",\"name\":\"request\",\"type\":\"tuple\"}],\"name\":\"startRequest\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"estimatedTotalCostJuels\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"client\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint72\",\"name\":\"adminFee\",\"type\":\"uint72\"},{\"internalType\":\"uint72\",\"name\":\"donFee\",\"type\":\"uint72\"},{\"internalType\":\"uint40\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint40\"},{\"internalType\":\"uint32\",\"name\":\"timeoutTimestamp\",\"type\":\"uint32\"}],\"internalType\":\"structFunctionsResponse.Commitment\",\"name\":\"commitment\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"transmitters\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxCallbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"feedStalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"requestTimeoutSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint72\",\"name\":\"donFee\",\"type\":\"uint72\"},{\"internalType\":\"uint16\",\"name\":\"maxSupportedRequestDataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentGasPriceOverEstimationBP\",\"type\":\"uint32\"},{\"internalType\":\"uint224\",\"name\":\"fallbackNativePerUnitLink\",\"type\":\"uint224\"}],\"internalType\":\"structFunctionsBilling.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"updateConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]",
- Bin: "0x60c06040523480156200001157600080fd5b50604051620056fb380380620056fb83398101604081905262000034916200044f565b8282828260013380600081620000915760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c457620000c48162000140565b50505015156080526001600160a01b038116620000f457604051632530e88560e11b815260040160405180910390fd5b6001600160a01b0390811660a052600b80549183166c01000000000000000000000000026001600160601b039092169190911790556200013482620001eb565b50505050505062000600565b336001600160a01b038216036200019a5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000088565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b620001f56200033a565b80516008805460208401516040808601516060870151608088015160a089015160c08a015163ffffffff998a166001600160401b031990981697909717640100000000968a16870217600160401b600160801b03191668010000000000000000948a169490940263ffffffff60601b1916939093176c010000000000000000000000009289169290920291909117600160801b600160e81b031916600160801b91881691909102600160a01b600160e81b03191617600160a01b6001600160481b03909216919091021761ffff60e81b1916600160e81b61ffff909416939093029290921790925560e084015161010085015193166001600160e01b0390931690910291909117600955517f5b6e2e1a03ea742ce04ca36d0175411a0772f99ef4ee84aeb9868a1ef6ddc82c906200032f90839062000558565b60405180910390a150565b6200034462000346565b565b6000546001600160a01b03163314620003445760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640162000088565b80516001600160a01b0381168114620003ba57600080fd5b919050565b60405161012081016001600160401b0381118282101715620003f157634e487b7160e01b600052604160045260246000fd5b60405290565b805163ffffffff81168114620003ba57600080fd5b80516001600160481b0381168114620003ba57600080fd5b805161ffff81168114620003ba57600080fd5b80516001600160e01b0381168114620003ba57600080fd5b60008060008385036101608112156200046757600080fd5b6200047285620003a2565b935061012080601f19830112156200048957600080fd5b62000493620003bf565b9150620004a360208701620003f7565b8252620004b360408701620003f7565b6020830152620004c660608701620003f7565b6040830152620004d960808701620003f7565b6060830152620004ec60a08701620003f7565b6080830152620004ff60c087016200040c565b60a08301526200051260e0870162000424565b60c083015261010062000527818801620003f7565b60e08401526200053982880162000437565b908301525091506200054f6101408501620003a2565b90509250925092565b815163ffffffff9081168252602080840151821690830152604080840151821690830152606080840151821690830152608080840151918216908301526101208201905060a0830151620005b760a08401826001600160481b03169052565b5060c0830151620005ce60c084018261ffff169052565b5060e0830151620005e760e084018263ffffffff169052565b50610100928301516001600160e01b0316919092015290565b60805160a0516150ab620006506000396000818161090901528181610cbe01528181610eec015281816112360152818161136d01528181611b5701526136a40152600061159501526150ab6000f3fe608060405234801561001057600080fd5b50600436106101ae5760003560e01c806381f1b938116100ee578063b1dc65a411610097578063d328a91e11610071578063d328a91e146105a3578063e3d0e712146105ab578063e4ddcea6146105be578063f2fde38b146105d457600080fd5b8063b1dc65a41461040e578063c3f909d414610421578063d227d2451461057357600080fd5b80638da5cb5b116100c85780638da5cb5b146103a6578063a631571e146103ce578063afcb95d7146103ee57600080fd5b806381f1b9381461030e57806381ff70481461031657806385b214cf1461038357600080fd5b806359b5b7ac1161015b5780637d480787116101355780637d480787146102cb5780637f15e166146102d357806380756031146102e657806381411834146102f957600080fd5b806359b5b7ac1461027857806366316d8d146102b057806379ba5097146102c357600080fd5b806326ceabac1161018c57806326ceabac1461022d5780632a905ccc14610240578063533989871461026257600080fd5b8063083a5466146101b3578063181f5a77146101c85780631bdf7f1b1461021a575b600080fd5b6101c66101c13660046139e6565b6105e7565b005b6102046040518060400160405280601c81526020017f46756e6374696f6e7320436f6f7264696e61746f722076312e302e300000000081525081565b6040516102119190613a8c565b60405180910390f35b6101c6610228366004613bef565b61063c565b6101c661023b366004613cd2565b61085f565b610248610905565b60405168ffffffffffffffffff9091168152602001610211565b61026a61099b565b604051610211929190613d40565b610248610286366004613e5e565b5060085474010000000000000000000000000000000000000000900468ffffffffffffffffff1690565b6101c66102be366004613ec0565b610bc2565b6101c6610d7b565b6101c6610e7d565b6101c66102e13660046139e6565b610fd5565b6101c66102f4366004613ef9565b611025565b6103016110dc565b6040516102119190613f4e565b61020461114b565b61036060015460025463ffffffff74010000000000000000000000000000000000000000830481169378010000000000000000000000000000000000000000000000009093041691565b6040805163ffffffff948516815293909216602084015290820152606001610211565b610396610391366004613f61565b61121c565b6040519015158152602001610211565b60005460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610211565b6103e16103dc366004613f7a565b6112fc565b60405161021191906140d9565b604080516001815260006020820181905291810191909152606001610211565b6101c661041c36600461412d565b61149c565b6105666040805161012081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081019190915250604080516101208101825260085463ffffffff8082168352640100000000808304821660208501526801000000000000000083048216948401949094526c0100000000000000000000000082048116606084015270010000000000000000000000000000000082048116608084015274010000000000000000000000000000000000000000820468ffffffffffffffffff1660a08401527d01000000000000000000000000000000000000000000000000000000000090910461ffff1660c083015260095490811660e0830152919091047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1661010082015290565b60405161021191906141e4565b6105866105813660046142c7565b611b53565b6040516bffffffffffffffffffffffff9091168152602001610211565b610204611cb2565b6101c66105b93660046143e0565b611d09565b6105c6612735565b604051908152602001610211565b6101c66105e2366004613cd2565b612966565b6105ef612977565b600081900361062a576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600e610637828483614546565b505050565b6106446129fa565b80516008805460208401516040808601516060870151608088015160a089015160c08a015163ffffffff998a167fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000090981697909717640100000000968a168702177fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff1668010000000000000000948a16949094027fffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffff16939093176c0100000000000000000000000092891692909202919091177fffffff00000000000000000000000000ffffffffffffffffffffffffffffffff16700100000000000000000000000000000000918816919091027fffffff000000000000000000ffffffffffffffffffffffffffffffffffffffff16177401000000000000000000000000000000000000000068ffffffffffffffffff90921691909102177fff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167d01000000000000000000000000000000000000000000000000000000000061ffff909416939093029290921790925560e084015161010085015193167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff90931690910291909117600955517f5b6e2e1a03ea742ce04ca36d0175411a0772f99ef4ee84aeb9868a1ef6ddc82c906108549083906141e4565b60405180910390a150565b60005473ffffffffffffffffffffffffffffffffffffffff16331480159061089d57503373ffffffffffffffffffffffffffffffffffffffff821614155b156108d4576040517fed6dd19b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81166000908152600d602052604081206109029161392f565b50565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16632a905ccc6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610972573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610996919061466c565b905090565b60608060006006805480602002602001604051908101604052809291908181526020018280548015610a0357602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff1681526001909101906020018083116109d8575b505050505090506000815167ffffffffffffffff811115610a2657610a26613aa6565b604051908082528060200260200182016040528015610a5957816020015b6060815260200190600190039081610a445790505b50905060005b8251811015610bb8576000600d6000858481518110610a8057610a80614689565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054610acd906144ad565b80601f0160208091040260200160405190810160405280929190818152602001828054610af9906144ad565b8015610b465780601f10610b1b57610100808354040283529160200191610b46565b820191906000526020600020905b815481529060010190602001808311610b2957829003601f168201915b505050505090508051600003610b88576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80838381518110610b9b57610b9b614689565b60200260200101819052505080610bb1906146e7565b9050610a5f565b5090939092509050565b610bca612a02565b806bffffffffffffffffffffffff16600003610c045750336000908152600a60205260409020546bffffffffffffffffffffffff16610c5e565b336000908152600a60205260409020546bffffffffffffffffffffffff80831691161015610c5e576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152600a602052604081208054839290610c8b9084906bffffffffffffffffffffffff1661471f565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550610ce07f000000000000000000000000000000000000000000000000000000000000000090565b6040517f66316d8d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84811660048301526bffffffffffffffffffffffff8416602483015291909116906366316d8d90604401600060405180830381600087803b158015610d5f57600080fd5b505af1158015610d73573d6000803e3d6000fd5b505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610e01576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610e856129fa565b610e8d612a02565b6000610e976110dc565b905060005b8151811015610fd157336000908152600a6020526040902080547fffffffffffffffffffffffffffffffffffffffff00000000000000000000000081169091556bffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166366316d8d848481518110610f3857610f38614689565b6020026020010151836040518363ffffffff1660e01b8152600401610f8d92919073ffffffffffffffffffffffffffffffffffffffff9290921682526bffffffffffffffffffffffff16602082015260400190565b600060405180830381600087803b158015610fa757600080fd5b505af1158015610fbb573d6000803e3d6000fd5b505050505080610fca906146e7565b9050610e9c565b5050565b610fdd612977565b6000819003611018576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600c610637828483614546565b60005473ffffffffffffffffffffffffffffffffffffffff16331480611070575061104f33612bad565b801561107057503373ffffffffffffffffffffffffffffffffffffffff8416145b6110a6576040517fed6dd19b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff83166000908152600d602052604090206110d6828483614546565b50505050565b6060600680548060200260200160405190810160405280929190818152602001828054801561114157602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311611116575b5050505050905090565b6060600e805461115a906144ad565b9050600003611195576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600e80546111a2906144ad565b80601f01602080910402602001604051908101604052809291908181526020018280546111ce906144ad565b80156111415780601f106111f057610100808354040283529160200191611141565b820191906000526020600020905b8154815290600101906020018083116111fe57509395945050505050565b60003373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161461128d576040517fc41a5b0900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828152600760205260409020546112a857506000919050565b60008281526007602052604080822091909155517f8a4b97add3359bd6bcf5e82874363670eb5ad0f7615abddbd0ed0a3a98f0f416906112eb9084815260200190565b60405180910390a15060015b919050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101919091523373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146113c4576040517fc41a5b0900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113d56113d083614744565b612c96565b90506113e76060830160408401613cd2565b815173ffffffffffffffffffffffffffffffffffffffff91909116907fbf50768ccf13bd0110ca6d53a9c4f1f3271abdd4c24a56878863ed25b20598ff3261143560c0870160a08801614831565b61144761016088016101408901613cd2565b611451888061484e565b6114636101208b016101008c016148b3565b60208b01356114796101008d0160e08e016148ce565b8b60405161148f999897969594939291906148eb565b60405180910390a3919050565b60005a604080518b3580825262ffffff6020808f0135600881901c929092169084015293945092917fb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62910160405180910390a16040805160608101825260025480825260035460ff80821660208501526101009091041692820192909252908314611583576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f636f6e666967446967657374206d69736d6174636800000000000000000000006044820152606401610df8565b6115918b8b8b8b8b8b6130a6565b60007f0000000000000000000000000000000000000000000000000000000000000000156115ee576002826020015183604001516115cf9190614993565b6115d991906149db565b6115e4906001614993565b60ff169050611604565b60208201516115fe906001614993565b60ff1690505b88811461166d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f77726f6e67206e756d626572206f66207369676e6174757265730000000000006044820152606401610df8565b8887146116d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f7369676e617475726573206f7574206f6620726567697374726174696f6e00006044820152606401610df8565b3360009081526004602090815260408083208151808301909252805460ff80821684529293919291840191610100909104166002811115611719576117196149fd565b600281111561172a5761172a6149fd565b9052509050600281602001516002811115611747576117476149fd565b14801561178e57506006816000015160ff168154811061176957611769614689565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1633145b6117f4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f756e617574686f72697a6564207472616e736d697474657200000000000000006044820152606401610df8565b5050505050611801613969565b6000808a8a604051611814929190614a2c565b60405190819003812061182b918e90602001614a3c565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120838301909252600080845290830152915060005b89811015611b3557600060018489846020811061189457611894614689565b6118a191901a601b614993565b8e8e868181106118b3576118b3614689565b905060200201358d8d878181106118cc576118cc614689565b9050602002013560405160008152602001604052604051611909949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa15801561192b573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff811660009081526004602090815290849020838501909452835460ff808216855292965092945084019161010090041660028111156119ab576119ab6149fd565b60028111156119bc576119bc6149fd565b90525092506001836020015160028111156119d9576119d96149fd565b14611a40576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f61646472657373206e6f7420617574686f72697a656420746f207369676e00006044820152606401610df8565b8251600090879060ff16601f8110611a5a57611a5a614689565b602002015173ffffffffffffffffffffffffffffffffffffffff1614611adc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f6e6f6e2d756e69717565207369676e61747572650000000000000000000000006044820152606401610df8565b8086846000015160ff16601f8110611af657611af6614689565b73ffffffffffffffffffffffffffffffffffffffff9092166020929092020152611b21600186614993565b94505080611b2e906146e7565b9050611875565b505050611b46833383858e8e61315d565b5050505050505050505050565b60007f00000000000000000000000000000000000000000000000000000000000000006040517f10fc49c100000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8816600482015263ffffffff8516602482015273ffffffffffffffffffffffffffffffffffffffff91909116906310fc49c19060440160006040518083038186803b158015611bf357600080fd5b505afa158015611c07573d6000803e3d6000fd5b505050620f42408311159050611c49576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611c53610905565b90506000611c9687878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061028692505050565b9050611ca48585838561332b565b925050505b95945050505050565b6060600c8054611cc1906144ad565b9050600003611cfc576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600c80546111a2906144ad565b855185518560ff16601f831115611d7c576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f746f6f206d616e79207369676e657273000000000000000000000000000000006044820152606401610df8565b80600003611de6576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f66206d75737420626520706f73697469766500000000000000000000000000006044820152606401610df8565b818314611e74576040517f89a61989000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f6f7261636c6520616464726573736573206f7574206f6620726567697374726160448201527f74696f6e000000000000000000000000000000000000000000000000000000006064820152608401610df8565b611e7f816003614a50565b8311611ee7576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f6661756c74792d6f7261636c65206620746f6f206869676800000000000000006044820152606401610df8565b611eef612977565b6040805160c0810182528a8152602081018a905260ff89169181018290526060810188905267ffffffffffffffff8716608082015260a0810186905290611f369088613415565b600554156120eb57600554600090611f5090600190614a67565b9050600060058281548110611f6757611f67614689565b60009182526020822001546006805473ffffffffffffffffffffffffffffffffffffffff90921693509084908110611fa157611fa1614689565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff85811684526004909252604080842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00009081169091559290911680845292208054909116905560058054919250908061202157612021614a7a565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055019055600680548061208a5761208a614a7a565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905501905550611f36915050565b60005b815151811015612552576000600460008460000151848151811061211457612114614689565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160002054610100900460ff16600281111561215e5761215e6149fd565b146121c5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f7265706561746564207369676e657220616464726573730000000000000000006044820152606401610df8565b6040805180820190915260ff821681526001602082015282518051600491600091859081106121f6576121f6614689565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040016000208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001617610100836002811115612297576122976149fd565b0217905550600091506122a79050565b60046000846020015184815181106122c1576122c1614689565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160002054610100900460ff16600281111561230b5761230b6149fd565b14612372576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f7265706561746564207472616e736d69747465722061646472657373000000006044820152606401610df8565b6040805180820190915260ff8216815260208101600281525060046000846020015184815181106123a5576123a5614689565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040016000208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001617610100836002811115612446576124466149fd565b02179055505082518051600592508390811061246457612464614689565b602090810291909101810151825460018101845560009384529282902090920180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff90931692909217909155820151805160069190839081106124e0576124e0614689565b60209081029190910181015182546001810184556000938452919092200180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9092169190911790558061254a816146e7565b9150506120ee565b506040810151600380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff909216919091179055600180547fffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffff8116780100000000000000000000000000000000000000000000000063ffffffff438116820292909217808555920481169291829160149161260a91849174010000000000000000000000000000000000000000900416614aa9565b92506101000a81548163ffffffff021916908363ffffffff1602179055506126694630600160149054906101000a900463ffffffff1663ffffffff16856000015186602001518760400151886060015189608001518a60a0015161342e565b600281905582518051600380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1661010060ff9093169290920291909117905560015460208501516040808701516060880151608089015160a08a015193517f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0598612720988b9891977401000000000000000000000000000000000000000090920463ffffffff16969095919491939192614ac6565b60405180910390a15050505050505050505050565b604080516101208101825260085463ffffffff8082168352640100000000808304821660208501526801000000000000000083048216848601526c010000000000000000000000008084048316606086015270010000000000000000000000000000000084048316608086015274010000000000000000000000000000000000000000840468ffffffffffffffffff1660a0808701919091527d01000000000000000000000000000000000000000000000000000000000090940461ffff1660c086015260095492831660e086015291047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16610100840152600b5484517ffeaf968c00000000000000000000000000000000000000000000000000000000815294516000958694859490930473ffffffffffffffffffffffffffffffffffffffff169263feaf968c926004808401938290030181865afa15801561289a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128be9190614b76565b5093505092505080426128d19190614a67565b836020015163ffffffff161080156128f357506000836020015163ffffffff16115b1561292257505061010001517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16919050565b6000821361295f576040517f43d4cf6600000000000000000000000000000000000000000000000000000000815260048101839052602401610df8565b5092915050565b61296e612977565b610902816134d9565b60005473ffffffffffffffffffffffffffffffffffffffff1633146129f8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610df8565b565b6129f8612977565b600b546bffffffffffffffffffffffff16600003612a1c57565b6000612a266110dc565b90508051600003612a63576040517f30274b3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600b54600091612a82916bffffffffffffffffffffffff16614bc6565b905060005b8251811015612b4e5781600a6000858481518110612aa757612aa7614689565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282829054906101000a90046bffffffffffffffffffffffff16612b0f9190614bf1565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555080612b47906146e7565b9050612a87565b508151612b5b9082614c16565b600b8054600090612b7b9084906bffffffffffffffffffffffff1661471f565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055505050565b6000806006805480602002602001604051908101604052809291908181526020018280548015612c1357602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311612be8575b5050505050905060005b8151811015612c8c578373ffffffffffffffffffffffffffffffffffffffff16828281518110612c4f57612c4f614689565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603612c7c575060019392505050565b612c85816146e7565b9050612c1d565b5060009392505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810191909152604080516101208101825260085463ffffffff8082168352640100000000808304821660208501526801000000000000000083048216948401949094526c0100000000000000000000000082048116606084015270010000000000000000000000000000000082048116608084015274010000000000000000000000000000000000000000820468ffffffffffffffffff1660a08401527d01000000000000000000000000000000000000000000000000000000000090910461ffff90811660c0840181905260095492831660e0850152939091047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1661010080840191909152850151919291161115612e2b576040517fdada758700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60085460009074010000000000000000000000000000000000000000900468ffffffffffffffffff1690506000612e6c8560e001513a84886080015161332b565b9050806bffffffffffffffffffffffff1685606001516bffffffffffffffffffffffff161015612ec8576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612f4b3087604001518860a001518960c001516001612ee99190614c3e565b6040805173ffffffffffffffffffffffffffffffffffffffff958616602080830191909152949095168582015267ffffffffffffffff928316606086015291166080808501919091528151808503909101815260a09093019052815191012090565b90506040518061016001604052808281526020013073ffffffffffffffffffffffffffffffffffffffff168152602001836bffffffffffffffffffffffff168152602001876040015173ffffffffffffffffffffffffffffffffffffffff1681526020018760a0015167ffffffffffffffff1681526020018760e0015163ffffffff168152602001876080015168ffffffffffffffffff1681526020018468ffffffffffffffffff168152602001856040015163ffffffff1664ffffffffff168152602001856060015163ffffffff1664ffffffffff168152602001856080015163ffffffff164261303d9190614c5f565b63ffffffff1681525094508460405160200161305991906140d9565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181528151602092830120600093845260079092529091205550919392505050565b60006130b3826020614a50565b6130be856020614a50565b6130ca88610144614c5f565b6130d49190614c5f565b6130de9190614c5f565b6130e9906000614c5f565b9050368114613154576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f63616c6c64617461206c656e677468206d69736d6174636800000000000000006044820152606401610df8565b50505050505050565b60608080808061316f86880188614d4d565b845194995092975090955093509150158061318c57508351855114155b8061319957508251855114155b806131a657508151855114155b806131b357508051855114155b156131ea576040517f0be3632800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b855181101561331d57600061328287838151811061320d5761320d614689565b602002602001015187848151811061322757613227614689565b602002602001015187858151811061324157613241614689565b602002602001015187868151811061325b5761325b614689565b602002602001015187878151811061327557613275614689565b60200260200101516135ce565b90506000816006811115613298576132986149fd565b14806132b5575060018160068111156132b3576132b36149fd565b145b1561330c578682815181106132cc576132cc614689565b60209081029190910181015160405133815290917fc708e0440951fd63499c0f7a73819b469ee5dd3ecc356c0ab4eb7f18389009d9910160405180910390a25b50613316816146e7565b90506131ed565b505050505050505050505050565b600854600090819086906133639063ffffffff6c01000000000000000000000000820481169168010000000000000000900416614aa9565b61336d9190614aa9565b60095463ffffffff91821692506000916127109161338c911688614a50565b6133969190614e1f565b6133a09087614c5f565b905060006133ad8261385e565b905060006133c9846bffffffffffffffffffffffff8416614a50565b905060006133e568ffffffffffffffffff808916908a16614bf1565b90506134076134026bffffffffffffffffffffffff831684614c5f565b61388d565b9a9950505050505050505050565b600061341f6110dc565b511115610fd157610fd1612a02565b6000808a8a8a8a8a8a8a8a8a60405160200161345299989796959493929190614e33565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b3373ffffffffffffffffffffffffffffffffffffffff821603613558576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610df8565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600080838060200190518101906135e59190614f09565b9050806040516020016135f891906140d9565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152815160209283012060008a815260079093529120541461364a576006915050611ca9565b600087815260076020526040902054613667576002915050611ca9565b60006136723a61385e565b9050600082610120015183610100015161368c9190614fd1565b61369d9064ffffffffff1683614c16565b90506000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663330605298b8b878960e0015168ffffffffffffffffff16886136fc9190614bf1565b338b6040518763ffffffff1660e01b815260040161371f96959493929190614fef565b60408051808303816000875af115801561373d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613761919061506b565b9092509050600082600681111561377a5761377a6149fd565b148061379757506001826006811115613795576137956149fd565b145b156138505760008b8152600760205260408120556137b58184614bf1565b336000908152600a6020526040812080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff93841617905560e0870151600b805468ffffffffffffffffff9092169390929161382191859116614bf1565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055505b509998505050505050505050565b600061388761386b612735565b61387d84670de0b6b3a7640000614a50565b6134029190614e1f565b92915050565b60006bffffffffffffffffffffffff82111561392b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203960448201527f36206269747300000000000000000000000000000000000000000000000000006064820152608401610df8565b5090565b50805461393b906144ad565b6000825580601f1061394b575050565b601f0160209004906000526020600020908101906109029190613988565b604051806103e00160405280601f906020820280368337509192915050565b5b8082111561392b5760008155600101613989565b60008083601f8401126139af57600080fd5b50813567ffffffffffffffff8111156139c757600080fd5b6020830191508360208285010111156139df57600080fd5b9250929050565b600080602083850312156139f957600080fd5b823567ffffffffffffffff811115613a1057600080fd5b613a1c8582860161399d565b90969095509350505050565b6000815180845260005b81811015613a4e57602081850181015186830182015201613a32565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000613a9f6020830184613a28565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610120810167ffffffffffffffff81118282101715613af957613af9613aa6565b60405290565b604051610160810167ffffffffffffffff81118282101715613af957613af9613aa6565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613b6a57613b6a613aa6565b604052919050565b63ffffffff8116811461090257600080fd5b80356112f781613b72565b68ffffffffffffffffff8116811461090257600080fd5b80356112f781613b8f565b803561ffff811681146112f757600080fd5b80357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811681146112f757600080fd5b60006101208284031215613c0257600080fd5b613c0a613ad5565b613c1383613b84565b8152613c2160208401613b84565b6020820152613c3260408401613b84565b6040820152613c4360608401613b84565b6060820152613c5460808401613b84565b6080820152613c6560a08401613ba6565b60a0820152613c7660c08401613bb1565b60c0820152613c8760e08401613b84565b60e0820152610100613c9a818501613bc3565b908201529392505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461090257600080fd5b80356112f781613ca5565b600060208284031215613ce457600080fd5b8135613a9f81613ca5565b600081518084526020808501945080840160005b83811015613d3557815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101613d03565b509495945050505050565b604081526000613d536040830185613cef565b6020838203818501528185518084528284019150828160051b85010183880160005b83811015613dc1577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0878403018552613daf838351613a28565b94860194925090850190600101613d75565b50909998505050505050505050565b600082601f830112613de157600080fd5b813567ffffffffffffffff811115613dfb57613dfb613aa6565b613e2c60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601613b23565b818152846020838601011115613e4157600080fd5b816020850160208301376000918101602001919091529392505050565b600060208284031215613e7057600080fd5b813567ffffffffffffffff811115613e8757600080fd5b613e9384828501613dd0565b949350505050565b6bffffffffffffffffffffffff8116811461090257600080fd5b80356112f781613e9b565b60008060408385031215613ed357600080fd5b8235613ede81613ca5565b91506020830135613eee81613e9b565b809150509250929050565b600080600060408486031215613f0e57600080fd5b8335613f1981613ca5565b9250602084013567ffffffffffffffff811115613f3557600080fd5b613f418682870161399d565b9497909650939450505050565b602081526000613a9f6020830184613cef565b600060208284031215613f7357600080fd5b5035919050565b600060208284031215613f8c57600080fd5b813567ffffffffffffffff811115613fa357600080fd5b82016101608185031215613a9f57600080fd5b805182526020810151613fe1602084018273ffffffffffffffffffffffffffffffffffffffff169052565b50604081015161400160408401826bffffffffffffffffffffffff169052565b506060810151614029606084018273ffffffffffffffffffffffffffffffffffffffff169052565b506080810151614045608084018267ffffffffffffffff169052565b5060a081015161405d60a084018263ffffffff169052565b5060c081015161407a60c084018268ffffffffffffffffff169052565b5060e081015161409760e084018268ffffffffffffffffff169052565b506101008181015164ffffffffff81168483015250506101208181015164ffffffffff81168483015250506101408181015163ffffffff8116848301526110d6565b61016081016138878284613fb6565b60008083601f8401126140fa57600080fd5b50813567ffffffffffffffff81111561411257600080fd5b6020830191508360208260051b85010111156139df57600080fd5b60008060008060008060008060e0898b03121561414957600080fd5b606089018a81111561415a57600080fd5b8998503567ffffffffffffffff8082111561417457600080fd5b6141808c838d0161399d565b909950975060808b013591508082111561419957600080fd5b6141a58c838d016140e8565b909750955060a08b01359150808211156141be57600080fd5b506141cb8b828c016140e8565b999c989b50969995989497949560c00135949350505050565b815163ffffffff9081168252602080840151821690830152604080840151821690830152606080840151821690830152608080840151918216908301526101208201905060a083015161424460a084018268ffffffffffffffffff169052565b5060c083015161425a60c084018261ffff169052565b5060e083015161427260e084018263ffffffff169052565b50610100838101517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8116848301525b505092915050565b67ffffffffffffffff8116811461090257600080fd5b80356112f7816142a6565b6000806000806000608086880312156142df57600080fd5b85356142ea816142a6565b9450602086013567ffffffffffffffff81111561430657600080fd5b6143128882890161399d565b909550935050604086013561432681613b72565b949793965091946060013592915050565b600067ffffffffffffffff82111561435157614351613aa6565b5060051b60200190565b600082601f83011261436c57600080fd5b8135602061438161437c83614337565b613b23565b82815260059290921b840181019181810190868411156143a057600080fd5b8286015b848110156143c45780356143b781613ca5565b83529183019183016143a4565b509695505050505050565b803560ff811681146112f757600080fd5b60008060008060008060c087890312156143f957600080fd5b863567ffffffffffffffff8082111561441157600080fd5b61441d8a838b0161435b565b9750602089013591508082111561443357600080fd5b61443f8a838b0161435b565b965061444d60408a016143cf565b9550606089013591508082111561446357600080fd5b61446f8a838b01613dd0565b945061447d60808a016142bc565b935060a089013591508082111561449357600080fd5b506144a089828a01613dd0565b9150509295509295509295565b600181811c908216806144c157607f821691505b6020821081036144fa577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b601f82111561063757600081815260208120601f850160051c810160208610156145275750805b601f850160051c820191505b81811015610d7357828155600101614533565b67ffffffffffffffff83111561455e5761455e613aa6565b6145728361456c83546144ad565b83614500565b6000601f8411600181146145c4576000851561458e5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b17835561465a565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b8281101561461357868501358255602094850194600190920191016145f3565b508682101561464e577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b80516112f781613b8f565b60006020828403121561467e57600080fd5b8151613a9f81613b8f565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203614718576147186146b8565b5060010190565b6bffffffffffffffffffffffff82811682821603908082111561295f5761295f6146b8565b6000610160823603121561475757600080fd5b61475f613aff565b823567ffffffffffffffff81111561477657600080fd5b61478236828601613dd0565b8252506020830135602082015261479b60408401613cc7565b60408201526147ac60608401613eb5565b60608201526147bd60808401613ba6565b60808201526147ce60a084016142bc565b60a08201526147df60c084016142bc565b60c08201526147f060e08401613b84565b60e0820152610100614803818501613bb1565b908201526101206148158482016142bc565b90820152610140614827848201613cc7565b9082015292915050565b60006020828403121561484357600080fd5b8135613a9f816142a6565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261488357600080fd5b83018035915067ffffffffffffffff82111561489e57600080fd5b6020019150368190038213156139df57600080fd5b6000602082840312156148c557600080fd5b613a9f82613bb1565b6000602082840312156148e057600080fd5b8135613a9f81613b72565b73ffffffffffffffffffffffffffffffffffffffff8a8116825267ffffffffffffffff8a166020830152881660408201526102406060820181905281018690526000610260878982850137600083890182015261ffff8716608084015260a0830186905263ffffffff851660c0840152601f88017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016830101905061340760e0830184613fb6565b60ff8181168382160190811115613887576138876146b8565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600060ff8316806149ee576149ee6149ac565b8060ff84160491505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b8183823760009101908152919050565b828152606082602083013760800192915050565b8082028115828204841417613887576138876146b8565b81810381811115613887576138876146b8565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b63ffffffff81811683821601908082111561295f5761295f6146b8565b600061012063ffffffff808d1684528b6020850152808b16604085015250806060840152614af68184018a613cef565b90508281036080840152614b0a8189613cef565b905060ff871660a084015282810360c0840152614b278187613a28565b905067ffffffffffffffff851660e0840152828103610100840152614b4c8185613a28565b9c9b505050505050505050505050565b805169ffffffffffffffffffff811681146112f757600080fd5b600080600080600060a08688031215614b8e57600080fd5b614b9786614b5c565b9450602086015193506040860151925060608601519150614bba60808701614b5c565b90509295509295909350565b60006bffffffffffffffffffffffff80841680614be557614be56149ac565b92169190910492915050565b6bffffffffffffffffffffffff81811683821601908082111561295f5761295f6146b8565b6bffffffffffffffffffffffff81811683821602808216919082811461429e5761429e6146b8565b67ffffffffffffffff81811683821601908082111561295f5761295f6146b8565b80820180821115613887576138876146b8565b600082601f830112614c8357600080fd5b81356020614c9361437c83614337565b82815260059290921b84018101918181019086841115614cb257600080fd5b8286015b848110156143c45780358352918301918301614cb6565b600082601f830112614cde57600080fd5b81356020614cee61437c83614337565b82815260059290921b84018101918181019086841115614d0d57600080fd5b8286015b848110156143c457803567ffffffffffffffff811115614d315760008081fd5b614d3f8986838b0101613dd0565b845250918301918301614d11565b600080600080600060a08688031215614d6557600080fd5b853567ffffffffffffffff80821115614d7d57600080fd5b614d8989838a01614c72565b96506020880135915080821115614d9f57600080fd5b614dab89838a01614ccd565b95506040880135915080821115614dc157600080fd5b614dcd89838a01614ccd565b94506060880135915080821115614de357600080fd5b614def89838a01614ccd565b93506080880135915080821115614e0557600080fd5b50614e1288828901614ccd565b9150509295509295909350565b600082614e2e57614e2e6149ac565b500490565b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b166040850152816060850152614e7a8285018b613cef565b91508382036080850152614e8e828a613cef565b915060ff881660a085015283820360c0850152614eab8288613a28565b90861660e08501528381036101008501529050614b4c8185613a28565b80516112f781613ca5565b80516112f781613e9b565b80516112f7816142a6565b80516112f781613b72565b805164ffffffffff811681146112f757600080fd5b60006101608284031215614f1c57600080fd5b614f24613aff565b82518152614f3460208401614ec8565b6020820152614f4560408401614ed3565b6040820152614f5660608401614ec8565b6060820152614f6760808401614ede565b6080820152614f7860a08401614ee9565b60a0820152614f8960c08401614661565b60c0820152614f9a60e08401614661565b60e0820152610100614fad818501614ef4565b90820152610120614fbf848201614ef4565b90820152610140613c9a848201614ee9565b64ffffffffff81811683821601908082111561295f5761295f6146b8565b60006102008083526150038184018a613a28565b905082810360208401526150178189613a28565b6bffffffffffffffffffffffff88811660408601528716606085015273ffffffffffffffffffffffffffffffffffffffff861660808501529150615060905060a0830184613fb6565b979650505050505050565b6000806040838503121561507e57600080fd5b82516007811061508d57600080fd5b6020840151909250613eee81613e9b56fea164736f6c6343000813000a",
+ ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"fulfillmentGasPriceOverEstimationBP\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"feedStalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"requestTimeoutSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint72\",\"name\":\"donFee\",\"type\":\"uint72\"},{\"internalType\":\"uint16\",\"name\":\"maxSupportedRequestDataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint224\",\"name\":\"fallbackNativePerUnitLink\",\"type\":\"uint224\"}],\"internalType\":\"structFunctionsBilling.Config\",\"name\":\"config\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"linkToNativeFeed\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"EmptyPublicKey\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InconsistentReportData\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidCalldata\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"linkWei\",\"type\":\"int256\"}],\"name\":\"InvalidLinkWeiPrice\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSubscription\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"MustBeSubOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoTransmittersSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByRouterOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PaymentTooLarge\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReportInvalid\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RouterMustBeSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedPublicKeyChange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedSender\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnsupportedRequestDataVersion\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"}],\"name\":\"CommitmentDeleted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"fulfillmentGasPriceOverEstimationBP\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"feedStalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"requestTimeoutSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint72\",\"name\":\"donFee\",\"type\":\"uint72\"},{\"internalType\":\"uint16\",\"name\":\"maxSupportedRequestDataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint224\",\"name\":\"fallbackNativePerUnitLink\",\"type\":\"uint224\"}],\"indexed\":false,\"internalType\":\"structFunctionsBilling.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"requestingContract\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"requestInitiator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"subscriptionOwner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"dataVersion\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"flags\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"callbackGasLimit\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"estimatedTotalCostJuels\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"client\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint72\",\"name\":\"adminFee\",\"type\":\"uint72\"},{\"internalType\":\"uint72\",\"name\":\"donFee\",\"type\":\"uint72\"},{\"internalType\":\"uint40\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint40\"},{\"internalType\":\"uint32\",\"name\":\"timeoutTimestamp\",\"type\":\"uint32\"}],\"indexed\":false,\"internalType\":\"structFunctionsResponse.Commitment\",\"name\":\"commitment\",\"type\":\"tuple\"}],\"name\":\"OracleRequest\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"}],\"name\":\"OracleResponse\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"}],\"name\":\"deleteCommitment\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"gasPriceWei\",\"type\":\"uint256\"}],\"name\":\"estimateCost\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAdminFee\",\"outputs\":[{\"internalType\":\"uint72\",\"name\":\"\",\"type\":\"uint72\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"fulfillmentGasPriceOverEstimationBP\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"feedStalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"requestTimeoutSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint72\",\"name\":\"donFee\",\"type\":\"uint72\"},{\"internalType\":\"uint16\",\"name\":\"maxSupportedRequestDataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint224\",\"name\":\"fallbackNativePerUnitLink\",\"type\":\"uint224\"}],\"internalType\":\"structFunctionsBilling.Config\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"getDONFee\",\"outputs\":[{\"internalType\":\"uint72\",\"name\":\"\",\"type\":\"uint72\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDONPublicKey\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getThresholdPublicKey\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getWeiPerUnitLink\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"oracleWithdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"oracleWithdrawAll\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"_transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"_f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"_onchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"_offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"_offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"donPublicKey\",\"type\":\"bytes\"}],\"name\":\"setDONPublicKey\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"thresholdPublicKey\",\"type\":\"bytes\"}],\"name\":\"setThresholdPublicKey\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"bytes32\",\"name\":\"flags\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"requestingContract\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"availableBalance\",\"type\":\"uint96\"},{\"internalType\":\"uint72\",\"name\":\"adminFee\",\"type\":\"uint72\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"initiatedRequests\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"dataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint64\",\"name\":\"completedRequests\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"subscriptionOwner\",\"type\":\"address\"}],\"internalType\":\"structFunctionsResponse.RequestMeta\",\"name\":\"request\",\"type\":\"tuple\"}],\"name\":\"startRequest\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"estimatedTotalCostJuels\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"client\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint72\",\"name\":\"adminFee\",\"type\":\"uint72\"},{\"internalType\":\"uint72\",\"name\":\"donFee\",\"type\":\"uint72\"},{\"internalType\":\"uint40\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint40\"},{\"internalType\":\"uint32\",\"name\":\"timeoutTimestamp\",\"type\":\"uint32\"}],\"internalType\":\"structFunctionsResponse.Commitment\",\"name\":\"commitment\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"transmitters\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"fulfillmentGasPriceOverEstimationBP\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"feedStalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"requestTimeoutSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint72\",\"name\":\"donFee\",\"type\":\"uint72\"},{\"internalType\":\"uint16\",\"name\":\"maxSupportedRequestDataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint224\",\"name\":\"fallbackNativePerUnitLink\",\"type\":\"uint224\"}],\"internalType\":\"structFunctionsBilling.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"updateConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]",
+ Bin: "0x60c06040523480156200001157600080fd5b50604051620050f4380380620050f4833981016040819052620000349162000418565b8282828260013380600081620000915760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c457620000c48162000140565b50505015156080526001600160a01b038116620000f457604051632530e88560e11b815260040160405180910390fd5b6001600160a01b0390811660a052600b80549183166c01000000000000000000000000026001600160601b039092169190911790556200013482620001eb565b505050505050620005c6565b336001600160a01b038216036200019a5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000088565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b620001f56200033b565b80516008805460208401516040808601516060870151608088015160a089015160c08a015161ffff16600160e81b0261ffff60e81b196001600160481b03909216600160a01b02600160a01b600160e81b031963ffffffff948516600160801b0216600160801b600160e81b03199585166c010000000000000000000000000263ffffffff60601b19978616680100000000000000000297909716600160401b600160801b0319998616640100000000026001600160401b0319909b1695909c1694909417989098179690961698909817929092171617929092179390931692909217905560e0820151600980546001600160e01b039092166001600160e01b0319909216919091179055517f8efd15b0efe82b55a8dc915f88e835007cc65ad0b442997d3c10604961e3907a906200033090839062000536565b60405180910390a150565b6200034562000347565b565b6000546001600160a01b03163314620003455760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640162000088565b80516001600160a01b0381168114620003bb57600080fd5b919050565b805163ffffffff81168114620003bb57600080fd5b80516001600160481b0381168114620003bb57600080fd5b805161ffff81168114620003bb57600080fd5b80516001600160e01b0381168114620003bb57600080fd5b60008060008385036101408112156200043057600080fd5b6200043b85620003a3565b935061010080601f19830112156200045257600080fd5b60405191508082016001600160401b03811183821017156200048457634e487b7160e01b600052604160045260246000fd5b6040526200049560208701620003c0565b8252620004a560408701620003c0565b6020830152620004b860608701620003c0565b6040830152620004cb60808701620003c0565b6060830152620004de60a08701620003c0565b6080830152620004f160c08701620003d5565b60a08301526200050460e08701620003ed565b60c08301526200051681870162000400565b60e08301525091506200052d6101208501620003a3565b90509250925092565b60006101008201905063ffffffff8084511683528060208501511660208401528060408501511660408401528060608501511660608401528060808501511660808401525060018060481b0360a08401511660a083015260c0830151620005a360c084018261ffff169052565b5060e0830151620005bf60e08401826001600160e01b03169052565b5092915050565b60805160a051614ade62000616600039600081816105be0152818161074c01528181610a1f01528181610cb301528181610ffa015281816117e50152613235015260006112230152614ade6000f3fe608060405234801561001057600080fd5b506004361061018d5760003560e01c806385b214cf116100e3578063c3f909d41161008c578063e3d0e71211610066578063e3d0e71214610529578063e4ddcea61461053c578063f2fde38b1461055257600080fd5b8063c3f909d4146103b4578063d227d245146104f1578063d328a91e1461052157600080fd5b8063a631571e116100bd578063a631571e14610361578063afcb95d714610381578063b1dc65a4146103a157600080fd5b806385b214cf146103135780638da5cb5b146103265780639314176d1461034e57600080fd5b806379ba509711610145578063814118341161011f578063814118341461028957806381f1b9381461029e57806381ff7048146102a657600080fd5b806379ba5097146102665780637d4807871461026e5780637f15e1661461027657600080fd5b80632a905ccc116101765780632a905ccc146101f957806359b5b7ac1461021b57806366316d8d1461025357600080fd5b8063083a546614610192578063181f5a77146101a7575b600080fd5b6101a56101a0366004613528565b610565565b005b6101e36040518060400160405280601c81526020017f46756e6374696f6e7320436f6f7264696e61746f722076312e302e300000000081525081565b6040516101f091906135ce565b60405180910390f35b6102016105ba565b60405168ffffffffffffffffff90911681526020016101f0565b61020161022936600461371e565b5060085474010000000000000000000000000000000000000000900468ffffffffffffffffff1690565b6101a56102613660046137ad565b610650565b6101a5610809565b6101a561090b565b6101a5610284366004613528565b610b0b565b610291610b5b565b6040516101f09190613837565b6101e3610bca565b6102f060015460025463ffffffff74010000000000000000000000000000000000000000830481169378010000000000000000000000000000000000000000000000009093041691565b6040805163ffffffff9485168152939092166020840152908201526060016101f0565b6101a561032136600461384a565b610c9b565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101f0565b6101a561035c3660046138e0565b610d58565b61037461036f3660046139aa565b610f89565b6040516101f09190613aff565b6040805160018152600060208201819052918101919091526060016101f0565b6101a56103af366004613b53565b61112a565b6104e46040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081019190915250604080516101008101825260085463ffffffff80821683526401000000008204811660208401526801000000000000000082048116938301939093526c010000000000000000000000008104831660608301527001000000000000000000000000000000008104909216608082015274010000000000000000000000000000000000000000820468ffffffffffffffffff1660a08201527d01000000000000000000000000000000000000000000000000000000000090910461ffff1660c08201526009547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660e082015290565b6040516101f09190613c0a565b6105046104ff366004613cca565b6117e1565b6040516bffffffffffffffffffffffff90911681526020016101f0565b6101e3611943565b6101a5610537366004613de3565b61199a565b6105446123c6565b6040519081526020016101f0565b6101a5610560366004613eb0565b6125eb565b61056d6125ff565b60008190036105a8576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600d6105b5828483613f66565b505050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16632a905ccc6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610627573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061064b919061408c565b905090565b610658612682565b806bffffffffffffffffffffffff166000036106925750336000908152600a60205260409020546bffffffffffffffffffffffff166106ec565b336000908152600a60205260409020546bffffffffffffffffffffffff808316911610156106ec576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152600a6020526040812080548392906107199084906bffffffffffffffffffffffff166140d8565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555061076e7f000000000000000000000000000000000000000000000000000000000000000090565b6040517f66316d8d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84811660048301526bffffffffffffffffffffffff8416602483015291909116906366316d8d90604401600060405180830381600087803b1580156107ed57600080fd5b505af1158015610801573d6000803e3d6000fd5b505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff16331461088f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b61091361282d565b61091b612682565b6000610925610b5b565b905060005b8151811015610b07576000600a600084848151811061094b5761094b6140fd565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252810191909152604001600020546bffffffffffffffffffffffff1690508015610af6576000600a60008585815181106109aa576109aa6140fd565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550610a417f000000000000000000000000000000000000000000000000000000000000000090565b73ffffffffffffffffffffffffffffffffffffffff166366316d8d848481518110610a6e57610a6e6140fd565b6020026020010151836040518363ffffffff1660e01b8152600401610ac392919073ffffffffffffffffffffffffffffffffffffffff9290921682526bffffffffffffffffffffffff16602082015260400190565b600060405180830381600087803b158015610add57600080fd5b505af1158015610af1573d6000803e3d6000fd5b505050505b50610b008161412c565b905061092a565b5050565b610b136125ff565b6000819003610b4e576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600c6105b5828483613f66565b60606006805480602002602001604051908101604052809291908181526020018280548015610bc057602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610b95575b5050505050905090565b6060600d8054610bd990613ecd565b9050600003610c14576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600d8054610c2190613ecd565b80601f0160208091040260200160405190810160405280929190818152602001828054610c4d90613ecd565b8015610bc05780601f10610c6f57610100808354040283529160200191610bc0565b820191906000526020600020905b815481529060010190602001808311610c7d57509395945050505050565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610d0a576040517fc41a5b0900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008181526007602052604080822091909155517f8a4b97add3359bd6bcf5e82874363670eb5ad0f7615abddbd0ed0a3a98f0f41690610d4d9083815260200190565b60405180910390a150565b610d6061282d565b80516008805460208401516040808601516060870151608088015160a089015160c08a015161ffff167d010000000000000000000000000000000000000000000000000000000000027fff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff68ffffffffffffffffff90921674010000000000000000000000000000000000000000027fffffff000000000000000000ffffffffffffffffffffffffffffffffffffffff63ffffffff94851670010000000000000000000000000000000002167fffffff00000000000000000000000000ffffffffffffffffffffffffffffffff9585166c01000000000000000000000000027fffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffff9786166801000000000000000002979097167fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff998616640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000909b1695909c1694909417989098179690961698909817929092171617929092179390931692909217905560e0820151600980547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff9092167fffffffff00000000000000000000000000000000000000000000000000000000909216919091179055517f8efd15b0efe82b55a8dc915f88e835007cc65ad0b442997d3c10604961e3907a90610d4d908390613c0a565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101919091523373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614611051576040517fc41a5b0900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61106261105d83614164565b612835565b90506110746060830160408401613eb0565b815173ffffffffffffffffffffffffffffffffffffffff91909116907fbf50768ccf13bd0110ca6d53a9c4f1f3271abdd4c24a56878863ed25b20598ff326110c260c0870160a08801614251565b6110d461016088016101408901613eb0565b6110de888061426e565b6110f06101208b016101008c016142d3565b60208b01356111066101008d0160e08e016142ee565b8b60405161111c9998979695949392919061430b565b60405180910390a35b919050565b60005a604080518b3580825262ffffff6020808f0135600881901c929092169084015293945092917fb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62910160405180910390a16040805160608101825260025480825260035460ff80821660208501526101009091041692820192909252908314611211576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f636f6e666967446967657374206d69736d6174636800000000000000000000006044820152606401610886565b61121f8b8b8b8b8b8b612c36565b60007f00000000000000000000000000000000000000000000000000000000000000001561127c5760028260200151836040015161125d91906143b3565b61126791906143fb565b6112729060016143b3565b60ff169050611292565b602082015161128c9060016143b3565b60ff1690505b8881146112fb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f77726f6e67206e756d626572206f66207369676e6174757265730000000000006044820152606401610886565b888714611364576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f7369676e617475726573206f7574206f6620726567697374726174696f6e00006044820152606401610886565b3360009081526004602090815260408083208151808301909252805460ff808216845292939192918401916101009091041660028111156113a7576113a761441d565b60028111156113b8576113b861441d565b90525090506002816020015160028111156113d5576113d561441d565b14801561141c57506006816000015160ff16815481106113f7576113f76140fd565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1633145b611482576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f756e617574686f72697a6564207472616e736d697474657200000000000000006044820152606401610886565b505050505061148f6134c0565b6000808a8a6040516114a292919061444c565b6040519081900381206114b9918e9060200161445c565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120838301909252600080845290830152915060005b898110156117c3576000600184898460208110611522576115226140fd565b61152f91901a601b6143b3565b8e8e86818110611541576115416140fd565b905060200201358d8d8781811061155a5761155a6140fd565b9050602002013560405160008152602001604052604051611597949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa1580156115b9573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff811660009081526004602090815290849020838501909452835460ff808216855292965092945084019161010090041660028111156116395761163961441d565b600281111561164a5761164a61441d565b90525092506001836020015160028111156116675761166761441d565b146116ce576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f61646472657373206e6f7420617574686f72697a656420746f207369676e00006044820152606401610886565b8251600090879060ff16601f81106116e8576116e86140fd565b602002015173ffffffffffffffffffffffffffffffffffffffff161461176a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f6e6f6e2d756e69717565207369676e61747572650000000000000000000000006044820152606401610886565b8086846000015160ff16601f8110611784576117846140fd565b73ffffffffffffffffffffffffffffffffffffffff90921660209290920201526117af6001866143b3565b945050806117bc9061412c565b9050611503565b5050506117d4833383858e8e612ced565b5050505050505050505050565b60007f00000000000000000000000000000000000000000000000000000000000000006040517f10fc49c100000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8816600482015263ffffffff8516602482015273ffffffffffffffffffffffffffffffffffffffff91909116906310fc49c19060440160006040518083038186803b15801561188157600080fd5b505afa158015611895573d6000803e3d6000fd5b5050505066038d7ea4c680008211156118da576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006118e46105ba565b9050600061192787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061022992505050565b905061193585858385612ebb565b925050505b95945050505050565b6060600c805461195290613ecd565b905060000361198d576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600c8054610c2190613ecd565b855185518560ff16601f831115611a0d576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f746f6f206d616e79207369676e657273000000000000000000000000000000006044820152606401610886565b80600003611a77576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f66206d75737420626520706f73697469766500000000000000000000000000006044820152606401610886565b818314611b05576040517f89a61989000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f6f7261636c6520616464726573736573206f7574206f6620726567697374726160448201527f74696f6e000000000000000000000000000000000000000000000000000000006064820152608401610886565b611b10816003614470565b8311611b78576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f6661756c74792d6f7261636c65206620746f6f206869676800000000000000006044820152606401610886565b611b806125ff565b6040805160c0810182528a8152602081018a905260ff89169181018290526060810188905267ffffffffffffffff8716608082015260a0810186905290611bc79088612fa5565b60055415611d7c57600554600090611be190600190614487565b9050600060058281548110611bf857611bf86140fd565b60009182526020822001546006805473ffffffffffffffffffffffffffffffffffffffff90921693509084908110611c3257611c326140fd565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff85811684526004909252604080842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000090811690915592909116808452922080549091169055600580549192509080611cb257611cb261449a565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff00000000000000000000000000000000000000001690550190556006805480611d1b57611d1b61449a565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905501905550611bc7915050565b60005b8151518110156121e35760006004600084600001518481518110611da557611da56140fd565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160002054610100900460ff166002811115611def57611def61441d565b14611e56576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f7265706561746564207369676e657220616464726573730000000000000000006044820152606401610886565b6040805180820190915260ff82168152600160208201528251805160049160009185908110611e8757611e876140fd565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040016000208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001617610100836002811115611f2857611f2861441d565b021790555060009150611f389050565b6004600084602001518481518110611f5257611f526140fd565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160002054610100900460ff166002811115611f9c57611f9c61441d565b14612003576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f7265706561746564207472616e736d69747465722061646472657373000000006044820152606401610886565b6040805180820190915260ff821681526020810160028152506004600084602001518481518110612036576120366140fd565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040016000208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000016176101008360028111156120d7576120d761441d565b0217905550508251805160059250839081106120f5576120f56140fd565b602090810291909101810151825460018101845560009384529282902090920180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9093169290921790915582015180516006919083908110612171576121716140fd565b60209081029190910181015182546001810184556000938452919092200180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909216919091179055806121db8161412c565b915050611d7f565b506040810151600380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff909216919091179055600180547fffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffff8116780100000000000000000000000000000000000000000000000063ffffffff438116820292909217808555920481169291829160149161229b918491740100000000000000000000000000000000000000009004166144c9565b92506101000a81548163ffffffff021916908363ffffffff1602179055506122fa4630600160149054906101000a900463ffffffff1663ffffffff16856000015186602001518760400151886060015189608001518a60a00151612fbe565b600281905582518051600380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1661010060ff9093169290920291909117905560015460208501516040808701516060880151608089015160a08a015193517f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e05986123b1988b9891977401000000000000000000000000000000000000000090920463ffffffff169690959194919391926144e6565b60405180910390a15050505050505050505050565b604080516101008101825260085463ffffffff80821683526401000000008204811660208401526801000000000000000082048116838501526c01000000000000000000000000808304821660608501527001000000000000000000000000000000008304909116608084015274010000000000000000000000000000000000000000820468ffffffffffffffffff1660a0808501919091527d01000000000000000000000000000000000000000000000000000000000090920461ffff1660c08401526009547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660e0840152600b5484517ffeaf968c00000000000000000000000000000000000000000000000000000000815294516000958694859490930473ffffffffffffffffffffffffffffffffffffffff169263feaf968c926004808401938290030181865afa158015612520573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125449190614596565b5093505092505080426125579190614487565b836020015163ffffffff1610801561257957506000836020015163ffffffff16115b156125a757505060e001517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16919050565b600082136125e4576040517f43d4cf6600000000000000000000000000000000000000000000000000000000815260048101839052602401610886565b5092915050565b6125f36125ff565b6125fc81613069565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314612680576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610886565b565b600b546bffffffffffffffffffffffff1660000361269c57565b60006126a6610b5b565b905080516000036126e3576040517f30274b3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600b54600091612702916bffffffffffffffffffffffff166145e6565b905060005b82518110156127ce5781600a6000858481518110612727576127276140fd565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282829054906101000a90046bffffffffffffffffffffffff1661278f9190614611565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550806127c79061412c565b9050612707565b5081516127db9082614636565b600b80546000906127fb9084906bffffffffffffffffffffffff166140d8565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055505050565b6126806125ff565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081019190915260408051610100808201835260085463ffffffff80821684526401000000008204811660208501526801000000000000000082048116948401949094526c010000000000000000000000008104841660608401527001000000000000000000000000000000008104909316608083015274010000000000000000000000000000000000000000830468ffffffffffffffffff1660a08301527d01000000000000000000000000000000000000000000000000000000000090920461ffff90811660c083018190526009547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660e0840152928501519192911611156129bb576040517fdada758700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60085460009074010000000000000000000000000000000000000000900468ffffffffffffffffff16905060006129fc8560e001513a848860800151612ebb565b9050806bffffffffffffffffffffffff1685606001516bffffffffffffffffffffffff161015612a58576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612adb3087604001518860a001518960c001516001612a799190614666565b6040805173ffffffffffffffffffffffffffffffffffffffff958616602080830191909152949095168582015267ffffffffffffffff928316606086015291166080808501919091528151808503909101815260a09093019052815191012090565b90506040518061016001604052808281526020013073ffffffffffffffffffffffffffffffffffffffff168152602001836bffffffffffffffffffffffff168152602001876040015173ffffffffffffffffffffffffffffffffffffffff1681526020018760a0015167ffffffffffffffff1681526020018760e0015163ffffffff168152602001876080015168ffffffffffffffffff1681526020018468ffffffffffffffffff168152602001856040015163ffffffff1664ffffffffff168152602001856060015163ffffffff1664ffffffffff168152602001856080015163ffffffff1642612bcd9190614687565b63ffffffff16815250945084604051602001612be99190613aff565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181528151602092830120600093845260079092529091205550919392505050565b6000612c43826020614470565b612c4e856020614470565b612c5a88610144614687565b612c649190614687565b612c6e9190614687565b612c79906000614687565b9050368114612ce4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f63616c6c64617461206c656e677468206d69736d6174636800000000000000006044820152606401610886565b50505050505050565b606080808080612cff86880188614775565b8451949950929750909550935091501580612d1c57508351855114155b80612d2957508251855114155b80612d3657508151855114155b80612d4357508051855114155b15612d7a576040517f0be3632800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8551811015612ead576000612e12878381518110612d9d57612d9d6140fd565b6020026020010151878481518110612db757612db76140fd565b6020026020010151878581518110612dd157612dd16140fd565b6020026020010151878681518110612deb57612deb6140fd565b6020026020010151878781518110612e0557612e056140fd565b602002602001015161315e565b90506000816006811115612e2857612e2861441d565b1480612e4557506001816006811115612e4357612e4361441d565b145b15612e9c57868281518110612e5c57612e5c6140fd565b60209081029190910181015160405133815290917fc708e0440951fd63499c0f7a73819b469ee5dd3ecc356c0ab4eb7f18389009d9910160405180910390a25b50612ea68161412c565b9050612d7d565b505050505050505050505050565b60085460009081908690612ef39063ffffffff6c010000000000000000000000008204811691680100000000000000009004166144c9565b612efd91906144c9565b60085463ffffffff918216925060009161271091612f1c911688614470565b612f269190614847565b612f309087614687565b90506000612f3d826133ef565b90506000612f59846bffffffffffffffffffffffff8416614470565b90506000612f7568ffffffffffffffffff808916908a16614611565b9050612f97612f926bffffffffffffffffffffffff831684614687565b61341e565b9a9950505050505050505050565b6000612faf610b5b565b511115610b0757610b07612682565b6000808a8a8a8a8a8a8a8a8a604051602001612fe29998979695949392919061485b565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b3373ffffffffffffffffffffffffffffffffffffffff8216036130e8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610886565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600080838060200190518101906131759190614931565b60008881526007602052604090205490915061319557600291505061193a565b806040516020016131a69190613aff565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152815160209283012060008a81526007909352912054146131f857600691505061193a565b60006132033a6133ef565b9050600082610120015183610100015161321d9190614a04565b61322e9064ffffffffff1683614636565b90506000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663330605298b8b878960e0015168ffffffffffffffffff168861328d9190614611565b338b6040518763ffffffff1660e01b81526004016132b096959493929190614a22565b60408051808303816000875af11580156132ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132f29190614a9e565b9092509050600082600681111561330b5761330b61441d565b1480613328575060018260068111156133265761332661441d565b145b156133e15760008b8152600760205260408120556133468184614611565b336000908152600a6020526040812080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff93841617905560e0870151600b805468ffffffffffffffffff909216939092916133b291859116614611565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055505b509998505050505050505050565b60006134186133fc6123c6565b61340e84670de0b6b3a7640000614470565b612f929190614847565b92915050565b60006bffffffffffffffffffffffff8211156134bc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203960448201527f36206269747300000000000000000000000000000000000000000000000000006064820152608401610886565b5090565b604051806103e00160405280601f906020820280368337509192915050565b60008083601f8401126134f157600080fd5b50813567ffffffffffffffff81111561350957600080fd5b60208301915083602082850101111561352157600080fd5b9250929050565b6000806020838503121561353b57600080fd5b823567ffffffffffffffff81111561355257600080fd5b61355e858286016134df565b90969095509350505050565b6000815180845260005b8181101561359057602081850181015186830182015201613574565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b6020815260006135e1602083018461356a565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610160810167ffffffffffffffff8111828210171561363b5761363b6135e8565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613688576136886135e8565b604052919050565b600082601f8301126136a157600080fd5b813567ffffffffffffffff8111156136bb576136bb6135e8565b6136ec60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601613641565b81815284602083860101111561370157600080fd5b816020850160208301376000918101602001919091529392505050565b60006020828403121561373057600080fd5b813567ffffffffffffffff81111561374757600080fd5b61375384828501613690565b949350505050565b73ffffffffffffffffffffffffffffffffffffffff811681146125fc57600080fd5b80356111258161375b565b6bffffffffffffffffffffffff811681146125fc57600080fd5b803561112581613788565b600080604083850312156137c057600080fd5b82356137cb8161375b565b915060208301356137db81613788565b809150509250929050565b600081518084526020808501945080840160005b8381101561382c57815173ffffffffffffffffffffffffffffffffffffffff16875295820195908201906001016137fa565b509495945050505050565b6020815260006135e160208301846137e6565b60006020828403121561385c57600080fd5b5035919050565b63ffffffff811681146125fc57600080fd5b803561112581613863565b68ffffffffffffffffff811681146125fc57600080fd5b803561112581613880565b803561ffff8116811461112557600080fd5b80357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8116811461112557600080fd5b60006101008083850312156138f457600080fd5b6040519081019067ffffffffffffffff82118183101715613917576139176135e8565b816040528335915061392882613863565b81815261393760208501613875565b602082015261394860408501613875565b604082015261395960608501613875565b606082015261396a60808501613875565b608082015261397b60a08501613897565b60a082015261398c60c085016138a2565b60c082015261399d60e085016138b4565b60e0820152949350505050565b6000602082840312156139bc57600080fd5b813567ffffffffffffffff8111156139d357600080fd5b820161016081850312156135e157600080fd5b805182526020810151613a11602084018273ffffffffffffffffffffffffffffffffffffffff169052565b506040810151613a3160408401826bffffffffffffffffffffffff169052565b506060810151613a59606084018273ffffffffffffffffffffffffffffffffffffffff169052565b506080810151613a75608084018267ffffffffffffffff169052565b5060a0810151613a8d60a084018263ffffffff169052565b5060c0810151613aaa60c084018268ffffffffffffffffff169052565b5060e0810151613ac760e084018268ffffffffffffffffff169052565b506101008181015164ffffffffff9081169184019190915261012080830151909116908301526101409081015163ffffffff16910152565b610160810161341882846139e6565b60008083601f840112613b2057600080fd5b50813567ffffffffffffffff811115613b3857600080fd5b6020830191508360208260051b850101111561352157600080fd5b60008060008060008060008060e0898b031215613b6f57600080fd5b606089018a811115613b8057600080fd5b8998503567ffffffffffffffff80821115613b9a57600080fd5b613ba68c838d016134df565b909950975060808b0135915080821115613bbf57600080fd5b613bcb8c838d01613b0e565b909750955060a08b0135915080821115613be457600080fd5b50613bf18b828c01613b0e565b999c989b50969995989497949560c00135949350505050565b60006101008201905063ffffffff8084511683528060208501511660208401528060408501511660408401528060608501511660608401528060808501511660808401525068ffffffffffffffffff60a08401511660a083015260c0830151613c7960c084018261ffff169052565b5060e08301516125e460e08401827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff169052565b67ffffffffffffffff811681146125fc57600080fd5b803561112581613ca9565b600080600080600060808688031215613ce257600080fd5b8535613ced81613ca9565b9450602086013567ffffffffffffffff811115613d0957600080fd5b613d15888289016134df565b9095509350506040860135613d2981613863565b949793965091946060013592915050565b600067ffffffffffffffff821115613d5457613d546135e8565b5060051b60200190565b600082601f830112613d6f57600080fd5b81356020613d84613d7f83613d3a565b613641565b82815260059290921b84018101918181019086841115613da357600080fd5b8286015b84811015613dc7578035613dba8161375b565b8352918301918301613da7565b509695505050505050565b803560ff8116811461112557600080fd5b60008060008060008060c08789031215613dfc57600080fd5b863567ffffffffffffffff80821115613e1457600080fd5b613e208a838b01613d5e565b97506020890135915080821115613e3657600080fd5b613e428a838b01613d5e565b9650613e5060408a01613dd2565b95506060890135915080821115613e6657600080fd5b613e728a838b01613690565b9450613e8060808a01613cbf565b935060a0890135915080821115613e9657600080fd5b50613ea389828a01613690565b9150509295509295509295565b600060208284031215613ec257600080fd5b81356135e18161375b565b600181811c90821680613ee157607f821691505b602082108103613f1a577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b601f8211156105b557600081815260208120601f850160051c81016020861015613f475750805b601f850160051c820191505b8181101561080157828155600101613f53565b67ffffffffffffffff831115613f7e57613f7e6135e8565b613f9283613f8c8354613ecd565b83613f20565b6000601f841160018114613fe45760008515613fae5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b17835561407a565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b828110156140335786850135825560209485019460019092019101614013565b508682101561406e577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b805161112581613880565b60006020828403121561409e57600080fd5b81516135e181613880565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6bffffffffffffffffffffffff8281168282160390808211156125e4576125e46140a9565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361415d5761415d6140a9565b5060010190565b6000610160823603121561417757600080fd5b61417f613617565b823567ffffffffffffffff81111561419657600080fd5b6141a236828601613690565b825250602083013560208201526141bb6040840161377d565b60408201526141cc606084016137a2565b60608201526141dd60808401613897565b60808201526141ee60a08401613cbf565b60a08201526141ff60c08401613cbf565b60c082015261421060e08401613875565b60e08201526101006142238185016138a2565b90820152610120614235848201613cbf565b9082015261014061424784820161377d565b9082015292915050565b60006020828403121561426357600080fd5b81356135e181613ca9565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126142a357600080fd5b83018035915067ffffffffffffffff8211156142be57600080fd5b60200191503681900382131561352157600080fd5b6000602082840312156142e557600080fd5b6135e1826138a2565b60006020828403121561430057600080fd5b81356135e181613863565b73ffffffffffffffffffffffffffffffffffffffff8a8116825267ffffffffffffffff8a166020830152881660408201526102406060820181905281018690526000610260878982850137600083890182015261ffff8716608084015260a0830186905263ffffffff851660c0840152601f88017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168301019050612f9760e08301846139e6565b60ff8181168382160190811115613418576134186140a9565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600060ff83168061440e5761440e6143cc565b8060ff84160491505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b8183823760009101908152919050565b828152606082602083013760800192915050565b8082028115828204841417613418576134186140a9565b81810381811115613418576134186140a9565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b63ffffffff8181168382160190808211156125e4576125e46140a9565b600061012063ffffffff808d1684528b6020850152808b166040850152508060608401526145168184018a6137e6565b9050828103608084015261452a81896137e6565b905060ff871660a084015282810360c0840152614547818761356a565b905067ffffffffffffffff851660e084015282810361010084015261456c818561356a565b9c9b505050505050505050505050565b805169ffffffffffffffffffff8116811461112557600080fd5b600080600080600060a086880312156145ae57600080fd5b6145b78661457c565b94506020860151935060408601519250606086015191506145da6080870161457c565b90509295509295909350565b60006bffffffffffffffffffffffff80841680614605576146056143cc565b92169190910492915050565b6bffffffffffffffffffffffff8181168382160190808211156125e4576125e46140a9565b6bffffffffffffffffffffffff81811683821602808216919082811461465e5761465e6140a9565b505092915050565b67ffffffffffffffff8181168382160190808211156125e4576125e46140a9565b80820180821115613418576134186140a9565b600082601f8301126146ab57600080fd5b813560206146bb613d7f83613d3a565b82815260059290921b840181019181810190868411156146da57600080fd5b8286015b84811015613dc757803583529183019183016146de565b600082601f83011261470657600080fd5b81356020614716613d7f83613d3a565b82815260059290921b8401810191818101908684111561473557600080fd5b8286015b84811015613dc757803567ffffffffffffffff8111156147595760008081fd5b6147678986838b0101613690565b845250918301918301614739565b600080600080600060a0868803121561478d57600080fd5b853567ffffffffffffffff808211156147a557600080fd5b6147b189838a0161469a565b965060208801359150808211156147c757600080fd5b6147d389838a016146f5565b955060408801359150808211156147e957600080fd5b6147f589838a016146f5565b9450606088013591508082111561480b57600080fd5b61481789838a016146f5565b9350608088013591508082111561482d57600080fd5b5061483a888289016146f5565b9150509295509295909350565b600082614856576148566143cc565b500490565b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b1660408501528160608501526148a28285018b6137e6565b915083820360808501526148b6828a6137e6565b915060ff881660a085015283820360c08501526148d3828861356a565b90861660e0850152838103610100850152905061456c818561356a565b80516111258161375b565b805161112581613788565b805161112581613ca9565b805161112581613863565b805164ffffffffff8116811461112557600080fd5b6000610160828403121561494457600080fd5b61494c613617565b8251815261495c602084016148f0565b602082015261496d604084016148fb565b604082015261497e606084016148f0565b606082015261498f60808401614906565b60808201526149a060a08401614911565b60a08201526149b160c08401614081565b60c08201526149c260e08401614081565b60e08201526101006149d581850161491c565b908201526101206149e784820161491c565b908201526101406149f9848201614911565b908201529392505050565b64ffffffffff8181168382160190808211156125e4576125e46140a9565b6000610200808352614a368184018a61356a565b90508281036020840152614a4a818961356a565b6bffffffffffffffffffffffff88811660408601528716606085015273ffffffffffffffffffffffffffffffffffffffff861660808501529150614a93905060a08301846139e6565b979650505050505050565b60008060408385031215614ab157600080fd5b825160078110614ac057600080fd5b60208401519092506137db8161378856fea164736f6c6343000813000a",
}
var FunctionsCoordinatorABI = FunctionsCoordinatorMetaData.ABI
@@ -211,9 +210,9 @@ func (_FunctionsCoordinator *FunctionsCoordinatorTransactorRaw) Transact(opts *b
return _FunctionsCoordinator.Contract.contract.Transact(opts, method, params...)
}
-func (_FunctionsCoordinator *FunctionsCoordinatorCaller) EstimateCost(opts *bind.CallOpts, subscriptionId uint64, data []byte, callbackGasLimit uint32, gasPriceGwei *big.Int) (*big.Int, error) {
+func (_FunctionsCoordinator *FunctionsCoordinatorCaller) EstimateCost(opts *bind.CallOpts, subscriptionId uint64, data []byte, callbackGasLimit uint32, gasPriceWei *big.Int) (*big.Int, error) {
var out []interface{}
- err := _FunctionsCoordinator.contract.Call(opts, &out, "estimateCost", subscriptionId, data, callbackGasLimit, gasPriceGwei)
+ err := _FunctionsCoordinator.contract.Call(opts, &out, "estimateCost", subscriptionId, data, callbackGasLimit, gasPriceWei)
if err != nil {
return *new(*big.Int), err
@@ -225,12 +224,12 @@ func (_FunctionsCoordinator *FunctionsCoordinatorCaller) EstimateCost(opts *bind
}
-func (_FunctionsCoordinator *FunctionsCoordinatorSession) EstimateCost(subscriptionId uint64, data []byte, callbackGasLimit uint32, gasPriceGwei *big.Int) (*big.Int, error) {
- return _FunctionsCoordinator.Contract.EstimateCost(&_FunctionsCoordinator.CallOpts, subscriptionId, data, callbackGasLimit, gasPriceGwei)
+func (_FunctionsCoordinator *FunctionsCoordinatorSession) EstimateCost(subscriptionId uint64, data []byte, callbackGasLimit uint32, gasPriceWei *big.Int) (*big.Int, error) {
+ return _FunctionsCoordinator.Contract.EstimateCost(&_FunctionsCoordinator.CallOpts, subscriptionId, data, callbackGasLimit, gasPriceWei)
}
-func (_FunctionsCoordinator *FunctionsCoordinatorCallerSession) EstimateCost(subscriptionId uint64, data []byte, callbackGasLimit uint32, gasPriceGwei *big.Int) (*big.Int, error) {
- return _FunctionsCoordinator.Contract.EstimateCost(&_FunctionsCoordinator.CallOpts, subscriptionId, data, callbackGasLimit, gasPriceGwei)
+func (_FunctionsCoordinator *FunctionsCoordinatorCallerSession) EstimateCost(subscriptionId uint64, data []byte, callbackGasLimit uint32, gasPriceWei *big.Int) (*big.Int, error) {
+ return _FunctionsCoordinator.Contract.EstimateCost(&_FunctionsCoordinator.CallOpts, subscriptionId, data, callbackGasLimit, gasPriceWei)
}
func (_FunctionsCoordinator *FunctionsCoordinatorCaller) GetAdminFee(opts *bind.CallOpts) (*big.Int, error) {
@@ -255,29 +254,6 @@ func (_FunctionsCoordinator *FunctionsCoordinatorCallerSession) GetAdminFee() (*
return _FunctionsCoordinator.Contract.GetAdminFee(&_FunctionsCoordinator.CallOpts)
}
-func (_FunctionsCoordinator *FunctionsCoordinatorCaller) GetAllNodePublicKeys(opts *bind.CallOpts) ([]common.Address, [][]byte, error) {
- var out []interface{}
- err := _FunctionsCoordinator.contract.Call(opts, &out, "getAllNodePublicKeys")
-
- if err != nil {
- return *new([]common.Address), *new([][]byte), err
- }
-
- out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address)
- out1 := *abi.ConvertType(out[1], new([][]byte)).(*[][]byte)
-
- return out0, out1, err
-
-}
-
-func (_FunctionsCoordinator *FunctionsCoordinatorSession) GetAllNodePublicKeys() ([]common.Address, [][]byte, error) {
- return _FunctionsCoordinator.Contract.GetAllNodePublicKeys(&_FunctionsCoordinator.CallOpts)
-}
-
-func (_FunctionsCoordinator *FunctionsCoordinatorCallerSession) GetAllNodePublicKeys() ([]common.Address, [][]byte, error) {
- return _FunctionsCoordinator.Contract.GetAllNodePublicKeys(&_FunctionsCoordinator.CallOpts)
-}
-
func (_FunctionsCoordinator *FunctionsCoordinatorCaller) GetConfig(opts *bind.CallOpts) (FunctionsBillingConfig, error) {
var out []interface{}
err := _FunctionsCoordinator.contract.Call(opts, &out, "getConfig")
@@ -540,18 +516,6 @@ func (_FunctionsCoordinator *FunctionsCoordinatorTransactorSession) DeleteCommit
return _FunctionsCoordinator.Contract.DeleteCommitment(&_FunctionsCoordinator.TransactOpts, requestId)
}
-func (_FunctionsCoordinator *FunctionsCoordinatorTransactor) DeleteNodePublicKey(opts *bind.TransactOpts, node common.Address) (*types.Transaction, error) {
- return _FunctionsCoordinator.contract.Transact(opts, "deleteNodePublicKey", node)
-}
-
-func (_FunctionsCoordinator *FunctionsCoordinatorSession) DeleteNodePublicKey(node common.Address) (*types.Transaction, error) {
- return _FunctionsCoordinator.Contract.DeleteNodePublicKey(&_FunctionsCoordinator.TransactOpts, node)
-}
-
-func (_FunctionsCoordinator *FunctionsCoordinatorTransactorSession) DeleteNodePublicKey(node common.Address) (*types.Transaction, error) {
- return _FunctionsCoordinator.Contract.DeleteNodePublicKey(&_FunctionsCoordinator.TransactOpts, node)
-}
-
func (_FunctionsCoordinator *FunctionsCoordinatorTransactor) OracleWithdraw(opts *bind.TransactOpts, recipient common.Address, amount *big.Int) (*types.Transaction, error) {
return _FunctionsCoordinator.contract.Transact(opts, "oracleWithdraw", recipient, amount)
}
@@ -600,18 +564,6 @@ func (_FunctionsCoordinator *FunctionsCoordinatorTransactorSession) SetDONPublic
return _FunctionsCoordinator.Contract.SetDONPublicKey(&_FunctionsCoordinator.TransactOpts, donPublicKey)
}
-func (_FunctionsCoordinator *FunctionsCoordinatorTransactor) SetNodePublicKey(opts *bind.TransactOpts, node common.Address, publicKey []byte) (*types.Transaction, error) {
- return _FunctionsCoordinator.contract.Transact(opts, "setNodePublicKey", node, publicKey)
-}
-
-func (_FunctionsCoordinator *FunctionsCoordinatorSession) SetNodePublicKey(node common.Address, publicKey []byte) (*types.Transaction, error) {
- return _FunctionsCoordinator.Contract.SetNodePublicKey(&_FunctionsCoordinator.TransactOpts, node, publicKey)
-}
-
-func (_FunctionsCoordinator *FunctionsCoordinatorTransactorSession) SetNodePublicKey(node common.Address, publicKey []byte) (*types.Transaction, error) {
- return _FunctionsCoordinator.Contract.SetNodePublicKey(&_FunctionsCoordinator.TransactOpts, node, publicKey)
-}
-
func (_FunctionsCoordinator *FunctionsCoordinatorTransactor) SetThresholdPublicKey(opts *bind.TransactOpts, thresholdPublicKey []byte) (*types.Transaction, error) {
return _FunctionsCoordinator.contract.Transact(opts, "setThresholdPublicKey", thresholdPublicKey)
}
@@ -1737,7 +1689,7 @@ func (FunctionsCoordinatorConfigSet) Topic() common.Hash {
}
func (FunctionsCoordinatorConfigUpdated) Topic() common.Hash {
- return common.HexToHash("0x5b6e2e1a03ea742ce04ca36d0175411a0772f99ef4ee84aeb9868a1ef6ddc82c")
+ return common.HexToHash("0x8efd15b0efe82b55a8dc915f88e835007cc65ad0b442997d3c10604961e3907a")
}
func (FunctionsCoordinatorOracleRequest) Topic() common.Hash {
@@ -1765,12 +1717,10 @@ func (_FunctionsCoordinator *FunctionsCoordinator) Address() common.Address {
}
type FunctionsCoordinatorInterface interface {
- EstimateCost(opts *bind.CallOpts, subscriptionId uint64, data []byte, callbackGasLimit uint32, gasPriceGwei *big.Int) (*big.Int, error)
+ EstimateCost(opts *bind.CallOpts, subscriptionId uint64, data []byte, callbackGasLimit uint32, gasPriceWei *big.Int) (*big.Int, error)
GetAdminFee(opts *bind.CallOpts) (*big.Int, error)
- GetAllNodePublicKeys(opts *bind.CallOpts) ([]common.Address, [][]byte, error)
-
GetConfig(opts *bind.CallOpts) (FunctionsBillingConfig, error)
GetDONFee(opts *bind.CallOpts, arg0 []byte) (*big.Int, error)
@@ -1799,8 +1749,6 @@ type FunctionsCoordinatorInterface interface {
DeleteCommitment(opts *bind.TransactOpts, requestId [32]byte) (*types.Transaction, error)
- DeleteNodePublicKey(opts *bind.TransactOpts, node common.Address) (*types.Transaction, error)
-
OracleWithdraw(opts *bind.TransactOpts, recipient common.Address, amount *big.Int) (*types.Transaction, error)
OracleWithdrawAll(opts *bind.TransactOpts) (*types.Transaction, error)
@@ -1809,8 +1757,6 @@ type FunctionsCoordinatorInterface interface {
SetDONPublicKey(opts *bind.TransactOpts, donPublicKey []byte) (*types.Transaction, error)
- SetNodePublicKey(opts *bind.TransactOpts, node common.Address, publicKey []byte) (*types.Transaction, error)
-
SetThresholdPublicKey(opts *bind.TransactOpts, thresholdPublicKey []byte) (*types.Transaction, error)
StartRequest(opts *bind.TransactOpts, request FunctionsResponseRequestMeta) (*types.Transaction, error)
diff --git a/core/gethwrappers/functions/generated/functions_load_test_client/functions_load_test_client.go b/core/gethwrappers/functions/generated/functions_load_test_client/functions_load_test_client.go
index 90d1ac33533..37a895fe8cd 100644
--- a/core/gethwrappers/functions/generated/functions_load_test_client/functions_load_test_client.go
+++ b/core/gethwrappers/functions/generated/functions_load_test_client/functions_load_test_client.go
@@ -31,8 +31,8 @@ var (
)
var FunctionsLoadTestClientMetaData = &bind.MetaData{
- ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"EmptyArgs\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptySecrets\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptySource\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoInlineSecrets\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyRouterCanFulfill\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"RequestFulfilled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"RequestSent\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MAX_CALLBACK_GAS\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"handleOracleFulfillment\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_lastError\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_lastErrorLength\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_lastRequestId\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_lastResponse\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_lastResponseLength\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"source\",\"type\":\"string\"},{\"internalType\":\"bytes\",\"name\":\"encryptedSecretsReferences\",\"type\":\"bytes\"},{\"internalType\":\"string[]\",\"name\":\"args\",\"type\":\"string[]\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"jobId\",\"type\":\"bytes32\"}],\"name\":\"sendRequest\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]",
- Bin: "0x60a06040523480156200001157600080fd5b5060405162001a3d38038062001a3d833981016040819052620000349162000180565b6001600160a01b0381166080523380600081620000985760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000cb57620000cb81620000d5565b50505050620001b2565b336001600160a01b038216036200012f5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200008f565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000602082840312156200019357600080fd5b81516001600160a01b0381168114620001ab57600080fd5b9392505050565b608051611868620001d5600039600081816101c601526109f101526118686000f3fe608060405234801561001057600080fd5b50600436106100c95760003560e01c80636d9809a011610081578063b1e217491161005b578063b1e2174914610182578063f2fde38b1461018b578063f7b4c06f1461019e57600080fd5b80636d9809a01461014857806379ba5097146101525780638da5cb5b1461015a57600080fd5b806342748b2a116100b257806342748b2a146100ff5780634b0795a81461012c5780635fa353e71461013557600080fd5b80630ca76175146100ce5780633944ea3a146100e3575b600080fd5b6100e16100dc3660046112b4565b6101ae565b005b6100ec60035481565b6040519081526020015b60405180910390f35b60055461011790640100000000900463ffffffff1681565b60405163ffffffff90911681526020016100f6565b6100ec60045481565b6100e1610143366004611387565b61022d565b6101176201117081565b6100e1610347565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100f6565b6100ec60025481565b6100e161019936600461146b565b610449565b6005546101179063ffffffff1681565b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161461021d576040517fc6829f8300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61022883838361045d565b505050565b6102356104f2565b61027e6040805161010081019091528060008152602001600081526020016000815260200160608152602001606081526020016060815260200160608152602001606081525090565b6102c089898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525085939250506105759050565b85156103085761030887878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525085939250506105869050565b83156103225761032261031b85876114a1565b82906105d0565b61033961032e82610613565b8462011170856109ec565b600255505050505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146103cd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6104516104f2565b61045a81610acb565b50565b600283905561046b82610bc0565b6003558151600580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff9092169190911790556104ad81610bc0565b600455516005805463ffffffff909216640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff9092169190911790555050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610573576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016103c4565b565b6105828260008084610c42565b5050565b80516000036105c1576040517fe889636f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60016020830152608090910152565b805160000361060b576040517ffe936cb700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c090910152565b60606000610622610100610cd9565b905061066c6040518060400160405280600c81526020017f636f64654c6f636174696f6e000000000000000000000000000000000000000081525082610cfa90919063ffffffff16565b825161068a90600281111561068357610683611539565b8290610d13565b60408051808201909152600881527f6c616e677561676500000000000000000000000000000000000000000000000060208201526106c9908290610cfa565b60408301516106e090801561068357610683611539565b60408051808201909152600681527f736f757263650000000000000000000000000000000000000000000000000000602082015261071f908290610cfa565b606083015161072f908290610cfa565b60a083015151156107895760408051808201909152601081527f726571756573745369676e6174757265000000000000000000000000000000006020820152610779908290610cfa565b60a0830151610789908290610d48565b60c083015151156108365760408051808201909152600481527f617267730000000000000000000000000000000000000000000000000000000060208201526107d3908290610cfa565b6107dc81610d55565b60005b8360c001515181101561082c5761081c8460c00151828151811061080557610805611568565b602002602001015183610cfa90919063ffffffff16565b610825816115c6565b90506107df565b5061083681610d79565b608083015151156109375760008360200151600281111561085957610859611539565b03610890576040517fa80d31f700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051808201909152600f81527f736563726574734c6f636174696f6e000000000000000000000000000000000060208201526108cf908290610cfa565b6108e88360200151600281111561068357610683611539565b60408051808201909152600781527f73656372657473000000000000000000000000000000000000000000000000006020820152610927908290610cfa565b6080830151610937908290610d48565b60e083015151156109e45760408051808201909152600981527f62797465734172677300000000000000000000000000000000000000000000006020820152610981908290610cfa565b61098a81610d55565b60005b8360e00151518110156109da576109ca8460e0015182815181106109b3576109b3611568565b602002602001015183610d4890919063ffffffff16565b6109d3816115c6565b905061098d565b506109e481610d79565b515192915050565b6000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663461d27628688600188886040518663ffffffff1660e01b8152600401610a519594939291906115fe565b6020604051808303816000875af1158015610a70573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a94919061169e565b60405190915081907f1131472297a800fee664d1d89cfa8f7676ff07189ecc53f80bbb5f4969099db890600090a295945050505050565b3373ffffffffffffffffffffffffffffffffffffffff821603610b4a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016103c4565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008060209050602083511015610bd5575081515b60005b81811015610c3b57610beb8160086116b7565b848281518110610bfd57610bfd611568565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016901c9290921791610c34816115c6565b9050610bd8565b5050919050565b8051600003610c7d576040517f22ce3edd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83836002811115610c9057610c90611539565b90816002811115610ca357610ca3611539565b90525060408401828015610cb957610cb9611539565b90818015610cc957610cc9611539565b9052506060909301929092525050565b610ce161116b565b8051610ced9083610d97565b5060006020820152919050565b610d078260038351610e11565b81516102289082610f38565b8151610d209060c2610f60565b506105828282604051602001610d3891815260200190565b6040516020818303038152906040525b610d078260028351610e11565b610d60816004610fc9565b600181602001818151610d7391906116ce565b90525050565b610d84816007610fc9565b600181602001818151610d7391906116e1565b604080518082019091526060815260006020820152610db76020836116f4565b15610ddf57610dc76020836116f4565b610dd29060206116e1565b610ddc90836116ce565b91505b602080840183905260405180855260008152908184010181811015610e0357600080fd5b604052508290505b92915050565b60178167ffffffffffffffff1611610e3e578251610e389060e0600585901b168317610f60565b50505050565b60ff8167ffffffffffffffff1611610e80578251610e67906018611fe0600586901b1617610f60565b508251610e389067ffffffffffffffff83166001610fe0565b61ffff8167ffffffffffffffff1611610ec3578251610eaa906019611fe0600586901b1617610f60565b508251610e389067ffffffffffffffff83166002610fe0565b63ffffffff8167ffffffffffffffff1611610f08578251610eef90601a611fe0600586901b1617610f60565b508251610e389067ffffffffffffffff83166004610fe0565b8251610f1f90601b611fe0600586901b1617610f60565b508251610e389067ffffffffffffffff83166008610fe0565b604080518082019091526060815260006020820152610f5983838451611065565b9392505050565b6040805180820190915260608152600060208201528251516000610f858260016116ce565b905084602001518210610fa657610fa685610fa18360026116b7565b611154565b8451602083820101858153508051821115610fbf578181525b5093949350505050565b815161022890601f611fe0600585901b1617610f60565b604080518082019091526060815260006020820152835151600061100482856116ce565b905085602001518111156110215761102186610fa18360026116b7565b600060016110318661010061184f565b61103b91906116e1565b90508651828101878319825116178152508051831115611059578281525b50959695505050505050565b604080518082019091526060815260006020820152825182111561108857600080fd5b835151600061109784836116ce565b905085602001518111156110b4576110b486610fa18360026116b7565b8551805183820160200191600091808511156110ce578482525b505050602086015b6020861061110e57805182526110ed6020836116ce565b91506110fa6020826116ce565b90506111076020876116e1565b95506110d6565b5181517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60208890036101000a0190811690199190911617905250849150509392505050565b81516111608383610d97565b50610e388382610f38565b6040518060400160405280611193604051806040016040528060608152602001600081525090565b8152602001600081525090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611216576112166111a0565b604052919050565b600067ffffffffffffffff831115611238576112386111a0565b61126960207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116016111cf565b905082815283838301111561127d57600080fd5b828260208301376000602084830101529392505050565b600082601f8301126112a557600080fd5b610f598383356020850161121e565b6000806000606084860312156112c957600080fd5b83359250602084013567ffffffffffffffff808211156112e857600080fd5b6112f487838801611294565b9350604086013591508082111561130a57600080fd5b5061131786828701611294565b9150509250925092565b60008083601f84011261133357600080fd5b50813567ffffffffffffffff81111561134b57600080fd5b60208301915083602082850101111561136357600080fd5b9250929050565b803567ffffffffffffffff8116811461138257600080fd5b919050565b60008060008060008060008060a0898b0312156113a357600080fd5b883567ffffffffffffffff808211156113bb57600080fd5b6113c78c838d01611321565b909a50985060208b01359150808211156113e057600080fd5b6113ec8c838d01611321565b909850965060408b013591508082111561140557600080fd5b818b0191508b601f83011261141957600080fd5b81358181111561142857600080fd5b8c60208260051b850101111561143d57600080fd5b60208301965080955050505061145560608a0161136a565b9150608089013590509295985092959890939650565b60006020828403121561147d57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610f5957600080fd5b600067ffffffffffffffff808411156114bc576114bc6111a0565b8360051b60206114cd8183016111cf565b8681529185019181810190368411156114e557600080fd5b865b8481101561152d578035868111156114ff5760008081fd5b880136601f8201126115115760008081fd5b61151f36823587840161121e565b8452509183019183016114e7565b50979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036115f7576115f7611597565b5060010190565b67ffffffffffffffff861681526000602060a08184015286518060a085015260005b8181101561163c5788810183015185820160c001528201611620565b50600060c0828601015260c07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010192505050611685604083018661ffff169052565b63ffffffff939093166060820152608001529392505050565b6000602082840312156116b057600080fd5b5051919050565b8082028115828204841417610e0b57610e0b611597565b80820180821115610e0b57610e0b611597565b81810381811115610e0b57610e0b611597565b60008261172a577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500690565b600181815b8085111561178857817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561176e5761176e611597565b8085161561177b57918102915b93841c9390800290611734565b509250929050565b60008261179f57506001610e0b565b816117ac57506000610e0b565b81600181146117c257600281146117cc576117e8565b6001915050610e0b565b60ff8411156117dd576117dd611597565b50506001821b610e0b565b5060208310610133831016604e8410600b841016171561180b575081810a610e0b565b611815838361172f565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561184757611847611597565b029392505050565b6000610f59838361179056fea164736f6c6343000813000a",
+ ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"EmptyArgs\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptySecrets\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptySource\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoInlineSecrets\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyRouterCanFulfill\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"RequestFulfilled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"RequestSent\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MAX_CALLBACK_GAS\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStats\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"}],\"name\":\"handleOracleFulfillment\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lastError\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lastRequestID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lastResponse\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"resetStats\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"times\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"cborEncodedRequest\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"donId\",\"type\":\"bytes32\"}],\"name\":\"sendEncodedRequest\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"times\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"source\",\"type\":\"string\"},{\"internalType\":\"bytes\",\"name\":\"encryptedSecretsReferences\",\"type\":\"bytes\"},{\"internalType\":\"string[]\",\"name\":\"args\",\"type\":\"string[]\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"donId\",\"type\":\"bytes32\"}],\"name\":\"sendRequest\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"times\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"source\",\"type\":\"string\"},{\"internalType\":\"uint8\",\"name\":\"slotId\",\"type\":\"uint8\"},{\"internalType\":\"uint64\",\"name\":\"slotVersion\",\"type\":\"uint64\"},{\"internalType\":\"string[]\",\"name\":\"args\",\"type\":\"string[]\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"donId\",\"type\":\"bytes32\"}],\"name\":\"sendRequestWithDONHostedSecrets\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalEmptyResponses\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalFailedResponses\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalRequests\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSucceededResponses\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]",
+ Bin: "0x60a06040523480156200001157600080fd5b50604051620023ff380380620023ff833981016040819052620000349162000180565b6001600160a01b0381166080523380600081620000985760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000cb57620000cb81620000d5565b50505050620001b2565b336001600160a01b038216036200012f5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200008f565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000602082840312156200019357600080fd5b81516001600160a01b0381168114620001ab57600080fd5b9392505050565b60805161222a620001d5600039600081816102ac0152610fa0015261222a6000f3fe608060405234801561001057600080fd5b506004361061011b5760003560e01c806379ba5097116100b2578063954491c111610081578063c59d484711610066578063c59d484714610246578063c9429e2a14610261578063f2fde38b1461028157600080fd5b8063954491c114610220578063b2518e0e1461023357600080fd5b806379ba5097146101cd578063887efe94146101d55780638aea61dc146101e85780638da5cb5b146101f857600080fd5b80635c1d92e9116100ee5780635c1d92e91461019b57806362747e42146101b35780636d9809a0146101bb578063724ec8a2146101c557600080fd5b80630ca761751461012057806329f0de3f146101355780632ab424da1461015357806347c0318614610184575b600080fd5b61013361012e3660046118b4565b610294565b005b61013d61033e565b60405161014a9190611985565b60405180910390f35b60055461016f9068010000000000000000900463ffffffff1681565b60405163ffffffff909116815260200161014a565b61018d60025481565b60405190815260200161014a565b60055461016f90640100000000900463ffffffff1681565b61013d6103cc565b61016f6203d09081565b6101336103d9565b61013361044b565b6101336101e3366004611a57565b61054d565b60055461016f9063ffffffff1681565b60005460405173ffffffffffffffffffffffffffffffffffffffff909116815260200161014a565b61013361022e366004611b1b565b6106bf565b610133610241366004611be1565b6107d5565b61024e610854565b60405161014a9796959493929190611c47565b60055461016f906c01000000000000000000000000900463ffffffff1681565b61013361028f366004611ca4565b6109dc565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610303576040517fc6829f8300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61030e8383836109f0565b60405183907f85e1543bf2f84fe80c6badbce3648c8539ad1df4d2b3d822938ca0538be727e690600090a2505050565b6004805461034b90611cda565b80601f016020809104026020016040519081016040528092919081815260200182805461037790611cda565b80156103c45780601f10610399576101008083540402835291602001916103c4565b820191906000526020600020905b8154815290600101906020018083116103a757829003601f168201915b505050505081565b6003805461034b90611cda565b6103e1610afb565b6000600281905560408051602081019091529081526003906104039082611d7b565b506040805160208101909152600081526004906104209082611d7b565b50600580547fffffffffffffffffffffffffffffffff00000000000000000000000000000000169055565b60015473ffffffffffffffffffffffffffffffffffffffff1633146104d1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610555610afb565b6105966040805160e0810190915280600081526020016000815260200160008152602001606081526020016060815260200160608152602001606081525090565b6105d889898080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508593925050610b7e9050565b85156106205761062087878080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508593925050610b8f9050565b831561063a5761063a6106338587611e95565b8290610bd9565b60005b8a63ffffffff168110156106b25761066261065783610c1c565b856203d09086610f9b565b600255600580546001919060009061068190849063ffffffff16611f5c565b92506101000a81548163ffffffff021916908363ffffffff16021790555080806106aa90611f80565b91505061063d565b5050505050505050505050565b6106c7610afb565b6107086040805160e0810190915280600081526020016000815260200160008152602001606081526020016060815260200160608152602001606081525090565b61074a89898080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508593925050610b7e9050565b61075581888861107a565b8315610768576107686106338587611e95565b60005b8a63ffffffff168110156106b25761078561065783610c1c565b60025560058054600191906000906107a490849063ffffffff16611f5c565b92506101000a81548163ffffffff021916908363ffffffff16021790555080806107cd90611f80565b91505061076b565b6107dd610afb565b60005b8463ffffffff1681101561084d576107fd84846203d09085610f9b565b600255600580546001919060009061081c90849063ffffffff16611f5c565b92506101000a81548163ffffffff021916908363ffffffff160217905550808061084590611f80565b9150506107e0565b5050505050565b6000606080600080600080610867610afb565b60025460055460038054909160049163ffffffff808316926801000000000000000081048216926c0100000000000000000000000082048316926401000000009092049091169086906108b990611cda565b80601f01602080910402602001604051908101604052809291908181526020018280546108e590611cda565b80156109325780601f1061090757610100808354040283529160200191610932565b820191906000526020600020905b81548152906001019060200180831161091557829003601f168201915b5050505050955084805461094590611cda565b80601f016020809104026020016040519081016040528092919081815260200182805461097190611cda565b80156109be5780601f10610993576101008083540402835291602001916109be565b820191906000526020600020905b8154815290600101906020018083116109a157829003601f168201915b50505050509450965096509650965096509650965090919293949596565b6109e4610afb565b6109ed8161113d565b50565b60028390556003610a018382611d7b565b506004610a0e8282611d7b565b508151600003610a59576001600560048282829054906101000a900463ffffffff16610a3a9190611f5c565b92506101000a81548163ffffffff021916908363ffffffff1602179055505b805115610aa15760016005600c8282829054906101000a900463ffffffff16610a829190611f5c565b92506101000a81548163ffffffff021916908363ffffffff1602179055505b815115801590610ab057508051155b15610af6576001600560088282829054906101000a900463ffffffff16610ad79190611f5c565b92506101000a81548163ffffffff021916908363ffffffff1602179055505b505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610b7c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016104c8565b565b610b8b8260008084611232565b5050565b8051600003610bca576040517fe889636f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60016020830152608090910152565b8051600003610c14576040517ffe936cb700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60a090910152565b60606000610c2b6101006112c9565b9050610c756040518060400160405280600c81526020017f636f64654c6f636174696f6e0000000000000000000000000000000000000000815250826112ea90919063ffffffff16565b8251610c93906002811115610c8c57610c8c611fb8565b8290611303565b60408051808201909152600881527f6c616e67756167650000000000000000000000000000000000000000000000006020820152610cd29082906112ea565b6040830151610ce9908015610c8c57610c8c611fb8565b60408051808201909152600681527f736f7572636500000000000000000000000000000000000000000000000000006020820152610d289082906112ea565b6060830151610d389082906112ea565b60a08301515115610de55760408051808201909152600481527f61726773000000000000000000000000000000000000000000000000000000006020820152610d829082906112ea565b610d8b8161133c565b60005b8360a0015151811015610ddb57610dcb8460a001518281518110610db457610db4611fe7565b6020026020010151836112ea90919063ffffffff16565b610dd481611f80565b9050610d8e565b50610de581611360565b60808301515115610ee657600083602001516002811115610e0857610e08611fb8565b03610e3f576040517fa80d31f700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051808201909152600f81527f736563726574734c6f636174696f6e00000000000000000000000000000000006020820152610e7e9082906112ea565b610e9783602001516002811115610c8c57610c8c611fb8565b60408051808201909152600781527f73656372657473000000000000000000000000000000000000000000000000006020820152610ed69082906112ea565b6080830151610ee690829061137e565b60c08301515115610f935760408051808201909152600981527f62797465734172677300000000000000000000000000000000000000000000006020820152610f309082906112ea565b610f398161133c565b60005b8360c0015151811015610f8957610f798460c001518281518110610f6257610f62611fe7565b60200260200101518361137e90919063ffffffff16565b610f8281611f80565b9050610f3c565b50610f9381611360565b515192915050565b6000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663461d27628688600188886040518663ffffffff1660e01b8152600401611000959493929190612016565b6020604051808303816000875af115801561101f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110439190612060565b60405190915081907f1131472297a800fee664d1d89cfa8f7676ff07189ecc53f80bbb5f4969099db890600090a295945050505050565b60006110876101006112c9565b90506110d16040518060400160405280600681526020017f736c6f7449440000000000000000000000000000000000000000000000000000815250826112ea90919063ffffffff16565b6110de8160ff851661138b565b60408051808201909152600781527f76657273696f6e00000000000000000000000000000000000000000000000000602082015261111d9082906112ea565b611127818361138b565b6002602085015251516080909301929092525050565b3373ffffffffffffffffffffffffffffffffffffffff8216036111bc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016104c8565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b805160000361126d576040517f22ce3edd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8383600281111561128057611280611fb8565b9081600281111561129357611293611fb8565b905250604084018280156112a9576112a9611fb8565b908180156112b9576112b9611fb8565b9052506060909301929092525050565b6112d161176b565b80516112dd9083611397565b5060006020820152919050565b6112f78260038351611411565b8151610af69082611538565b81516113109060c2611560565b50610b8b828260405160200161132891815260200190565b60405160208183030381529060405261137e565b6113478160046115c9565b60018160200181815161135a9190612079565b90525050565b61136b8160076115c9565b60018160200181815161135a919061208c565b6112f78260028351611411565b610b8b82600083611411565b6040805180820190915260608152600060208201526113b760208361209f565b156113df576113c760208361209f565b6113d290602061208c565b6113dc9083612079565b91505b60208084018390526040518085526000815290818401018181101561140357600080fd5b604052508290505b92915050565b60178167ffffffffffffffff161161143e5782516114389060e0600585901b168317611560565b50505050565b60ff8167ffffffffffffffff1611611480578251611467906018611fe0600586901b1617611560565b5082516114389067ffffffffffffffff831660016115e0565b61ffff8167ffffffffffffffff16116114c35782516114aa906019611fe0600586901b1617611560565b5082516114389067ffffffffffffffff831660026115e0565b63ffffffff8167ffffffffffffffff16116115085782516114ef90601a611fe0600586901b1617611560565b5082516114389067ffffffffffffffff831660046115e0565b825161151f90601b611fe0600586901b1617611560565b5082516114389067ffffffffffffffff831660086115e0565b60408051808201909152606081526000602082015261155983838451611665565b9392505050565b6040805180820190915260608152600060208201528251516000611585826001612079565b9050846020015182106115a6576115a6856115a18360026120da565b611754565b84516020838201018581535080518211156115bf578181525b5093949350505050565b8151610af690601f611fe0600585901b1617611560565b60408051808201909152606081526000602082015283515160006116048285612079565b9050856020015181111561162157611621866115a18360026120da565b6000600161163186610100612211565b61163b919061208c565b90508651828101878319825116178152508051831115611659578281525b50959695505050505050565b604080518082019091526060815260006020820152825182111561168857600080fd5b83515160006116978483612079565b905085602001518111156116b4576116b4866115a18360026120da565b8551805183820160200191600091808511156116ce578482525b505050602086015b6020861061170e57805182526116ed602083612079565b91506116fa602082612079565b905061170760208761208c565b95506116d6565b5181517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60208890036101000a0190811690199190911617905250849150509392505050565b81516117608383611397565b506114388382611538565b6040518060400160405280611793604051806040016040528060608152602001600081525090565b8152602001600081525090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611816576118166117a0565b604052919050565b600067ffffffffffffffff831115611838576118386117a0565b61186960207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f860116016117cf565b905082815283838301111561187d57600080fd5b828260208301376000602084830101529392505050565b600082601f8301126118a557600080fd5b6115598383356020850161181e565b6000806000606084860312156118c957600080fd5b83359250602084013567ffffffffffffffff808211156118e857600080fd5b6118f487838801611894565b9350604086013591508082111561190a57600080fd5b5061191786828701611894565b9150509250925092565b6000815180845260005b818110156119475760208185018101518683018201520161192b565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b6020815260006115596020830184611921565b803563ffffffff811681146119ac57600080fd5b919050565b60008083601f8401126119c357600080fd5b50813567ffffffffffffffff8111156119db57600080fd5b6020830191508360208285010111156119f357600080fd5b9250929050565b60008083601f840112611a0c57600080fd5b50813567ffffffffffffffff811115611a2457600080fd5b6020830191508360208260051b85010111156119f357600080fd5b803567ffffffffffffffff811681146119ac57600080fd5b600080600080600080600080600060c08a8c031215611a7557600080fd5b611a7e8a611998565b985060208a013567ffffffffffffffff80821115611a9b57600080fd5b611aa78d838e016119b1565b909a50985060408c0135915080821115611ac057600080fd5b611acc8d838e016119b1565b909850965060608c0135915080821115611ae557600080fd5b50611af28c828d016119fa565b9095509350611b05905060808b01611a3f565b915060a08a013590509295985092959850929598565b600080600080600080600080600060e08a8c031215611b3957600080fd5b611b428a611998565b985060208a013567ffffffffffffffff80821115611b5f57600080fd5b611b6b8d838e016119b1565b909a50985060408c0135915060ff82168214611b8657600080fd5b819750611b9560608d01611a3f565b965060808c0135915080821115611bab57600080fd5b50611bb88c828d016119fa565b9095509350611bcb905060a08b01611a3f565b915060c08a013590509295985092959850929598565b60008060008060808587031215611bf757600080fd5b611c0085611998565b9350602085013567ffffffffffffffff811115611c1c57600080fd5b611c2887828801611894565b935050611c3760408601611a3f565b9396929550929360600135925050565b87815260e060208201526000611c6060e0830189611921565b8281036040840152611c728189611921565b63ffffffff97881660608501529587166080840152505091841660a083015290921660c0909201919091529392505050565b600060208284031215611cb657600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461155957600080fd5b600181811c90821680611cee57607f821691505b602082108103611d27577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b601f821115610af657600081815260208120601f850160051c81016020861015611d545750805b601f850160051c820191505b81811015611d7357828155600101611d60565b505050505050565b815167ffffffffffffffff811115611d9557611d956117a0565b611da981611da38454611cda565b84611d2d565b602080601f831160018114611dfc5760008415611dc65750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555611d73565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015611e4957888601518255948401946001909101908401611e2a565b5085821015611e8557878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600067ffffffffffffffff80841115611eb057611eb06117a0565b8360051b6020611ec18183016117cf565b868152918501918181019036841115611ed957600080fd5b865b84811015611f2157803586811115611ef35760008081fd5b880136601f820112611f055760008081fd5b611f1336823587840161181e565b845250918301918301611edb565b50979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b63ffffffff818116838216019080821115611f7957611f79611f2d565b5092915050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611fb157611fb1611f2d565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b67ffffffffffffffff8616815260a06020820152600061203960a0830187611921565b61ffff9590951660408301525063ffffffff92909216606083015260809091015292915050565b60006020828403121561207257600080fd5b5051919050565b8082018082111561140b5761140b611f2d565b8181038181111561140b5761140b611f2d565b6000826120d5577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500690565b808202811582820484141761140b5761140b611f2d565b600181815b8085111561214a57817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561213057612130611f2d565b8085161561213d57918102915b93841c93908002906120f6565b509250929050565b6000826121615750600161140b565b8161216e5750600061140b565b8160018114612184576002811461218e576121aa565b600191505061140b565b60ff84111561219f5761219f611f2d565b50506001821b61140b565b5060208310610133831016604e8410600b84101617156121cd575081810a61140b565b6121d783836120f1565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561220957612209611f2d565b029392505050565b6000611559838361215256fea164736f6c6343000813000a",
}
var FunctionsLoadTestClientABI = FunctionsLoadTestClientMetaData.ABI
@@ -193,31 +193,59 @@ func (_FunctionsLoadTestClient *FunctionsLoadTestClientCallerSession) MAXCALLBAC
return _FunctionsLoadTestClient.Contract.MAXCALLBACKGAS(&_FunctionsLoadTestClient.CallOpts)
}
-func (_FunctionsLoadTestClient *FunctionsLoadTestClientCaller) Owner(opts *bind.CallOpts) (common.Address, error) {
+func (_FunctionsLoadTestClient *FunctionsLoadTestClientCaller) GetStats(opts *bind.CallOpts) ([32]byte, []byte, []byte, uint32, uint32, uint32, uint32, error) {
var out []interface{}
- err := _FunctionsLoadTestClient.contract.Call(opts, &out, "owner")
+ err := _FunctionsLoadTestClient.contract.Call(opts, &out, "getStats")
if err != nil {
- return *new(common.Address), err
+ return *new([32]byte), *new([]byte), *new([]byte), *new(uint32), *new(uint32), *new(uint32), *new(uint32), err
}
- out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address)
+ out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte)
+ out1 := *abi.ConvertType(out[1], new([]byte)).(*[]byte)
+ out2 := *abi.ConvertType(out[2], new([]byte)).(*[]byte)
+ out3 := *abi.ConvertType(out[3], new(uint32)).(*uint32)
+ out4 := *abi.ConvertType(out[4], new(uint32)).(*uint32)
+ out5 := *abi.ConvertType(out[5], new(uint32)).(*uint32)
+ out6 := *abi.ConvertType(out[6], new(uint32)).(*uint32)
+
+ return out0, out1, out2, out3, out4, out5, out6, err
+
+}
+
+func (_FunctionsLoadTestClient *FunctionsLoadTestClientSession) GetStats() ([32]byte, []byte, []byte, uint32, uint32, uint32, uint32, error) {
+ return _FunctionsLoadTestClient.Contract.GetStats(&_FunctionsLoadTestClient.CallOpts)
+}
+
+func (_FunctionsLoadTestClient *FunctionsLoadTestClientCallerSession) GetStats() ([32]byte, []byte, []byte, uint32, uint32, uint32, uint32, error) {
+ return _FunctionsLoadTestClient.Contract.GetStats(&_FunctionsLoadTestClient.CallOpts)
+}
+
+func (_FunctionsLoadTestClient *FunctionsLoadTestClientCaller) LastError(opts *bind.CallOpts) ([]byte, error) {
+ var out []interface{}
+ err := _FunctionsLoadTestClient.contract.Call(opts, &out, "lastError")
+
+ if err != nil {
+ return *new([]byte), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte)
return out0, err
}
-func (_FunctionsLoadTestClient *FunctionsLoadTestClientSession) Owner() (common.Address, error) {
- return _FunctionsLoadTestClient.Contract.Owner(&_FunctionsLoadTestClient.CallOpts)
+func (_FunctionsLoadTestClient *FunctionsLoadTestClientSession) LastError() ([]byte, error) {
+ return _FunctionsLoadTestClient.Contract.LastError(&_FunctionsLoadTestClient.CallOpts)
}
-func (_FunctionsLoadTestClient *FunctionsLoadTestClientCallerSession) Owner() (common.Address, error) {
- return _FunctionsLoadTestClient.Contract.Owner(&_FunctionsLoadTestClient.CallOpts)
+func (_FunctionsLoadTestClient *FunctionsLoadTestClientCallerSession) LastError() ([]byte, error) {
+ return _FunctionsLoadTestClient.Contract.LastError(&_FunctionsLoadTestClient.CallOpts)
}
-func (_FunctionsLoadTestClient *FunctionsLoadTestClientCaller) SLastError(opts *bind.CallOpts) ([32]byte, error) {
+func (_FunctionsLoadTestClient *FunctionsLoadTestClientCaller) LastRequestID(opts *bind.CallOpts) ([32]byte, error) {
var out []interface{}
- err := _FunctionsLoadTestClient.contract.Call(opts, &out, "s_lastError")
+ err := _FunctionsLoadTestClient.contract.Call(opts, &out, "lastRequestID")
if err != nil {
return *new([32]byte), err
@@ -229,17 +257,61 @@ func (_FunctionsLoadTestClient *FunctionsLoadTestClientCaller) SLastError(opts *
}
-func (_FunctionsLoadTestClient *FunctionsLoadTestClientSession) SLastError() ([32]byte, error) {
- return _FunctionsLoadTestClient.Contract.SLastError(&_FunctionsLoadTestClient.CallOpts)
+func (_FunctionsLoadTestClient *FunctionsLoadTestClientSession) LastRequestID() ([32]byte, error) {
+ return _FunctionsLoadTestClient.Contract.LastRequestID(&_FunctionsLoadTestClient.CallOpts)
+}
+
+func (_FunctionsLoadTestClient *FunctionsLoadTestClientCallerSession) LastRequestID() ([32]byte, error) {
+ return _FunctionsLoadTestClient.Contract.LastRequestID(&_FunctionsLoadTestClient.CallOpts)
+}
+
+func (_FunctionsLoadTestClient *FunctionsLoadTestClientCaller) LastResponse(opts *bind.CallOpts) ([]byte, error) {
+ var out []interface{}
+ err := _FunctionsLoadTestClient.contract.Call(opts, &out, "lastResponse")
+
+ if err != nil {
+ return *new([]byte), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte)
+
+ return out0, err
+
+}
+
+func (_FunctionsLoadTestClient *FunctionsLoadTestClientSession) LastResponse() ([]byte, error) {
+ return _FunctionsLoadTestClient.Contract.LastResponse(&_FunctionsLoadTestClient.CallOpts)
+}
+
+func (_FunctionsLoadTestClient *FunctionsLoadTestClientCallerSession) LastResponse() ([]byte, error) {
+ return _FunctionsLoadTestClient.Contract.LastResponse(&_FunctionsLoadTestClient.CallOpts)
+}
+
+func (_FunctionsLoadTestClient *FunctionsLoadTestClientCaller) Owner(opts *bind.CallOpts) (common.Address, error) {
+ var out []interface{}
+ err := _FunctionsLoadTestClient.contract.Call(opts, &out, "owner")
+
+ if err != nil {
+ return *new(common.Address), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address)
+
+ return out0, err
+
+}
+
+func (_FunctionsLoadTestClient *FunctionsLoadTestClientSession) Owner() (common.Address, error) {
+ return _FunctionsLoadTestClient.Contract.Owner(&_FunctionsLoadTestClient.CallOpts)
}
-func (_FunctionsLoadTestClient *FunctionsLoadTestClientCallerSession) SLastError() ([32]byte, error) {
- return _FunctionsLoadTestClient.Contract.SLastError(&_FunctionsLoadTestClient.CallOpts)
+func (_FunctionsLoadTestClient *FunctionsLoadTestClientCallerSession) Owner() (common.Address, error) {
+ return _FunctionsLoadTestClient.Contract.Owner(&_FunctionsLoadTestClient.CallOpts)
}
-func (_FunctionsLoadTestClient *FunctionsLoadTestClientCaller) SLastErrorLength(opts *bind.CallOpts) (uint32, error) {
+func (_FunctionsLoadTestClient *FunctionsLoadTestClientCaller) TotalEmptyResponses(opts *bind.CallOpts) (uint32, error) {
var out []interface{}
- err := _FunctionsLoadTestClient.contract.Call(opts, &out, "s_lastErrorLength")
+ err := _FunctionsLoadTestClient.contract.Call(opts, &out, "totalEmptyResponses")
if err != nil {
return *new(uint32), err
@@ -251,61 +323,61 @@ func (_FunctionsLoadTestClient *FunctionsLoadTestClientCaller) SLastErrorLength(
}
-func (_FunctionsLoadTestClient *FunctionsLoadTestClientSession) SLastErrorLength() (uint32, error) {
- return _FunctionsLoadTestClient.Contract.SLastErrorLength(&_FunctionsLoadTestClient.CallOpts)
+func (_FunctionsLoadTestClient *FunctionsLoadTestClientSession) TotalEmptyResponses() (uint32, error) {
+ return _FunctionsLoadTestClient.Contract.TotalEmptyResponses(&_FunctionsLoadTestClient.CallOpts)
}
-func (_FunctionsLoadTestClient *FunctionsLoadTestClientCallerSession) SLastErrorLength() (uint32, error) {
- return _FunctionsLoadTestClient.Contract.SLastErrorLength(&_FunctionsLoadTestClient.CallOpts)
+func (_FunctionsLoadTestClient *FunctionsLoadTestClientCallerSession) TotalEmptyResponses() (uint32, error) {
+ return _FunctionsLoadTestClient.Contract.TotalEmptyResponses(&_FunctionsLoadTestClient.CallOpts)
}
-func (_FunctionsLoadTestClient *FunctionsLoadTestClientCaller) SLastRequestId(opts *bind.CallOpts) ([32]byte, error) {
+func (_FunctionsLoadTestClient *FunctionsLoadTestClientCaller) TotalFailedResponses(opts *bind.CallOpts) (uint32, error) {
var out []interface{}
- err := _FunctionsLoadTestClient.contract.Call(opts, &out, "s_lastRequestId")
+ err := _FunctionsLoadTestClient.contract.Call(opts, &out, "totalFailedResponses")
if err != nil {
- return *new([32]byte), err
+ return *new(uint32), err
}
- out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte)
+ out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32)
return out0, err
}
-func (_FunctionsLoadTestClient *FunctionsLoadTestClientSession) SLastRequestId() ([32]byte, error) {
- return _FunctionsLoadTestClient.Contract.SLastRequestId(&_FunctionsLoadTestClient.CallOpts)
+func (_FunctionsLoadTestClient *FunctionsLoadTestClientSession) TotalFailedResponses() (uint32, error) {
+ return _FunctionsLoadTestClient.Contract.TotalFailedResponses(&_FunctionsLoadTestClient.CallOpts)
}
-func (_FunctionsLoadTestClient *FunctionsLoadTestClientCallerSession) SLastRequestId() ([32]byte, error) {
- return _FunctionsLoadTestClient.Contract.SLastRequestId(&_FunctionsLoadTestClient.CallOpts)
+func (_FunctionsLoadTestClient *FunctionsLoadTestClientCallerSession) TotalFailedResponses() (uint32, error) {
+ return _FunctionsLoadTestClient.Contract.TotalFailedResponses(&_FunctionsLoadTestClient.CallOpts)
}
-func (_FunctionsLoadTestClient *FunctionsLoadTestClientCaller) SLastResponse(opts *bind.CallOpts) ([32]byte, error) {
+func (_FunctionsLoadTestClient *FunctionsLoadTestClientCaller) TotalRequests(opts *bind.CallOpts) (uint32, error) {
var out []interface{}
- err := _FunctionsLoadTestClient.contract.Call(opts, &out, "s_lastResponse")
+ err := _FunctionsLoadTestClient.contract.Call(opts, &out, "totalRequests")
if err != nil {
- return *new([32]byte), err
+ return *new(uint32), err
}
- out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte)
+ out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32)
return out0, err
}
-func (_FunctionsLoadTestClient *FunctionsLoadTestClientSession) SLastResponse() ([32]byte, error) {
- return _FunctionsLoadTestClient.Contract.SLastResponse(&_FunctionsLoadTestClient.CallOpts)
+func (_FunctionsLoadTestClient *FunctionsLoadTestClientSession) TotalRequests() (uint32, error) {
+ return _FunctionsLoadTestClient.Contract.TotalRequests(&_FunctionsLoadTestClient.CallOpts)
}
-func (_FunctionsLoadTestClient *FunctionsLoadTestClientCallerSession) SLastResponse() ([32]byte, error) {
- return _FunctionsLoadTestClient.Contract.SLastResponse(&_FunctionsLoadTestClient.CallOpts)
+func (_FunctionsLoadTestClient *FunctionsLoadTestClientCallerSession) TotalRequests() (uint32, error) {
+ return _FunctionsLoadTestClient.Contract.TotalRequests(&_FunctionsLoadTestClient.CallOpts)
}
-func (_FunctionsLoadTestClient *FunctionsLoadTestClientCaller) SLastResponseLength(opts *bind.CallOpts) (uint32, error) {
+func (_FunctionsLoadTestClient *FunctionsLoadTestClientCaller) TotalSucceededResponses(opts *bind.CallOpts) (uint32, error) {
var out []interface{}
- err := _FunctionsLoadTestClient.contract.Call(opts, &out, "s_lastResponseLength")
+ err := _FunctionsLoadTestClient.contract.Call(opts, &out, "totalSucceededResponses")
if err != nil {
return *new(uint32), err
@@ -317,12 +389,12 @@ func (_FunctionsLoadTestClient *FunctionsLoadTestClientCaller) SLastResponseLeng
}
-func (_FunctionsLoadTestClient *FunctionsLoadTestClientSession) SLastResponseLength() (uint32, error) {
- return _FunctionsLoadTestClient.Contract.SLastResponseLength(&_FunctionsLoadTestClient.CallOpts)
+func (_FunctionsLoadTestClient *FunctionsLoadTestClientSession) TotalSucceededResponses() (uint32, error) {
+ return _FunctionsLoadTestClient.Contract.TotalSucceededResponses(&_FunctionsLoadTestClient.CallOpts)
}
-func (_FunctionsLoadTestClient *FunctionsLoadTestClientCallerSession) SLastResponseLength() (uint32, error) {
- return _FunctionsLoadTestClient.Contract.SLastResponseLength(&_FunctionsLoadTestClient.CallOpts)
+func (_FunctionsLoadTestClient *FunctionsLoadTestClientCallerSession) TotalSucceededResponses() (uint32, error) {
+ return _FunctionsLoadTestClient.Contract.TotalSucceededResponses(&_FunctionsLoadTestClient.CallOpts)
}
func (_FunctionsLoadTestClient *FunctionsLoadTestClientTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) {
@@ -349,16 +421,52 @@ func (_FunctionsLoadTestClient *FunctionsLoadTestClientTransactorSession) Handle
return _FunctionsLoadTestClient.Contract.HandleOracleFulfillment(&_FunctionsLoadTestClient.TransactOpts, requestId, response, err)
}
-func (_FunctionsLoadTestClient *FunctionsLoadTestClientTransactor) SendRequest(opts *bind.TransactOpts, source string, encryptedSecretsReferences []byte, args []string, subscriptionId uint64, jobId [32]byte) (*types.Transaction, error) {
- return _FunctionsLoadTestClient.contract.Transact(opts, "sendRequest", source, encryptedSecretsReferences, args, subscriptionId, jobId)
+func (_FunctionsLoadTestClient *FunctionsLoadTestClientTransactor) ResetStats(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _FunctionsLoadTestClient.contract.Transact(opts, "resetStats")
+}
+
+func (_FunctionsLoadTestClient *FunctionsLoadTestClientSession) ResetStats() (*types.Transaction, error) {
+ return _FunctionsLoadTestClient.Contract.ResetStats(&_FunctionsLoadTestClient.TransactOpts)
+}
+
+func (_FunctionsLoadTestClient *FunctionsLoadTestClientTransactorSession) ResetStats() (*types.Transaction, error) {
+ return _FunctionsLoadTestClient.Contract.ResetStats(&_FunctionsLoadTestClient.TransactOpts)
+}
+
+func (_FunctionsLoadTestClient *FunctionsLoadTestClientTransactor) SendEncodedRequest(opts *bind.TransactOpts, times uint32, cborEncodedRequest []byte, subscriptionId uint64, donId [32]byte) (*types.Transaction, error) {
+ return _FunctionsLoadTestClient.contract.Transact(opts, "sendEncodedRequest", times, cborEncodedRequest, subscriptionId, donId)
+}
+
+func (_FunctionsLoadTestClient *FunctionsLoadTestClientSession) SendEncodedRequest(times uint32, cborEncodedRequest []byte, subscriptionId uint64, donId [32]byte) (*types.Transaction, error) {
+ return _FunctionsLoadTestClient.Contract.SendEncodedRequest(&_FunctionsLoadTestClient.TransactOpts, times, cborEncodedRequest, subscriptionId, donId)
+}
+
+func (_FunctionsLoadTestClient *FunctionsLoadTestClientTransactorSession) SendEncodedRequest(times uint32, cborEncodedRequest []byte, subscriptionId uint64, donId [32]byte) (*types.Transaction, error) {
+ return _FunctionsLoadTestClient.Contract.SendEncodedRequest(&_FunctionsLoadTestClient.TransactOpts, times, cborEncodedRequest, subscriptionId, donId)
+}
+
+func (_FunctionsLoadTestClient *FunctionsLoadTestClientTransactor) SendRequest(opts *bind.TransactOpts, times uint32, source string, encryptedSecretsReferences []byte, args []string, subscriptionId uint64, donId [32]byte) (*types.Transaction, error) {
+ return _FunctionsLoadTestClient.contract.Transact(opts, "sendRequest", times, source, encryptedSecretsReferences, args, subscriptionId, donId)
}
-func (_FunctionsLoadTestClient *FunctionsLoadTestClientSession) SendRequest(source string, encryptedSecretsReferences []byte, args []string, subscriptionId uint64, jobId [32]byte) (*types.Transaction, error) {
- return _FunctionsLoadTestClient.Contract.SendRequest(&_FunctionsLoadTestClient.TransactOpts, source, encryptedSecretsReferences, args, subscriptionId, jobId)
+func (_FunctionsLoadTestClient *FunctionsLoadTestClientSession) SendRequest(times uint32, source string, encryptedSecretsReferences []byte, args []string, subscriptionId uint64, donId [32]byte) (*types.Transaction, error) {
+ return _FunctionsLoadTestClient.Contract.SendRequest(&_FunctionsLoadTestClient.TransactOpts, times, source, encryptedSecretsReferences, args, subscriptionId, donId)
}
-func (_FunctionsLoadTestClient *FunctionsLoadTestClientTransactorSession) SendRequest(source string, encryptedSecretsReferences []byte, args []string, subscriptionId uint64, jobId [32]byte) (*types.Transaction, error) {
- return _FunctionsLoadTestClient.Contract.SendRequest(&_FunctionsLoadTestClient.TransactOpts, source, encryptedSecretsReferences, args, subscriptionId, jobId)
+func (_FunctionsLoadTestClient *FunctionsLoadTestClientTransactorSession) SendRequest(times uint32, source string, encryptedSecretsReferences []byte, args []string, subscriptionId uint64, donId [32]byte) (*types.Transaction, error) {
+ return _FunctionsLoadTestClient.Contract.SendRequest(&_FunctionsLoadTestClient.TransactOpts, times, source, encryptedSecretsReferences, args, subscriptionId, donId)
+}
+
+func (_FunctionsLoadTestClient *FunctionsLoadTestClientTransactor) SendRequestWithDONHostedSecrets(opts *bind.TransactOpts, times uint32, source string, slotId uint8, slotVersion uint64, args []string, subscriptionId uint64, donId [32]byte) (*types.Transaction, error) {
+ return _FunctionsLoadTestClient.contract.Transact(opts, "sendRequestWithDONHostedSecrets", times, source, slotId, slotVersion, args, subscriptionId, donId)
+}
+
+func (_FunctionsLoadTestClient *FunctionsLoadTestClientSession) SendRequestWithDONHostedSecrets(times uint32, source string, slotId uint8, slotVersion uint64, args []string, subscriptionId uint64, donId [32]byte) (*types.Transaction, error) {
+ return _FunctionsLoadTestClient.Contract.SendRequestWithDONHostedSecrets(&_FunctionsLoadTestClient.TransactOpts, times, source, slotId, slotVersion, args, subscriptionId, donId)
+}
+
+func (_FunctionsLoadTestClient *FunctionsLoadTestClientTransactorSession) SendRequestWithDONHostedSecrets(times uint32, source string, slotId uint8, slotVersion uint64, args []string, subscriptionId uint64, donId [32]byte) (*types.Transaction, error) {
+ return _FunctionsLoadTestClient.Contract.SendRequestWithDONHostedSecrets(&_FunctionsLoadTestClient.TransactOpts, times, source, slotId, slotVersion, args, subscriptionId, donId)
}
func (_FunctionsLoadTestClient *FunctionsLoadTestClientTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) {
@@ -938,23 +1046,35 @@ func (_FunctionsLoadTestClient *FunctionsLoadTestClient) Address() common.Addres
type FunctionsLoadTestClientInterface interface {
MAXCALLBACKGAS(opts *bind.CallOpts) (uint32, error)
- Owner(opts *bind.CallOpts) (common.Address, error)
+ GetStats(opts *bind.CallOpts) ([32]byte, []byte, []byte, uint32, uint32, uint32, uint32, error)
+
+ LastError(opts *bind.CallOpts) ([]byte, error)
- SLastError(opts *bind.CallOpts) ([32]byte, error)
+ LastRequestID(opts *bind.CallOpts) ([32]byte, error)
- SLastErrorLength(opts *bind.CallOpts) (uint32, error)
+ LastResponse(opts *bind.CallOpts) ([]byte, error)
- SLastRequestId(opts *bind.CallOpts) ([32]byte, error)
+ Owner(opts *bind.CallOpts) (common.Address, error)
- SLastResponse(opts *bind.CallOpts) ([32]byte, error)
+ TotalEmptyResponses(opts *bind.CallOpts) (uint32, error)
- SLastResponseLength(opts *bind.CallOpts) (uint32, error)
+ TotalFailedResponses(opts *bind.CallOpts) (uint32, error)
+
+ TotalRequests(opts *bind.CallOpts) (uint32, error)
+
+ TotalSucceededResponses(opts *bind.CallOpts) (uint32, error)
AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error)
HandleOracleFulfillment(opts *bind.TransactOpts, requestId [32]byte, response []byte, err []byte) (*types.Transaction, error)
- SendRequest(opts *bind.TransactOpts, source string, encryptedSecretsReferences []byte, args []string, subscriptionId uint64, jobId [32]byte) (*types.Transaction, error)
+ ResetStats(opts *bind.TransactOpts) (*types.Transaction, error)
+
+ SendEncodedRequest(opts *bind.TransactOpts, times uint32, cborEncodedRequest []byte, subscriptionId uint64, donId [32]byte) (*types.Transaction, error)
+
+ SendRequest(opts *bind.TransactOpts, times uint32, source string, encryptedSecretsReferences []byte, args []string, subscriptionId uint64, donId [32]byte) (*types.Transaction, error)
+
+ SendRequestWithDONHostedSecrets(opts *bind.TransactOpts, times uint32, source string, slotId uint8, slotVersion uint64, args []string, subscriptionId uint64, donId [32]byte) (*types.Transaction, error)
TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error)
diff --git a/core/gethwrappers/functions/generated/functions_router/functions_router.go b/core/gethwrappers/functions/generated/functions_router/functions_router.go
index 83c3f9b6132..2c482048c49 100644
--- a/core/gethwrappers/functions/generated/functions_router/functions_router.go
+++ b/core/gethwrappers/functions/generated/functions_router/functions_router.go
@@ -45,11 +45,13 @@ type FunctionsResponseCommitment struct {
}
type FunctionsRouterConfig struct {
- MaxConsumersPerSubscription uint16
- AdminFee *big.Int
- HandleOracleFulfillmentSelector [4]byte
- GasForCallExactCheck uint16
- MaxCallbackGasLimits []uint32
+ MaxConsumersPerSubscription uint16
+ AdminFee *big.Int
+ HandleOracleFulfillmentSelector [4]byte
+ GasForCallExactCheck uint16
+ MaxCallbackGasLimits []uint32
+ SubscriptionDepositMinimumRequests uint16
+ SubscriptionDepositJuels *big.Int
}
type IFunctionsSubscriptionsConsumer struct {
@@ -68,8 +70,8 @@ type IFunctionsSubscriptionsSubscription struct {
}
var FunctionsRouterMetaData = &bind.MetaData{
- ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint16\",\"name\":\"maxConsumersPerSubscription\",\"type\":\"uint16\"},{\"internalType\":\"uint72\",\"name\":\"adminFee\",\"type\":\"uint72\"},{\"internalType\":\"bytes4\",\"name\":\"handleOracleFulfillmentSelector\",\"type\":\"bytes4\"},{\"internalType\":\"uint16\",\"name\":\"gasForCallExactCheck\",\"type\":\"uint16\"},{\"internalType\":\"uint32[]\",\"name\":\"maxCallbackGasLimits\",\"type\":\"uint32[]\"}],\"internalType\":\"structFunctionsRouter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"CannotRemoveWithPendingRequests\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptyRequestData\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"limit\",\"type\":\"uint32\"}],\"name\":\"GasLimitTooBig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"IdentifierIsReserved\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint96\",\"name\":\"currentBalanceJuels\",\"type\":\"uint96\"}],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidCalldata\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidConsumer\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"value\",\"type\":\"uint8\"}],\"name\":\"InvalidGasFlagValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidProposal\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSubscription\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"proposedOwner\",\"type\":\"address\"}],\"name\":\"MustBeProposedOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeSubscriptionOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableFromCoordinator\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableFromLink\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"RouteNotFound\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderMustAcceptTermsOfService\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TimeoutNotExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"maximumConsumers\",\"type\":\"uint16\"}],\"name\":\"TooManyConsumers\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"totalBalance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"deductionAttempt\",\"type\":\"uint256\"}],\"name\":\"TotalBalanceInvariantViolated\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint16\",\"name\":\"maxConsumersPerSubscription\",\"type\":\"uint16\"},{\"internalType\":\"uint72\",\"name\":\"adminFee\",\"type\":\"uint72\"},{\"internalType\":\"bytes4\",\"name\":\"handleOracleFulfillmentSelector\",\"type\":\"bytes4\"},{\"internalType\":\"uint16\",\"name\":\"gasForCallExactCheck\",\"type\":\"uint16\"},{\"internalType\":\"uint32[]\",\"name\":\"maxCallbackGasLimits\",\"type\":\"uint32[]\"}],\"indexed\":false,\"internalType\":\"structFunctionsRouter.Config\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"ConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"proposedContractSetId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"proposedContractSetFromAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"proposedContractSetToAddress\",\"type\":\"address\"}],\"name\":\"ContractProposed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"ContractUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FundsRecovered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"enumFunctionsResponse.FulfillResult\",\"name\":\"resultCode\",\"type\":\"uint8\"}],\"name\":\"RequestNotProcessed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"totalCostJuels\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"enumFunctionsResponse.FulfillResult\",\"name\":\"resultCode\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"callbackReturnData\",\"type\":\"bytes\"}],\"name\":\"RequestProcessed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"donId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"subscriptionOwner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"requestingContract\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"requestInitiator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"dataVersion\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"estimatedTotalCostJuels\",\"type\":\"uint96\"}],\"name\":\"RequestStart\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"}],\"name\":\"RequestTimedOut\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"fundsRecipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"fundsAmount\",\"type\":\"uint256\"}],\"name\":\"SubscriptionCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"SubscriptionConsumerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"SubscriptionConsumerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"SubscriptionCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newBalance\",\"type\":\"uint256\"}],\"name\":\"SubscriptionFunded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"SubscriptionOwnerTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"SubscriptionOwnerTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MAX_CALLBACK_RETURN_BYTES\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"acceptSubscriptionOwnerTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"addConsumer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"cancelSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"createSubscription\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"createSubscriptionWithConsumer\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"},{\"internalType\":\"uint96\",\"name\":\"juelsPerGas\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"costWithoutCallback\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"estimatedTotalCostJuels\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"client\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint72\",\"name\":\"adminFee\",\"type\":\"uint72\"},{\"internalType\":\"uint72\",\"name\":\"donFee\",\"type\":\"uint72\"},{\"internalType\":\"uint40\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint40\"},{\"internalType\":\"uint32\",\"name\":\"timeoutTimestamp\",\"type\":\"uint32\"}],\"internalType\":\"structFunctionsResponse.Commitment\",\"name\":\"commitment\",\"type\":\"tuple\"}],\"name\":\"fulfill\",\"outputs\":[{\"internalType\":\"enumFunctionsResponse.FulfillResult\",\"name\":\"resultCode\",\"type\":\"uint8\"},{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAdminFee\",\"outputs\":[{\"internalType\":\"uint72\",\"name\":\"\",\"type\":\"uint72\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListId\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint16\",\"name\":\"maxConsumersPerSubscription\",\"type\":\"uint16\"},{\"internalType\":\"uint72\",\"name\":\"adminFee\",\"type\":\"uint72\"},{\"internalType\":\"bytes4\",\"name\":\"handleOracleFulfillmentSelector\",\"type\":\"bytes4\"},{\"internalType\":\"uint16\",\"name\":\"gasForCallExactCheck\",\"type\":\"uint16\"},{\"internalType\":\"uint32[]\",\"name\":\"maxCallbackGasLimits\",\"type\":\"uint32[]\"}],\"internalType\":\"structFunctionsRouter.Config\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"client\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"getConsumer\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"initiatedRequests\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"completedRequests\",\"type\":\"uint64\"}],\"internalType\":\"structIFunctionsSubscriptions.Consumer\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"getContractById\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"getFlags\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"getProposedContractById\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getProposedContractSet\",\"outputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"\",\"type\":\"bytes32[]\"},{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"getSubscription\",\"outputs\":[{\"components\":[{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"blockedBalance\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"proposedOwner\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"consumers\",\"type\":\"address[]\"},{\"internalType\":\"bytes32\",\"name\":\"flags\",\"type\":\"bytes32\"}],\"internalType\":\"structIFunctionsSubscriptions.Subscription\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSubscriptionCount\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTotalBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"}],\"name\":\"isValidCallbackGasLimit\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"onTokenTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"oracleWithdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"ownerCancelSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"ownerWithdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"pendingRequestExists\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"proposedContractSetIds\",\"type\":\"bytes32[]\"},{\"internalType\":\"address[]\",\"name\":\"proposedContractSetAddresses\",\"type\":\"address[]\"}],\"name\":\"proposeContractsUpdate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"proposeSubscriptionOwnerTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"recoverFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"removeConsumer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint16\",\"name\":\"dataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"donId\",\"type\":\"bytes32\"}],\"name\":\"sendRequest\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint16\",\"name\":\"dataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"donId\",\"type\":\"bytes32\"}],\"name\":\"sendRequestToProposed\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"allowListId\",\"type\":\"bytes32\"}],\"name\":\"setAllowListId\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"flags\",\"type\":\"bytes32\"}],\"name\":\"setFlags\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"estimatedTotalCostJuels\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"client\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint72\",\"name\":\"adminFee\",\"type\":\"uint72\"},{\"internalType\":\"uint72\",\"name\":\"donFee\",\"type\":\"uint72\"},{\"internalType\":\"uint40\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint40\"},{\"internalType\":\"uint32\",\"name\":\"timeoutTimestamp\",\"type\":\"uint32\"}],\"internalType\":\"structFunctionsResponse.Commitment[]\",\"name\":\"requestsToTimeoutByCommitment\",\"type\":\"tuple[]\"}],\"name\":\"timeoutRequests\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint16\",\"name\":\"maxConsumersPerSubscription\",\"type\":\"uint16\"},{\"internalType\":\"uint72\",\"name\":\"adminFee\",\"type\":\"uint72\"},{\"internalType\":\"bytes4\",\"name\":\"handleOracleFulfillmentSelector\",\"type\":\"bytes4\"},{\"internalType\":\"uint16\",\"name\":\"gasForCallExactCheck\",\"type\":\"uint16\"},{\"internalType\":\"uint32[]\",\"name\":\"maxCallbackGasLimits\",\"type\":\"uint32[]\"}],\"internalType\":\"structFunctionsRouter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"updateConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updateContracts\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]",
- Bin: "0x60a06040523480156200001157600080fd5b5060405162006254380380620062548339810160408190526200003491620004df565b6001600160a01b0382166080526006805460ff191690553380600081620000a25760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600680546001600160a01b0380851661010002610100600160a81b031990921691909117909155811615620000dc57620000dc81620000f8565b505050620000f081620001aa60201b60201c565b50506200067b565b336001600160a01b03821603620001525760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000099565b600780546001600160a01b0319166001600160a01b03838116918217909255600654604051919261010090910416907fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae127890600090a350565b620001b462000287565b8051600a80546020808501516040860151606087015161ffff908116600160781b0261ffff60781b1960e09390931c6b010000000000000000000000029290921665ffffffffffff60581b196001600160481b0390941662010000026001600160581b031990961691909716179390931716939093171781556080830151805184936200024792600b92910190620002ea565b509050507f049ce2e6e1420eb4b07b425e90129186833eb346bda40b37d5d921aad482f71c816040516200027c9190620005dd565b60405180910390a150565b60065461010090046001600160a01b03163314620002e85760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640162000099565b565b828054828255906000526020600020906007016008900481019282156200038e5791602002820160005b838211156200035a57835183826101000a81548163ffffffff021916908363ffffffff160217905550926020019260040160208160030104928301926001030262000314565b80156200038c5782816101000a81549063ffffffff02191690556004016020816003010492830192600103026200035a565b505b506200039c929150620003a0565b5090565b5b808211156200039c5760008155600101620003a1565b634e487b7160e01b600052604160045260246000fd5b60405160a081016001600160401b0381118282101715620003f257620003f2620003b7565b60405290565b604051601f8201601f191681016001600160401b0381118282101715620004235762000423620003b7565b604052919050565b805161ffff811681146200043e57600080fd5b919050565b600082601f8301126200045557600080fd5b815160206001600160401b03821115620004735762000473620003b7565b8160051b62000484828201620003f8565b92835284810182019282810190878511156200049f57600080fd5b83870192505b84831015620004d457825163ffffffff81168114620004c45760008081fd5b82529183019190830190620004a5565b979650505050505050565b60008060408385031215620004f357600080fd5b82516001600160a01b03811681146200050b57600080fd5b60208401519092506001600160401b03808211156200052957600080fd5b9084019060a082870312156200053e57600080fd5b62000548620003cd565b62000553836200042b565b815260208301516001600160481b03811681146200057057600080fd5b602082015260408301516001600160e01b0319811681146200059157600080fd5b6040820152620005a4606084016200042b565b6060820152608083015182811115620005bc57600080fd5b620005ca8882860162000443565b6080830152508093505050509250929050565b6020808252825161ffff90811683830152838201516001600160481b03166040808501919091528401516001600160e01b0319166060808501919091528401511660808084019190915283015160a080840152805160c0840181905260009291820190839060e08601905b808310156200067057835163ffffffff16825292840192600192909201919084019062000648565b509695505050505050565b608051615ba1620006b3600039600081816113b40152818161218701528181612a7f01528181612b4301526132be0152615ba16000f3fe608060405234801561001057600080fd5b50600436106102de5760003560e01c80637341c10c11610186578063aab396bd116100e3578063d7ae1d3011610097578063e82ad7d411610071578063e82ad7d4146106bf578063ea320e0b146106d2578063f2fde38b146106e557600080fd5b8063d7ae1d3014610686578063e72f6e3014610699578063e82622aa146106ac57600080fd5b8063badc3eb6116100c8578063badc3eb614610648578063c3f909d41461065e578063cc77470a1461067357600080fd5b8063aab396bd14610638578063b734c0f41461064057600080fd5b80639f87fad71161013a578063a47c76961161011f578063a47c7696146105f2578063a4c0ed3614610612578063a9c9a9181461062557600080fd5b80639f87fad7146105d7578063a21a23e4146105ea57600080fd5b8063823597401161016b57806382359740146105995780638456cb59146105ac5780638da5cb5b146105b457600080fd5b80637341c10c1461057e57806379ba50971461059157600080fd5b80633f4ba83a1161023f5780635c975abb116101f357806366419970116101cd57806366419970146104d6578063674603d0146104fd5780636a2215de1461054657600080fd5b80635c975abb146104995780635ed6dfba146104b057806366316d8d146104c357600080fd5b8063461d276211610224578063461d2762146104455780634b8832d31461045857806355fedefa1461046b57600080fd5b80633f4ba83a1461041c57806341db4ca31461042457600080fd5b80631ded3b36116102965780632a905ccc1161027b5780632a905ccc146103ba57806333060529146103e85780633e871e4d1461040957600080fd5b80631ded3b361461039457806321b60e7f146103a757600080fd5b806310fc49c1116102c757806310fc49c11461031857806312b583491461032b578063181f5a771461034b57600080fd5b806302bcc5b6146102e35780630c5d49cb146102f8575b600080fd5b6102f66102f136600461487a565b6106f8565b005b610300608481565b60405161ffff90911681526020015b60405180910390f35b6102f66103263660046148bb565b610757565b6000546040516bffffffffffffffffffffffff909116815260200161030f565b6103876040518060400160405280601781526020017f46756e6374696f6e7320526f757465722076312e302e3000000000000000000081525081565b60405161030f9190614962565b6102f66103a2366004614975565b610853565b6102f66103b5366004614b38565b610885565b600a5462010000900468ffffffffffffffffff1660405168ffffffffffffffffff909116815260200161030f565b6103fb6103f6366004614de4565b6109b2565b60405161030f929190614ecc565b6102f6610417366004614f59565b610d8a565b6102f661100f565b61043761043236600461505b565b611021565b60405190815260200161030f565b61043761045336600461505b565b611081565b6102f66104663660046150df565b61108d565b61043761047936600461487a565b67ffffffffffffffff166000908152600360208190526040909120015490565b60065460ff165b604051901515815260200161030f565b6102f66104be36600461510d565b6111db565b6102f66104d136600461510d565b6113fd565b60025467ffffffffffffffff165b60405167ffffffffffffffff909116815260200161030f565b61051061050b36600461513b565b61154f565b6040805182511515815260208084015167ffffffffffffffff90811691830191909152928201519092169082015260600161030f565b610559610554366004615169565b6115df565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161030f565b6102f661058c3660046150df565b61169e565b6102f6611852565b6102f66105a736600461487a565b611979565b6102f6611ac0565b600654610100900473ffffffffffffffffffffffffffffffffffffffff16610559565b6102f66105e53660046150df565b611ad0565b6104e4611ea5565b61060561060036600461487a565b612032565b60405161030f91906151d3565b6102f661062036600461525b565b612167565b610559610633366004615169565b6123b3565b600954610437565b6102f6612412565b61065061255e565b60405161030f9291906152b7565b61066661262e565b60405161030f919061530e565b6104e46106813660046153b8565b612763565b6102f66106943660046150df565b6129e3565b6102f66106a73660046153b8565b612a46565b6102f66106ba3660046153d5565b612bbf565b6104a06106cd36600461487a565b612e90565b6102f66106e0366004615169565b612fdf565b6102f66106f33660046153b8565b612fec565b610700612ffd565b61070981613005565b67ffffffffffffffff81166000908152600360205260409020546107549082906c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1661307b565b50565b67ffffffffffffffff8216600090815260036020819052604082200154600b54911a9081106107bc576040517f45c108ce00000000000000000000000000000000000000000000000000000000815260ff821660048201526024015b60405180910390fd5b6000600a6001018260ff16815481106107d7576107d761544b565b90600052602060002090600891828204019190066004029054906101000a900463ffffffff1690508063ffffffff168363ffffffff16111561084d576040517f1d70f87a00000000000000000000000000000000000000000000000000000000815263ffffffff821660048201526024016107b3565b50505050565b61085b612ffd565b61086482613005565b67ffffffffffffffff90911660009081526003602081905260409091200155565b61088d613367565b8051600a80546020808501516040860151606087015161ffff9081166f01000000000000000000000000000000027fffffffffffffffffffffffffffffff0000ffffffffffffffffffffffffffffff60e09390931c6b01000000000000000000000002929092167fffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffff68ffffffffffffffffff90941662010000027fffffffffffffffffffffffffffffffffffffffffff0000000000000000000000909616919097161793909317169390931717815560808301518051849361097492600b929101906146c5565b509050507f049ce2e6e1420eb4b07b425e90129186833eb346bda40b37d5d921aad482f71c816040516109a7919061530e565b60405180910390a150565b6000806109bd6133ed565b826020015173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a26576040517f8bec23e700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8251600090815260056020526040902054610a885782516020840151604051600294507f1a90e9a50793db2e394cf581e7c522e10c358a81e70acf6b5a0edd620c08dee191610a78918890879061547a565b60405180910390a2506000610d7f565b8251600090815260056020908152604091829020549151610aab918691016154ac565b6040516020818303038152906040528051906020012014610b035782516020840151604051600694507f1a90e9a50793db2e394cf581e7c522e10c358a81e70acf6b5a0edd620c08dee191610a78918890879061547a565b8261012001518360a0015163ffffffff16610b1e9190615608565b64ffffffffff165a1015610b695782516020840151604051600494507f1a90e9a50793db2e394cf581e7c522e10c358a81e70acf6b5a0edd620c08dee191610a78918890879061547a565b6000610b7e8460a0015163ffffffff166133f5565b610b88908861562d565b9050600081878660c0015168ffffffffffffffffff16610ba89190615655565b610bb29190615655565b9050610bc18560800151612032565b600001516bffffffffffffffffffffffff16816bffffffffffffffffffffffff161115610c395784516020860151604051600596507f1a90e9a50793db2e394cf581e7c522e10c358a81e70acf6b5a0edd620c08dee191610c25918a90899061547a565b60405180910390a25060009150610d7f9050565b84604001516bffffffffffffffffffffffff16816bffffffffffffffffffffffff161115610c9e5784516020860151604051600396507f1a90e9a50793db2e394cf581e7c522e10c358a81e70acf6b5a0edd620c08dee191610c25918a90899061547a565b505082516000908152600560205260408120819055835160a08501516060860151610cce92918c918c9190613497565b8051909150610cde576001610ce1565b60005b92506000610d1b8560800151866040015187606001518860c0015168ffffffffffffffffff168c610d1588602001516133f5565b8d613626565b9050846080015167ffffffffffffffff1685600001517f64778f26c70b60a8d7e29e2451b3844302d959448401c0535b768ed88c6b505e836020015189888f8f8960400151604051610d729695949392919061567a565b60405180910390a3519150505b965096945050505050565b610d92613367565b8151815181141580610da45750600881115b15610ddb576040517fee03280800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610ecd576000848281518110610dfa57610dfa61544b565b602002602001015190506000848381518110610e1857610e1861544b565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161480610e83575060008281526008602052604090205473ffffffffffffffffffffffffffffffffffffffff8281169116145b15610eba576040517fee03280800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505080610ec6906156fd565b9050610dde565b506040805180820190915283815260208082018490528451600c91610ef6918391880190614770565b506020828101518051610f0f92600185019201906147ab565b5090505060005b835181101561084d577f8b052f0f4bf82fede7daffea71592b29d5ef86af1f3c7daaa0345dbb2f52f481848281518110610f5257610f5261544b565b602002602001015160086000878581518110610f7057610f7061544b565b6020026020010151815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16858481518110610fb957610fb961544b565b6020026020010151604051610ff79392919092835273ffffffffffffffffffffffffffffffffffffffff918216602084015216604082015260600190565b60405180910390a1611008816156fd565b9050610f16565b611017613367565b61101f6139a8565b565b60008061102d836115df565b905061107583828a8a8a8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508c92508b9150613a259050565b98975050505050505050565b60008061102d836123b3565b6110956133ed565b61109e82613dce565b6110a6613e94565b73ffffffffffffffffffffffffffffffffffffffff8116158061110d575067ffffffffffffffff821660009081526003602052604090206001015473ffffffffffffffffffffffffffffffffffffffff8281166c0100000000000000000000000090920416145b15611144576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff821660008181526003602090815260409182902060010180546bffffffffffffffffffffffff166c0100000000000000000000000073ffffffffffffffffffffffffffffffffffffffff8716908102919091179091558251338152918201527f69436ea6df009049404f564eff6622cd00522b0bd6a89efd9e52a355c4a879be910160405180910390a25050565b6111e3612ffd565b806bffffffffffffffffffffffff166000036112195750306000908152600160205260409020546bffffffffffffffffffffffff165b306000908152600160205260409020546bffffffffffffffffffffffff908116908216811015611285576040517f6b0fe56f0000000000000000000000000000000000000000000000000000000081526bffffffffffffffffffffffff821660048201526024016107b3565b6000546bffffffffffffffffffffffff808416911610156112ee576000546040517fdda2b2160000000000000000000000000000000000000000000000000000000081526bffffffffffffffffffffffff918216600482015290831660248201526044016107b3565b306000908152600160205260408120805484929061131b9084906bffffffffffffffffffffffff16615735565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550816000808282829054906101000a90046bffffffffffffffffffffffff166113719190615735565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055506113f883836bffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16613f9e9092919063ffffffff16565b505050565b6114056133ed565b806bffffffffffffffffffffffff1660000361144d576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152600160205260409020546bffffffffffffffffffffffff9081169082168110156114b9576040517f6b0fe56f0000000000000000000000000000000000000000000000000000000081526bffffffffffffffffffffffff821660048201526024016107b3565b6000546bffffffffffffffffffffffff80841691161015611522576000546040517fdda2b2160000000000000000000000000000000000000000000000000000000081526bffffffffffffffffffffffff918216600482015290831660248201526044016107b3565b336000908152600160205260408120805484929061131b9084906bffffffffffffffffffffffff16615735565b60408051606080820183526000808352602080840182905292840181905273ffffffffffffffffffffffffffffffffffffffff861681526004835283812067ffffffffffffffff868116835290845290849020845192830185525460ff81161515835261010081048216938301939093526901000000000000000000909204909116918101919091525b92915050565b6000805b600c5460ff8216101561166857600c805460ff83169081106116075761160761544b565b9060005260206000200154830361165857600d805460ff831690811061162f5761162f61544b565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff169392505050565b6116618161575a565b90506115e3565b506040517f80833e33000000000000000000000000000000000000000000000000000000008152600481018390526024016107b3565b6116a66133ed565b6116af82613dce565b6116b7613e94565b60006116c6600a5461ffff1690565b67ffffffffffffffff841660009081526003602052604090206002015490915061ffff82169003611729576040517fb72bc70300000000000000000000000000000000000000000000000000000000815261ffff821660048201526024016107b3565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260046020908152604080832067ffffffffffffffff8716845290915290205460ff161561177157505050565b73ffffffffffffffffffffffffffffffffffffffff8216600081815260046020908152604080832067ffffffffffffffff881680855290835281842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001908117909155600384528285206002018054918201815585529383902090930180547fffffffffffffffffffffffff000000000000000000000000000000000000000016851790555192835290917f43dc749a04ac8fb825cbd514f7c0e13f13bc6f2ee66043b76629d51776cff8e091015b60405180910390a2505050565b60075473ffffffffffffffffffffffffffffffffffffffff1633146118d3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016107b3565b600680547fffffffffffffffffffffff0000000000000000000000000000000000000000ff81166101003381810292909217909355600780547fffffffffffffffffffffffff00000000000000000000000000000000000000001690556040519290910473ffffffffffffffffffffffffffffffffffffffff169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a350565b6119816133ed565b611989613e94565b67ffffffffffffffff81166000908152600360205260409020805460019091015473ffffffffffffffffffffffffffffffffffffffff6c010000000000000000000000009283900481169290910416338114611a29576040517f4e1d9f1800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016107b3565b67ffffffffffffffff831660008181526003602090815260409182902080546c01000000000000000000000000339081026bffffffffffffffffffffffff928316178355600190920180549091169055825173ffffffffffffffffffffffffffffffffffffffff87168152918201527f6f1dc65165ffffedfd8e507b4a0f1fcfdada045ed11f6c26ba27cedfe87802f09101611845565b611ac8613367565b61101f61402b565b611ad86133ed565b611ae182613dce565b611ae9613e94565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260046020908152604080832067ffffffffffffffff8087168552908352928190208151606081018352905460ff8116151580835261010082048616948301949094526901000000000000000000900490931690830152611b91576040517f71e8313700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806040015167ffffffffffffffff16816020015167ffffffffffffffff1614611be6576040517f06eb10c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff8316600090815260036020908152604080832060020180548251818502810185019093528083529192909190830182828015611c6157602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311611c36575b5050505050905060005b8151811015611e09578373ffffffffffffffffffffffffffffffffffffffff16828281518110611c9d57611c9d61544b565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603611df9578160018351611ccf9190615779565b81518110611cdf57611cdf61544b565b6020026020010151600360008767ffffffffffffffff1667ffffffffffffffff1681526020019081526020016000206002018281548110611d2257611d2261544b565b600091825260208083209190910180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff949094169390931790925567ffffffffffffffff87168152600390915260409020600201805480611d9c57611d9c61578c565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055019055611e09565b611e02816156fd565b9050611c6b565b5073ffffffffffffffffffffffffffffffffffffffff8316600081815260046020908152604080832067ffffffffffffffff89168085529083529281902080547fffffffffffffffffffffffffffffff00000000000000000000000000000000001690555192835290917f182bff9831466789164ca77075fffd84916d35a8180ba73c27e45634549b445b91015b60405180910390a250505050565b6000611eaf6133ed565b611eb7613e94565b60028054600090611ed19067ffffffffffffffff166157bb565b825467ffffffffffffffff8083166101009490940a93840293021916919091179091556040805160c0810182526000808252336020830152918101829052606081018290529192506080820190604051908082528060200260200182016040528015611f47578160200160208202803683370190505b5081526000602091820181905267ffffffffffffffff841681526003825260409081902083518484015173ffffffffffffffffffffffffffffffffffffffff9081166c010000000000000000000000009081026bffffffffffffffffffffffff9384161784559386015160608701519091169093029216919091176001820155608083015180519192611fe2926002850192909101906147ab565b5060a0919091015160039091015560405133815267ffffffffffffffff8216907f464722b4166576d3dcbba877b999bc35cf911f4eaf434b7eba68fa113951d0bf9060200160405180910390a290565b6040805160c0810182526000808252602082018190529181018290526060808201839052608082015260a081019190915261206c82613005565b67ffffffffffffffff8216600090815260036020908152604091829020825160c08101845281546bffffffffffffffffffffffff808216835273ffffffffffffffffffffffffffffffffffffffff6c0100000000000000000000000092839004811684870152600185015491821684880152919004166060820152600282018054855181860281018601909652808652919492936080860193929083018282801561214d57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311612122575b505050505081526020016003820154815250509050919050565b61216f6133ed565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146121de576040517f44b0e3c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208114612218576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006122268284018461487a565b67ffffffffffffffff81166000908152600360205260409020549091506c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1661229f576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff8116600090815260036020526040812080546bffffffffffffffffffffffff16918691906122d68385615655565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550846000808282829054906101000a90046bffffffffffffffffffffffff1661232c9190615655565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508167ffffffffffffffff167fd39ec07f4e209f627a4c427971473820dc129761ba28de8906bd56f57101d4f882878461239391906157e2565b6040805192835260208301919091520160405180910390a2505050505050565b60008181526008602052604081205473ffffffffffffffffffffffffffffffffffffffff16806115d9576040517f80833e33000000000000000000000000000000000000000000000000000000008152600481018490526024016107b3565b61241a613367565b60005b600c5481101561253d576000600c600001828154811061243f5761243f61544b565b906000526020600020015490506000600c60010183815481106124645761246461544b565b6000918252602080832091909101548483526008825260409283902054835186815273ffffffffffffffffffffffffffffffffffffffff91821693810193909352169181018290529091507ff8a6175bca1ba37d682089187edc5e20a859989727f10ca6bd9a5bc0de8caf949060600160405180910390a160009182526008602052604090912080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909216919091179055612536816156fd565b905061241d565b50600c600061254c8282614825565b61255a600183016000614825565b5050565b606080600c600001600c600101818054806020026020016040519081016040528092919081815260200182805480156125b657602002820191906000526020600020905b8154815260200190600101908083116125a2575b505050505091508080548060200260200160405190810160405280929190818152602001828054801561261f57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff1681526001909101906020018083116125f4575b50505050509050915091509091565b6040805160a08101825260008082526020820181905291810182905260608082019290925260808101919091526040805160a081018252600a805461ffff808216845268ffffffffffffffffff620100008304166020808601919091527fffffffff000000000000000000000000000000000000000000000000000000006b010000000000000000000000840460e01b16858701526f01000000000000000000000000000000909204166060840152600b80548551818402810184019096528086529394929360808601939283018282801561275557602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff16815260200190600401906020826003010492830192600103820291508084116127185790505b505050505081525050905090565b600061276d6133ed565b612775613e94565b6002805460009061278f9067ffffffffffffffff166157bb565b825467ffffffffffffffff8083166101009490940a93840293021916919091179091556040805160c0810182526000808252336020830152918101829052606081018290529192506080820190604051908082528060200260200182016040528015612805578160200160208202803683370190505b5081526000602091820181905267ffffffffffffffff841681526003825260409081902083518484015173ffffffffffffffffffffffffffffffffffffffff9081166c010000000000000000000000009081026bffffffffffffffffffffffff93841617845593860151606087015190911690930292169190911760018201556080830151805191926128a0926002850192909101906147ab565b5060a0919091015160039182015567ffffffffffffffff82166000818152602092835260408082206002018054600180820183559184528584200180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff891690811790915583526004855281832084845285529181902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169092179091555133815290917f464722b4166576d3dcbba877b999bc35cf911f4eaf434b7eba68fa113951d0bf910160405180910390a260405173ffffffffffffffffffffffffffffffffffffffff8316815267ffffffffffffffff8216907f43dc749a04ac8fb825cbd514f7c0e13f13bc6f2ee66043b76629d51776cff8e09060200160405180910390a2919050565b6129eb6133ed565b6129f482613dce565b6129fc613e94565b612a0582612e90565b15612a3c576040517f06eb10c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61255a828261307b565b612a4e612ffd565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612adb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612aff91906157f5565b6000549091506bffffffffffffffffffffffff16818110156113f8576000612b278284615779565b9050612b6a73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168583613f9e565b6040805173ffffffffffffffffffffffffffffffffffffffff86168152602081018390527f59bfc682b673f8cbf945f1e454df9334834abf7dfe7f92237ca29ecb9b436600910160405180910390a150505050565b612bc76133ed565b60005b818110156113f8576000838383818110612be657612be661544b565b90506101600201803603810190612bfd919061580e565b80516080820151600082815260056020908152604091829020549151949550929391929091612c2e918691016154ac565b6040516020818303038152906040528051906020012014612c7b576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82610140015163ffffffff16421015612cc0576040517fa2376fe800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208301516040517f85b214cf0000000000000000000000000000000000000000000000000000000081526004810184905273ffffffffffffffffffffffffffffffffffffffff909116906385b214cf906024016020604051808303816000875af1158015612d33573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d57919061582b565b5060408084015167ffffffffffffffff831660009081526003602052918220600101805491929091612d989084906bffffffffffffffffffffffff16615735565b82546bffffffffffffffffffffffff9182166101009390930a928302919092021990911617905550606083015173ffffffffffffffffffffffffffffffffffffffff16600090815260046020908152604080832067ffffffffffffffff808616855292529091208054600192600991612e20918591690100000000000000000090041661584d565b825467ffffffffffffffff9182166101009390930a9283029190920219909116179055506000828152600560205260408082208290555183917ff1ca1e9147be737b04a2b018a79405f687a97de8dd8a2559bbe62357343af41491a250505080612e89906156fd565b9050612bca565b67ffffffffffffffff8116600090815260036020908152604080832060020180548251818502810185019093528083528493830182828015612f0857602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311612edd575b5050505050905060005b8151811015612fd557600060046000848481518110612f3357612f3361544b565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040908101600090812067ffffffffffffffff808a168352908452908290208251606081018452905460ff8116151582526101008104831694820185905269010000000000000000009004909116918101829052925014612fc457506001949350505050565b50612fce816156fd565b9050612f12565b5060009392505050565b612fe7613367565b600955565b612ff4613367565b61075481614086565b61101f613367565b67ffffffffffffffff81166000908152600360205260409020546c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff16610754576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff82166000908152600360209081526040808320815160c08101835281546bffffffffffffffffffffffff808216835273ffffffffffffffffffffffffffffffffffffffff6c010000000000000000000000009283900481168488015260018501549182168487015291900416606082015260028201805484518187028101870190955280855291949293608086019390929083018282801561315c57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311613131575b505050918352505060039190910154602090910152805190915060005b82608001515181101561321d5760046000846080015183815181106131a0576131a061544b565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040908101600090812067ffffffffffffffff89168252909252902080547fffffffffffffffffffffffffffffff0000000000000000000000000000000000169055613216816156fd565b9050613179565b5067ffffffffffffffff84166000908152600360205260408120818155600181018290559061324f6002830182614825565b5060006003919091018190558054829190819061327b9084906bffffffffffffffffffffffff16615735565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555061330283826bffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16613f9e9092919063ffffffff16565b6040805173ffffffffffffffffffffffffffffffffffffffff851681526bffffffffffffffffffffffff8316602082015267ffffffffffffffff8616917fe8ed5b475a5b5987aa9165e8731bb78043f39eee32ec5a1169a89e27fcd498159101611e97565b600654610100900473ffffffffffffffffffffffffffffffffffffffff16331461101f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016107b3565b61101f614182565b60006bffffffffffffffffffffffff821115613493576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203960448201527f362062697473000000000000000000000000000000000000000000000000000060648201526084016107b3565b5090565b60408051606080820183526000808352602083015291810191909152600a546040516000916b010000000000000000000000900460e01b906134e19089908990899060240161586e565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152602080830180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009590951694909417909352600a548151608480825260c0820190935292945061ffff6f0100000000000000000000000000000090910416926000928392839282018180368337019050509050863b6135ac57600080fd5b5a848110156135ba57600080fd5b84900360408104810389106135ce57600080fd5b505a60008087516020890160008c8ef193505a900391503d60848111156135f3575060845b808252806000602084013e5060408051606081018252931515845260208401929092529082015298975050505050505050565b60408051808201909152600080825260208201526000613646848661562d565b90506000816136558886615655565b61365f9190615655565b67ffffffffffffffff8b166000908152600360205260409020549091506bffffffffffffffffffffffff808316911610156136f25767ffffffffffffffff8a16600090815260036020526040908190205490517f6b0fe56f0000000000000000000000000000000000000000000000000000000081526bffffffffffffffffffffffff90911660048201526024016107b3565b67ffffffffffffffff8a16600090815260036020526040812080548392906137299084906bffffffffffffffffffffffff16615735565b82546101009290920a6bffffffffffffffffffffffff81810219909316918316021790915567ffffffffffffffff8c166000908152600360205260409020600101548b82169116101590506137d65767ffffffffffffffff8a16600090815260036020526040908190205490517f6b0fe56f0000000000000000000000000000000000000000000000000000000081526bffffffffffffffffffffffff90911660048201526024016107b3565b67ffffffffffffffff8a16600090815260036020526040812060010180548b92906138109084906bffffffffffffffffffffffff16615735565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550818461384a9190615655565b33600090815260016020526040812080549091906138779084906bffffffffffffffffffffffff16615655565b82546101009290920a6bffffffffffffffffffffffff81810219909316918316021790915530600090815260016020526040812080548b945090926138be91859116615655565b82546bffffffffffffffffffffffff9182166101009390930a92830291909202199091161790555073ffffffffffffffffffffffffffffffffffffffff8816600090815260046020908152604080832067ffffffffffffffff808f16855292529091208054600192600991613942918591690100000000000000000090041661584d565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506040518060400160405280836bffffffffffffffffffffffff168152602001826bffffffffffffffffffffffff1681525092505050979650505050505050565b6139b06141ef565b600680547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390a1565b6000613a2f6133ed565b613a3885613005565b613a42338661425b565b613a4c8583610757565b8351600003613a86576040517ec1cfc000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000613a9186612032565b90506000613a9f338861154f565b905060008873ffffffffffffffffffffffffffffffffffffffff1663a631571e6040518061016001604052808a8152602001613af58c67ffffffffffffffff166000908152600360208190526040909120015490565b815233602082015260408781015188519190920191613b1391615735565b6bffffffffffffffffffffffff168152602001600a60000160029054906101000a900468ffffffffffffffffff1668ffffffffffffffffff1681526020018b67ffffffffffffffff168152602001856020015167ffffffffffffffff1681526020018863ffffffff1681526020018961ffff168152602001856040015167ffffffffffffffff168152602001866020015173ffffffffffffffffffffffffffffffffffffffff168152506040518263ffffffff1660e01b8152600401613bd99190615899565b610160604051808303816000875af1158015613bf9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c1d91906159fe565b9050604051806101600160405280826000015181526020018a73ffffffffffffffffffffffffffffffffffffffff16815260200182604001516bffffffffffffffffffffffff1681526020013373ffffffffffffffffffffffffffffffffffffffff1681526020018967ffffffffffffffff1681526020018663ffffffff168152602001600a60000160029054906101000a900468ffffffffffffffffff1668ffffffffffffffffff1681526020018260e0015168ffffffffffffffffff16815260200182610100015164ffffffffff16815260200182610120015164ffffffffff16815260200182610140015163ffffffff16815250604051602001613d2491906154ac565b60405160208183030381529060405280519060200120600560008360000151815260200190815260200160002081905550613d64338983604001516142cf565b8767ffffffffffffffff168a82600001517ff67aec45c9a7ede407974a3e0c3a743dffeab99ee3f2d4c9a8144c2ebf2c7ec9866020015133328d8d8d8a60400151604051613db89796959493929190615ad1565b60405180910390a4519998505050505050505050565b67ffffffffffffffff81166000908152600360205260409020546c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1680613e45576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff82161461255a576040517f5a68151d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60095460009081526008602052604090205473ffffffffffffffffffffffffffffffffffffffff1680613ec45750565b604080516000815260208101918290527f6b14daf80000000000000000000000000000000000000000000000000000000090915273ffffffffffffffffffffffffffffffffffffffff821690636b14daf890613f2590339060248101615b49565b602060405180830381865afa158015613f42573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f66919061582b565b610754576040517f229062630000000000000000000000000000000000000000000000000000000081523360048201526024016107b3565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790526113f89084906143aa565b614033614182565b600680547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586139fb3390565b3373ffffffffffffffffffffffffffffffffffffffff821603614105576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016107b3565b600780547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff838116918217909255600654604051919261010090910416907fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae127890600090a350565b60065460ff161561101f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a207061757365640000000000000000000000000000000060448201526064016107b3565b60065460ff1661101f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5061757361626c653a206e6f742070617573656400000000000000000000000060448201526064016107b3565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260046020908152604080832067ffffffffffffffff8516845290915290205460ff1661255a576040517f71e8313700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff8216600090815260036020526040812060010180548392906143099084906bffffffffffffffffffffffff16615655565b82546bffffffffffffffffffffffff91821661010093840a908102920219161790915573ffffffffffffffffffffffffffffffffffffffff8516600090815260046020908152604080832067ffffffffffffffff808916855292529091208054600194509092849261437f92849290041661584d565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550505050565b600061440c826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166144b69092919063ffffffff16565b8051909150156113f8578080602001905181019061442a919061582b565b6113f8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016107b3565b60606144c584846000856144cd565b949350505050565b60608247101561455f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016107b3565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516145889190615b78565b60006040518083038185875af1925050503d80600081146145c5576040519150601f19603f3d011682016040523d82523d6000602084013e6145ca565b606091505b50915091506145db878383876145e6565b979650505050505050565b6060831561467c5782516000036146755773ffffffffffffffffffffffffffffffffffffffff85163b614675576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016107b3565b50816144c5565b6144c583838151156146915781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107b39190614962565b828054828255906000526020600020906007016008900481019282156147645791602002820160005b8382111561473257835183826101000a81548163ffffffff021916908363ffffffff16021790555092602001926004016020816003010492830192600103026146ee565b80156147625782816101000a81549063ffffffff0219169055600401602081600301049283019260010302614732565b505b5061349392915061483f565b828054828255906000526020600020908101928215614764579160200282015b82811115614764578251825591602001919060010190614790565b828054828255906000526020600020908101928215614764579160200282015b8281111561476457825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9091161782556020909201916001909101906147cb565b508054600082559060005260206000209081019061075491905b5b808211156134935760008155600101614840565b67ffffffffffffffff8116811461075457600080fd5b803561487581614854565b919050565b60006020828403121561488c57600080fd5b813561489781614854565b9392505050565b63ffffffff8116811461075457600080fd5b80356148758161489e565b600080604083850312156148ce57600080fd5b82356148d981614854565b915060208301356148e98161489e565b809150509250929050565b60005b8381101561490f5781810151838201526020016148f7565b50506000910152565b600081518084526149308160208601602086016148f4565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006148976020830184614918565b6000806040838503121561498857600080fd5b823561499381614854565b946020939093013593505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160a0810167ffffffffffffffff811182821017156149f3576149f36149a1565b60405290565b604051610160810167ffffffffffffffff811182821017156149f3576149f36149a1565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614a6457614a646149a1565b604052919050565b803561ffff8116811461487557600080fd5b68ffffffffffffffffff8116811461075457600080fd5b803561487581614a7e565b600067ffffffffffffffff821115614aba57614aba6149a1565b5060051b60200190565b600082601f830112614ad557600080fd5b81356020614aea614ae583614aa0565b614a1d565b82815260059290921b84018101918181019086841115614b0957600080fd5b8286015b84811015614b2d578035614b208161489e565b8352918301918301614b0d565b509695505050505050565b600060208284031215614b4a57600080fd5b813567ffffffffffffffff80821115614b6257600080fd5b9083019060a08286031215614b7657600080fd5b614b7e6149d0565b614b8783614a6c565b81526020830135614b9781614a7e565b602082015260408301357fffffffff0000000000000000000000000000000000000000000000000000000081168114614bcf57600080fd5b6040820152614be060608401614a6c565b6060820152608083013582811115614bf757600080fd5b614c0387828601614ac4565b60808301525095945050505050565b600082601f830112614c2357600080fd5b813567ffffffffffffffff811115614c3d57614c3d6149a1565b614c6e60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614a1d565b818152846020838601011115614c8357600080fd5b816020850160208301376000918101602001919091529392505050565b6bffffffffffffffffffffffff8116811461075457600080fd5b803561487581614ca0565b73ffffffffffffffffffffffffffffffffffffffff8116811461075457600080fd5b803561487581614cc5565b64ffffffffff8116811461075457600080fd5b803561487581614cf2565b60006101608284031215614d2357600080fd5b614d2b6149f9565b905081358152614d3d60208301614ce7565b6020820152614d4e60408301614cba565b6040820152614d5f60608301614ce7565b6060820152614d706080830161486a565b6080820152614d8160a083016148b0565b60a0820152614d9260c08301614a95565b60c0820152614da360e08301614a95565b60e0820152610100614db6818401614d05565b90820152610120614dc8838201614d05565b90820152610140614dda8382016148b0565b9082015292915050565b6000806000806000806102008789031215614dfe57600080fd5b863567ffffffffffffffff80821115614e1657600080fd5b614e228a838b01614c12565b97506020890135915080821115614e3857600080fd5b50614e4589828a01614c12565b9550506040870135614e5681614ca0565b93506060870135614e6681614ca0565b92506080870135614e7681614cc5565b9150614e858860a08901614d10565b90509295509295509295565b60078110614ec8577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b60408101614eda8285614e91565b6bffffffffffffffffffffffff831660208301529392505050565b600082601f830112614f0657600080fd5b81356020614f16614ae583614aa0565b82815260059290921b84018101918181019086841115614f3557600080fd5b8286015b84811015614b2d578035614f4c81614cc5565b8352918301918301614f39565b60008060408385031215614f6c57600080fd5b823567ffffffffffffffff80821115614f8457600080fd5b818501915085601f830112614f9857600080fd5b81356020614fa8614ae583614aa0565b82815260059290921b84018101918181019089841115614fc757600080fd5b948201945b83861015614fe557853582529482019490820190614fcc565b96505086013592505080821115614ffb57600080fd5b5061500885828601614ef5565b9150509250929050565b60008083601f84011261502457600080fd5b50813567ffffffffffffffff81111561503c57600080fd5b60208301915083602082850101111561505457600080fd5b9250929050565b60008060008060008060a0878903121561507457600080fd5b863561507f81614854565b9550602087013567ffffffffffffffff81111561509b57600080fd5b6150a789828a01615012565b90965094506150ba905060408801614a6c565b925060608701356150ca8161489e565b80925050608087013590509295509295509295565b600080604083850312156150f257600080fd5b82356150fd81614854565b915060208301356148e981614cc5565b6000806040838503121561512057600080fd5b823561512b81614cc5565b915060208301356148e981614ca0565b6000806040838503121561514e57600080fd5b823561515981614cc5565b915060208301356148e981614854565b60006020828403121561517b57600080fd5b5035919050565b600081518084526020808501945080840160005b838110156151c857815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101615196565b509495945050505050565b6020815260006bffffffffffffffffffffffff808451166020840152602084015173ffffffffffffffffffffffffffffffffffffffff8082166040860152826040870151166060860152806060870151166080860152505050608083015160c060a084015261524560e0840182615182565b905060a084015160c08401528091505092915050565b6000806000806060858703121561527157600080fd5b843561527c81614cc5565b935060208501359250604085013567ffffffffffffffff81111561529f57600080fd5b6152ab87828801615012565b95989497509550505050565b604080825283519082018190526000906020906060840190828701845b828110156152f0578151845292840192908401906001016152d4565b505050838103828501526153048186615182565b9695505050505050565b6000602080835260c0830161ffff808651168386015268ffffffffffffffffff838701511660408601527fffffffff00000000000000000000000000000000000000000000000000000000604087015116606086015280606087015116608086015250608085015160a08086015281815180845260e0870191508483019350600092505b80831015614b2d57835163ffffffff168252928401926001929092019190840190615392565b6000602082840312156153ca57600080fd5b813561489781614cc5565b600080602083850312156153e857600080fd5b823567ffffffffffffffff8082111561540057600080fd5b818501915085601f83011261541457600080fd5b81358181111561542357600080fd5b8660206101608302850101111561543957600080fd5b60209290920196919550909350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b73ffffffffffffffffffffffffffffffffffffffff848116825283166020820152606081016144c56040830184614e91565b815181526020808301516101608301916154dd9084018273ffffffffffffffffffffffffffffffffffffffff169052565b5060408301516154fd60408401826bffffffffffffffffffffffff169052565b506060830151615525606084018273ffffffffffffffffffffffffffffffffffffffff169052565b506080830151615541608084018267ffffffffffffffff169052565b5060a083015161555960a084018263ffffffff169052565b5060c083015161557660c084018268ffffffffffffffffff169052565b5060e083015161559360e084018268ffffffffffffffffff169052565b506101008381015164ffffffffff81168483015250506101208381015164ffffffffff81168483015250506101408381015163ffffffff8116848301525b505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b64ffffffffff818116838216019080821115615626576156266155d9565b5092915050565b6bffffffffffffffffffffffff8181168382160280821691908281146155d1576155d16155d9565b6bffffffffffffffffffffffff818116838216019080821115615626576156266155d9565b6bffffffffffffffffffffffff8716815273ffffffffffffffffffffffffffffffffffffffff861660208201526156b46040820186614e91565b60c0606082015260006156ca60c0830186614918565b82810360808401526156dc8186614918565b905082810360a08401526156f08185614918565b9998505050505050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361572e5761572e6155d9565b5060010190565b6bffffffffffffffffffffffff828116828216039080821115615626576156266155d9565b600060ff821660ff8103615770576157706155d9565b60010192915050565b818103818111156115d9576115d96155d9565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600067ffffffffffffffff8083168181036157d8576157d86155d9565b6001019392505050565b808201808211156115d9576115d96155d9565b60006020828403121561580757600080fd5b5051919050565b6000610160828403121561582157600080fd5b6148978383614d10565b60006020828403121561583d57600080fd5b8151801515811461489757600080fd5b67ffffffffffffffff818116838216019080821115615626576156266155d9565b8381526060602082015260006158876060830185614918565b82810360408401526153048185614918565b60208152600082516101608060208501526158b8610180850183614918565b91506020850151604085015260408501516158eb606086018273ffffffffffffffffffffffffffffffffffffffff169052565b5060608501516bffffffffffffffffffffffff8116608086015250608085015168ffffffffffffffffff811660a08601525060a085015167ffffffffffffffff811660c08601525060c085015167ffffffffffffffff811660e08601525060e08501516101006159628187018363ffffffff169052565b86015190506101206159798682018361ffff169052565b86015190506101406159968682018367ffffffffffffffff169052565b9095015173ffffffffffffffffffffffffffffffffffffffff1693019290925250919050565b805161487581614cc5565b805161487581614ca0565b805161487581614854565b80516148758161489e565b805161487581614a7e565b805161487581614cf2565b60006101608284031215615a1157600080fd5b615a196149f9565b82518152615a29602084016159bc565b6020820152615a3a604084016159c7565b6040820152615a4b606084016159bc565b6060820152615a5c608084016159d2565b6080820152615a6d60a084016159dd565b60a0820152615a7e60c084016159e8565b60c0820152615a8f60e084016159e8565b60e0820152610100615aa28185016159f3565b90820152610120615ab48482016159f3565b90820152610140615ac68482016159dd565b908201529392505050565b600073ffffffffffffffffffffffffffffffffffffffff808a168352808916602084015280881660408401525060e06060830152615b1260e0830187614918565b61ffff9590951660808301525063ffffffff9290921660a08301526bffffffffffffffffffffffff1660c090910152949350505050565b73ffffffffffffffffffffffffffffffffffffffff831681526040602082015260006144c56040830184614918565b60008251615b8a8184602087016148f4565b919091019291505056fea164736f6c6343000813000a",
+ ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint16\",\"name\":\"maxConsumersPerSubscription\",\"type\":\"uint16\"},{\"internalType\":\"uint72\",\"name\":\"adminFee\",\"type\":\"uint72\"},{\"internalType\":\"bytes4\",\"name\":\"handleOracleFulfillmentSelector\",\"type\":\"bytes4\"},{\"internalType\":\"uint16\",\"name\":\"gasForCallExactCheck\",\"type\":\"uint16\"},{\"internalType\":\"uint32[]\",\"name\":\"maxCallbackGasLimits\",\"type\":\"uint32[]\"},{\"internalType\":\"uint16\",\"name\":\"subscriptionDepositMinimumRequests\",\"type\":\"uint16\"},{\"internalType\":\"uint72\",\"name\":\"subscriptionDepositJuels\",\"type\":\"uint72\"}],\"internalType\":\"structFunctionsRouter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"CannotRemoveWithPendingRequests\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"}],\"name\":\"DuplicateRequestId\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptyRequestData\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"limit\",\"type\":\"uint32\"}],\"name\":\"GasLimitTooBig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"IdentifierIsReserved\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint96\",\"name\":\"currentBalanceJuels\",\"type\":\"uint96\"}],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidCalldata\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidConsumer\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"value\",\"type\":\"uint8\"}],\"name\":\"InvalidGasFlagValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidProposal\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSubscription\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"proposedOwner\",\"type\":\"address\"}],\"name\":\"MustBeProposedOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeSubscriptionOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableFromCoordinator\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableFromLink\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"RouteNotFound\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderMustAcceptTermsOfService\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TimeoutNotExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"maximumConsumers\",\"type\":\"uint16\"}],\"name\":\"TooManyConsumers\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint16\",\"name\":\"maxConsumersPerSubscription\",\"type\":\"uint16\"},{\"internalType\":\"uint72\",\"name\":\"adminFee\",\"type\":\"uint72\"},{\"internalType\":\"bytes4\",\"name\":\"handleOracleFulfillmentSelector\",\"type\":\"bytes4\"},{\"internalType\":\"uint16\",\"name\":\"gasForCallExactCheck\",\"type\":\"uint16\"},{\"internalType\":\"uint32[]\",\"name\":\"maxCallbackGasLimits\",\"type\":\"uint32[]\"},{\"internalType\":\"uint16\",\"name\":\"subscriptionDepositMinimumRequests\",\"type\":\"uint16\"},{\"internalType\":\"uint72\",\"name\":\"subscriptionDepositJuels\",\"type\":\"uint72\"}],\"indexed\":false,\"internalType\":\"structFunctionsRouter.Config\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"ConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"proposedContractSetId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"proposedContractSetFromAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"proposedContractSetToAddress\",\"type\":\"address\"}],\"name\":\"ContractProposed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"ContractUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FundsRecovered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"enumFunctionsResponse.FulfillResult\",\"name\":\"resultCode\",\"type\":\"uint8\"}],\"name\":\"RequestNotProcessed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"totalCostJuels\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"enumFunctionsResponse.FulfillResult\",\"name\":\"resultCode\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"callbackReturnData\",\"type\":\"bytes\"}],\"name\":\"RequestProcessed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"donId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"subscriptionOwner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"requestingContract\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"requestInitiator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"dataVersion\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"estimatedTotalCostJuels\",\"type\":\"uint96\"}],\"name\":\"RequestStart\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"}],\"name\":\"RequestTimedOut\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"fundsRecipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"fundsAmount\",\"type\":\"uint256\"}],\"name\":\"SubscriptionCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"SubscriptionConsumerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"SubscriptionConsumerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"SubscriptionCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newBalance\",\"type\":\"uint256\"}],\"name\":\"SubscriptionFunded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"SubscriptionOwnerTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"SubscriptionOwnerTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MAX_CALLBACK_RETURN_BYTES\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"acceptSubscriptionOwnerTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"addConsumer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"cancelSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"createSubscription\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"createSubscriptionWithConsumer\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"},{\"internalType\":\"uint96\",\"name\":\"juelsPerGas\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"costWithoutCallback\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"estimatedTotalCostJuels\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"client\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint72\",\"name\":\"adminFee\",\"type\":\"uint72\"},{\"internalType\":\"uint72\",\"name\":\"donFee\",\"type\":\"uint72\"},{\"internalType\":\"uint40\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint40\"},{\"internalType\":\"uint32\",\"name\":\"timeoutTimestamp\",\"type\":\"uint32\"}],\"internalType\":\"structFunctionsResponse.Commitment\",\"name\":\"commitment\",\"type\":\"tuple\"}],\"name\":\"fulfill\",\"outputs\":[{\"internalType\":\"enumFunctionsResponse.FulfillResult\",\"name\":\"resultCode\",\"type\":\"uint8\"},{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAdminFee\",\"outputs\":[{\"internalType\":\"uint72\",\"name\":\"\",\"type\":\"uint72\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListId\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint16\",\"name\":\"maxConsumersPerSubscription\",\"type\":\"uint16\"},{\"internalType\":\"uint72\",\"name\":\"adminFee\",\"type\":\"uint72\"},{\"internalType\":\"bytes4\",\"name\":\"handleOracleFulfillmentSelector\",\"type\":\"bytes4\"},{\"internalType\":\"uint16\",\"name\":\"gasForCallExactCheck\",\"type\":\"uint16\"},{\"internalType\":\"uint32[]\",\"name\":\"maxCallbackGasLimits\",\"type\":\"uint32[]\"},{\"internalType\":\"uint16\",\"name\":\"subscriptionDepositMinimumRequests\",\"type\":\"uint16\"},{\"internalType\":\"uint72\",\"name\":\"subscriptionDepositJuels\",\"type\":\"uint72\"}],\"internalType\":\"structFunctionsRouter.Config\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"client\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"getConsumer\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"initiatedRequests\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"completedRequests\",\"type\":\"uint64\"}],\"internalType\":\"structIFunctionsSubscriptions.Consumer\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"getContractById\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"getFlags\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"getProposedContractById\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getProposedContractSet\",\"outputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"\",\"type\":\"bytes32[]\"},{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"getSubscription\",\"outputs\":[{\"components\":[{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"blockedBalance\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"proposedOwner\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"consumers\",\"type\":\"address[]\"},{\"internalType\":\"bytes32\",\"name\":\"flags\",\"type\":\"bytes32\"}],\"internalType\":\"structIFunctionsSubscriptions.Subscription\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSubscriptionCount\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionIdStart\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionIdEnd\",\"type\":\"uint64\"}],\"name\":\"getSubscriptionsInRange\",\"outputs\":[{\"components\":[{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"blockedBalance\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"proposedOwner\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"consumers\",\"type\":\"address[]\"},{\"internalType\":\"bytes32\",\"name\":\"flags\",\"type\":\"bytes32\"}],\"internalType\":\"structIFunctionsSubscriptions.Subscription[]\",\"name\":\"subscriptions\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTotalBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"}],\"name\":\"isValidCallbackGasLimit\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"onTokenTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"oracleWithdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"ownerCancelSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"ownerWithdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"pendingRequestExists\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"proposedContractSetIds\",\"type\":\"bytes32[]\"},{\"internalType\":\"address[]\",\"name\":\"proposedContractSetAddresses\",\"type\":\"address[]\"}],\"name\":\"proposeContractsUpdate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"proposeSubscriptionOwnerTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"recoverFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"removeConsumer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint16\",\"name\":\"dataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"donId\",\"type\":\"bytes32\"}],\"name\":\"sendRequest\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint16\",\"name\":\"dataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"donId\",\"type\":\"bytes32\"}],\"name\":\"sendRequestToProposed\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"allowListId\",\"type\":\"bytes32\"}],\"name\":\"setAllowListId\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"flags\",\"type\":\"bytes32\"}],\"name\":\"setFlags\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"estimatedTotalCostJuels\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"client\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint72\",\"name\":\"adminFee\",\"type\":\"uint72\"},{\"internalType\":\"uint72\",\"name\":\"donFee\",\"type\":\"uint72\"},{\"internalType\":\"uint40\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint40\"},{\"internalType\":\"uint32\",\"name\":\"timeoutTimestamp\",\"type\":\"uint32\"}],\"internalType\":\"structFunctionsResponse.Commitment[]\",\"name\":\"requestsToTimeoutByCommitment\",\"type\":\"tuple[]\"}],\"name\":\"timeoutRequests\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint16\",\"name\":\"maxConsumersPerSubscription\",\"type\":\"uint16\"},{\"internalType\":\"uint72\",\"name\":\"adminFee\",\"type\":\"uint72\"},{\"internalType\":\"bytes4\",\"name\":\"handleOracleFulfillmentSelector\",\"type\":\"bytes4\"},{\"internalType\":\"uint16\",\"name\":\"gasForCallExactCheck\",\"type\":\"uint16\"},{\"internalType\":\"uint32[]\",\"name\":\"maxCallbackGasLimits\",\"type\":\"uint32[]\"},{\"internalType\":\"uint16\",\"name\":\"subscriptionDepositMinimumRequests\",\"type\":\"uint16\"},{\"internalType\":\"uint72\",\"name\":\"subscriptionDepositJuels\",\"type\":\"uint72\"}],\"internalType\":\"structFunctionsRouter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"updateConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updateContracts\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]",
+ Bin: "0x60a06040523480156200001157600080fd5b506040516200673c3803806200673c833981016040819052620000349162000549565b6001600160a01b0382166080526006805460ff191690553380600081620000a25760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600680546001600160a01b0380851661010002610100600160a81b031990921691909117909155811615620000dc57620000dc81620000f8565b505050620000f081620001aa60201b60201c565b50506200071a565b336001600160a01b03821603620001525760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000099565b600780546001600160a01b0319166001600160a01b03838116918217909255600654604051919261010090910416907fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae127890600090a350565b620001b4620002c0565b8051600a80546020808501516040860151606087015161ffff908116600160781b0261ffff60781b1960e09390931c6b010000000000000000000000029290921665ffffffffffff60581b196001600160481b0390941662010000026001600160581b031990961691909716179390931716939093171781556080830151805184936200024792600b9291019062000323565b5060a08201516002909101805460c0909301516001600160481b031662010000026001600160581b031990931661ffff909216919091179190911790556040517ea5832bf95f66c7814294cc4db681f20ee79608bfb8912a5321d66cfed5e98590620002b590839062000652565b60405180910390a150565b60065461010090046001600160a01b03163314620003215760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640162000099565b565b82805482825590600052602060002090600701600890048101928215620003c75791602002820160005b838211156200039357835183826101000a81548163ffffffff021916908363ffffffff16021790555092602001926004016020816003010492830192600103026200034d565b8015620003c55782816101000a81549063ffffffff021916905560040160208160030104928301926001030262000393565b505b50620003d5929150620003d9565b5090565b5b80821115620003d55760008155600101620003da565b634e487b7160e01b600052604160045260246000fd5b60405160e081016001600160401b03811182821017156200042b576200042b620003f0565b60405290565b604051601f8201601f191681016001600160401b03811182821017156200045c576200045c620003f0565b604052919050565b805161ffff811681146200047757600080fd5b919050565b80516001600160481b03811681146200047757600080fd5b80516001600160e01b0319811681146200047757600080fd5b600082601f830112620004bf57600080fd5b815160206001600160401b03821115620004dd57620004dd620003f0565b8160051b620004ee82820162000431565b92835284810182019282810190878511156200050957600080fd5b83870192505b848310156200053e57825163ffffffff811681146200052e5760008081fd5b825291830191908301906200050f565b979650505050505050565b600080604083850312156200055d57600080fd5b82516001600160a01b03811681146200057557600080fd5b60208401519092506001600160401b03808211156200059357600080fd5b9084019060e08287031215620005a857600080fd5b620005b262000406565b620005bd8362000464565b8152620005cd602084016200047c565b6020820152620005e06040840162000494565b6040820152620005f36060840162000464565b60608201526080830151828111156200060b57600080fd5b6200061988828601620004ad565b6080830152506200062d60a0840162000464565b60a08201526200064060c084016200047c565b60c08201528093505050509250929050565b6020808252825161ffff90811683830152838201516001600160481b03166040808501919091528401516001600160e01b0319166060808501919091528401511660808084019190915283015160e060a0840152805161010084018190526000929182019083906101208601905b80831015620006e857835163ffffffff168252928401926001929092019190840190620006c0565b5060a087015161ffff811660c0880152935060c08701516001600160481b03811660e088015293509695505050505050565b608051615fea62000752600039600081816111cd0152818161208c015281816129b801528181612a7c01526135d30152615fea6000f3fe608060405234801561001057600080fd5b50600436106102e95760003560e01c80637341c10c11610191578063b734c0f4116100e3578063e72f6e3011610097578063ea320e0b11610071578063ea320e0b146106dd578063ec2454e5146106f0578063f2fde38b1461071057600080fd5b8063e72f6e30146106a4578063e82622aa146106b7578063e82ad7d4146106ca57600080fd5b8063c3f909d4116100c8578063c3f909d414610669578063cc77470a1461067e578063d7ae1d301461069157600080fd5b8063b734c0f41461064b578063badc3eb61461065357600080fd5b80639f87fad711610145578063a4c0ed361161011f578063a4c0ed361461061d578063a9c9a91814610630578063aab396bd1461064357600080fd5b80639f87fad7146105e2578063a21a23e4146105f5578063a47c7696146105fd57600080fd5b8063823597401161017657806382359740146105a45780638456cb59146105b75780638da5cb5b146105bf57600080fd5b80637341c10c1461058957806379ba50971461059c57600080fd5b806341db4ca31161024a5780635ed6dfba116101fe57806366419970116101d857806366419970146104e1578063674603d0146105085780636a2215de1461055157600080fd5b80635ed6dfba146104a85780636162a323146104bb57806366316d8d146104ce57600080fd5b80634b8832d31161022f5780634b8832d31461045057806355fedefa146104635780635c975abb1461049157600080fd5b806341db4ca31461041c578063461d27621461043d57600080fd5b80631ded3b36116102a1578063330605291161028657806333060529146103e05780633e871e4d146104015780633f4ba83a1461041457600080fd5b80631ded3b361461039f5780632a905ccc146103b257600080fd5b806310fc49c1116102d257806310fc49c11461032357806312b5834914610336578063181f5a771461035657600080fd5b806302bcc5b6146102ee5780630c5d49cb14610303575b600080fd5b6103016102fc366004614ba6565b610723565b005b61030b608481565b60405161ffff90911681526020015b60405180910390f35b610301610331366004614be7565b610783565b6000546040516bffffffffffffffffffffffff909116815260200161031a565b6103926040518060400160405280601781526020017f46756e6374696f6e7320526f757465722076312e302e3000000000000000000081525081565b60405161031a9190614c8e565b6103016103ad366004614ca1565b61087f565b600a5462010000900468ffffffffffffffffff1660405168ffffffffffffffffff909116815260200161031a565b6103f36103ee366004614f8c565b6108b1565b60405161031a929190615074565b61030161040f366004615135565b610c7c565b610301610e91565b61042f61042a366004615249565b610ea3565b60405190815260200161031a565b61042f61044b366004615249565b610f03565b61030161045e3660046152cd565b610f0f565b61042f610471366004614ba6565b67ffffffffffffffff166000908152600360208190526040909120015490565b60065460ff165b604051901515815260200161031a565b6103016104b63660046152fb565b61105d565b6103016104c93660046153bd565b611216565b6103016104dc3660046152fb565b611396565b60025467ffffffffffffffff165b60405167ffffffffffffffff909116815260200161031a565b61051b610516366004615490565b61147f565b6040805182511515815260208084015167ffffffffffffffff90811691830191909152928201519092169082015260600161031a565b61056461055f3660046154be565b61150f565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161031a565b6103016105973660046152cd565b6115ce565b610301611781565b6103016105b2366004614ba6565b6118a8565b6103016119ef565b600654610100900473ffffffffffffffffffffffffffffffffffffffff16610564565b6103016105f03660046152cd565b6119ff565b6104ef611daa565b61061061060b366004614ba6565b611f37565b60405161031a91906155a7565b61030161062b3660046155ba565b61206c565b61056461063e3660046154be565b6122b8565b60095461042f565b610301612317565b61065b612463565b60405161031a929190615616565b610671612533565b60405161031a919061566d565b6104ef61068c366004615749565b61269a565b61030161069f3660046152cd565b61291a565b6103016106b2366004615749565b61297f565b6103016106c5366004615766565b612af8565b6104986106d8366004614ba6565b612db7565b6103016106eb3660046154be565b612f06565b6107036106fe3660046157dc565b612f13565b60405161031a91906157fa565b61030161071e366004615749565b6131a8565b61072b6131b9565b610734816131c1565b67ffffffffffffffff81166000908152600360205260408120546107809183916c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1690613237565b50565b67ffffffffffffffff8216600090815260036020819052604082200154600b54911a9081106107e8576040517f45c108ce00000000000000000000000000000000000000000000000000000000815260ff821660048201526024015b60405180910390fd5b6000600a6001018260ff16815481106108035761080361587a565b90600052602060002090600891828204019190066004029054906101000a900463ffffffff1690508063ffffffff168363ffffffff161115610879576040517f1d70f87a00000000000000000000000000000000000000000000000000000000815263ffffffff821660048201526024016107df565b50505050565b6108876131b9565b610890826131c1565b67ffffffffffffffff90911660009081526003602081905260409091200155565b6000806108bc613689565b826020015173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610925576040517f8bec23e700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82516000908152600560205260409020548061098a5783516020850151604051600295507f1a90e9a50793db2e394cf581e7c522e10c358a81e70acf6b5a0edd620c08dee19161097891899088906158a9565b60405180910390a25060009050610c71565b808460405160200161099c91906158db565b60405160208183030381529060405280519060200120146109f45783516020850151604051600695507f1a90e9a50793db2e394cf581e7c522e10c358a81e70acf6b5a0edd620c08dee19161097891899088906158a9565b8361012001518460a0015163ffffffff16610a0f9190615a37565b64ffffffffff165a1015610a5a5783516020850151604051600495507f1a90e9a50793db2e394cf581e7c522e10c358a81e70acf6b5a0edd620c08dee19161097891899088906158a9565b506000610a708460a0015163ffffffff16613691565b610a7a9088615a55565b9050600081878660c0015168ffffffffffffffffff16610a9a9190615a7d565b610aa49190615a7d565b9050610ab38560800151611f37565b600001516bffffffffffffffffffffffff16816bffffffffffffffffffffffff161115610b2b5784516020860151604051600596507f1a90e9a50793db2e394cf581e7c522e10c358a81e70acf6b5a0edd620c08dee191610b17918a9089906158a9565b60405180910390a25060009150610c719050565b84604001516bffffffffffffffffffffffff16816bffffffffffffffffffffffff161115610b905784516020860151604051600396507f1a90e9a50793db2e394cf581e7c522e10c358a81e70acf6b5a0edd620c08dee191610b17918a9089906158a9565b505082516000908152600560205260408120819055835160a08501516060860151610bc092918c918c9190613733565b8051909150610bd0576001610bd3565b60005b92506000610c0d8560800151866040015187606001518860c0015168ffffffffffffffffff168c610c078860200151613691565b8d6138f1565b9050846080015167ffffffffffffffff1685600001517f64778f26c70b60a8d7e29e2451b3844302d959448401c0535b768ed88c6b505e836020015189888f8f8960400151604051610c6496959493929190615aa2565b60405180910390a3519150505b965096945050505050565b610c84613c17565b8151815181141580610c965750600881115b15610ccd576040517fee03280800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610e47576000848281518110610cec57610cec61587a565b602002602001015190506000848381518110610d0a57610d0a61587a565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161480610d75575060008281526008602052604090205473ffffffffffffffffffffffffffffffffffffffff8281169116145b15610dac576040517fee03280800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260086020526040908190205490517f8b052f0f4bf82fede7daffea71592b29d5ef86af1f3c7daaa0345dbb2f52f48191610e2c91859173ffffffffffffffffffffffffffffffffffffffff1690859092835273ffffffffffffffffffffffffffffffffffffffff918216602084015216604082015260600190565b60405180910390a1505080610e4090615b25565b9050610cd0565b506040805180820190915283815260208082018490528451600d91610e709183918801906149e6565b506020828101518051610e899260018501920190614a2d565b505050505050565b610e99613c17565b610ea1613c9d565b565b600080610eaf8361150f565b9050610ef783828a8a8a8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508c92508b9150613d1a9050565b98975050505050505050565b600080610eaf836122b8565b610f17613689565b610f20826140ef565b610f286141b5565b73ffffffffffffffffffffffffffffffffffffffff81161580610f8f575067ffffffffffffffff821660009081526003602052604090206001015473ffffffffffffffffffffffffffffffffffffffff8281166c0100000000000000000000000090920416145b15610fc6576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff821660008181526003602090815260409182902060010180546bffffffffffffffffffffffff166c0100000000000000000000000073ffffffffffffffffffffffffffffffffffffffff8716908102919091179091558251338152918201527f69436ea6df009049404f564eff6622cd00522b0bd6a89efd9e52a355c4a879be910160405180910390a25050565b6110656131b9565b806bffffffffffffffffffffffff1660000361109b5750306000908152600160205260409020546bffffffffffffffffffffffff165b306000908152600160205260409020546bffffffffffffffffffffffff908116908216811015611107576040517f6b0fe56f0000000000000000000000000000000000000000000000000000000081526bffffffffffffffffffffffff821660048201526024016107df565b30600090815260016020526040812080548492906111349084906bffffffffffffffffffffffff16615b5d565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550816000808282829054906101000a90046bffffffffffffffffffffffff1661118a9190615b5d565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555061121183836bffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166142bf9092919063ffffffff16565b505050565b61121e613c17565b8051600a80546020808501516040860151606087015161ffff9081166f01000000000000000000000000000000027fffffffffffffffffffffffffffffff0000ffffffffffffffffffffffffffffff60e09390931c6b01000000000000000000000002929092167fffffffffffffffffffffffffffffff000000000000ffffffffffffffffffffff68ffffffffffffffffff90941662010000027fffffffffffffffffffffffffffffffffffffffffff0000000000000000000000909616919097161793909317169390931717815560808301518051849361130592600b92910190614aa7565b5060a08201516002909101805460c09093015168ffffffffffffffffff1662010000027fffffffffffffffffffffffffffffffffffffffffff000000000000000000000090931661ffff909216919091179190911790556040517ea5832bf95f66c7814294cc4db681f20ee79608bfb8912a5321d66cfed5e9859061138b90839061566d565b60405180910390a150565b61139e613689565b806bffffffffffffffffffffffff166000036113e6576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152600160205260409020546bffffffffffffffffffffffff908116908216811015611452576040517f6b0fe56f0000000000000000000000000000000000000000000000000000000081526bffffffffffffffffffffffff821660048201526024016107df565b33600090815260016020526040812080548492906111349084906bffffffffffffffffffffffff16615b5d565b60408051606080820183526000808352602080840182905292840181905273ffffffffffffffffffffffffffffffffffffffff861681526004835283812067ffffffffffffffff868116835290845290849020845192830185525460ff81161515835261010081048216938301939093526901000000000000000000909204909116918101919091525b92915050565b6000805b600d5460ff8216101561159857600d805460ff83169081106115375761153761587a565b9060005260206000200154830361158857600e805460ff831690811061155f5761155f61587a565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff169392505050565b61159181615b82565b9050611513565b506040517f80833e33000000000000000000000000000000000000000000000000000000008152600481018390526024016107df565b6115d6613689565b6115df826140ef565b6115e76141b5565b60006115f6600a5461ffff1690565b67ffffffffffffffff841660009081526003602052604090206002015490915061ffff821611611658576040517fb72bc70300000000000000000000000000000000000000000000000000000000815261ffff821660048201526024016107df565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260046020908152604080832067ffffffffffffffff8716845290915290205460ff16156116a057505050565b73ffffffffffffffffffffffffffffffffffffffff8216600081815260046020908152604080832067ffffffffffffffff881680855290835281842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001908117909155600384528285206002018054918201815585529383902090930180547fffffffffffffffffffffffff000000000000000000000000000000000000000016851790555192835290917f43dc749a04ac8fb825cbd514f7c0e13f13bc6f2ee66043b76629d51776cff8e091015b60405180910390a2505050565b60075473ffffffffffffffffffffffffffffffffffffffff163314611802576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016107df565b600680547fffffffffffffffffffffff0000000000000000000000000000000000000000ff81166101003381810292909217909355600780547fffffffffffffffffffffffff00000000000000000000000000000000000000001690556040519290910473ffffffffffffffffffffffffffffffffffffffff169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a350565b6118b0613689565b6118b86141b5565b67ffffffffffffffff81166000908152600360205260409020805460019091015473ffffffffffffffffffffffffffffffffffffffff6c010000000000000000000000009283900481169290910416338114611958576040517f4e1d9f1800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016107df565b67ffffffffffffffff831660008181526003602090815260409182902080546c01000000000000000000000000339081026bffffffffffffffffffffffff928316178355600190920180549091169055825173ffffffffffffffffffffffffffffffffffffffff87168152918201527f6f1dc65165ffffedfd8e507b4a0f1fcfdada045ed11f6c26ba27cedfe87802f09101611774565b6119f7613c17565b610ea161434c565b611a07613689565b611a10826140ef565b611a186141b5565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260046020908152604080832067ffffffffffffffff8087168552908352928190208151606081018352905460ff8116151582526101008104851693820193909352690100000000000000000090920490921691810191909152611a9782846143a7565b806040015167ffffffffffffffff16816020015167ffffffffffffffff1614611aec576040517f06eb10c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff8316600090815260036020908152604080832060020180548251818502810185019093528083529192909190830182828015611b6757602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311611b3c575b5050505050905060005b8151811015611d0f578373ffffffffffffffffffffffffffffffffffffffff16828281518110611ba357611ba361587a565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603611cff578160018351611bd59190615ba1565b81518110611be557611be561587a565b6020026020010151600360008767ffffffffffffffff1667ffffffffffffffff1681526020019081526020016000206002018281548110611c2857611c2861587a565b600091825260208083209190910180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff949094169390931790925567ffffffffffffffff87168152600390915260409020600201805480611ca257611ca2615bb4565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055019055611d0f565b611d0881615b25565b9050611b71565b5073ffffffffffffffffffffffffffffffffffffffff8316600081815260046020908152604080832067ffffffffffffffff89168085529083529281902080547fffffffffffffffffffffffffffffff00000000000000000000000000000000001690555192835290917f182bff9831466789164ca77075fffd84916d35a8180ba73c27e45634549b445b910160405180910390a250505050565b6000611db4613689565b611dbc6141b5565b60028054600090611dd69067ffffffffffffffff16615be3565b825467ffffffffffffffff8083166101009490940a93840293021916919091179091556040805160c0810182526000808252336020830152918101829052606081018290529192506080820190604051908082528060200260200182016040528015611e4c578160200160208202803683370190505b5081526000602091820181905267ffffffffffffffff841681526003825260409081902083518484015173ffffffffffffffffffffffffffffffffffffffff9081166c010000000000000000000000009081026bffffffffffffffffffffffff9384161784559386015160608701519091169093029216919091176001820155608083015180519192611ee792600285019290910190614a2d565b5060a0919091015160039091015560405133815267ffffffffffffffff8216907f464722b4166576d3dcbba877b999bc35cf911f4eaf434b7eba68fa113951d0bf9060200160405180910390a290565b6040805160c0810182526000808252602082018190529181018290526060808201839052608082015260a0810191909152611f71826131c1565b67ffffffffffffffff8216600090815260036020908152604091829020825160c08101845281546bffffffffffffffffffffffff808216835273ffffffffffffffffffffffffffffffffffffffff6c0100000000000000000000000092839004811684870152600185015491821684880152919004166060820152600282018054855181860281018601909652808652919492936080860193929083018282801561205257602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311612027575b505050505081526020016003820154815250509050919050565b612074613689565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146120e3576040517f44b0e3c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020811461211d576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061212b82840184614ba6565b67ffffffffffffffff81166000908152600360205260409020549091506c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff166121a4576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff8116600090815260036020526040812080546bffffffffffffffffffffffff16918691906121db8385615a7d565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550846000808282829054906101000a90046bffffffffffffffffffffffff166122319190615a7d565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508167ffffffffffffffff167fd39ec07f4e209f627a4c427971473820dc129761ba28de8906bd56f57101d4f88287846122989190615c0a565b6040805192835260208301919091520160405180910390a2505050505050565b60008181526008602052604081205473ffffffffffffffffffffffffffffffffffffffff1680611509576040517f80833e33000000000000000000000000000000000000000000000000000000008152600481018490526024016107df565b61231f613c17565b60005b600d54811015612442576000600d60000182815481106123445761234461587a565b906000526020600020015490506000600d60010183815481106123695761236961587a565b6000918252602080832091909101548483526008825260409283902054835186815273ffffffffffffffffffffffffffffffffffffffff91821693810193909352169181018290529091507ff8a6175bca1ba37d682089187edc5e20a859989727f10ca6bd9a5bc0de8caf949060600160405180910390a160009182526008602052604090912080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff90921691909117905561243b81615b25565b9050612322565b50600d60006124518282614b51565b61245f600183016000614b51565b5050565b606080600d600001600d600101818054806020026020016040519081016040528092919081815260200182805480156124bb57602002820191906000526020600020905b8154815260200190600101908083116124a7575b505050505091508080548060200260200160405190810160405280929190818152602001828054801561252457602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff1681526001909101906020018083116124f9575b50505050509050915091509091565b6040805160e0810182526000808252602082018190529181018290526060808201839052608082015260a0810182905260c08101919091526040805160e08082018352600a805461ffff808216855262010000820468ffffffffffffffffff166020808701919091526b010000000000000000000000830490941b7fffffffff0000000000000000000000000000000000000000000000000000000016858701526f01000000000000000000000000000000909104166060840152600b805485518185028101850190965280865293949193608086019383018282801561266557602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff16815260200190600401906020826003010492830192600103820291508084116126285790505b50505091835250506002919091015461ffff8116602083015262010000900468ffffffffffffffffff16604090910152919050565b60006126a4613689565b6126ac6141b5565b600280546000906126c69067ffffffffffffffff16615be3565b825467ffffffffffffffff8083166101009490940a93840293021916919091179091556040805160c081018252600080825233602083015291810182905260608101829052919250608082019060405190808252806020026020018201604052801561273c578160200160208202803683370190505b5081526000602091820181905267ffffffffffffffff841681526003825260409081902083518484015173ffffffffffffffffffffffffffffffffffffffff9081166c010000000000000000000000009081026bffffffffffffffffffffffff93841617845593860151606087015190911690930292169190911760018201556080830151805191926127d792600285019290910190614a2d565b5060a0919091015160039182015567ffffffffffffffff82166000818152602092835260408082206002018054600180820183559184528584200180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff891690811790915583526004855281832084845285529181902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169092179091555133815290917f464722b4166576d3dcbba877b999bc35cf911f4eaf434b7eba68fa113951d0bf910160405180910390a260405173ffffffffffffffffffffffffffffffffffffffff8316815267ffffffffffffffff8216907f43dc749a04ac8fb825cbd514f7c0e13f13bc6f2ee66043b76629d51776cff8e09060200160405180910390a2919050565b612922613689565b61292b826140ef565b6129336141b5565b61293c82612db7565b15612973576040517f06eb10c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61245f82826001613237565b6129876131b9565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612a14573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a389190615c1d565b6000549091506bffffffffffffffffffffffff1681811015611211576000612a608284615ba1565b9050612aa373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001685836142bf565b6040805173ffffffffffffffffffffffffffffffffffffffff86168152602081018390527f59bfc682b673f8cbf945f1e454df9334834abf7dfe7f92237ca29ecb9b436600910160405180910390a150505050565b612b00613689565b60005b81811015611211576000838383818110612b1f57612b1f61587a565b90506101600201803603810190612b369190615c36565b80516080820151600082815260056020908152604091829020549151949550929391929091612b67918691016158db565b6040516020818303038152906040528051906020012014612bb4576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82610140015163ffffffff16421015612bf9576040517fa2376fe800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208301516040517f85b214cf0000000000000000000000000000000000000000000000000000000081526004810184905273ffffffffffffffffffffffffffffffffffffffff909116906385b214cf90602401600060405180830381600087803b158015612c6757600080fd5b505af1158015612c7b573d6000803e3d6000fd5b50505060408085015167ffffffffffffffff84166000908152600360205291822060010180549193509190612cbf9084906bffffffffffffffffffffffff16615b5d565b82546bffffffffffffffffffffffff9182166101009390930a928302919092021990911617905550606083015173ffffffffffffffffffffffffffffffffffffffff16600090815260046020908152604080832067ffffffffffffffff808616855292529091208054600192600991612d479185916901000000000000000000900416615c53565b825467ffffffffffffffff9182166101009390930a9283029190920219909116179055506000828152600560205260408082208290555183917ff1ca1e9147be737b04a2b018a79405f687a97de8dd8a2559bbe62357343af41491a250505080612db090615b25565b9050612b03565b67ffffffffffffffff8116600090815260036020908152604080832060020180548251818502810185019093528083528493830182828015612e2f57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311612e04575b5050505050905060005b8151811015612efc57600060046000848481518110612e5a57612e5a61587a565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040908101600090812067ffffffffffffffff808a168352908452908290208251606081018452905460ff8116151582526101008104831694820185905269010000000000000000009004909116918101829052925014612eeb57506001949350505050565b50612ef581615b25565b9050612e39565b5060009392505050565b612f0e613c17565b600955565b60608167ffffffffffffffff168367ffffffffffffffff161180612f46575060025467ffffffffffffffff908116908316115b80612f5b575060025467ffffffffffffffff16155b15612f92576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612f9c8383615c74565b612fa7906001615c53565b67ffffffffffffffff1667ffffffffffffffff811115612fc957612fc9614ccd565b60405190808252806020026020018201604052801561304657816020015b6040805160c081018252600080825260208083018290529282018190526060808301829052608083015260a082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909201910181612fe75790505b50905060005b6130568484615c74565b67ffffffffffffffff1681116131a1576003600061307e8367ffffffffffffffff8816615c0a565b67ffffffffffffffff1681526020808201929092526040908101600020815160c08101835281546bffffffffffffffffffffffff808216835273ffffffffffffffffffffffffffffffffffffffff6c010000000000000000000000009283900481168488015260018501549182168487015291900416606082015260028201805484518187028101870190955280855291949293608086019390929083018282801561316057602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311613135575b505050505081526020016003820154815250508282815181106131855761318561587a565b60200260200101819052508061319a90615b25565b905061304c565b5092915050565b6131b0613c17565b6107808161441b565b610ea1613c17565b67ffffffffffffffff81166000908152600360205260409020546c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff16610780576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff83166000908152600360209081526040808320815160c08101835281546bffffffffffffffffffffffff808216835273ffffffffffffffffffffffffffffffffffffffff6c010000000000000000000000009283900481168488015260018501549182168487015291900416606082015260028201805484518187028101870190955280855291949293608086019390929083018282801561331857602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff1681526001909101906020018083116132ed575b50505091835250506003919091015460209091015280519091506000805b83608001515181101561342e5760008460800151828151811061335b5761335b61587a565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff8116600090815260048352604080822067ffffffffffffffff808e16845294529020549092506133bb9169010000000000000000009091041684615c53565b73ffffffffffffffffffffffffffffffffffffffff909116600090815260046020908152604080832067ffffffffffffffff8c168452909152902080547fffffffffffffffffffffffffffffff0000000000000000000000000000000000169055915061342781615b25565b9050613336565b5067ffffffffffffffff8616600090815260036020526040812081815560018101829055906134606002830182614b51565b50600060039190910155600c5461ffff81169062010000900468ffffffffffffffffff1685801561349e57508161ffff168367ffffffffffffffff16105b1561355a576000846bffffffffffffffffffffffff168268ffffffffffffffffff16116134d6578168ffffffffffffffffff166134d8565b845b90506bffffffffffffffffffffffff81161561355857306000908152600160205260408120805483929061351b9084906bffffffffffffffffffffffff16615a7d565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555080856135559190615b5d565b94505b505b6bffffffffffffffffffffffff841615613617576000805485919081906135909084906bffffffffffffffffffffffff16615b5d565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555061361787856bffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166142bf9092919063ffffffff16565b6040805173ffffffffffffffffffffffffffffffffffffffff891681526bffffffffffffffffffffffff8616602082015267ffffffffffffffff8a16917fe8ed5b475a5b5987aa9165e8731bb78043f39eee32ec5a1169a89e27fcd49815910160405180910390a25050505050505050565b610ea1614517565b60006bffffffffffffffffffffffff82111561372f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203960448201527f362062697473000000000000000000000000000000000000000000000000000060648201526084016107df565b5090565b60408051606080820183526000808352602083015291810191909152813b1580156137865750506040805160608101825260008082526020808301829052835191825281018352918101919091526138e8565b600a546040516000916b010000000000000000000000900460e01b906137b4908a908a908a90602401615c95565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152602080830180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009590951694909417909352600a548151608480825260c0820190935292945061ffff6f01000000000000000000000000000000909104169260009283928392820181803683370190505090505a8481101561388257600080fd5b8490036040810481038a1061389657600080fd5b505a60008087516020890160008d8ff193505a900391503d60848111156138bb575060845b808252806000602084013e5060408051606081018252931515845260208401929092529082015293505050505b95945050505050565b604080518082019091526000808252602082015260006139118486615a55565b90506000816139208886615a7d565b61392a9190615a7d565b67ffffffffffffffff8b166000908152600360205260409020549091506bffffffffffffffffffffffff80831691161080613991575067ffffffffffffffff8a166000908152600360205260409020600101546bffffffffffffffffffffffff808b169116105b156139f45767ffffffffffffffff8a16600090815260036020526040908190205490517f6b0fe56f0000000000000000000000000000000000000000000000000000000081526bffffffffffffffffffffffff90911660048201526024016107df565b67ffffffffffffffff8a1660009081526003602052604081208054839290613a2b9084906bffffffffffffffffffffffff16615b5d565b82546101009290920a6bffffffffffffffffffffffff81810219909316918316021790915567ffffffffffffffff8c16600090815260036020526040812060010180548d94509092613a7f91859116615b5d565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508184613ab99190615a7d565b3360009081526001602052604081208054909190613ae69084906bffffffffffffffffffffffff16615a7d565b82546101009290920a6bffffffffffffffffffffffff81810219909316918316021790915530600090815260016020526040812080548b94509092613b2d91859116615a7d565b82546bffffffffffffffffffffffff9182166101009390930a92830291909202199091161790555073ffffffffffffffffffffffffffffffffffffffff8816600090815260046020908152604080832067ffffffffffffffff808f16855292529091208054600192600991613bb19185916901000000000000000000900416615c53565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506040518060400160405280836bffffffffffffffffffffffff168152602001826bffffffffffffffffffffffff1681525092505050979650505050505050565b600654610100900473ffffffffffffffffffffffffffffffffffffffff163314610ea1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016107df565b613ca5614584565b600680547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390a1565b6000613d24613689565b613d2d856131c1565b613d3733866143a7565b613d418583610783565b8351600003613d7b576040517ec1cfc000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000613d8686611f37565b90506000613d94338861147f565b600a54604080516101608101825289815267ffffffffffffffff8b1660009081526003602081815293822001549495506201000090930468ffffffffffffffffff169373ffffffffffffffffffffffffffffffffffffffff8d169263a631571e929190820190815233602082015260408881015189519190920191613e1891615b5d565b6bffffffffffffffffffffffff1681526020018568ffffffffffffffffff1681526020018c67ffffffffffffffff168152602001866020015167ffffffffffffffff1681526020018963ffffffff1681526020018a61ffff168152602001866040015167ffffffffffffffff168152602001876020015173ffffffffffffffffffffffffffffffffffffffff168152506040518263ffffffff1660e01b8152600401613ec49190615cc0565b610160604051808303816000875af1158015613ee4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f089190615e25565b805160009081526005602052604090205490915015613f595780516040517f304f32e800000000000000000000000000000000000000000000000000000000815260048101919091526024016107df565b604051806101600160405280826000015181526020018b73ffffffffffffffffffffffffffffffffffffffff16815260200182604001516bffffffffffffffffffffffff1681526020013373ffffffffffffffffffffffffffffffffffffffff1681526020018a67ffffffffffffffff1681526020018763ffffffff1681526020018368ffffffffffffffffff1681526020018260e0015168ffffffffffffffffff16815260200182610100015164ffffffffff16815260200182610120015164ffffffffff16815260200182610140015163ffffffff1681525060405160200161404491906158db565b60405160208183030381529060405280519060200120600560008360000151815260200190815260200160002081905550614084338a83604001516145f0565b8867ffffffffffffffff168b82600001517ff67aec45c9a7ede407974a3e0c3a743dffeab99ee3f2d4c9a8144c2ebf2c7ec9876020015133328e8e8e8a604001516040516140d89796959493929190615ef8565b60405180910390a4519a9950505050505050505050565b67ffffffffffffffff81166000908152600360205260409020546c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1680614166576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff82161461245f576040517f5a68151d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60095460009081526008602052604090205473ffffffffffffffffffffffffffffffffffffffff16806141e55750565b604080516000815260208101918290527f6b14daf80000000000000000000000000000000000000000000000000000000090915273ffffffffffffffffffffffffffffffffffffffff821690636b14daf89061424690339060248101615f70565b602060405180830381865afa158015614263573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906142879190615f9f565b610780576040517f229062630000000000000000000000000000000000000000000000000000000081523360048201526024016107df565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790526112119084906146cb565b614354614517565b600680547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258613cf03390565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260046020908152604080832067ffffffffffffffff8516845290915290205460ff1661245f576040517f71e8313700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff82160361449a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016107df565b600780547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff838116918217909255600654604051919261010090910416907fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae127890600090a350565b60065460ff1615610ea1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a207061757365640000000000000000000000000000000060448201526064016107df565b60065460ff16610ea1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5061757361626c653a206e6f742070617573656400000000000000000000000060448201526064016107df565b67ffffffffffffffff82166000908152600360205260408120600101805483929061462a9084906bffffffffffffffffffffffff16615a7d565b82546bffffffffffffffffffffffff91821661010093840a908102920219161790915573ffffffffffffffffffffffffffffffffffffffff8516600090815260046020908152604080832067ffffffffffffffff80891685529252909120805460019450909284926146a0928492900416615c53565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550505050565b600061472d826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166147d79092919063ffffffff16565b805190915015611211578080602001905181019061474b9190615f9f565b611211576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016107df565b60606147e684846000856147ee565b949350505050565b606082471015614880576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016107df565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516148a99190615fc1565b60006040518083038185875af1925050503d80600081146148e6576040519150601f19603f3d011682016040523d82523d6000602084013e6148eb565b606091505b50915091506148fc87838387614907565b979650505050505050565b6060831561499d5782516000036149965773ffffffffffffffffffffffffffffffffffffffff85163b614996576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016107df565b50816147e6565b6147e683838151156149b25781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107df9190614c8e565b828054828255906000526020600020908101928215614a21579160200282015b82811115614a21578251825591602001919060010190614a06565b5061372f929150614b6b565b828054828255906000526020600020908101928215614a21579160200282015b82811115614a2157825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909116178255602090920191600190910190614a4d565b82805482825590600052602060002090600701600890048101928215614a215791602002820160005b83821115614b1457835183826101000a81548163ffffffff021916908363ffffffff1602179055509260200192600401602081600301049283019260010302614ad0565b8015614b445782816101000a81549063ffffffff0219169055600401602081600301049283019260010302614b14565b505061372f929150614b6b565b508054600082559060005260206000209081019061078091905b5b8082111561372f5760008155600101614b6c565b67ffffffffffffffff8116811461078057600080fd5b8035614ba181614b80565b919050565b600060208284031215614bb857600080fd5b8135614bc381614b80565b9392505050565b63ffffffff8116811461078057600080fd5b8035614ba181614bca565b60008060408385031215614bfa57600080fd5b8235614c0581614b80565b91506020830135614c1581614bca565b809150509250929050565b60005b83811015614c3b578181015183820152602001614c23565b50506000910152565b60008151808452614c5c816020860160208601614c20565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000614bc36020830184614c44565b60008060408385031215614cb457600080fd5b8235614cbf81614b80565b946020939093013593505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610160810167ffffffffffffffff81118282101715614d2057614d20614ccd565b60405290565b60405160e0810167ffffffffffffffff81118282101715614d2057614d20614ccd565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614d9057614d90614ccd565b604052919050565b600082601f830112614da957600080fd5b813567ffffffffffffffff811115614dc357614dc3614ccd565b614df460207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614d49565b818152846020838601011115614e0957600080fd5b816020850160208301376000918101602001919091529392505050565b6bffffffffffffffffffffffff8116811461078057600080fd5b8035614ba181614e26565b73ffffffffffffffffffffffffffffffffffffffff8116811461078057600080fd5b8035614ba181614e4b565b68ffffffffffffffffff8116811461078057600080fd5b8035614ba181614e78565b64ffffffffff8116811461078057600080fd5b8035614ba181614e9a565b60006101608284031215614ecb57600080fd5b614ed3614cfc565b905081358152614ee560208301614e6d565b6020820152614ef660408301614e40565b6040820152614f0760608301614e6d565b6060820152614f1860808301614b96565b6080820152614f2960a08301614bdc565b60a0820152614f3a60c08301614e8f565b60c0820152614f4b60e08301614e8f565b60e0820152610100614f5e818401614ead565b90820152610120614f70838201614ead565b90820152610140614f82838201614bdc565b9082015292915050565b6000806000806000806102008789031215614fa657600080fd5b863567ffffffffffffffff80821115614fbe57600080fd5b614fca8a838b01614d98565b97506020890135915080821115614fe057600080fd5b50614fed89828a01614d98565b9550506040870135614ffe81614e26565b9350606087013561500e81614e26565b9250608087013561501e81614e4b565b915061502d8860a08901614eb8565b90509295509295509295565b60078110615070577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b604081016150828285615039565b6bffffffffffffffffffffffff831660208301529392505050565b600067ffffffffffffffff8211156150b7576150b7614ccd565b5060051b60200190565b600082601f8301126150d257600080fd5b813560206150e76150e28361509d565b614d49565b82815260059290921b8401810191818101908684111561510657600080fd5b8286015b8481101561512a57803561511d81614e4b565b835291830191830161510a565b509695505050505050565b6000806040838503121561514857600080fd5b823567ffffffffffffffff8082111561516057600080fd5b818501915085601f83011261517457600080fd5b813560206151846150e28361509d565b82815260059290921b840181019181810190898411156151a357600080fd5b948201945b838610156151c1578535825294820194908201906151a8565b965050860135925050808211156151d757600080fd5b506151e4858286016150c1565b9150509250929050565b60008083601f84011261520057600080fd5b50813567ffffffffffffffff81111561521857600080fd5b60208301915083602082850101111561523057600080fd5b9250929050565b803561ffff81168114614ba157600080fd5b60008060008060008060a0878903121561526257600080fd5b863561526d81614b80565b9550602087013567ffffffffffffffff81111561528957600080fd5b61529589828a016151ee565b90965094506152a8905060408801615237565b925060608701356152b881614bca565b80925050608087013590509295509295509295565b600080604083850312156152e057600080fd5b82356152eb81614b80565b91506020830135614c1581614e4b565b6000806040838503121561530e57600080fd5b823561531981614e4b565b91506020830135614c1581614e26565b80357fffffffff0000000000000000000000000000000000000000000000000000000081168114614ba157600080fd5b600082601f83011261536a57600080fd5b8135602061537a6150e28361509d565b82815260059290921b8401810191818101908684111561539957600080fd5b8286015b8481101561512a5780356153b081614bca565b835291830191830161539d565b6000602082840312156153cf57600080fd5b813567ffffffffffffffff808211156153e757600080fd5b9083019060e082860312156153fb57600080fd5b615403614d26565b61540c83615237565b815261541a60208401614e8f565b602082015261542b60408401615329565b604082015261543c60608401615237565b606082015260808301358281111561545357600080fd5b61545f87828601615359565b60808301525061547160a08401615237565b60a082015261548260c08401614e8f565b60c082015295945050505050565b600080604083850312156154a357600080fd5b82356154ae81614e4b565b91506020830135614c1581614b80565b6000602082840312156154d057600080fd5b5035919050565b600081518084526020808501945080840160005b8381101561551d57815173ffffffffffffffffffffffffffffffffffffffff16875295820195908201906001016154eb565b509495945050505050565b60006bffffffffffffffffffffffff808351168452602083015173ffffffffffffffffffffffffffffffffffffffff8082166020870152826040860151166040870152806060860151166060870152505050608082015160c0608085015261559360c08501826154d7565b60a093840151949093019390935250919050565b602081526000614bc36020830184615528565b600080600080606085870312156155d057600080fd5b84356155db81614e4b565b935060208501359250604085013567ffffffffffffffff8111156155fe57600080fd5b61560a878288016151ee565b95989497509550505050565b604080825283519082018190526000906020906060840190828701845b8281101561564f57815184529284019290840190600101615633565b5050508381038285015261566381866154d7565b9695505050505050565b60006020808352610100830161ffff808651168386015268ffffffffffffffffff838701511660408601527fffffffff00000000000000000000000000000000000000000000000000000000604087015116606086015280606087015116608086015250608085015160e060a0860152818151808452610120870191508483019350600092505b8083101561571a57835163ffffffff1682529284019260019290920191908401906156f4565b5060a087015161ffff811660c0880152935060c087015168ffffffffffffffffff811660e08801529350615663565b60006020828403121561575b57600080fd5b8135614bc381614e4b565b6000806020838503121561577957600080fd5b823567ffffffffffffffff8082111561579157600080fd5b818501915085601f8301126157a557600080fd5b8135818111156157b457600080fd5b866020610160830285010111156157ca57600080fd5b60209290920196919550909350505050565b600080604083850312156157ef57600080fd5b82356154ae81614b80565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b8281101561586d577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc088860301845261585b858351615528565b94509285019290850190600101615821565b5092979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b73ffffffffffffffffffffffffffffffffffffffff848116825283166020820152606081016147e66040830184615039565b8151815260208083015161016083019161590c9084018273ffffffffffffffffffffffffffffffffffffffff169052565b50604083015161592c60408401826bffffffffffffffffffffffff169052565b506060830151615954606084018273ffffffffffffffffffffffffffffffffffffffff169052565b506080830151615970608084018267ffffffffffffffff169052565b5060a083015161598860a084018263ffffffff169052565b5060c08301516159a560c084018268ffffffffffffffffff169052565b5060e08301516159c260e084018268ffffffffffffffffff169052565b506101008381015164ffffffffff81168483015250506101208381015164ffffffffff81168483015250506101408381015163ffffffff8116848301525b505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b64ffffffffff8181168382160190808211156131a1576131a1615a08565b6bffffffffffffffffffffffff818116838216028082169190828114615a0057615a00615a08565b6bffffffffffffffffffffffff8181168382160190808211156131a1576131a1615a08565b6bffffffffffffffffffffffff8716815273ffffffffffffffffffffffffffffffffffffffff86166020820152615adc6040820186615039565b60c060608201526000615af260c0830186614c44565b8281036080840152615b048186614c44565b905082810360a0840152615b188185614c44565b9998505050505050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203615b5657615b56615a08565b5060010190565b6bffffffffffffffffffffffff8281168282160390808211156131a1576131a1615a08565b600060ff821660ff8103615b9857615b98615a08565b60010192915050565b8181038181111561150957611509615a08565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600067ffffffffffffffff808316818103615c0057615c00615a08565b6001019392505050565b8082018082111561150957611509615a08565b600060208284031215615c2f57600080fd5b5051919050565b60006101608284031215615c4957600080fd5b614bc38383614eb8565b67ffffffffffffffff8181168382160190808211156131a1576131a1615a08565b67ffffffffffffffff8281168282160390808211156131a1576131a1615a08565b838152606060208201526000615cae6060830185614c44565b82810360408401526156638185614c44565b6020815260008251610160806020850152615cdf610180850183614c44565b9150602085015160408501526040850151615d12606086018273ffffffffffffffffffffffffffffffffffffffff169052565b5060608501516bffffffffffffffffffffffff8116608086015250608085015168ffffffffffffffffff811660a08601525060a085015167ffffffffffffffff811660c08601525060c085015167ffffffffffffffff811660e08601525060e0850151610100615d898187018363ffffffff169052565b8601519050610120615da08682018361ffff169052565b8601519050610140615dbd8682018367ffffffffffffffff169052565b9095015173ffffffffffffffffffffffffffffffffffffffff1693019290925250919050565b8051614ba181614e4b565b8051614ba181614e26565b8051614ba181614b80565b8051614ba181614bca565b8051614ba181614e78565b8051614ba181614e9a565b60006101608284031215615e3857600080fd5b615e40614cfc565b82518152615e5060208401615de3565b6020820152615e6160408401615dee565b6040820152615e7260608401615de3565b6060820152615e8360808401615df9565b6080820152615e9460a08401615e04565b60a0820152615ea560c08401615e0f565b60c0820152615eb660e08401615e0f565b60e0820152610100615ec9818501615e1a565b90820152610120615edb848201615e1a565b90820152610140615eed848201615e04565b908201529392505050565b600073ffffffffffffffffffffffffffffffffffffffff808a168352808916602084015280881660408401525060e06060830152615f3960e0830187614c44565b61ffff9590951660808301525063ffffffff9290921660a08301526bffffffffffffffffffffffff1660c090910152949350505050565b73ffffffffffffffffffffffffffffffffffffffff831681526040602082015260006147e66040830184614c44565b600060208284031215615fb157600080fd5b81518015158114614bc357600080fd5b60008251615fd3818460208701614c20565b919091019291505056fea164736f6c6343000813000a",
}
var FunctionsRouterABI = FunctionsRouterMetaData.ABI
@@ -451,6 +453,28 @@ func (_FunctionsRouter *FunctionsRouterCallerSession) GetSubscriptionCount() (ui
return _FunctionsRouter.Contract.GetSubscriptionCount(&_FunctionsRouter.CallOpts)
}
+func (_FunctionsRouter *FunctionsRouterCaller) GetSubscriptionsInRange(opts *bind.CallOpts, subscriptionIdStart uint64, subscriptionIdEnd uint64) ([]IFunctionsSubscriptionsSubscription, error) {
+ var out []interface{}
+ err := _FunctionsRouter.contract.Call(opts, &out, "getSubscriptionsInRange", subscriptionIdStart, subscriptionIdEnd)
+
+ if err != nil {
+ return *new([]IFunctionsSubscriptionsSubscription), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new([]IFunctionsSubscriptionsSubscription)).(*[]IFunctionsSubscriptionsSubscription)
+
+ return out0, err
+
+}
+
+func (_FunctionsRouter *FunctionsRouterSession) GetSubscriptionsInRange(subscriptionIdStart uint64, subscriptionIdEnd uint64) ([]IFunctionsSubscriptionsSubscription, error) {
+ return _FunctionsRouter.Contract.GetSubscriptionsInRange(&_FunctionsRouter.CallOpts, subscriptionIdStart, subscriptionIdEnd)
+}
+
+func (_FunctionsRouter *FunctionsRouterCallerSession) GetSubscriptionsInRange(subscriptionIdStart uint64, subscriptionIdEnd uint64) ([]IFunctionsSubscriptionsSubscription, error) {
+ return _FunctionsRouter.Contract.GetSubscriptionsInRange(&_FunctionsRouter.CallOpts, subscriptionIdStart, subscriptionIdEnd)
+}
+
func (_FunctionsRouter *FunctionsRouterCaller) GetTotalBalance(opts *bind.CallOpts) (*big.Int, error) {
var out []interface{}
err := _FunctionsRouter.contract.Call(opts, &out, "getTotalBalance")
@@ -3358,7 +3382,7 @@ func (_FunctionsRouter *FunctionsRouter) ParseLog(log types.Log) (generated.Abig
}
func (FunctionsRouterConfigUpdated) Topic() common.Hash {
- return common.HexToHash("0x049ce2e6e1420eb4b07b425e90129186833eb346bda40b37d5d921aad482f71c")
+ return common.HexToHash("0x00a5832bf95f66c7814294cc4db681f20ee79608bfb8912a5321d66cfed5e985")
}
func (FunctionsRouterContractProposed) Topic() common.Hash {
@@ -3460,6 +3484,8 @@ type FunctionsRouterInterface interface {
GetSubscriptionCount(opts *bind.CallOpts) (uint64, error)
+ GetSubscriptionsInRange(opts *bind.CallOpts, subscriptionIdStart uint64, subscriptionIdEnd uint64) ([]IFunctionsSubscriptionsSubscription, error)
+
GetTotalBalance(opts *bind.CallOpts) (*big.Int, error)
IsValidCallbackGasLimit(opts *bind.CallOpts, subscriptionId uint64, callbackGasLimit uint32) error
diff --git a/core/gethwrappers/functions/generated/functions_v1_events_mock/functions_v1_events_mock.go b/core/gethwrappers/functions/generated/functions_v1_events_mock/functions_v1_events_mock.go
new file mode 100644
index 00000000000..ae1fe20401c
--- /dev/null
+++ b/core/gethwrappers/functions/generated/functions_v1_events_mock/functions_v1_events_mock.go
@@ -0,0 +1,3122 @@
+// Code generated - DO NOT EDIT.
+// This file is a generated binding and any manual changes will be lost.
+
+package functions_v1_events_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
+)
+
+type FunctionsV1EventsMockConfig struct {
+ MaxConsumersPerSubscription uint16
+ AdminFee *big.Int
+ HandleOracleFulfillmentSelector [4]byte
+ GasForCallExactCheck uint16
+ MaxCallbackGasLimits []uint32
+}
+
+var FunctionsV1EventsMockMetaData = &bind.MetaData{
+ ABI: "[{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint16\",\"name\":\"maxConsumersPerSubscription\",\"type\":\"uint16\"},{\"internalType\":\"uint72\",\"name\":\"adminFee\",\"type\":\"uint72\"},{\"internalType\":\"bytes4\",\"name\":\"handleOracleFulfillmentSelector\",\"type\":\"bytes4\"},{\"internalType\":\"uint16\",\"name\":\"gasForCallExactCheck\",\"type\":\"uint16\"},{\"internalType\":\"uint32[]\",\"name\":\"maxCallbackGasLimits\",\"type\":\"uint32[]\"}],\"indexed\":false,\"internalType\":\"structFunctionsV1EventsMock.Config\",\"name\":\"param1\",\"type\":\"tuple\"}],\"name\":\"ConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"proposedContractSetId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"proposedContractSetFromAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"proposedContractSetToAddress\",\"type\":\"address\"}],\"name\":\"ContractProposed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"ContractUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FundsRecovered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"resultCode\",\"type\":\"uint8\"}],\"name\":\"RequestNotProcessed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"totalCostJuels\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"resultCode\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"callbackReturnData\",\"type\":\"bytes\"}],\"name\":\"RequestProcessed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"donId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"subscriptionOwner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"requestingContract\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"requestInitiator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"dataVersion\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"estimatedTotalCostJuels\",\"type\":\"uint96\"}],\"name\":\"RequestStart\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"}],\"name\":\"RequestTimedOut\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"fundsRecipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"fundsAmount\",\"type\":\"uint256\"}],\"name\":\"SubscriptionCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"SubscriptionConsumerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"SubscriptionConsumerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"SubscriptionCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newBalance\",\"type\":\"uint256\"}],\"name\":\"SubscriptionFunded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"SubscriptionOwnerTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"SubscriptionOwnerTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint16\",\"name\":\"maxConsumersPerSubscription\",\"type\":\"uint16\"},{\"internalType\":\"uint72\",\"name\":\"adminFee\",\"type\":\"uint72\"},{\"internalType\":\"bytes4\",\"name\":\"handleOracleFulfillmentSelector\",\"type\":\"bytes4\"},{\"internalType\":\"uint16\",\"name\":\"gasForCallExactCheck\",\"type\":\"uint16\"},{\"internalType\":\"uint32[]\",\"name\":\"maxCallbackGasLimits\",\"type\":\"uint32[]\"}],\"internalType\":\"structFunctionsV1EventsMock.Config\",\"name\":\"param1\",\"type\":\"tuple\"}],\"name\":\"emitConfigUpdated\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"proposedContractSetId\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"proposedContractSetFromAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"proposedContractSetToAddress\",\"type\":\"address\"}],\"name\":\"emitContractProposed\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"emitContractUpdated\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"emitFundsRecovered\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"emitOwnershipTransferRequested\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"emitOwnershipTransferred\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"emitPaused\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"resultCode\",\"type\":\"uint8\"}],\"name\":\"emitRequestNotProcessed\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"uint96\",\"name\":\"totalCostJuels\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"resultCode\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callbackReturnData\",\"type\":\"bytes\"}],\"name\":\"emitRequestProcessed\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"donId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"subscriptionOwner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"requestingContract\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"requestInitiator\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint16\",\"name\":\"dataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint96\",\"name\":\"estimatedTotalCostJuels\",\"type\":\"uint96\"}],\"name\":\"emitRequestStart\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"}],\"name\":\"emitRequestTimedOut\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"fundsRecipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fundsAmount\",\"type\":\"uint256\"}],\"name\":\"emitSubscriptionCanceled\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"emitSubscriptionConsumerAdded\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"emitSubscriptionConsumerRemoved\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"emitSubscriptionCreated\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"oldBalance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"newBalance\",\"type\":\"uint256\"}],\"name\":\"emitSubscriptionFunded\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"emitSubscriptionOwnerTransferRequested\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"emitSubscriptionOwnerTransferred\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"emitUnpaused\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]",
+ Bin: "0x608060405234801561001057600080fd5b506111a8806100206000396000f3fe608060405234801561001057600080fd5b50600436106101515760003560e01c8063a5257226116100cd578063e0f6eff111610081578063e9bfcd1811610066578063e9bfcd1814610288578063f7420bc21461029b578063fa7dd96b146102ae57600080fd5b8063e0f6eff114610262578063e2cab57b1461027557600080fd5b8063b24a02cb116100b2578063b24a02cb14610229578063ce150ef11461023c578063dde69b3f1461024f57600080fd5b8063a525722614610203578063b019b4e81461021657600080fd5b8063689300ea116101245780637e1b44c0116101095780637e1b44c0146101ca57806389d38eb4146101dd5780639ec3ce4b146101f057600080fd5b8063689300ea146101a45780637be5c756146101b757600080fd5b8063027d7d22146101565780633f70afb61461016b5780634bf6a80d1461017e578063675b924414610191575b600080fd5b610169610164366004610919565b6102c1565b005b61016961017936600461097e565b610323565b61016961018c3660046109b1565b61037d565b61016961019f36600461097e565b6103df565b6101696101b23660046109f4565b610431565b6101696101c5366004610a1e565b610484565b6101696101d8366004610a40565b6104d1565b6101696101eb366004610bd0565b6104ff565b6101696101fe366004610a1e565b61055b565b61016961021136600461097e565b6105a1565b610169610224366004610c97565b6105f3565b610169610237366004610cb3565b610651565b61016961024a366004610cd8565b6106b1565b61016961025d366004610dad565b610708565b6101696102703660046109b1565b610760565b610169610283366004610de9565b6107b9565b610169610296366004610cb3565b6107fb565b6101696102a9366004610c97565b610852565b6101696102bc366004610ea3565b6108b0565b6040805173ffffffffffffffffffffffffffffffffffffffff85811682528416602082015260ff831681830152905185917f1a90e9a50793db2e394cf581e7c522e10c358a81e70acf6b5a0edd620c08dee1919081900360600190a250505050565b60405173ffffffffffffffffffffffffffffffffffffffff8216815267ffffffffffffffff8316907f464722b4166576d3dcbba877b999bc35cf911f4eaf434b7eba68fa113951d0bf906020015b60405180910390a25050565b6040805173ffffffffffffffffffffffffffffffffffffffff80851682528316602082015267ffffffffffffffff8516917f6f1dc65165ffffedfd8e507b4a0f1fcfdada045ed11f6c26ba27cedfe87802f091015b60405180910390a2505050565b60405173ffffffffffffffffffffffffffffffffffffffff8216815267ffffffffffffffff8316907f43dc749a04ac8fb825cbd514f7c0e13f13bc6f2ee66043b76629d51776cff8e090602001610371565b6040805173ffffffffffffffffffffffffffffffffffffffff84168152602081018390527f59bfc682b673f8cbf945f1e454df9334834abf7dfe7f92237ca29ecb9b436600910160405180910390a15050565b60405173ffffffffffffffffffffffffffffffffffffffff821681527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258906020015b60405180910390a150565b60405181907ff1ca1e9147be737b04a2b018a79405f687a97de8dd8a2559bbe62357343af41490600090a250565b8767ffffffffffffffff16898b7ff67aec45c9a7ede407974a3e0c3a743dffeab99ee3f2d4c9a8144c2ebf2c7ec98a8a8a8a8a8a8a6040516105479796959493929190610fef565b60405180910390a450505050505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff821681527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa906020016104c6565b60405173ffffffffffffffffffffffffffffffffffffffff8216815267ffffffffffffffff8316907f182bff9831466789164ca77075fffd84916d35a8180ba73c27e45634549b445b90602001610371565b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6040805184815273ffffffffffffffffffffffffffffffffffffffff80851660208301528316918101919091527f8b052f0f4bf82fede7daffea71592b29d5ef86af1f3c7daaa0345dbb2f52f481906060015b60405180910390a1505050565b8667ffffffffffffffff16887f64778f26c70b60a8d7e29e2451b3844302d959448401c0535b768ed88c6b505e8888888888886040516106f696959493929190611067565b60405180910390a35050505050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff841681526020810183905267ffffffffffffffff8516917fe8ed5b475a5b5987aa9165e8731bb78043f39eee32ec5a1169a89e27fcd4981591016103d2565b6040805173ffffffffffffffffffffffffffffffffffffffff80851682528316602082015267ffffffffffffffff8516917f69436ea6df009049404f564eff6622cd00522b0bd6a89efd9e52a355c4a879be91016103d2565b604080518381526020810183905267ffffffffffffffff8516917fd39ec07f4e209f627a4c427971473820dc129761ba28de8906bd56f57101d4f891016103d2565b6040805184815273ffffffffffffffffffffffffffffffffffffffff80851660208301528316918101919091527ff8a6175bca1ba37d682089187edc5e20a859989727f10ca6bd9a5bc0de8caf94906060016106a4565b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae127860405160405180910390a35050565b7f049ce2e6e1420eb4b07b425e90129186833eb346bda40b37d5d921aad482f71c816040516104c691906110e6565b803573ffffffffffffffffffffffffffffffffffffffff8116811461090357600080fd5b919050565b803560ff8116811461090357600080fd5b6000806000806080858703121561092f57600080fd5b8435935061093f602086016108df565b925061094d604086016108df565b915061095b60608601610908565b905092959194509250565b803567ffffffffffffffff8116811461090357600080fd5b6000806040838503121561099157600080fd5b61099a83610966565b91506109a8602084016108df565b90509250929050565b6000806000606084860312156109c657600080fd5b6109cf84610966565b92506109dd602085016108df565b91506109eb604085016108df565b90509250925092565b60008060408385031215610a0757600080fd5b610a10836108df565b946020939093013593505050565b600060208284031215610a3057600080fd5b610a39826108df565b9392505050565b600060208284031215610a5257600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160a0810167ffffffffffffffff81118282101715610aab57610aab610a59565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610af857610af8610a59565b604052919050565b600082601f830112610b1157600080fd5b813567ffffffffffffffff811115610b2b57610b2b610a59565b610b5c60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601610ab1565b818152846020838601011115610b7157600080fd5b816020850160208301376000918101602001919091529392505050565b803561ffff8116811461090357600080fd5b803563ffffffff8116811461090357600080fd5b80356bffffffffffffffffffffffff8116811461090357600080fd5b6000806000806000806000806000806101408b8d031215610bf057600080fd5b8a35995060208b01359850610c0760408c01610966565b9750610c1560608c016108df565b9650610c2360808c016108df565b9550610c3160a08c016108df565b945060c08b013567ffffffffffffffff811115610c4d57600080fd5b610c598d828e01610b00565b945050610c6860e08c01610b8e565b9250610c776101008c01610ba0565b9150610c866101208c01610bb4565b90509295989b9194979a5092959850565b60008060408385031215610caa57600080fd5b61099a836108df565b600080600060608486031215610cc857600080fd5b833592506109dd602085016108df565b600080600080600080600080610100898b031215610cf557600080fd5b88359750610d0560208a01610966565b9650610d1360408a01610bb4565b9550610d2160608a016108df565b9450610d2f60808a01610908565b935060a089013567ffffffffffffffff80821115610d4c57600080fd5b610d588c838d01610b00565b945060c08b0135915080821115610d6e57600080fd5b610d7a8c838d01610b00565b935060e08b0135915080821115610d9057600080fd5b50610d9d8b828c01610b00565b9150509295985092959890939650565b600080600060608486031215610dc257600080fd5b610dcb84610966565b9250610dd9602085016108df565b9150604084013590509250925092565b600080600060608486031215610dfe57600080fd5b610e0784610966565b95602085013595506040909401359392505050565b600082601f830112610e2d57600080fd5b8135602067ffffffffffffffff821115610e4957610e49610a59565b8160051b610e58828201610ab1565b9283528481018201928281019087851115610e7257600080fd5b83870192505b84831015610e9857610e8983610ba0565b82529183019190830190610e78565b979650505050505050565b600060208284031215610eb557600080fd5b813567ffffffffffffffff80821115610ecd57600080fd5b9083019060a08286031215610ee157600080fd5b610ee9610a88565b610ef283610b8e565b8152602083013568ffffffffffffffffff81168114610f1057600080fd5b602082015260408301357fffffffff0000000000000000000000000000000000000000000000000000000081168114610f4857600080fd5b6040820152610f5960608401610b8e565b6060820152608083013582811115610f7057600080fd5b610f7c87828601610e1c565b60808301525095945050505050565b6000815180845260005b81811015610fb157602081850181015186830182015201610f95565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b600073ffffffffffffffffffffffffffffffffffffffff808a168352808916602084015280881660408401525060e0606083015261103060e0830187610f8b565b61ffff9590951660808301525063ffffffff9290921660a08301526bffffffffffffffffffffffff1660c090910152949350505050565b6bffffffffffffffffffffffff8716815273ffffffffffffffffffffffffffffffffffffffff8616602082015260ff8516604082015260c0606082015260006110b360c0830186610f8b565b82810360808401526110c58186610f8b565b905082810360a08401526110d98185610f8b565b9998505050505050505050565b6000602080835260c0830161ffff808651168386015268ffffffffffffffffff838701511660408601527fffffffff00000000000000000000000000000000000000000000000000000000604087015116606086015280606087015116608086015250608085015160a08086015281815180845260e0870191508483019350600092505b8083101561119057835163ffffffff16825292840192600192909201919084019061116a565b50969550505050505056fea164736f6c6343000813000a",
+}
+
+var FunctionsV1EventsMockABI = FunctionsV1EventsMockMetaData.ABI
+
+var FunctionsV1EventsMockBin = FunctionsV1EventsMockMetaData.Bin
+
+func DeployFunctionsV1EventsMock(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *FunctionsV1EventsMock, error) {
+ parsed, err := FunctionsV1EventsMockMetaData.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(FunctionsV1EventsMockBin), backend)
+ if err != nil {
+ return common.Address{}, nil, nil, err
+ }
+ return address, tx, &FunctionsV1EventsMock{FunctionsV1EventsMockCaller: FunctionsV1EventsMockCaller{contract: contract}, FunctionsV1EventsMockTransactor: FunctionsV1EventsMockTransactor{contract: contract}, FunctionsV1EventsMockFilterer: FunctionsV1EventsMockFilterer{contract: contract}}, nil
+}
+
+type FunctionsV1EventsMock struct {
+ address common.Address
+ abi abi.ABI
+ FunctionsV1EventsMockCaller
+ FunctionsV1EventsMockTransactor
+ FunctionsV1EventsMockFilterer
+}
+
+type FunctionsV1EventsMockCaller struct {
+ contract *bind.BoundContract
+}
+
+type FunctionsV1EventsMockTransactor struct {
+ contract *bind.BoundContract
+}
+
+type FunctionsV1EventsMockFilterer struct {
+ contract *bind.BoundContract
+}
+
+type FunctionsV1EventsMockSession struct {
+ Contract *FunctionsV1EventsMock
+ CallOpts bind.CallOpts
+ TransactOpts bind.TransactOpts
+}
+
+type FunctionsV1EventsMockCallerSession struct {
+ Contract *FunctionsV1EventsMockCaller
+ CallOpts bind.CallOpts
+}
+
+type FunctionsV1EventsMockTransactorSession struct {
+ Contract *FunctionsV1EventsMockTransactor
+ TransactOpts bind.TransactOpts
+}
+
+type FunctionsV1EventsMockRaw struct {
+ Contract *FunctionsV1EventsMock
+}
+
+type FunctionsV1EventsMockCallerRaw struct {
+ Contract *FunctionsV1EventsMockCaller
+}
+
+type FunctionsV1EventsMockTransactorRaw struct {
+ Contract *FunctionsV1EventsMockTransactor
+}
+
+func NewFunctionsV1EventsMock(address common.Address, backend bind.ContractBackend) (*FunctionsV1EventsMock, error) {
+ abi, err := abi.JSON(strings.NewReader(FunctionsV1EventsMockABI))
+ if err != nil {
+ return nil, err
+ }
+ contract, err := bindFunctionsV1EventsMock(address, backend, backend, backend)
+ if err != nil {
+ return nil, err
+ }
+ return &FunctionsV1EventsMock{address: address, abi: abi, FunctionsV1EventsMockCaller: FunctionsV1EventsMockCaller{contract: contract}, FunctionsV1EventsMockTransactor: FunctionsV1EventsMockTransactor{contract: contract}, FunctionsV1EventsMockFilterer: FunctionsV1EventsMockFilterer{contract: contract}}, nil
+}
+
+func NewFunctionsV1EventsMockCaller(address common.Address, caller bind.ContractCaller) (*FunctionsV1EventsMockCaller, error) {
+ contract, err := bindFunctionsV1EventsMock(address, caller, nil, nil)
+ if err != nil {
+ return nil, err
+ }
+ return &FunctionsV1EventsMockCaller{contract: contract}, nil
+}
+
+func NewFunctionsV1EventsMockTransactor(address common.Address, transactor bind.ContractTransactor) (*FunctionsV1EventsMockTransactor, error) {
+ contract, err := bindFunctionsV1EventsMock(address, nil, transactor, nil)
+ if err != nil {
+ return nil, err
+ }
+ return &FunctionsV1EventsMockTransactor{contract: contract}, nil
+}
+
+func NewFunctionsV1EventsMockFilterer(address common.Address, filterer bind.ContractFilterer) (*FunctionsV1EventsMockFilterer, error) {
+ contract, err := bindFunctionsV1EventsMock(address, nil, nil, filterer)
+ if err != nil {
+ return nil, err
+ }
+ return &FunctionsV1EventsMockFilterer{contract: contract}, nil
+}
+
+func bindFunctionsV1EventsMock(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) {
+ parsed, err := FunctionsV1EventsMockMetaData.GetAbi()
+ if err != nil {
+ return nil, err
+ }
+ return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
+ return _FunctionsV1EventsMock.Contract.FunctionsV1EventsMockCaller.contract.Call(opts, result, method, params...)
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _FunctionsV1EventsMock.Contract.FunctionsV1EventsMockTransactor.contract.Transfer(opts)
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+ return _FunctionsV1EventsMock.Contract.FunctionsV1EventsMockTransactor.contract.Transact(opts, method, params...)
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
+ return _FunctionsV1EventsMock.Contract.contract.Call(opts, result, method, params...)
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _FunctionsV1EventsMock.Contract.contract.Transfer(opts)
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+ return _FunctionsV1EventsMock.Contract.contract.Transact(opts, method, params...)
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockTransactor) EmitConfigUpdated(opts *bind.TransactOpts, param1 FunctionsV1EventsMockConfig) (*types.Transaction, error) {
+ return _FunctionsV1EventsMock.contract.Transact(opts, "emitConfigUpdated", param1)
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockSession) EmitConfigUpdated(param1 FunctionsV1EventsMockConfig) (*types.Transaction, error) {
+ return _FunctionsV1EventsMock.Contract.EmitConfigUpdated(&_FunctionsV1EventsMock.TransactOpts, param1)
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockTransactorSession) EmitConfigUpdated(param1 FunctionsV1EventsMockConfig) (*types.Transaction, error) {
+ return _FunctionsV1EventsMock.Contract.EmitConfigUpdated(&_FunctionsV1EventsMock.TransactOpts, param1)
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockTransactor) EmitContractProposed(opts *bind.TransactOpts, proposedContractSetId [32]byte, proposedContractSetFromAddress common.Address, proposedContractSetToAddress common.Address) (*types.Transaction, error) {
+ return _FunctionsV1EventsMock.contract.Transact(opts, "emitContractProposed", proposedContractSetId, proposedContractSetFromAddress, proposedContractSetToAddress)
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockSession) EmitContractProposed(proposedContractSetId [32]byte, proposedContractSetFromAddress common.Address, proposedContractSetToAddress common.Address) (*types.Transaction, error) {
+ return _FunctionsV1EventsMock.Contract.EmitContractProposed(&_FunctionsV1EventsMock.TransactOpts, proposedContractSetId, proposedContractSetFromAddress, proposedContractSetToAddress)
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockTransactorSession) EmitContractProposed(proposedContractSetId [32]byte, proposedContractSetFromAddress common.Address, proposedContractSetToAddress common.Address) (*types.Transaction, error) {
+ return _FunctionsV1EventsMock.Contract.EmitContractProposed(&_FunctionsV1EventsMock.TransactOpts, proposedContractSetId, proposedContractSetFromAddress, proposedContractSetToAddress)
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockTransactor) EmitContractUpdated(opts *bind.TransactOpts, id [32]byte, from common.Address, to common.Address) (*types.Transaction, error) {
+ return _FunctionsV1EventsMock.contract.Transact(opts, "emitContractUpdated", id, from, to)
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockSession) EmitContractUpdated(id [32]byte, from common.Address, to common.Address) (*types.Transaction, error) {
+ return _FunctionsV1EventsMock.Contract.EmitContractUpdated(&_FunctionsV1EventsMock.TransactOpts, id, from, to)
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockTransactorSession) EmitContractUpdated(id [32]byte, from common.Address, to common.Address) (*types.Transaction, error) {
+ return _FunctionsV1EventsMock.Contract.EmitContractUpdated(&_FunctionsV1EventsMock.TransactOpts, id, from, to)
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockTransactor) EmitFundsRecovered(opts *bind.TransactOpts, to common.Address, amount *big.Int) (*types.Transaction, error) {
+ return _FunctionsV1EventsMock.contract.Transact(opts, "emitFundsRecovered", to, amount)
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockSession) EmitFundsRecovered(to common.Address, amount *big.Int) (*types.Transaction, error) {
+ return _FunctionsV1EventsMock.Contract.EmitFundsRecovered(&_FunctionsV1EventsMock.TransactOpts, to, amount)
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockTransactorSession) EmitFundsRecovered(to common.Address, amount *big.Int) (*types.Transaction, error) {
+ return _FunctionsV1EventsMock.Contract.EmitFundsRecovered(&_FunctionsV1EventsMock.TransactOpts, to, amount)
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockTransactor) EmitOwnershipTransferRequested(opts *bind.TransactOpts, from common.Address, to common.Address) (*types.Transaction, error) {
+ return _FunctionsV1EventsMock.contract.Transact(opts, "emitOwnershipTransferRequested", from, to)
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockSession) EmitOwnershipTransferRequested(from common.Address, to common.Address) (*types.Transaction, error) {
+ return _FunctionsV1EventsMock.Contract.EmitOwnershipTransferRequested(&_FunctionsV1EventsMock.TransactOpts, from, to)
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockTransactorSession) EmitOwnershipTransferRequested(from common.Address, to common.Address) (*types.Transaction, error) {
+ return _FunctionsV1EventsMock.Contract.EmitOwnershipTransferRequested(&_FunctionsV1EventsMock.TransactOpts, from, to)
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockTransactor) EmitOwnershipTransferred(opts *bind.TransactOpts, from common.Address, to common.Address) (*types.Transaction, error) {
+ return _FunctionsV1EventsMock.contract.Transact(opts, "emitOwnershipTransferred", from, to)
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockSession) EmitOwnershipTransferred(from common.Address, to common.Address) (*types.Transaction, error) {
+ return _FunctionsV1EventsMock.Contract.EmitOwnershipTransferred(&_FunctionsV1EventsMock.TransactOpts, from, to)
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockTransactorSession) EmitOwnershipTransferred(from common.Address, to common.Address) (*types.Transaction, error) {
+ return _FunctionsV1EventsMock.Contract.EmitOwnershipTransferred(&_FunctionsV1EventsMock.TransactOpts, from, to)
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockTransactor) EmitPaused(opts *bind.TransactOpts, account common.Address) (*types.Transaction, error) {
+ return _FunctionsV1EventsMock.contract.Transact(opts, "emitPaused", account)
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockSession) EmitPaused(account common.Address) (*types.Transaction, error) {
+ return _FunctionsV1EventsMock.Contract.EmitPaused(&_FunctionsV1EventsMock.TransactOpts, account)
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockTransactorSession) EmitPaused(account common.Address) (*types.Transaction, error) {
+ return _FunctionsV1EventsMock.Contract.EmitPaused(&_FunctionsV1EventsMock.TransactOpts, account)
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockTransactor) EmitRequestNotProcessed(opts *bind.TransactOpts, requestId [32]byte, coordinator common.Address, transmitter common.Address, resultCode uint8) (*types.Transaction, error) {
+ return _FunctionsV1EventsMock.contract.Transact(opts, "emitRequestNotProcessed", requestId, coordinator, transmitter, resultCode)
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockSession) EmitRequestNotProcessed(requestId [32]byte, coordinator common.Address, transmitter common.Address, resultCode uint8) (*types.Transaction, error) {
+ return _FunctionsV1EventsMock.Contract.EmitRequestNotProcessed(&_FunctionsV1EventsMock.TransactOpts, requestId, coordinator, transmitter, resultCode)
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockTransactorSession) EmitRequestNotProcessed(requestId [32]byte, coordinator common.Address, transmitter common.Address, resultCode uint8) (*types.Transaction, error) {
+ return _FunctionsV1EventsMock.Contract.EmitRequestNotProcessed(&_FunctionsV1EventsMock.TransactOpts, requestId, coordinator, transmitter, resultCode)
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockTransactor) EmitRequestProcessed(opts *bind.TransactOpts, requestId [32]byte, subscriptionId uint64, totalCostJuels *big.Int, transmitter common.Address, resultCode uint8, response []byte, err []byte, callbackReturnData []byte) (*types.Transaction, error) {
+ return _FunctionsV1EventsMock.contract.Transact(opts, "emitRequestProcessed", requestId, subscriptionId, totalCostJuels, transmitter, resultCode, response, err, callbackReturnData)
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockSession) EmitRequestProcessed(requestId [32]byte, subscriptionId uint64, totalCostJuels *big.Int, transmitter common.Address, resultCode uint8, response []byte, err []byte, callbackReturnData []byte) (*types.Transaction, error) {
+ return _FunctionsV1EventsMock.Contract.EmitRequestProcessed(&_FunctionsV1EventsMock.TransactOpts, requestId, subscriptionId, totalCostJuels, transmitter, resultCode, response, err, callbackReturnData)
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockTransactorSession) EmitRequestProcessed(requestId [32]byte, subscriptionId uint64, totalCostJuels *big.Int, transmitter common.Address, resultCode uint8, response []byte, err []byte, callbackReturnData []byte) (*types.Transaction, error) {
+ return _FunctionsV1EventsMock.Contract.EmitRequestProcessed(&_FunctionsV1EventsMock.TransactOpts, requestId, subscriptionId, totalCostJuels, transmitter, resultCode, response, err, callbackReturnData)
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockTransactor) EmitRequestStart(opts *bind.TransactOpts, requestId [32]byte, donId [32]byte, subscriptionId uint64, subscriptionOwner common.Address, requestingContract common.Address, requestInitiator common.Address, data []byte, dataVersion uint16, callbackGasLimit uint32, estimatedTotalCostJuels *big.Int) (*types.Transaction, error) {
+ return _FunctionsV1EventsMock.contract.Transact(opts, "emitRequestStart", requestId, donId, subscriptionId, subscriptionOwner, requestingContract, requestInitiator, data, dataVersion, callbackGasLimit, estimatedTotalCostJuels)
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockSession) EmitRequestStart(requestId [32]byte, donId [32]byte, subscriptionId uint64, subscriptionOwner common.Address, requestingContract common.Address, requestInitiator common.Address, data []byte, dataVersion uint16, callbackGasLimit uint32, estimatedTotalCostJuels *big.Int) (*types.Transaction, error) {
+ return _FunctionsV1EventsMock.Contract.EmitRequestStart(&_FunctionsV1EventsMock.TransactOpts, requestId, donId, subscriptionId, subscriptionOwner, requestingContract, requestInitiator, data, dataVersion, callbackGasLimit, estimatedTotalCostJuels)
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockTransactorSession) EmitRequestStart(requestId [32]byte, donId [32]byte, subscriptionId uint64, subscriptionOwner common.Address, requestingContract common.Address, requestInitiator common.Address, data []byte, dataVersion uint16, callbackGasLimit uint32, estimatedTotalCostJuels *big.Int) (*types.Transaction, error) {
+ return _FunctionsV1EventsMock.Contract.EmitRequestStart(&_FunctionsV1EventsMock.TransactOpts, requestId, donId, subscriptionId, subscriptionOwner, requestingContract, requestInitiator, data, dataVersion, callbackGasLimit, estimatedTotalCostJuels)
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockTransactor) EmitRequestTimedOut(opts *bind.TransactOpts, requestId [32]byte) (*types.Transaction, error) {
+ return _FunctionsV1EventsMock.contract.Transact(opts, "emitRequestTimedOut", requestId)
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockSession) EmitRequestTimedOut(requestId [32]byte) (*types.Transaction, error) {
+ return _FunctionsV1EventsMock.Contract.EmitRequestTimedOut(&_FunctionsV1EventsMock.TransactOpts, requestId)
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockTransactorSession) EmitRequestTimedOut(requestId [32]byte) (*types.Transaction, error) {
+ return _FunctionsV1EventsMock.Contract.EmitRequestTimedOut(&_FunctionsV1EventsMock.TransactOpts, requestId)
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockTransactor) EmitSubscriptionCanceled(opts *bind.TransactOpts, subscriptionId uint64, fundsRecipient common.Address, fundsAmount *big.Int) (*types.Transaction, error) {
+ return _FunctionsV1EventsMock.contract.Transact(opts, "emitSubscriptionCanceled", subscriptionId, fundsRecipient, fundsAmount)
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockSession) EmitSubscriptionCanceled(subscriptionId uint64, fundsRecipient common.Address, fundsAmount *big.Int) (*types.Transaction, error) {
+ return _FunctionsV1EventsMock.Contract.EmitSubscriptionCanceled(&_FunctionsV1EventsMock.TransactOpts, subscriptionId, fundsRecipient, fundsAmount)
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockTransactorSession) EmitSubscriptionCanceled(subscriptionId uint64, fundsRecipient common.Address, fundsAmount *big.Int) (*types.Transaction, error) {
+ return _FunctionsV1EventsMock.Contract.EmitSubscriptionCanceled(&_FunctionsV1EventsMock.TransactOpts, subscriptionId, fundsRecipient, fundsAmount)
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockTransactor) EmitSubscriptionConsumerAdded(opts *bind.TransactOpts, subscriptionId uint64, consumer common.Address) (*types.Transaction, error) {
+ return _FunctionsV1EventsMock.contract.Transact(opts, "emitSubscriptionConsumerAdded", subscriptionId, consumer)
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockSession) EmitSubscriptionConsumerAdded(subscriptionId uint64, consumer common.Address) (*types.Transaction, error) {
+ return _FunctionsV1EventsMock.Contract.EmitSubscriptionConsumerAdded(&_FunctionsV1EventsMock.TransactOpts, subscriptionId, consumer)
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockTransactorSession) EmitSubscriptionConsumerAdded(subscriptionId uint64, consumer common.Address) (*types.Transaction, error) {
+ return _FunctionsV1EventsMock.Contract.EmitSubscriptionConsumerAdded(&_FunctionsV1EventsMock.TransactOpts, subscriptionId, consumer)
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockTransactor) EmitSubscriptionConsumerRemoved(opts *bind.TransactOpts, subscriptionId uint64, consumer common.Address) (*types.Transaction, error) {
+ return _FunctionsV1EventsMock.contract.Transact(opts, "emitSubscriptionConsumerRemoved", subscriptionId, consumer)
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockSession) EmitSubscriptionConsumerRemoved(subscriptionId uint64, consumer common.Address) (*types.Transaction, error) {
+ return _FunctionsV1EventsMock.Contract.EmitSubscriptionConsumerRemoved(&_FunctionsV1EventsMock.TransactOpts, subscriptionId, consumer)
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockTransactorSession) EmitSubscriptionConsumerRemoved(subscriptionId uint64, consumer common.Address) (*types.Transaction, error) {
+ return _FunctionsV1EventsMock.Contract.EmitSubscriptionConsumerRemoved(&_FunctionsV1EventsMock.TransactOpts, subscriptionId, consumer)
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockTransactor) EmitSubscriptionCreated(opts *bind.TransactOpts, subscriptionId uint64, owner common.Address) (*types.Transaction, error) {
+ return _FunctionsV1EventsMock.contract.Transact(opts, "emitSubscriptionCreated", subscriptionId, owner)
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockSession) EmitSubscriptionCreated(subscriptionId uint64, owner common.Address) (*types.Transaction, error) {
+ return _FunctionsV1EventsMock.Contract.EmitSubscriptionCreated(&_FunctionsV1EventsMock.TransactOpts, subscriptionId, owner)
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockTransactorSession) EmitSubscriptionCreated(subscriptionId uint64, owner common.Address) (*types.Transaction, error) {
+ return _FunctionsV1EventsMock.Contract.EmitSubscriptionCreated(&_FunctionsV1EventsMock.TransactOpts, subscriptionId, owner)
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockTransactor) EmitSubscriptionFunded(opts *bind.TransactOpts, subscriptionId uint64, oldBalance *big.Int, newBalance *big.Int) (*types.Transaction, error) {
+ return _FunctionsV1EventsMock.contract.Transact(opts, "emitSubscriptionFunded", subscriptionId, oldBalance, newBalance)
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockSession) EmitSubscriptionFunded(subscriptionId uint64, oldBalance *big.Int, newBalance *big.Int) (*types.Transaction, error) {
+ return _FunctionsV1EventsMock.Contract.EmitSubscriptionFunded(&_FunctionsV1EventsMock.TransactOpts, subscriptionId, oldBalance, newBalance)
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockTransactorSession) EmitSubscriptionFunded(subscriptionId uint64, oldBalance *big.Int, newBalance *big.Int) (*types.Transaction, error) {
+ return _FunctionsV1EventsMock.Contract.EmitSubscriptionFunded(&_FunctionsV1EventsMock.TransactOpts, subscriptionId, oldBalance, newBalance)
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockTransactor) EmitSubscriptionOwnerTransferRequested(opts *bind.TransactOpts, subscriptionId uint64, from common.Address, to common.Address) (*types.Transaction, error) {
+ return _FunctionsV1EventsMock.contract.Transact(opts, "emitSubscriptionOwnerTransferRequested", subscriptionId, from, to)
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockSession) EmitSubscriptionOwnerTransferRequested(subscriptionId uint64, from common.Address, to common.Address) (*types.Transaction, error) {
+ return _FunctionsV1EventsMock.Contract.EmitSubscriptionOwnerTransferRequested(&_FunctionsV1EventsMock.TransactOpts, subscriptionId, from, to)
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockTransactorSession) EmitSubscriptionOwnerTransferRequested(subscriptionId uint64, from common.Address, to common.Address) (*types.Transaction, error) {
+ return _FunctionsV1EventsMock.Contract.EmitSubscriptionOwnerTransferRequested(&_FunctionsV1EventsMock.TransactOpts, subscriptionId, from, to)
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockTransactor) EmitSubscriptionOwnerTransferred(opts *bind.TransactOpts, subscriptionId uint64, from common.Address, to common.Address) (*types.Transaction, error) {
+ return _FunctionsV1EventsMock.contract.Transact(opts, "emitSubscriptionOwnerTransferred", subscriptionId, from, to)
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockSession) EmitSubscriptionOwnerTransferred(subscriptionId uint64, from common.Address, to common.Address) (*types.Transaction, error) {
+ return _FunctionsV1EventsMock.Contract.EmitSubscriptionOwnerTransferred(&_FunctionsV1EventsMock.TransactOpts, subscriptionId, from, to)
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockTransactorSession) EmitSubscriptionOwnerTransferred(subscriptionId uint64, from common.Address, to common.Address) (*types.Transaction, error) {
+ return _FunctionsV1EventsMock.Contract.EmitSubscriptionOwnerTransferred(&_FunctionsV1EventsMock.TransactOpts, subscriptionId, from, to)
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockTransactor) EmitUnpaused(opts *bind.TransactOpts, account common.Address) (*types.Transaction, error) {
+ return _FunctionsV1EventsMock.contract.Transact(opts, "emitUnpaused", account)
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockSession) EmitUnpaused(account common.Address) (*types.Transaction, error) {
+ return _FunctionsV1EventsMock.Contract.EmitUnpaused(&_FunctionsV1EventsMock.TransactOpts, account)
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockTransactorSession) EmitUnpaused(account common.Address) (*types.Transaction, error) {
+ return _FunctionsV1EventsMock.Contract.EmitUnpaused(&_FunctionsV1EventsMock.TransactOpts, account)
+}
+
+type FunctionsV1EventsMockConfigUpdatedIterator struct {
+ Event *FunctionsV1EventsMockConfigUpdated
+
+ contract *bind.BoundContract
+ event string
+
+ logs chan types.Log
+ sub ethereum.Subscription
+ done bool
+ fail error
+}
+
+func (it *FunctionsV1EventsMockConfigUpdatedIterator) Next() bool {
+
+ if it.fail != nil {
+ return false
+ }
+
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(FunctionsV1EventsMockConfigUpdated)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+
+ select {
+ case log := <-it.logs:
+ it.Event = new(FunctionsV1EventsMockConfigUpdated)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+func (it *FunctionsV1EventsMockConfigUpdatedIterator) Error() error {
+ return it.fail
+}
+
+func (it *FunctionsV1EventsMockConfigUpdatedIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+type FunctionsV1EventsMockConfigUpdated struct {
+ Param1 FunctionsV1EventsMockConfig
+ Raw types.Log
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockFilterer) FilterConfigUpdated(opts *bind.FilterOpts) (*FunctionsV1EventsMockConfigUpdatedIterator, error) {
+
+ logs, sub, err := _FunctionsV1EventsMock.contract.FilterLogs(opts, "ConfigUpdated")
+ if err != nil {
+ return nil, err
+ }
+ return &FunctionsV1EventsMockConfigUpdatedIterator{contract: _FunctionsV1EventsMock.contract, event: "ConfigUpdated", logs: logs, sub: sub}, nil
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockFilterer) WatchConfigUpdated(opts *bind.WatchOpts, sink chan<- *FunctionsV1EventsMockConfigUpdated) (event.Subscription, error) {
+
+ logs, sub, err := _FunctionsV1EventsMock.contract.WatchLogs(opts, "ConfigUpdated")
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+
+ event := new(FunctionsV1EventsMockConfigUpdated)
+ if err := _FunctionsV1EventsMock.contract.UnpackLog(event, "ConfigUpdated", log); err != nil {
+ return err
+ }
+ event.Raw = log
+
+ select {
+ case sink <- event:
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ }
+ }), nil
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockFilterer) ParseConfigUpdated(log types.Log) (*FunctionsV1EventsMockConfigUpdated, error) {
+ event := new(FunctionsV1EventsMockConfigUpdated)
+ if err := _FunctionsV1EventsMock.contract.UnpackLog(event, "ConfigUpdated", log); err != nil {
+ return nil, err
+ }
+ event.Raw = log
+ return event, nil
+}
+
+type FunctionsV1EventsMockContractProposedIterator struct {
+ Event *FunctionsV1EventsMockContractProposed
+
+ contract *bind.BoundContract
+ event string
+
+ logs chan types.Log
+ sub ethereum.Subscription
+ done bool
+ fail error
+}
+
+func (it *FunctionsV1EventsMockContractProposedIterator) Next() bool {
+
+ if it.fail != nil {
+ return false
+ }
+
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(FunctionsV1EventsMockContractProposed)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+
+ select {
+ case log := <-it.logs:
+ it.Event = new(FunctionsV1EventsMockContractProposed)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+func (it *FunctionsV1EventsMockContractProposedIterator) Error() error {
+ return it.fail
+}
+
+func (it *FunctionsV1EventsMockContractProposedIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+type FunctionsV1EventsMockContractProposed struct {
+ ProposedContractSetId [32]byte
+ ProposedContractSetFromAddress common.Address
+ ProposedContractSetToAddress common.Address
+ Raw types.Log
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockFilterer) FilterContractProposed(opts *bind.FilterOpts) (*FunctionsV1EventsMockContractProposedIterator, error) {
+
+ logs, sub, err := _FunctionsV1EventsMock.contract.FilterLogs(opts, "ContractProposed")
+ if err != nil {
+ return nil, err
+ }
+ return &FunctionsV1EventsMockContractProposedIterator{contract: _FunctionsV1EventsMock.contract, event: "ContractProposed", logs: logs, sub: sub}, nil
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockFilterer) WatchContractProposed(opts *bind.WatchOpts, sink chan<- *FunctionsV1EventsMockContractProposed) (event.Subscription, error) {
+
+ logs, sub, err := _FunctionsV1EventsMock.contract.WatchLogs(opts, "ContractProposed")
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+
+ event := new(FunctionsV1EventsMockContractProposed)
+ if err := _FunctionsV1EventsMock.contract.UnpackLog(event, "ContractProposed", log); err != nil {
+ return err
+ }
+ event.Raw = log
+
+ select {
+ case sink <- event:
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ }
+ }), nil
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockFilterer) ParseContractProposed(log types.Log) (*FunctionsV1EventsMockContractProposed, error) {
+ event := new(FunctionsV1EventsMockContractProposed)
+ if err := _FunctionsV1EventsMock.contract.UnpackLog(event, "ContractProposed", log); err != nil {
+ return nil, err
+ }
+ event.Raw = log
+ return event, nil
+}
+
+type FunctionsV1EventsMockContractUpdatedIterator struct {
+ Event *FunctionsV1EventsMockContractUpdated
+
+ contract *bind.BoundContract
+ event string
+
+ logs chan types.Log
+ sub ethereum.Subscription
+ done bool
+ fail error
+}
+
+func (it *FunctionsV1EventsMockContractUpdatedIterator) Next() bool {
+
+ if it.fail != nil {
+ return false
+ }
+
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(FunctionsV1EventsMockContractUpdated)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+
+ select {
+ case log := <-it.logs:
+ it.Event = new(FunctionsV1EventsMockContractUpdated)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+func (it *FunctionsV1EventsMockContractUpdatedIterator) Error() error {
+ return it.fail
+}
+
+func (it *FunctionsV1EventsMockContractUpdatedIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+type FunctionsV1EventsMockContractUpdated struct {
+ Id [32]byte
+ From common.Address
+ To common.Address
+ Raw types.Log
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockFilterer) FilterContractUpdated(opts *bind.FilterOpts) (*FunctionsV1EventsMockContractUpdatedIterator, error) {
+
+ logs, sub, err := _FunctionsV1EventsMock.contract.FilterLogs(opts, "ContractUpdated")
+ if err != nil {
+ return nil, err
+ }
+ return &FunctionsV1EventsMockContractUpdatedIterator{contract: _FunctionsV1EventsMock.contract, event: "ContractUpdated", logs: logs, sub: sub}, nil
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockFilterer) WatchContractUpdated(opts *bind.WatchOpts, sink chan<- *FunctionsV1EventsMockContractUpdated) (event.Subscription, error) {
+
+ logs, sub, err := _FunctionsV1EventsMock.contract.WatchLogs(opts, "ContractUpdated")
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+
+ event := new(FunctionsV1EventsMockContractUpdated)
+ if err := _FunctionsV1EventsMock.contract.UnpackLog(event, "ContractUpdated", log); err != nil {
+ return err
+ }
+ event.Raw = log
+
+ select {
+ case sink <- event:
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ }
+ }), nil
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockFilterer) ParseContractUpdated(log types.Log) (*FunctionsV1EventsMockContractUpdated, error) {
+ event := new(FunctionsV1EventsMockContractUpdated)
+ if err := _FunctionsV1EventsMock.contract.UnpackLog(event, "ContractUpdated", log); err != nil {
+ return nil, err
+ }
+ event.Raw = log
+ return event, nil
+}
+
+type FunctionsV1EventsMockFundsRecoveredIterator struct {
+ Event *FunctionsV1EventsMockFundsRecovered
+
+ contract *bind.BoundContract
+ event string
+
+ logs chan types.Log
+ sub ethereum.Subscription
+ done bool
+ fail error
+}
+
+func (it *FunctionsV1EventsMockFundsRecoveredIterator) Next() bool {
+
+ if it.fail != nil {
+ return false
+ }
+
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(FunctionsV1EventsMockFundsRecovered)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+
+ select {
+ case log := <-it.logs:
+ it.Event = new(FunctionsV1EventsMockFundsRecovered)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+func (it *FunctionsV1EventsMockFundsRecoveredIterator) Error() error {
+ return it.fail
+}
+
+func (it *FunctionsV1EventsMockFundsRecoveredIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+type FunctionsV1EventsMockFundsRecovered struct {
+ To common.Address
+ Amount *big.Int
+ Raw types.Log
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockFilterer) FilterFundsRecovered(opts *bind.FilterOpts) (*FunctionsV1EventsMockFundsRecoveredIterator, error) {
+
+ logs, sub, err := _FunctionsV1EventsMock.contract.FilterLogs(opts, "FundsRecovered")
+ if err != nil {
+ return nil, err
+ }
+ return &FunctionsV1EventsMockFundsRecoveredIterator{contract: _FunctionsV1EventsMock.contract, event: "FundsRecovered", logs: logs, sub: sub}, nil
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockFilterer) WatchFundsRecovered(opts *bind.WatchOpts, sink chan<- *FunctionsV1EventsMockFundsRecovered) (event.Subscription, error) {
+
+ logs, sub, err := _FunctionsV1EventsMock.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(FunctionsV1EventsMockFundsRecovered)
+ if err := _FunctionsV1EventsMock.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 (_FunctionsV1EventsMock *FunctionsV1EventsMockFilterer) ParseFundsRecovered(log types.Log) (*FunctionsV1EventsMockFundsRecovered, error) {
+ event := new(FunctionsV1EventsMockFundsRecovered)
+ if err := _FunctionsV1EventsMock.contract.UnpackLog(event, "FundsRecovered", log); err != nil {
+ return nil, err
+ }
+ event.Raw = log
+ return event, nil
+}
+
+type FunctionsV1EventsMockOwnershipTransferRequestedIterator struct {
+ Event *FunctionsV1EventsMockOwnershipTransferRequested
+
+ contract *bind.BoundContract
+ event string
+
+ logs chan types.Log
+ sub ethereum.Subscription
+ done bool
+ fail error
+}
+
+func (it *FunctionsV1EventsMockOwnershipTransferRequestedIterator) Next() bool {
+
+ if it.fail != nil {
+ return false
+ }
+
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(FunctionsV1EventsMockOwnershipTransferRequested)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+
+ select {
+ case log := <-it.logs:
+ it.Event = new(FunctionsV1EventsMockOwnershipTransferRequested)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+func (it *FunctionsV1EventsMockOwnershipTransferRequestedIterator) Error() error {
+ return it.fail
+}
+
+func (it *FunctionsV1EventsMockOwnershipTransferRequestedIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+type FunctionsV1EventsMockOwnershipTransferRequested struct {
+ From common.Address
+ To common.Address
+ Raw types.Log
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*FunctionsV1EventsMockOwnershipTransferRequestedIterator, 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 := _FunctionsV1EventsMock.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule)
+ if err != nil {
+ return nil, err
+ }
+ return &FunctionsV1EventsMockOwnershipTransferRequestedIterator{contract: _FunctionsV1EventsMock.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *FunctionsV1EventsMockOwnershipTransferRequested, 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 := _FunctionsV1EventsMock.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(FunctionsV1EventsMockOwnershipTransferRequested)
+ if err := _FunctionsV1EventsMock.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 (_FunctionsV1EventsMock *FunctionsV1EventsMockFilterer) ParseOwnershipTransferRequested(log types.Log) (*FunctionsV1EventsMockOwnershipTransferRequested, error) {
+ event := new(FunctionsV1EventsMockOwnershipTransferRequested)
+ if err := _FunctionsV1EventsMock.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil {
+ return nil, err
+ }
+ event.Raw = log
+ return event, nil
+}
+
+type FunctionsV1EventsMockOwnershipTransferredIterator struct {
+ Event *FunctionsV1EventsMockOwnershipTransferred
+
+ contract *bind.BoundContract
+ event string
+
+ logs chan types.Log
+ sub ethereum.Subscription
+ done bool
+ fail error
+}
+
+func (it *FunctionsV1EventsMockOwnershipTransferredIterator) Next() bool {
+
+ if it.fail != nil {
+ return false
+ }
+
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(FunctionsV1EventsMockOwnershipTransferred)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+
+ select {
+ case log := <-it.logs:
+ it.Event = new(FunctionsV1EventsMockOwnershipTransferred)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+func (it *FunctionsV1EventsMockOwnershipTransferredIterator) Error() error {
+ return it.fail
+}
+
+func (it *FunctionsV1EventsMockOwnershipTransferredIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+type FunctionsV1EventsMockOwnershipTransferred struct {
+ From common.Address
+ To common.Address
+ Raw types.Log
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*FunctionsV1EventsMockOwnershipTransferredIterator, 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 := _FunctionsV1EventsMock.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule)
+ if err != nil {
+ return nil, err
+ }
+ return &FunctionsV1EventsMockOwnershipTransferredIterator{contract: _FunctionsV1EventsMock.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *FunctionsV1EventsMockOwnershipTransferred, 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 := _FunctionsV1EventsMock.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(FunctionsV1EventsMockOwnershipTransferred)
+ if err := _FunctionsV1EventsMock.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 (_FunctionsV1EventsMock *FunctionsV1EventsMockFilterer) ParseOwnershipTransferred(log types.Log) (*FunctionsV1EventsMockOwnershipTransferred, error) {
+ event := new(FunctionsV1EventsMockOwnershipTransferred)
+ if err := _FunctionsV1EventsMock.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil {
+ return nil, err
+ }
+ event.Raw = log
+ return event, nil
+}
+
+type FunctionsV1EventsMockPausedIterator struct {
+ Event *FunctionsV1EventsMockPaused
+
+ contract *bind.BoundContract
+ event string
+
+ logs chan types.Log
+ sub ethereum.Subscription
+ done bool
+ fail error
+}
+
+func (it *FunctionsV1EventsMockPausedIterator) Next() bool {
+
+ if it.fail != nil {
+ return false
+ }
+
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(FunctionsV1EventsMockPaused)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+
+ select {
+ case log := <-it.logs:
+ it.Event = new(FunctionsV1EventsMockPaused)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+func (it *FunctionsV1EventsMockPausedIterator) Error() error {
+ return it.fail
+}
+
+func (it *FunctionsV1EventsMockPausedIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+type FunctionsV1EventsMockPaused struct {
+ Account common.Address
+ Raw types.Log
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockFilterer) FilterPaused(opts *bind.FilterOpts) (*FunctionsV1EventsMockPausedIterator, error) {
+
+ logs, sub, err := _FunctionsV1EventsMock.contract.FilterLogs(opts, "Paused")
+ if err != nil {
+ return nil, err
+ }
+ return &FunctionsV1EventsMockPausedIterator{contract: _FunctionsV1EventsMock.contract, event: "Paused", logs: logs, sub: sub}, nil
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockFilterer) WatchPaused(opts *bind.WatchOpts, sink chan<- *FunctionsV1EventsMockPaused) (event.Subscription, error) {
+
+ logs, sub, err := _FunctionsV1EventsMock.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(FunctionsV1EventsMockPaused)
+ if err := _FunctionsV1EventsMock.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 (_FunctionsV1EventsMock *FunctionsV1EventsMockFilterer) ParsePaused(log types.Log) (*FunctionsV1EventsMockPaused, error) {
+ event := new(FunctionsV1EventsMockPaused)
+ if err := _FunctionsV1EventsMock.contract.UnpackLog(event, "Paused", log); err != nil {
+ return nil, err
+ }
+ event.Raw = log
+ return event, nil
+}
+
+type FunctionsV1EventsMockRequestNotProcessedIterator struct {
+ Event *FunctionsV1EventsMockRequestNotProcessed
+
+ contract *bind.BoundContract
+ event string
+
+ logs chan types.Log
+ sub ethereum.Subscription
+ done bool
+ fail error
+}
+
+func (it *FunctionsV1EventsMockRequestNotProcessedIterator) Next() bool {
+
+ if it.fail != nil {
+ return false
+ }
+
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(FunctionsV1EventsMockRequestNotProcessed)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+
+ select {
+ case log := <-it.logs:
+ it.Event = new(FunctionsV1EventsMockRequestNotProcessed)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+func (it *FunctionsV1EventsMockRequestNotProcessedIterator) Error() error {
+ return it.fail
+}
+
+func (it *FunctionsV1EventsMockRequestNotProcessedIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+type FunctionsV1EventsMockRequestNotProcessed struct {
+ RequestId [32]byte
+ Coordinator common.Address
+ Transmitter common.Address
+ ResultCode uint8
+ Raw types.Log
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockFilterer) FilterRequestNotProcessed(opts *bind.FilterOpts, requestId [][32]byte) (*FunctionsV1EventsMockRequestNotProcessedIterator, error) {
+
+ var requestIdRule []interface{}
+ for _, requestIdItem := range requestId {
+ requestIdRule = append(requestIdRule, requestIdItem)
+ }
+
+ logs, sub, err := _FunctionsV1EventsMock.contract.FilterLogs(opts, "RequestNotProcessed", requestIdRule)
+ if err != nil {
+ return nil, err
+ }
+ return &FunctionsV1EventsMockRequestNotProcessedIterator{contract: _FunctionsV1EventsMock.contract, event: "RequestNotProcessed", logs: logs, sub: sub}, nil
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockFilterer) WatchRequestNotProcessed(opts *bind.WatchOpts, sink chan<- *FunctionsV1EventsMockRequestNotProcessed, requestId [][32]byte) (event.Subscription, error) {
+
+ var requestIdRule []interface{}
+ for _, requestIdItem := range requestId {
+ requestIdRule = append(requestIdRule, requestIdItem)
+ }
+
+ logs, sub, err := _FunctionsV1EventsMock.contract.WatchLogs(opts, "RequestNotProcessed", 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(FunctionsV1EventsMockRequestNotProcessed)
+ if err := _FunctionsV1EventsMock.contract.UnpackLog(event, "RequestNotProcessed", log); err != nil {
+ return err
+ }
+ event.Raw = log
+
+ select {
+ case sink <- event:
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ }
+ }), nil
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockFilterer) ParseRequestNotProcessed(log types.Log) (*FunctionsV1EventsMockRequestNotProcessed, error) {
+ event := new(FunctionsV1EventsMockRequestNotProcessed)
+ if err := _FunctionsV1EventsMock.contract.UnpackLog(event, "RequestNotProcessed", log); err != nil {
+ return nil, err
+ }
+ event.Raw = log
+ return event, nil
+}
+
+type FunctionsV1EventsMockRequestProcessedIterator struct {
+ Event *FunctionsV1EventsMockRequestProcessed
+
+ contract *bind.BoundContract
+ event string
+
+ logs chan types.Log
+ sub ethereum.Subscription
+ done bool
+ fail error
+}
+
+func (it *FunctionsV1EventsMockRequestProcessedIterator) Next() bool {
+
+ if it.fail != nil {
+ return false
+ }
+
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(FunctionsV1EventsMockRequestProcessed)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+
+ select {
+ case log := <-it.logs:
+ it.Event = new(FunctionsV1EventsMockRequestProcessed)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+func (it *FunctionsV1EventsMockRequestProcessedIterator) Error() error {
+ return it.fail
+}
+
+func (it *FunctionsV1EventsMockRequestProcessedIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+type FunctionsV1EventsMockRequestProcessed struct {
+ RequestId [32]byte
+ SubscriptionId uint64
+ TotalCostJuels *big.Int
+ Transmitter common.Address
+ ResultCode uint8
+ Response []byte
+ Err []byte
+ CallbackReturnData []byte
+ Raw types.Log
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockFilterer) FilterRequestProcessed(opts *bind.FilterOpts, requestId [][32]byte, subscriptionId []uint64) (*FunctionsV1EventsMockRequestProcessedIterator, error) {
+
+ var requestIdRule []interface{}
+ for _, requestIdItem := range requestId {
+ requestIdRule = append(requestIdRule, requestIdItem)
+ }
+ var subscriptionIdRule []interface{}
+ for _, subscriptionIdItem := range subscriptionId {
+ subscriptionIdRule = append(subscriptionIdRule, subscriptionIdItem)
+ }
+
+ logs, sub, err := _FunctionsV1EventsMock.contract.FilterLogs(opts, "RequestProcessed", requestIdRule, subscriptionIdRule)
+ if err != nil {
+ return nil, err
+ }
+ return &FunctionsV1EventsMockRequestProcessedIterator{contract: _FunctionsV1EventsMock.contract, event: "RequestProcessed", logs: logs, sub: sub}, nil
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockFilterer) WatchRequestProcessed(opts *bind.WatchOpts, sink chan<- *FunctionsV1EventsMockRequestProcessed, requestId [][32]byte, subscriptionId []uint64) (event.Subscription, error) {
+
+ var requestIdRule []interface{}
+ for _, requestIdItem := range requestId {
+ requestIdRule = append(requestIdRule, requestIdItem)
+ }
+ var subscriptionIdRule []interface{}
+ for _, subscriptionIdItem := range subscriptionId {
+ subscriptionIdRule = append(subscriptionIdRule, subscriptionIdItem)
+ }
+
+ logs, sub, err := _FunctionsV1EventsMock.contract.WatchLogs(opts, "RequestProcessed", requestIdRule, subscriptionIdRule)
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+
+ event := new(FunctionsV1EventsMockRequestProcessed)
+ if err := _FunctionsV1EventsMock.contract.UnpackLog(event, "RequestProcessed", log); err != nil {
+ return err
+ }
+ event.Raw = log
+
+ select {
+ case sink <- event:
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ }
+ }), nil
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockFilterer) ParseRequestProcessed(log types.Log) (*FunctionsV1EventsMockRequestProcessed, error) {
+ event := new(FunctionsV1EventsMockRequestProcessed)
+ if err := _FunctionsV1EventsMock.contract.UnpackLog(event, "RequestProcessed", log); err != nil {
+ return nil, err
+ }
+ event.Raw = log
+ return event, nil
+}
+
+type FunctionsV1EventsMockRequestStartIterator struct {
+ Event *FunctionsV1EventsMockRequestStart
+
+ contract *bind.BoundContract
+ event string
+
+ logs chan types.Log
+ sub ethereum.Subscription
+ done bool
+ fail error
+}
+
+func (it *FunctionsV1EventsMockRequestStartIterator) Next() bool {
+
+ if it.fail != nil {
+ return false
+ }
+
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(FunctionsV1EventsMockRequestStart)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+
+ select {
+ case log := <-it.logs:
+ it.Event = new(FunctionsV1EventsMockRequestStart)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+func (it *FunctionsV1EventsMockRequestStartIterator) Error() error {
+ return it.fail
+}
+
+func (it *FunctionsV1EventsMockRequestStartIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+type FunctionsV1EventsMockRequestStart struct {
+ RequestId [32]byte
+ DonId [32]byte
+ SubscriptionId uint64
+ SubscriptionOwner common.Address
+ RequestingContract common.Address
+ RequestInitiator common.Address
+ Data []byte
+ DataVersion uint16
+ CallbackGasLimit uint32
+ EstimatedTotalCostJuels *big.Int
+ Raw types.Log
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockFilterer) FilterRequestStart(opts *bind.FilterOpts, requestId [][32]byte, donId [][32]byte, subscriptionId []uint64) (*FunctionsV1EventsMockRequestStartIterator, error) {
+
+ var requestIdRule []interface{}
+ for _, requestIdItem := range requestId {
+ requestIdRule = append(requestIdRule, requestIdItem)
+ }
+ var donIdRule []interface{}
+ for _, donIdItem := range donId {
+ donIdRule = append(donIdRule, donIdItem)
+ }
+ var subscriptionIdRule []interface{}
+ for _, subscriptionIdItem := range subscriptionId {
+ subscriptionIdRule = append(subscriptionIdRule, subscriptionIdItem)
+ }
+
+ logs, sub, err := _FunctionsV1EventsMock.contract.FilterLogs(opts, "RequestStart", requestIdRule, donIdRule, subscriptionIdRule)
+ if err != nil {
+ return nil, err
+ }
+ return &FunctionsV1EventsMockRequestStartIterator{contract: _FunctionsV1EventsMock.contract, event: "RequestStart", logs: logs, sub: sub}, nil
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockFilterer) WatchRequestStart(opts *bind.WatchOpts, sink chan<- *FunctionsV1EventsMockRequestStart, requestId [][32]byte, donId [][32]byte, subscriptionId []uint64) (event.Subscription, error) {
+
+ var requestIdRule []interface{}
+ for _, requestIdItem := range requestId {
+ requestIdRule = append(requestIdRule, requestIdItem)
+ }
+ var donIdRule []interface{}
+ for _, donIdItem := range donId {
+ donIdRule = append(donIdRule, donIdItem)
+ }
+ var subscriptionIdRule []interface{}
+ for _, subscriptionIdItem := range subscriptionId {
+ subscriptionIdRule = append(subscriptionIdRule, subscriptionIdItem)
+ }
+
+ logs, sub, err := _FunctionsV1EventsMock.contract.WatchLogs(opts, "RequestStart", requestIdRule, donIdRule, subscriptionIdRule)
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+
+ event := new(FunctionsV1EventsMockRequestStart)
+ if err := _FunctionsV1EventsMock.contract.UnpackLog(event, "RequestStart", log); err != nil {
+ return err
+ }
+ event.Raw = log
+
+ select {
+ case sink <- event:
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ }
+ }), nil
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockFilterer) ParseRequestStart(log types.Log) (*FunctionsV1EventsMockRequestStart, error) {
+ event := new(FunctionsV1EventsMockRequestStart)
+ if err := _FunctionsV1EventsMock.contract.UnpackLog(event, "RequestStart", log); err != nil {
+ return nil, err
+ }
+ event.Raw = log
+ return event, nil
+}
+
+type FunctionsV1EventsMockRequestTimedOutIterator struct {
+ Event *FunctionsV1EventsMockRequestTimedOut
+
+ contract *bind.BoundContract
+ event string
+
+ logs chan types.Log
+ sub ethereum.Subscription
+ done bool
+ fail error
+}
+
+func (it *FunctionsV1EventsMockRequestTimedOutIterator) Next() bool {
+
+ if it.fail != nil {
+ return false
+ }
+
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(FunctionsV1EventsMockRequestTimedOut)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+
+ select {
+ case log := <-it.logs:
+ it.Event = new(FunctionsV1EventsMockRequestTimedOut)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+func (it *FunctionsV1EventsMockRequestTimedOutIterator) Error() error {
+ return it.fail
+}
+
+func (it *FunctionsV1EventsMockRequestTimedOutIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+type FunctionsV1EventsMockRequestTimedOut struct {
+ RequestId [32]byte
+ Raw types.Log
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockFilterer) FilterRequestTimedOut(opts *bind.FilterOpts, requestId [][32]byte) (*FunctionsV1EventsMockRequestTimedOutIterator, error) {
+
+ var requestIdRule []interface{}
+ for _, requestIdItem := range requestId {
+ requestIdRule = append(requestIdRule, requestIdItem)
+ }
+
+ logs, sub, err := _FunctionsV1EventsMock.contract.FilterLogs(opts, "RequestTimedOut", requestIdRule)
+ if err != nil {
+ return nil, err
+ }
+ return &FunctionsV1EventsMockRequestTimedOutIterator{contract: _FunctionsV1EventsMock.contract, event: "RequestTimedOut", logs: logs, sub: sub}, nil
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockFilterer) WatchRequestTimedOut(opts *bind.WatchOpts, sink chan<- *FunctionsV1EventsMockRequestTimedOut, requestId [][32]byte) (event.Subscription, error) {
+
+ var requestIdRule []interface{}
+ for _, requestIdItem := range requestId {
+ requestIdRule = append(requestIdRule, requestIdItem)
+ }
+
+ logs, sub, err := _FunctionsV1EventsMock.contract.WatchLogs(opts, "RequestTimedOut", requestIdRule)
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+
+ event := new(FunctionsV1EventsMockRequestTimedOut)
+ if err := _FunctionsV1EventsMock.contract.UnpackLog(event, "RequestTimedOut", log); err != nil {
+ return err
+ }
+ event.Raw = log
+
+ select {
+ case sink <- event:
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ }
+ }), nil
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockFilterer) ParseRequestTimedOut(log types.Log) (*FunctionsV1EventsMockRequestTimedOut, error) {
+ event := new(FunctionsV1EventsMockRequestTimedOut)
+ if err := _FunctionsV1EventsMock.contract.UnpackLog(event, "RequestTimedOut", log); err != nil {
+ return nil, err
+ }
+ event.Raw = log
+ return event, nil
+}
+
+type FunctionsV1EventsMockSubscriptionCanceledIterator struct {
+ Event *FunctionsV1EventsMockSubscriptionCanceled
+
+ contract *bind.BoundContract
+ event string
+
+ logs chan types.Log
+ sub ethereum.Subscription
+ done bool
+ fail error
+}
+
+func (it *FunctionsV1EventsMockSubscriptionCanceledIterator) Next() bool {
+
+ if it.fail != nil {
+ return false
+ }
+
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(FunctionsV1EventsMockSubscriptionCanceled)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+
+ select {
+ case log := <-it.logs:
+ it.Event = new(FunctionsV1EventsMockSubscriptionCanceled)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+func (it *FunctionsV1EventsMockSubscriptionCanceledIterator) Error() error {
+ return it.fail
+}
+
+func (it *FunctionsV1EventsMockSubscriptionCanceledIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+type FunctionsV1EventsMockSubscriptionCanceled struct {
+ SubscriptionId uint64
+ FundsRecipient common.Address
+ FundsAmount *big.Int
+ Raw types.Log
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockFilterer) FilterSubscriptionCanceled(opts *bind.FilterOpts, subscriptionId []uint64) (*FunctionsV1EventsMockSubscriptionCanceledIterator, error) {
+
+ var subscriptionIdRule []interface{}
+ for _, subscriptionIdItem := range subscriptionId {
+ subscriptionIdRule = append(subscriptionIdRule, subscriptionIdItem)
+ }
+
+ logs, sub, err := _FunctionsV1EventsMock.contract.FilterLogs(opts, "SubscriptionCanceled", subscriptionIdRule)
+ if err != nil {
+ return nil, err
+ }
+ return &FunctionsV1EventsMockSubscriptionCanceledIterator{contract: _FunctionsV1EventsMock.contract, event: "SubscriptionCanceled", logs: logs, sub: sub}, nil
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockFilterer) WatchSubscriptionCanceled(opts *bind.WatchOpts, sink chan<- *FunctionsV1EventsMockSubscriptionCanceled, subscriptionId []uint64) (event.Subscription, error) {
+
+ var subscriptionIdRule []interface{}
+ for _, subscriptionIdItem := range subscriptionId {
+ subscriptionIdRule = append(subscriptionIdRule, subscriptionIdItem)
+ }
+
+ logs, sub, err := _FunctionsV1EventsMock.contract.WatchLogs(opts, "SubscriptionCanceled", subscriptionIdRule)
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+
+ event := new(FunctionsV1EventsMockSubscriptionCanceled)
+ if err := _FunctionsV1EventsMock.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 (_FunctionsV1EventsMock *FunctionsV1EventsMockFilterer) ParseSubscriptionCanceled(log types.Log) (*FunctionsV1EventsMockSubscriptionCanceled, error) {
+ event := new(FunctionsV1EventsMockSubscriptionCanceled)
+ if err := _FunctionsV1EventsMock.contract.UnpackLog(event, "SubscriptionCanceled", log); err != nil {
+ return nil, err
+ }
+ event.Raw = log
+ return event, nil
+}
+
+type FunctionsV1EventsMockSubscriptionConsumerAddedIterator struct {
+ Event *FunctionsV1EventsMockSubscriptionConsumerAdded
+
+ contract *bind.BoundContract
+ event string
+
+ logs chan types.Log
+ sub ethereum.Subscription
+ done bool
+ fail error
+}
+
+func (it *FunctionsV1EventsMockSubscriptionConsumerAddedIterator) Next() bool {
+
+ if it.fail != nil {
+ return false
+ }
+
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(FunctionsV1EventsMockSubscriptionConsumerAdded)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+
+ select {
+ case log := <-it.logs:
+ it.Event = new(FunctionsV1EventsMockSubscriptionConsumerAdded)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+func (it *FunctionsV1EventsMockSubscriptionConsumerAddedIterator) Error() error {
+ return it.fail
+}
+
+func (it *FunctionsV1EventsMockSubscriptionConsumerAddedIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+type FunctionsV1EventsMockSubscriptionConsumerAdded struct {
+ SubscriptionId uint64
+ Consumer common.Address
+ Raw types.Log
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockFilterer) FilterSubscriptionConsumerAdded(opts *bind.FilterOpts, subscriptionId []uint64) (*FunctionsV1EventsMockSubscriptionConsumerAddedIterator, error) {
+
+ var subscriptionIdRule []interface{}
+ for _, subscriptionIdItem := range subscriptionId {
+ subscriptionIdRule = append(subscriptionIdRule, subscriptionIdItem)
+ }
+
+ logs, sub, err := _FunctionsV1EventsMock.contract.FilterLogs(opts, "SubscriptionConsumerAdded", subscriptionIdRule)
+ if err != nil {
+ return nil, err
+ }
+ return &FunctionsV1EventsMockSubscriptionConsumerAddedIterator{contract: _FunctionsV1EventsMock.contract, event: "SubscriptionConsumerAdded", logs: logs, sub: sub}, nil
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockFilterer) WatchSubscriptionConsumerAdded(opts *bind.WatchOpts, sink chan<- *FunctionsV1EventsMockSubscriptionConsumerAdded, subscriptionId []uint64) (event.Subscription, error) {
+
+ var subscriptionIdRule []interface{}
+ for _, subscriptionIdItem := range subscriptionId {
+ subscriptionIdRule = append(subscriptionIdRule, subscriptionIdItem)
+ }
+
+ logs, sub, err := _FunctionsV1EventsMock.contract.WatchLogs(opts, "SubscriptionConsumerAdded", subscriptionIdRule)
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+
+ event := new(FunctionsV1EventsMockSubscriptionConsumerAdded)
+ if err := _FunctionsV1EventsMock.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 (_FunctionsV1EventsMock *FunctionsV1EventsMockFilterer) ParseSubscriptionConsumerAdded(log types.Log) (*FunctionsV1EventsMockSubscriptionConsumerAdded, error) {
+ event := new(FunctionsV1EventsMockSubscriptionConsumerAdded)
+ if err := _FunctionsV1EventsMock.contract.UnpackLog(event, "SubscriptionConsumerAdded", log); err != nil {
+ return nil, err
+ }
+ event.Raw = log
+ return event, nil
+}
+
+type FunctionsV1EventsMockSubscriptionConsumerRemovedIterator struct {
+ Event *FunctionsV1EventsMockSubscriptionConsumerRemoved
+
+ contract *bind.BoundContract
+ event string
+
+ logs chan types.Log
+ sub ethereum.Subscription
+ done bool
+ fail error
+}
+
+func (it *FunctionsV1EventsMockSubscriptionConsumerRemovedIterator) Next() bool {
+
+ if it.fail != nil {
+ return false
+ }
+
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(FunctionsV1EventsMockSubscriptionConsumerRemoved)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+
+ select {
+ case log := <-it.logs:
+ it.Event = new(FunctionsV1EventsMockSubscriptionConsumerRemoved)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+func (it *FunctionsV1EventsMockSubscriptionConsumerRemovedIterator) Error() error {
+ return it.fail
+}
+
+func (it *FunctionsV1EventsMockSubscriptionConsumerRemovedIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+type FunctionsV1EventsMockSubscriptionConsumerRemoved struct {
+ SubscriptionId uint64
+ Consumer common.Address
+ Raw types.Log
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockFilterer) FilterSubscriptionConsumerRemoved(opts *bind.FilterOpts, subscriptionId []uint64) (*FunctionsV1EventsMockSubscriptionConsumerRemovedIterator, error) {
+
+ var subscriptionIdRule []interface{}
+ for _, subscriptionIdItem := range subscriptionId {
+ subscriptionIdRule = append(subscriptionIdRule, subscriptionIdItem)
+ }
+
+ logs, sub, err := _FunctionsV1EventsMock.contract.FilterLogs(opts, "SubscriptionConsumerRemoved", subscriptionIdRule)
+ if err != nil {
+ return nil, err
+ }
+ return &FunctionsV1EventsMockSubscriptionConsumerRemovedIterator{contract: _FunctionsV1EventsMock.contract, event: "SubscriptionConsumerRemoved", logs: logs, sub: sub}, nil
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockFilterer) WatchSubscriptionConsumerRemoved(opts *bind.WatchOpts, sink chan<- *FunctionsV1EventsMockSubscriptionConsumerRemoved, subscriptionId []uint64) (event.Subscription, error) {
+
+ var subscriptionIdRule []interface{}
+ for _, subscriptionIdItem := range subscriptionId {
+ subscriptionIdRule = append(subscriptionIdRule, subscriptionIdItem)
+ }
+
+ logs, sub, err := _FunctionsV1EventsMock.contract.WatchLogs(opts, "SubscriptionConsumerRemoved", subscriptionIdRule)
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+
+ event := new(FunctionsV1EventsMockSubscriptionConsumerRemoved)
+ if err := _FunctionsV1EventsMock.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 (_FunctionsV1EventsMock *FunctionsV1EventsMockFilterer) ParseSubscriptionConsumerRemoved(log types.Log) (*FunctionsV1EventsMockSubscriptionConsumerRemoved, error) {
+ event := new(FunctionsV1EventsMockSubscriptionConsumerRemoved)
+ if err := _FunctionsV1EventsMock.contract.UnpackLog(event, "SubscriptionConsumerRemoved", log); err != nil {
+ return nil, err
+ }
+ event.Raw = log
+ return event, nil
+}
+
+type FunctionsV1EventsMockSubscriptionCreatedIterator struct {
+ Event *FunctionsV1EventsMockSubscriptionCreated
+
+ contract *bind.BoundContract
+ event string
+
+ logs chan types.Log
+ sub ethereum.Subscription
+ done bool
+ fail error
+}
+
+func (it *FunctionsV1EventsMockSubscriptionCreatedIterator) Next() bool {
+
+ if it.fail != nil {
+ return false
+ }
+
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(FunctionsV1EventsMockSubscriptionCreated)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+
+ select {
+ case log := <-it.logs:
+ it.Event = new(FunctionsV1EventsMockSubscriptionCreated)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+func (it *FunctionsV1EventsMockSubscriptionCreatedIterator) Error() error {
+ return it.fail
+}
+
+func (it *FunctionsV1EventsMockSubscriptionCreatedIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+type FunctionsV1EventsMockSubscriptionCreated struct {
+ SubscriptionId uint64
+ Owner common.Address
+ Raw types.Log
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockFilterer) FilterSubscriptionCreated(opts *bind.FilterOpts, subscriptionId []uint64) (*FunctionsV1EventsMockSubscriptionCreatedIterator, error) {
+
+ var subscriptionIdRule []interface{}
+ for _, subscriptionIdItem := range subscriptionId {
+ subscriptionIdRule = append(subscriptionIdRule, subscriptionIdItem)
+ }
+
+ logs, sub, err := _FunctionsV1EventsMock.contract.FilterLogs(opts, "SubscriptionCreated", subscriptionIdRule)
+ if err != nil {
+ return nil, err
+ }
+ return &FunctionsV1EventsMockSubscriptionCreatedIterator{contract: _FunctionsV1EventsMock.contract, event: "SubscriptionCreated", logs: logs, sub: sub}, nil
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockFilterer) WatchSubscriptionCreated(opts *bind.WatchOpts, sink chan<- *FunctionsV1EventsMockSubscriptionCreated, subscriptionId []uint64) (event.Subscription, error) {
+
+ var subscriptionIdRule []interface{}
+ for _, subscriptionIdItem := range subscriptionId {
+ subscriptionIdRule = append(subscriptionIdRule, subscriptionIdItem)
+ }
+
+ logs, sub, err := _FunctionsV1EventsMock.contract.WatchLogs(opts, "SubscriptionCreated", subscriptionIdRule)
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+
+ event := new(FunctionsV1EventsMockSubscriptionCreated)
+ if err := _FunctionsV1EventsMock.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 (_FunctionsV1EventsMock *FunctionsV1EventsMockFilterer) ParseSubscriptionCreated(log types.Log) (*FunctionsV1EventsMockSubscriptionCreated, error) {
+ event := new(FunctionsV1EventsMockSubscriptionCreated)
+ if err := _FunctionsV1EventsMock.contract.UnpackLog(event, "SubscriptionCreated", log); err != nil {
+ return nil, err
+ }
+ event.Raw = log
+ return event, nil
+}
+
+type FunctionsV1EventsMockSubscriptionFundedIterator struct {
+ Event *FunctionsV1EventsMockSubscriptionFunded
+
+ contract *bind.BoundContract
+ event string
+
+ logs chan types.Log
+ sub ethereum.Subscription
+ done bool
+ fail error
+}
+
+func (it *FunctionsV1EventsMockSubscriptionFundedIterator) Next() bool {
+
+ if it.fail != nil {
+ return false
+ }
+
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(FunctionsV1EventsMockSubscriptionFunded)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+
+ select {
+ case log := <-it.logs:
+ it.Event = new(FunctionsV1EventsMockSubscriptionFunded)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+func (it *FunctionsV1EventsMockSubscriptionFundedIterator) Error() error {
+ return it.fail
+}
+
+func (it *FunctionsV1EventsMockSubscriptionFundedIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+type FunctionsV1EventsMockSubscriptionFunded struct {
+ SubscriptionId uint64
+ OldBalance *big.Int
+ NewBalance *big.Int
+ Raw types.Log
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockFilterer) FilterSubscriptionFunded(opts *bind.FilterOpts, subscriptionId []uint64) (*FunctionsV1EventsMockSubscriptionFundedIterator, error) {
+
+ var subscriptionIdRule []interface{}
+ for _, subscriptionIdItem := range subscriptionId {
+ subscriptionIdRule = append(subscriptionIdRule, subscriptionIdItem)
+ }
+
+ logs, sub, err := _FunctionsV1EventsMock.contract.FilterLogs(opts, "SubscriptionFunded", subscriptionIdRule)
+ if err != nil {
+ return nil, err
+ }
+ return &FunctionsV1EventsMockSubscriptionFundedIterator{contract: _FunctionsV1EventsMock.contract, event: "SubscriptionFunded", logs: logs, sub: sub}, nil
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockFilterer) WatchSubscriptionFunded(opts *bind.WatchOpts, sink chan<- *FunctionsV1EventsMockSubscriptionFunded, subscriptionId []uint64) (event.Subscription, error) {
+
+ var subscriptionIdRule []interface{}
+ for _, subscriptionIdItem := range subscriptionId {
+ subscriptionIdRule = append(subscriptionIdRule, subscriptionIdItem)
+ }
+
+ logs, sub, err := _FunctionsV1EventsMock.contract.WatchLogs(opts, "SubscriptionFunded", subscriptionIdRule)
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+
+ event := new(FunctionsV1EventsMockSubscriptionFunded)
+ if err := _FunctionsV1EventsMock.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 (_FunctionsV1EventsMock *FunctionsV1EventsMockFilterer) ParseSubscriptionFunded(log types.Log) (*FunctionsV1EventsMockSubscriptionFunded, error) {
+ event := new(FunctionsV1EventsMockSubscriptionFunded)
+ if err := _FunctionsV1EventsMock.contract.UnpackLog(event, "SubscriptionFunded", log); err != nil {
+ return nil, err
+ }
+ event.Raw = log
+ return event, nil
+}
+
+type FunctionsV1EventsMockSubscriptionOwnerTransferRequestedIterator struct {
+ Event *FunctionsV1EventsMockSubscriptionOwnerTransferRequested
+
+ contract *bind.BoundContract
+ event string
+
+ logs chan types.Log
+ sub ethereum.Subscription
+ done bool
+ fail error
+}
+
+func (it *FunctionsV1EventsMockSubscriptionOwnerTransferRequestedIterator) Next() bool {
+
+ if it.fail != nil {
+ return false
+ }
+
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(FunctionsV1EventsMockSubscriptionOwnerTransferRequested)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+
+ select {
+ case log := <-it.logs:
+ it.Event = new(FunctionsV1EventsMockSubscriptionOwnerTransferRequested)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+func (it *FunctionsV1EventsMockSubscriptionOwnerTransferRequestedIterator) Error() error {
+ return it.fail
+}
+
+func (it *FunctionsV1EventsMockSubscriptionOwnerTransferRequestedIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+type FunctionsV1EventsMockSubscriptionOwnerTransferRequested struct {
+ SubscriptionId uint64
+ From common.Address
+ To common.Address
+ Raw types.Log
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockFilterer) FilterSubscriptionOwnerTransferRequested(opts *bind.FilterOpts, subscriptionId []uint64) (*FunctionsV1EventsMockSubscriptionOwnerTransferRequestedIterator, error) {
+
+ var subscriptionIdRule []interface{}
+ for _, subscriptionIdItem := range subscriptionId {
+ subscriptionIdRule = append(subscriptionIdRule, subscriptionIdItem)
+ }
+
+ logs, sub, err := _FunctionsV1EventsMock.contract.FilterLogs(opts, "SubscriptionOwnerTransferRequested", subscriptionIdRule)
+ if err != nil {
+ return nil, err
+ }
+ return &FunctionsV1EventsMockSubscriptionOwnerTransferRequestedIterator{contract: _FunctionsV1EventsMock.contract, event: "SubscriptionOwnerTransferRequested", logs: logs, sub: sub}, nil
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockFilterer) WatchSubscriptionOwnerTransferRequested(opts *bind.WatchOpts, sink chan<- *FunctionsV1EventsMockSubscriptionOwnerTransferRequested, subscriptionId []uint64) (event.Subscription, error) {
+
+ var subscriptionIdRule []interface{}
+ for _, subscriptionIdItem := range subscriptionId {
+ subscriptionIdRule = append(subscriptionIdRule, subscriptionIdItem)
+ }
+
+ logs, sub, err := _FunctionsV1EventsMock.contract.WatchLogs(opts, "SubscriptionOwnerTransferRequested", subscriptionIdRule)
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+
+ event := new(FunctionsV1EventsMockSubscriptionOwnerTransferRequested)
+ if err := _FunctionsV1EventsMock.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 (_FunctionsV1EventsMock *FunctionsV1EventsMockFilterer) ParseSubscriptionOwnerTransferRequested(log types.Log) (*FunctionsV1EventsMockSubscriptionOwnerTransferRequested, error) {
+ event := new(FunctionsV1EventsMockSubscriptionOwnerTransferRequested)
+ if err := _FunctionsV1EventsMock.contract.UnpackLog(event, "SubscriptionOwnerTransferRequested", log); err != nil {
+ return nil, err
+ }
+ event.Raw = log
+ return event, nil
+}
+
+type FunctionsV1EventsMockSubscriptionOwnerTransferredIterator struct {
+ Event *FunctionsV1EventsMockSubscriptionOwnerTransferred
+
+ contract *bind.BoundContract
+ event string
+
+ logs chan types.Log
+ sub ethereum.Subscription
+ done bool
+ fail error
+}
+
+func (it *FunctionsV1EventsMockSubscriptionOwnerTransferredIterator) Next() bool {
+
+ if it.fail != nil {
+ return false
+ }
+
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(FunctionsV1EventsMockSubscriptionOwnerTransferred)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+
+ select {
+ case log := <-it.logs:
+ it.Event = new(FunctionsV1EventsMockSubscriptionOwnerTransferred)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+func (it *FunctionsV1EventsMockSubscriptionOwnerTransferredIterator) Error() error {
+ return it.fail
+}
+
+func (it *FunctionsV1EventsMockSubscriptionOwnerTransferredIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+type FunctionsV1EventsMockSubscriptionOwnerTransferred struct {
+ SubscriptionId uint64
+ From common.Address
+ To common.Address
+ Raw types.Log
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockFilterer) FilterSubscriptionOwnerTransferred(opts *bind.FilterOpts, subscriptionId []uint64) (*FunctionsV1EventsMockSubscriptionOwnerTransferredIterator, error) {
+
+ var subscriptionIdRule []interface{}
+ for _, subscriptionIdItem := range subscriptionId {
+ subscriptionIdRule = append(subscriptionIdRule, subscriptionIdItem)
+ }
+
+ logs, sub, err := _FunctionsV1EventsMock.contract.FilterLogs(opts, "SubscriptionOwnerTransferred", subscriptionIdRule)
+ if err != nil {
+ return nil, err
+ }
+ return &FunctionsV1EventsMockSubscriptionOwnerTransferredIterator{contract: _FunctionsV1EventsMock.contract, event: "SubscriptionOwnerTransferred", logs: logs, sub: sub}, nil
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockFilterer) WatchSubscriptionOwnerTransferred(opts *bind.WatchOpts, sink chan<- *FunctionsV1EventsMockSubscriptionOwnerTransferred, subscriptionId []uint64) (event.Subscription, error) {
+
+ var subscriptionIdRule []interface{}
+ for _, subscriptionIdItem := range subscriptionId {
+ subscriptionIdRule = append(subscriptionIdRule, subscriptionIdItem)
+ }
+
+ logs, sub, err := _FunctionsV1EventsMock.contract.WatchLogs(opts, "SubscriptionOwnerTransferred", subscriptionIdRule)
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+
+ event := new(FunctionsV1EventsMockSubscriptionOwnerTransferred)
+ if err := _FunctionsV1EventsMock.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 (_FunctionsV1EventsMock *FunctionsV1EventsMockFilterer) ParseSubscriptionOwnerTransferred(log types.Log) (*FunctionsV1EventsMockSubscriptionOwnerTransferred, error) {
+ event := new(FunctionsV1EventsMockSubscriptionOwnerTransferred)
+ if err := _FunctionsV1EventsMock.contract.UnpackLog(event, "SubscriptionOwnerTransferred", log); err != nil {
+ return nil, err
+ }
+ event.Raw = log
+ return event, nil
+}
+
+type FunctionsV1EventsMockUnpausedIterator struct {
+ Event *FunctionsV1EventsMockUnpaused
+
+ contract *bind.BoundContract
+ event string
+
+ logs chan types.Log
+ sub ethereum.Subscription
+ done bool
+ fail error
+}
+
+func (it *FunctionsV1EventsMockUnpausedIterator) Next() bool {
+
+ if it.fail != nil {
+ return false
+ }
+
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(FunctionsV1EventsMockUnpaused)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+
+ select {
+ case log := <-it.logs:
+ it.Event = new(FunctionsV1EventsMockUnpaused)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+func (it *FunctionsV1EventsMockUnpausedIterator) Error() error {
+ return it.fail
+}
+
+func (it *FunctionsV1EventsMockUnpausedIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+type FunctionsV1EventsMockUnpaused struct {
+ Account common.Address
+ Raw types.Log
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockFilterer) FilterUnpaused(opts *bind.FilterOpts) (*FunctionsV1EventsMockUnpausedIterator, error) {
+
+ logs, sub, err := _FunctionsV1EventsMock.contract.FilterLogs(opts, "Unpaused")
+ if err != nil {
+ return nil, err
+ }
+ return &FunctionsV1EventsMockUnpausedIterator{contract: _FunctionsV1EventsMock.contract, event: "Unpaused", logs: logs, sub: sub}, nil
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMockFilterer) WatchUnpaused(opts *bind.WatchOpts, sink chan<- *FunctionsV1EventsMockUnpaused) (event.Subscription, error) {
+
+ logs, sub, err := _FunctionsV1EventsMock.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(FunctionsV1EventsMockUnpaused)
+ if err := _FunctionsV1EventsMock.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 (_FunctionsV1EventsMock *FunctionsV1EventsMockFilterer) ParseUnpaused(log types.Log) (*FunctionsV1EventsMockUnpaused, error) {
+ event := new(FunctionsV1EventsMockUnpaused)
+ if err := _FunctionsV1EventsMock.contract.UnpackLog(event, "Unpaused", log); err != nil {
+ return nil, err
+ }
+ event.Raw = log
+ return event, nil
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMock) ParseLog(log types.Log) (generated.AbigenLog, error) {
+ switch log.Topics[0] {
+ case _FunctionsV1EventsMock.abi.Events["ConfigUpdated"].ID:
+ return _FunctionsV1EventsMock.ParseConfigUpdated(log)
+ case _FunctionsV1EventsMock.abi.Events["ContractProposed"].ID:
+ return _FunctionsV1EventsMock.ParseContractProposed(log)
+ case _FunctionsV1EventsMock.abi.Events["ContractUpdated"].ID:
+ return _FunctionsV1EventsMock.ParseContractUpdated(log)
+ case _FunctionsV1EventsMock.abi.Events["FundsRecovered"].ID:
+ return _FunctionsV1EventsMock.ParseFundsRecovered(log)
+ case _FunctionsV1EventsMock.abi.Events["OwnershipTransferRequested"].ID:
+ return _FunctionsV1EventsMock.ParseOwnershipTransferRequested(log)
+ case _FunctionsV1EventsMock.abi.Events["OwnershipTransferred"].ID:
+ return _FunctionsV1EventsMock.ParseOwnershipTransferred(log)
+ case _FunctionsV1EventsMock.abi.Events["Paused"].ID:
+ return _FunctionsV1EventsMock.ParsePaused(log)
+ case _FunctionsV1EventsMock.abi.Events["RequestNotProcessed"].ID:
+ return _FunctionsV1EventsMock.ParseRequestNotProcessed(log)
+ case _FunctionsV1EventsMock.abi.Events["RequestProcessed"].ID:
+ return _FunctionsV1EventsMock.ParseRequestProcessed(log)
+ case _FunctionsV1EventsMock.abi.Events["RequestStart"].ID:
+ return _FunctionsV1EventsMock.ParseRequestStart(log)
+ case _FunctionsV1EventsMock.abi.Events["RequestTimedOut"].ID:
+ return _FunctionsV1EventsMock.ParseRequestTimedOut(log)
+ case _FunctionsV1EventsMock.abi.Events["SubscriptionCanceled"].ID:
+ return _FunctionsV1EventsMock.ParseSubscriptionCanceled(log)
+ case _FunctionsV1EventsMock.abi.Events["SubscriptionConsumerAdded"].ID:
+ return _FunctionsV1EventsMock.ParseSubscriptionConsumerAdded(log)
+ case _FunctionsV1EventsMock.abi.Events["SubscriptionConsumerRemoved"].ID:
+ return _FunctionsV1EventsMock.ParseSubscriptionConsumerRemoved(log)
+ case _FunctionsV1EventsMock.abi.Events["SubscriptionCreated"].ID:
+ return _FunctionsV1EventsMock.ParseSubscriptionCreated(log)
+ case _FunctionsV1EventsMock.abi.Events["SubscriptionFunded"].ID:
+ return _FunctionsV1EventsMock.ParseSubscriptionFunded(log)
+ case _FunctionsV1EventsMock.abi.Events["SubscriptionOwnerTransferRequested"].ID:
+ return _FunctionsV1EventsMock.ParseSubscriptionOwnerTransferRequested(log)
+ case _FunctionsV1EventsMock.abi.Events["SubscriptionOwnerTransferred"].ID:
+ return _FunctionsV1EventsMock.ParseSubscriptionOwnerTransferred(log)
+ case _FunctionsV1EventsMock.abi.Events["Unpaused"].ID:
+ return _FunctionsV1EventsMock.ParseUnpaused(log)
+
+ default:
+ return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0])
+ }
+}
+
+func (FunctionsV1EventsMockConfigUpdated) Topic() common.Hash {
+ return common.HexToHash("0x049ce2e6e1420eb4b07b425e90129186833eb346bda40b37d5d921aad482f71c")
+}
+
+func (FunctionsV1EventsMockContractProposed) Topic() common.Hash {
+ return common.HexToHash("0x8b052f0f4bf82fede7daffea71592b29d5ef86af1f3c7daaa0345dbb2f52f481")
+}
+
+func (FunctionsV1EventsMockContractUpdated) Topic() common.Hash {
+ return common.HexToHash("0xf8a6175bca1ba37d682089187edc5e20a859989727f10ca6bd9a5bc0de8caf94")
+}
+
+func (FunctionsV1EventsMockFundsRecovered) Topic() common.Hash {
+ return common.HexToHash("0x59bfc682b673f8cbf945f1e454df9334834abf7dfe7f92237ca29ecb9b436600")
+}
+
+func (FunctionsV1EventsMockOwnershipTransferRequested) Topic() common.Hash {
+ return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278")
+}
+
+func (FunctionsV1EventsMockOwnershipTransferred) Topic() common.Hash {
+ return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0")
+}
+
+func (FunctionsV1EventsMockPaused) Topic() common.Hash {
+ return common.HexToHash("0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258")
+}
+
+func (FunctionsV1EventsMockRequestNotProcessed) Topic() common.Hash {
+ return common.HexToHash("0x1a90e9a50793db2e394cf581e7c522e10c358a81e70acf6b5a0edd620c08dee1")
+}
+
+func (FunctionsV1EventsMockRequestProcessed) Topic() common.Hash {
+ return common.HexToHash("0x64778f26c70b60a8d7e29e2451b3844302d959448401c0535b768ed88c6b505e")
+}
+
+func (FunctionsV1EventsMockRequestStart) Topic() common.Hash {
+ return common.HexToHash("0xf67aec45c9a7ede407974a3e0c3a743dffeab99ee3f2d4c9a8144c2ebf2c7ec9")
+}
+
+func (FunctionsV1EventsMockRequestTimedOut) Topic() common.Hash {
+ return common.HexToHash("0xf1ca1e9147be737b04a2b018a79405f687a97de8dd8a2559bbe62357343af414")
+}
+
+func (FunctionsV1EventsMockSubscriptionCanceled) Topic() common.Hash {
+ return common.HexToHash("0xe8ed5b475a5b5987aa9165e8731bb78043f39eee32ec5a1169a89e27fcd49815")
+}
+
+func (FunctionsV1EventsMockSubscriptionConsumerAdded) Topic() common.Hash {
+ return common.HexToHash("0x43dc749a04ac8fb825cbd514f7c0e13f13bc6f2ee66043b76629d51776cff8e0")
+}
+
+func (FunctionsV1EventsMockSubscriptionConsumerRemoved) Topic() common.Hash {
+ return common.HexToHash("0x182bff9831466789164ca77075fffd84916d35a8180ba73c27e45634549b445b")
+}
+
+func (FunctionsV1EventsMockSubscriptionCreated) Topic() common.Hash {
+ return common.HexToHash("0x464722b4166576d3dcbba877b999bc35cf911f4eaf434b7eba68fa113951d0bf")
+}
+
+func (FunctionsV1EventsMockSubscriptionFunded) Topic() common.Hash {
+ return common.HexToHash("0xd39ec07f4e209f627a4c427971473820dc129761ba28de8906bd56f57101d4f8")
+}
+
+func (FunctionsV1EventsMockSubscriptionOwnerTransferRequested) Topic() common.Hash {
+ return common.HexToHash("0x69436ea6df009049404f564eff6622cd00522b0bd6a89efd9e52a355c4a879be")
+}
+
+func (FunctionsV1EventsMockSubscriptionOwnerTransferred) Topic() common.Hash {
+ return common.HexToHash("0x6f1dc65165ffffedfd8e507b4a0f1fcfdada045ed11f6c26ba27cedfe87802f0")
+}
+
+func (FunctionsV1EventsMockUnpaused) Topic() common.Hash {
+ return common.HexToHash("0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa")
+}
+
+func (_FunctionsV1EventsMock *FunctionsV1EventsMock) Address() common.Address {
+ return _FunctionsV1EventsMock.address
+}
+
+type FunctionsV1EventsMockInterface interface {
+ EmitConfigUpdated(opts *bind.TransactOpts, param1 FunctionsV1EventsMockConfig) (*types.Transaction, error)
+
+ EmitContractProposed(opts *bind.TransactOpts, proposedContractSetId [32]byte, proposedContractSetFromAddress common.Address, proposedContractSetToAddress common.Address) (*types.Transaction, error)
+
+ EmitContractUpdated(opts *bind.TransactOpts, id [32]byte, from common.Address, to common.Address) (*types.Transaction, error)
+
+ EmitFundsRecovered(opts *bind.TransactOpts, to common.Address, amount *big.Int) (*types.Transaction, error)
+
+ EmitOwnershipTransferRequested(opts *bind.TransactOpts, from common.Address, to common.Address) (*types.Transaction, error)
+
+ EmitOwnershipTransferred(opts *bind.TransactOpts, from common.Address, to common.Address) (*types.Transaction, error)
+
+ EmitPaused(opts *bind.TransactOpts, account common.Address) (*types.Transaction, error)
+
+ EmitRequestNotProcessed(opts *bind.TransactOpts, requestId [32]byte, coordinator common.Address, transmitter common.Address, resultCode uint8) (*types.Transaction, error)
+
+ EmitRequestProcessed(opts *bind.TransactOpts, requestId [32]byte, subscriptionId uint64, totalCostJuels *big.Int, transmitter common.Address, resultCode uint8, response []byte, err []byte, callbackReturnData []byte) (*types.Transaction, error)
+
+ EmitRequestStart(opts *bind.TransactOpts, requestId [32]byte, donId [32]byte, subscriptionId uint64, subscriptionOwner common.Address, requestingContract common.Address, requestInitiator common.Address, data []byte, dataVersion uint16, callbackGasLimit uint32, estimatedTotalCostJuels *big.Int) (*types.Transaction, error)
+
+ EmitRequestTimedOut(opts *bind.TransactOpts, requestId [32]byte) (*types.Transaction, error)
+
+ EmitSubscriptionCanceled(opts *bind.TransactOpts, subscriptionId uint64, fundsRecipient common.Address, fundsAmount *big.Int) (*types.Transaction, error)
+
+ EmitSubscriptionConsumerAdded(opts *bind.TransactOpts, subscriptionId uint64, consumer common.Address) (*types.Transaction, error)
+
+ EmitSubscriptionConsumerRemoved(opts *bind.TransactOpts, subscriptionId uint64, consumer common.Address) (*types.Transaction, error)
+
+ EmitSubscriptionCreated(opts *bind.TransactOpts, subscriptionId uint64, owner common.Address) (*types.Transaction, error)
+
+ EmitSubscriptionFunded(opts *bind.TransactOpts, subscriptionId uint64, oldBalance *big.Int, newBalance *big.Int) (*types.Transaction, error)
+
+ EmitSubscriptionOwnerTransferRequested(opts *bind.TransactOpts, subscriptionId uint64, from common.Address, to common.Address) (*types.Transaction, error)
+
+ EmitSubscriptionOwnerTransferred(opts *bind.TransactOpts, subscriptionId uint64, from common.Address, to common.Address) (*types.Transaction, error)
+
+ EmitUnpaused(opts *bind.TransactOpts, account common.Address) (*types.Transaction, error)
+
+ FilterConfigUpdated(opts *bind.FilterOpts) (*FunctionsV1EventsMockConfigUpdatedIterator, error)
+
+ WatchConfigUpdated(opts *bind.WatchOpts, sink chan<- *FunctionsV1EventsMockConfigUpdated) (event.Subscription, error)
+
+ ParseConfigUpdated(log types.Log) (*FunctionsV1EventsMockConfigUpdated, error)
+
+ FilterContractProposed(opts *bind.FilterOpts) (*FunctionsV1EventsMockContractProposedIterator, error)
+
+ WatchContractProposed(opts *bind.WatchOpts, sink chan<- *FunctionsV1EventsMockContractProposed) (event.Subscription, error)
+
+ ParseContractProposed(log types.Log) (*FunctionsV1EventsMockContractProposed, error)
+
+ FilterContractUpdated(opts *bind.FilterOpts) (*FunctionsV1EventsMockContractUpdatedIterator, error)
+
+ WatchContractUpdated(opts *bind.WatchOpts, sink chan<- *FunctionsV1EventsMockContractUpdated) (event.Subscription, error)
+
+ ParseContractUpdated(log types.Log) (*FunctionsV1EventsMockContractUpdated, error)
+
+ FilterFundsRecovered(opts *bind.FilterOpts) (*FunctionsV1EventsMockFundsRecoveredIterator, error)
+
+ WatchFundsRecovered(opts *bind.WatchOpts, sink chan<- *FunctionsV1EventsMockFundsRecovered) (event.Subscription, error)
+
+ ParseFundsRecovered(log types.Log) (*FunctionsV1EventsMockFundsRecovered, error)
+
+ FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*FunctionsV1EventsMockOwnershipTransferRequestedIterator, error)
+
+ WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *FunctionsV1EventsMockOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error)
+
+ ParseOwnershipTransferRequested(log types.Log) (*FunctionsV1EventsMockOwnershipTransferRequested, error)
+
+ FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*FunctionsV1EventsMockOwnershipTransferredIterator, error)
+
+ WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *FunctionsV1EventsMockOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error)
+
+ ParseOwnershipTransferred(log types.Log) (*FunctionsV1EventsMockOwnershipTransferred, error)
+
+ FilterPaused(opts *bind.FilterOpts) (*FunctionsV1EventsMockPausedIterator, error)
+
+ WatchPaused(opts *bind.WatchOpts, sink chan<- *FunctionsV1EventsMockPaused) (event.Subscription, error)
+
+ ParsePaused(log types.Log) (*FunctionsV1EventsMockPaused, error)
+
+ FilterRequestNotProcessed(opts *bind.FilterOpts, requestId [][32]byte) (*FunctionsV1EventsMockRequestNotProcessedIterator, error)
+
+ WatchRequestNotProcessed(opts *bind.WatchOpts, sink chan<- *FunctionsV1EventsMockRequestNotProcessed, requestId [][32]byte) (event.Subscription, error)
+
+ ParseRequestNotProcessed(log types.Log) (*FunctionsV1EventsMockRequestNotProcessed, error)
+
+ FilterRequestProcessed(opts *bind.FilterOpts, requestId [][32]byte, subscriptionId []uint64) (*FunctionsV1EventsMockRequestProcessedIterator, error)
+
+ WatchRequestProcessed(opts *bind.WatchOpts, sink chan<- *FunctionsV1EventsMockRequestProcessed, requestId [][32]byte, subscriptionId []uint64) (event.Subscription, error)
+
+ ParseRequestProcessed(log types.Log) (*FunctionsV1EventsMockRequestProcessed, error)
+
+ FilterRequestStart(opts *bind.FilterOpts, requestId [][32]byte, donId [][32]byte, subscriptionId []uint64) (*FunctionsV1EventsMockRequestStartIterator, error)
+
+ WatchRequestStart(opts *bind.WatchOpts, sink chan<- *FunctionsV1EventsMockRequestStart, requestId [][32]byte, donId [][32]byte, subscriptionId []uint64) (event.Subscription, error)
+
+ ParseRequestStart(log types.Log) (*FunctionsV1EventsMockRequestStart, error)
+
+ FilterRequestTimedOut(opts *bind.FilterOpts, requestId [][32]byte) (*FunctionsV1EventsMockRequestTimedOutIterator, error)
+
+ WatchRequestTimedOut(opts *bind.WatchOpts, sink chan<- *FunctionsV1EventsMockRequestTimedOut, requestId [][32]byte) (event.Subscription, error)
+
+ ParseRequestTimedOut(log types.Log) (*FunctionsV1EventsMockRequestTimedOut, error)
+
+ FilterSubscriptionCanceled(opts *bind.FilterOpts, subscriptionId []uint64) (*FunctionsV1EventsMockSubscriptionCanceledIterator, error)
+
+ WatchSubscriptionCanceled(opts *bind.WatchOpts, sink chan<- *FunctionsV1EventsMockSubscriptionCanceled, subscriptionId []uint64) (event.Subscription, error)
+
+ ParseSubscriptionCanceled(log types.Log) (*FunctionsV1EventsMockSubscriptionCanceled, error)
+
+ FilterSubscriptionConsumerAdded(opts *bind.FilterOpts, subscriptionId []uint64) (*FunctionsV1EventsMockSubscriptionConsumerAddedIterator, error)
+
+ WatchSubscriptionConsumerAdded(opts *bind.WatchOpts, sink chan<- *FunctionsV1EventsMockSubscriptionConsumerAdded, subscriptionId []uint64) (event.Subscription, error)
+
+ ParseSubscriptionConsumerAdded(log types.Log) (*FunctionsV1EventsMockSubscriptionConsumerAdded, error)
+
+ FilterSubscriptionConsumerRemoved(opts *bind.FilterOpts, subscriptionId []uint64) (*FunctionsV1EventsMockSubscriptionConsumerRemovedIterator, error)
+
+ WatchSubscriptionConsumerRemoved(opts *bind.WatchOpts, sink chan<- *FunctionsV1EventsMockSubscriptionConsumerRemoved, subscriptionId []uint64) (event.Subscription, error)
+
+ ParseSubscriptionConsumerRemoved(log types.Log) (*FunctionsV1EventsMockSubscriptionConsumerRemoved, error)
+
+ FilterSubscriptionCreated(opts *bind.FilterOpts, subscriptionId []uint64) (*FunctionsV1EventsMockSubscriptionCreatedIterator, error)
+
+ WatchSubscriptionCreated(opts *bind.WatchOpts, sink chan<- *FunctionsV1EventsMockSubscriptionCreated, subscriptionId []uint64) (event.Subscription, error)
+
+ ParseSubscriptionCreated(log types.Log) (*FunctionsV1EventsMockSubscriptionCreated, error)
+
+ FilterSubscriptionFunded(opts *bind.FilterOpts, subscriptionId []uint64) (*FunctionsV1EventsMockSubscriptionFundedIterator, error)
+
+ WatchSubscriptionFunded(opts *bind.WatchOpts, sink chan<- *FunctionsV1EventsMockSubscriptionFunded, subscriptionId []uint64) (event.Subscription, error)
+
+ ParseSubscriptionFunded(log types.Log) (*FunctionsV1EventsMockSubscriptionFunded, error)
+
+ FilterSubscriptionOwnerTransferRequested(opts *bind.FilterOpts, subscriptionId []uint64) (*FunctionsV1EventsMockSubscriptionOwnerTransferRequestedIterator, error)
+
+ WatchSubscriptionOwnerTransferRequested(opts *bind.WatchOpts, sink chan<- *FunctionsV1EventsMockSubscriptionOwnerTransferRequested, subscriptionId []uint64) (event.Subscription, error)
+
+ ParseSubscriptionOwnerTransferRequested(log types.Log) (*FunctionsV1EventsMockSubscriptionOwnerTransferRequested, error)
+
+ FilterSubscriptionOwnerTransferred(opts *bind.FilterOpts, subscriptionId []uint64) (*FunctionsV1EventsMockSubscriptionOwnerTransferredIterator, error)
+
+ WatchSubscriptionOwnerTransferred(opts *bind.WatchOpts, sink chan<- *FunctionsV1EventsMockSubscriptionOwnerTransferred, subscriptionId []uint64) (event.Subscription, error)
+
+ ParseSubscriptionOwnerTransferred(log types.Log) (*FunctionsV1EventsMockSubscriptionOwnerTransferred, error)
+
+ FilterUnpaused(opts *bind.FilterOpts) (*FunctionsV1EventsMockUnpausedIterator, error)
+
+ WatchUnpaused(opts *bind.WatchOpts, sink chan<- *FunctionsV1EventsMockUnpaused) (event.Subscription, error)
+
+ ParseUnpaused(log types.Log) (*FunctionsV1EventsMockUnpaused, error)
+
+ ParseLog(log types.Log) (generated.AbigenLog, error)
+
+ Address() common.Address
+}
diff --git a/core/gethwrappers/functions/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/functions/generation/generated-wrapper-dependency-versions-do-not-edit.txt
index 0fb2b611b4d..6b77b889e3b 100644
--- a/core/gethwrappers/functions/generation/generated-wrapper-dependency-versions-do-not-edit.txt
+++ b/core/gethwrappers/functions/generation/generated-wrapper-dependency-versions-do-not-edit.txt
@@ -1,15 +1,16 @@
GETH_VERSION: 1.12.0
-functions: ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsRequest.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsRequest.bin 3c972870b0afeb6d73a29ebb182f24956a2cebb127b21c4f867d1ecf19a762db
-functions_allow_list: ../../../contracts/solc/v0.8.19/functions/1_0_0/TermsOfServiceAllowList.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/TermsOfServiceAllowList.bin b2697ad4dfece903a1d34028826a017fa445eb3cd984006f1734fa9d47836ca0
-functions_billing_registry_events_mock: ../../../contracts/solc/v0.8.6/functions/0_0_0/FunctionsBillingRegistryEventsMock.abi ../../../contracts/solc/v0.8.6/functions/0_0_0/FunctionsBillingRegistryEventsMock.bin 50deeb883bd9c3729702be335c0388f9d8553bab4be5e26ecacac496a89e2b77
-functions_client: ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsClient.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsClient.bin 2368f537a04489c720a46733f8596c4fc88a31062ecfa966d05f25dd98608aca
-functions_client_example: ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsClientExample.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsClientExample.bin 25036bdb94a50a81df4222418bf9aa1e0c8540d5834b7e6e639aa63a2a2c8206
-functions_coordinator: ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsCoordinator.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsCoordinator.bin 7b2fb23e2f49121dfe4b096de5e60fe57be0a196c2423a4693293c23c96f9af4
-functions_load_test_client: ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsLoadTestClient.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsLoadTestClient.bin 28f2834dea12b3aefa7c696b64ca5272a1ab5cdf33365c9f7fafdc0b7d5669e8
-functions_oracle_events_mock: ../../../contracts/solc/v0.8.6/functions/0_0_0/FunctionsOracleEventsMock.abi ../../../contracts/solc/v0.8.6/functions/0_0_0/FunctionsOracleEventsMock.bin 3ca70f966f8fe751987f0ccb50bebb6aa5be77e4a9f835d1ae99e0e9bfb7d52c
-functions_router: ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsRouter.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsRouter.bin dd1d3527e19d65efe029c4a131ded44dc0ca961e5c4f459743992435431ec478
-ocr2dr: ../../../contracts/solc/v0.8.6/functions/0_0_0/Functions.abi ../../../contracts/solc/v0.8.6/functions/0_0_0/Functions.bin d9a794b33f47cc57563d216f7cf3a612309fc3062356a27e30005cf1d59e449d
-ocr2dr_client: ../../../contracts/solc/v0.8.6/functions/0_0_0/FunctionsClient.abi ../../../contracts/solc/v0.8.6/functions/0_0_0/FunctionsClient.bin 84aa63f9dbc5c7eac240db699b09e613ca4c6cd56dab10bdc25b02461b717e21
-ocr2dr_client_example: ../../../contracts/solc/v0.8.6/functions/0_0_0/FunctionsClientExample.abi ../../../contracts/solc/v0.8.6/functions/0_0_0/FunctionsClientExample.bin a978d9b52a5a2da19eef0975979de256e62980a0cfb3084fe6d66a351b4ef534
-ocr2dr_oracle: ../../../contracts/solc/v0.8.6/functions/0_0_0/FunctionsOracleWithInit.abi ../../../contracts/solc/v0.8.6/functions/0_0_0/FunctionsOracleWithInit.bin b9084b34b0ee2e89adc72f068a868f0f22e361c96677fe20e44801e84bbd0c18
-ocr2dr_registry: ../../../contracts/solc/v0.8.6/functions/0_0_0/FunctionsBillingRegistryWithInit.abi ../../../contracts/solc/v0.8.6/functions/0_0_0/FunctionsBillingRegistryWithInit.bin be588d5036cbeb8d67bbc124fefbdc6fd354802a30b8e87093b2b94a6549741b
+functions: ../../../contracts/solc/v0.8.19/functions/v1_0_0/FunctionsRequest.abi ../../../contracts/solc/v0.8.19/functions/v1_0_0/FunctionsRequest.bin 3c972870b0afeb6d73a29ebb182f24956a2cebb127b21c4f867d1ecf19a762db
+functions_allow_list: ../../../contracts/solc/v0.8.19/functions/v1_0_0/TermsOfServiceAllowList.abi ../../../contracts/solc/v0.8.19/functions/v1_0_0/TermsOfServiceAllowList.bin b2697ad4dfece903a1d34028826a017fa445eb3cd984006f1734fa9d47836ca0
+functions_billing_registry_events_mock: ../../../contracts/solc/v0.8.6/functions/v0_0_0/FunctionsBillingRegistryEventsMock.abi ../../../contracts/solc/v0.8.6/functions/v0_0_0/FunctionsBillingRegistryEventsMock.bin 50deeb883bd9c3729702be335c0388f9d8553bab4be5e26ecacac496a89e2b77
+functions_client: ../../../contracts/solc/v0.8.19/functions/v1_0_0/FunctionsClient.abi ../../../contracts/solc/v0.8.19/functions/v1_0_0/FunctionsClient.bin 2368f537a04489c720a46733f8596c4fc88a31062ecfa966d05f25dd98608aca
+functions_client_example: ../../../contracts/solc/v0.8.19/functions/v1_0_0/FunctionsClientExample.abi ../../../contracts/solc/v0.8.19/functions/v1_0_0/FunctionsClientExample.bin abf32e69f268f40e8530eb8d8e96bf310b798a4c0049a58022d9d2fb527b601b
+functions_coordinator: ../../../contracts/solc/v0.8.19/functions/v1_0_0/FunctionsCoordinator.abi ../../../contracts/solc/v0.8.19/functions/v1_0_0/FunctionsCoordinator.bin 21bd322caf977c4802d2c17419b57487cca438c7c5fafc52a9a9e1c9f4a72289
+functions_load_test_client: ../../../contracts/solc/v0.8.19/functions/v1_0_0/FunctionsLoadTestClient.abi ../../../contracts/solc/v0.8.19/functions/v1_0_0/FunctionsLoadTestClient.bin c8dbbd5ebb34435800d6674700068837c3a252db60046a14b0e61e829db517de
+functions_oracle_events_mock: ../../../contracts/solc/v0.8.6/functions/v0_0_0/FunctionsOracleEventsMock.abi ../../../contracts/solc/v0.8.6/functions/v0_0_0/FunctionsOracleEventsMock.bin 3ca70f966f8fe751987f0ccb50bebb6aa5be77e4a9f835d1ae99e0e9bfb7d52c
+functions_router: ../../../contracts/solc/v0.8.19/functions/v1_0_0/FunctionsRouter.abi ../../../contracts/solc/v0.8.19/functions/v1_0_0/FunctionsRouter.bin 9dedd3a36043605fd9bedf821e7ec5b4281a5c7ae2e4a1955f37aff8ba13519f
+functions_v1_events_mock: ../../../contracts/solc/v0.8.19/functions/v1_0_0/FunctionsV1EventsMock.abi ../../../contracts/solc/v0.8.19/functions/v1_0_0/FunctionsV1EventsMock.bin 0f0ba42e0cc33c7abc8b8fd4fdfce903748a169886dd5f16cfdd56e75bcf708d
+ocr2dr: ../../../contracts/solc/v0.8.6/functions/v0_0_0/Functions.abi ../../../contracts/solc/v0.8.6/functions/v0_0_0/Functions.bin d9a794b33f47cc57563d216f7cf3a612309fc3062356a27e30005cf1d59e449d
+ocr2dr_client: ../../../contracts/solc/v0.8.6/functions/v0_0_0/FunctionsClient.abi ../../../contracts/solc/v0.8.6/functions/v0_0_0/FunctionsClient.bin 84aa63f9dbc5c7eac240db699b09e613ca4c6cd56dab10bdc25b02461b717e21
+ocr2dr_client_example: ../../../contracts/solc/v0.8.6/functions/v0_0_0/FunctionsClientExample.abi ../../../contracts/solc/v0.8.6/functions/v0_0_0/FunctionsClientExample.bin a978d9b52a5a2da19eef0975979de256e62980a0cfb3084fe6d66a351b4ef534
+ocr2dr_oracle: ../../../contracts/solc/v0.8.6/functions/v0_0_0/FunctionsOracleWithInit.abi ../../../contracts/solc/v0.8.6/functions/v0_0_0/FunctionsOracleWithInit.bin b9084b34b0ee2e89adc72f068a868f0f22e361c96677fe20e44801e84bbd0c18
+ocr2dr_registry: ../../../contracts/solc/v0.8.6/functions/v0_0_0/FunctionsBillingRegistryWithInit.abi ../../../contracts/solc/v0.8.6/functions/v0_0_0/FunctionsBillingRegistryWithInit.bin be588d5036cbeb8d67bbc124fefbdc6fd354802a30b8e87093b2b94a6549741b
diff --git a/core/gethwrappers/functions/go_generate.go b/core/gethwrappers/functions/go_generate.go
index bc0fcd2a0ce..2cb6c4ffaec 100644
--- a/core/gethwrappers/functions/go_generate.go
+++ b/core/gethwrappers/functions/go_generate.go
@@ -5,17 +5,18 @@ package gethwrappers
// Chainlink Functions (OCR2DR)
// Version 0 (Testnet Beta)
-//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.6/functions/0_0_0/Functions.abi ../../../contracts/solc/v0.8.6/functions/0_0_0/Functions.bin OCR2DR ocr2dr
-//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.6/functions/0_0_0/FunctionsClient.abi ../../../contracts/solc/v0.8.6/functions/0_0_0/FunctionsClient.bin OCR2DRClient ocr2dr_client
-//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.6/functions/0_0_0/FunctionsClientExample.abi ../../../contracts/solc/v0.8.6/functions/0_0_0/FunctionsClientExample.bin OCR2DRClientExample ocr2dr_client_example
-//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.6/functions/0_0_0/FunctionsOracleWithInit.abi ../../../contracts/solc/v0.8.6/functions/0_0_0/FunctionsOracleWithInit.bin OCR2DROracle ocr2dr_oracle
-//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.6/functions/0_0_0/FunctionsBillingRegistryWithInit.abi ../../../contracts/solc/v0.8.6/functions/0_0_0/FunctionsBillingRegistryWithInit.bin OCR2DRRegistry ocr2dr_registry
+//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.6/functions/v0_0_0/Functions.abi ../../../contracts/solc/v0.8.6/functions/v0_0_0/Functions.bin OCR2DR ocr2dr
+//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.6/functions/v0_0_0/FunctionsClient.abi ../../../contracts/solc/v0.8.6/functions/v0_0_0/FunctionsClient.bin OCR2DRClient ocr2dr_client
+//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.6/functions/v0_0_0/FunctionsClientExample.abi ../../../contracts/solc/v0.8.6/functions/v0_0_0/FunctionsClientExample.bin OCR2DRClientExample ocr2dr_client_example
+//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.6/functions/v0_0_0/FunctionsOracleWithInit.abi ../../../contracts/solc/v0.8.6/functions/v0_0_0/FunctionsOracleWithInit.bin OCR2DROracle ocr2dr_oracle
+//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.6/functions/v0_0_0/FunctionsBillingRegistryWithInit.abi ../../../contracts/solc/v0.8.6/functions/v0_0_0/FunctionsBillingRegistryWithInit.bin OCR2DRRegistry ocr2dr_registry
// Version 1 (Mainnet Preview)
-//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsRequest.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsRequest.bin Functions functions
-//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsClient.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsClient.bin FunctionsClient functions_client
-//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsClientExample.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsClientExample.bin FunctionsClientExample functions_client_example
-//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsLoadTestClient.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsLoadTestClient.bin FunctionsLoadTestClient functions_load_test_client
-//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsCoordinator.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsCoordinator.bin FunctionsCoordinator functions_coordinator
-//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsRouter.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsRouter.bin FunctionsRouter functions_router
-//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/functions/1_0_0/TermsOfServiceAllowList.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/TermsOfServiceAllowList.bin TermsOfServiceAllowList functions_allow_list
+//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/functions/v1_0_0/FunctionsRequest.abi ../../../contracts/solc/v0.8.19/functions/v1_0_0/FunctionsRequest.bin Functions functions
+//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/functions/v1_0_0/FunctionsClient.abi ../../../contracts/solc/v0.8.19/functions/v1_0_0/FunctionsClient.bin FunctionsClient functions_client
+//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/functions/v1_0_0/FunctionsClientExample.abi ../../../contracts/solc/v0.8.19/functions/v1_0_0/FunctionsClientExample.bin FunctionsClientExample functions_client_example
+//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/functions/v1_0_0/FunctionsLoadTestClient.abi ../../../contracts/solc/v0.8.19/functions/v1_0_0/FunctionsLoadTestClient.bin FunctionsLoadTestClient functions_load_test_client
+//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/functions/v1_0_0/FunctionsCoordinator.abi ../../../contracts/solc/v0.8.19/functions/v1_0_0/FunctionsCoordinator.bin FunctionsCoordinator functions_coordinator
+//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/functions/v1_0_0/FunctionsRouter.abi ../../../contracts/solc/v0.8.19/functions/v1_0_0/FunctionsRouter.bin FunctionsRouter functions_router
+//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/functions/v1_0_0/TermsOfServiceAllowList.abi ../../../contracts/solc/v0.8.19/functions/v1_0_0/TermsOfServiceAllowList.bin TermsOfServiceAllowList functions_allow_list
+//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/functions/v1_0_0/FunctionsV1EventsMock.abi ../../../contracts/solc/v0.8.19/functions/v1_0_0/FunctionsV1EventsMock.bin FunctionsV1EventsMock functions_v1_events_mock
diff --git a/core/gethwrappers/generated/automation_utils_2_1/automation_utils_2_1.go b/core/gethwrappers/generated/automation_utils_2_1/automation_utils_2_1.go
index 6d6991546f0..1eaa4ea03fe 100644
--- a/core/gethwrappers/generated/automation_utils_2_1/automation_utils_2_1.go
+++ b/core/gethwrappers/generated/automation_utils_2_1/automation_utils_2_1.go
@@ -34,10 +34,11 @@ type KeeperRegistryBase21ConditionalTrigger struct {
}
type KeeperRegistryBase21LogTrigger struct {
- TxHash [32]byte
- LogIndex uint32
- BlockNum uint32
- BlockHash [32]byte
+ LogBlockHash [32]byte
+ TxHash [32]byte
+ LogIndex uint32
+ BlockNum uint32
+ BlockHash [32]byte
}
type KeeperRegistryBase21OnchainConfig struct {
@@ -69,7 +70,7 @@ type KeeperRegistryBase21Report struct {
type Log struct {
Index *big.Int
- TxIndex *big.Int
+ Timestamp *big.Int
TxHash [32]byte
BlockNumber *big.Int
BlockHash [32]byte
@@ -88,8 +89,8 @@ type LogTriggerConfig struct {
}
var AutomationUtilsMetaData = &bind.MetaData{
- ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"blockNum\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"}],\"internalType\":\"structKeeperRegistryBase2_1.ConditionalTrigger\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"_conditionalTrigger\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"txIndex\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"txHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"source\",\"type\":\"address\"},{\"internalType\":\"bytes32[]\",\"name\":\"topics\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"structLog\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"_log\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"txHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"logIndex\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNum\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"}],\"internalType\":\"structKeeperRegistryBase2_1.LogTrigger\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"_logTrigger\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"filterSelector\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"topic0\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"topic1\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"topic2\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"topic3\",\"type\":\"bytes32\"}],\"internalType\":\"structLogTriggerConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"_logTriggerConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"paymentPremiumPPB\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"flatFeeMicroLink\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"checkGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"stalenessSeconds\",\"type\":\"uint24\"},{\"internalType\":\"uint16\",\"name\":\"gasCeilingMultiplier\",\"type\":\"uint16\"},{\"internalType\":\"uint96\",\"name\":\"minUpkeepSpend\",\"type\":\"uint96\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxCheckDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxRevertDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"fallbackGasPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fallbackLinkPrice\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"transcoder\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"registrars\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"upkeepPrivilegeManager\",\"type\":\"address\"}],\"internalType\":\"structKeeperRegistryBase2_1.OnchainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"_onChainConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"fastGasWei\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"linkNative\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"gasLimits\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes[]\",\"name\":\"triggers\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes[]\",\"name\":\"performDatas\",\"type\":\"bytes[]\"}],\"internalType\":\"structKeeperRegistryBase2_1.Report\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"_report\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]",
- Bin: "0x608060405234801561001057600080fd5b506108be806100206000396000f3fe608060405234801561001057600080fd5b50600436106100725760003560e01c80634b6df294116100505780634b6df294146100a6578063e65d6546146100b4578063e9720a49146100c257600080fd5b80631c8d82601461007757806321f373d71461008a5780632ff92a8114610098575b600080fd5b6100886100853660046101d8565b50565b005b61008861008536600461026e565b6100886100853660046103d5565b61008861008536600461052f565b6100886100853660046106ef565b6100886100853660046107dc565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516101e0810167ffffffffffffffff81118282101715610123576101236100d0565b60405290565b60405160c0810167ffffffffffffffff81118282101715610123576101236100d0565b604051610100810167ffffffffffffffff81118282101715610123576101236100d0565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156101b7576101b76100d0565b604052919050565b803563ffffffff811681146101d357600080fd5b919050565b6000608082840312156101ea57600080fd5b6040516080810181811067ffffffffffffffff8211171561020d5761020d6100d0565b60405282358152610220602084016101bf565b6020820152610231604084016101bf565b6040820152606083013560608201528091505092915050565b803573ffffffffffffffffffffffffffffffffffffffff811681146101d357600080fd5b600060c0828403121561028057600080fd5b60405160c0810181811067ffffffffffffffff821117156102a3576102a36100d0565b6040526102af8361024a565b8152602083013560ff811681146102c557600080fd5b8060208301525060408301356040820152606083013560608201526080830135608082015260a083013560a08201528091505092915050565b803562ffffff811681146101d357600080fd5b803561ffff811681146101d357600080fd5b80356bffffffffffffffffffffffff811681146101d357600080fd5b600067ffffffffffffffff821115610359576103596100d0565b5060051b60200190565b600082601f83011261037457600080fd5b813560206103896103848361033f565b610170565b82815260059290921b840181019181810190868411156103a857600080fd5b8286015b848110156103ca576103bd8161024a565b83529183019183016103ac565b509695505050505050565b6000602082840312156103e757600080fd5b813567ffffffffffffffff808211156103ff57600080fd5b908301906101e0828603121561041457600080fd5b61041c6100ff565b610425836101bf565b8152610433602084016101bf565b6020820152610444604084016101bf565b6040820152610455606084016102fe565b606082015261046660808401610311565b608082015261047760a08401610323565b60a082015261048860c084016101bf565b60c082015261049960e084016101bf565b60e08201526101006104ac8185016101bf565b908201526101206104be8482016101bf565b90820152610140838101359082015261016080840135908201526101806104e681850161024a565b908201526101a083810135838111156104fe57600080fd5b61050a88828701610363565b8284015250506101c0915061052082840161024a565b91810191909152949350505050565b60006040828403121561054157600080fd5b6040516040810181811067ffffffffffffffff82111715610564576105646100d0565b604052610570836101bf565b8152602083013560208201528091505092915050565b600082601f83011261059757600080fd5b813560206105a76103848361033f565b82815260059290921b840181019181810190868411156105c657600080fd5b8286015b848110156103ca57803583529183019183016105ca565b600082601f8301126105f257600080fd5b813567ffffffffffffffff81111561060c5761060c6100d0565b61063d60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601610170565b81815284602083860101111561065257600080fd5b816020850160208301376000918101602001919091529392505050565b600082601f83011261068057600080fd5b813560206106906103848361033f565b82815260059290921b840181019181810190868411156106af57600080fd5b8286015b848110156103ca57803567ffffffffffffffff8111156106d35760008081fd5b6106e18986838b01016105e1565b8452509183019183016106b3565b60006020828403121561070157600080fd5b813567ffffffffffffffff8082111561071957600080fd5b9083019060c0828603121561072d57600080fd5b610735610129565b823581526020830135602082015260408301358281111561075557600080fd5b61076187828601610586565b60408301525060608301358281111561077957600080fd5b61078587828601610586565b60608301525060808301358281111561079d57600080fd5b6107a98782860161066f565b60808301525060a0830135828111156107c157600080fd5b6107cd8782860161066f565b60a08301525095945050505050565b6000602082840312156107ee57600080fd5b813567ffffffffffffffff8082111561080657600080fd5b90830190610100828603121561081b57600080fd5b61082361014c565b823581526020830135602082015260408301356040820152606083013560608201526080830135608082015261085b60a0840161024a565b60a082015260c08301358281111561087257600080fd5b61087e87828601610586565b60c08301525060e08301358281111561089657600080fd5b6108a2878286016105e1565b60e0830152509594505050505056fea164736f6c6343000810000a",
+ ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"blockNum\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"}],\"internalType\":\"structKeeperRegistryBase2_1.ConditionalTrigger\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"_conditionalTrigger\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"txHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"source\",\"type\":\"address\"},{\"internalType\":\"bytes32[]\",\"name\":\"topics\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"structLog\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"_log\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"logBlockHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"txHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"logIndex\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNum\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"}],\"internalType\":\"structKeeperRegistryBase2_1.LogTrigger\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"_logTrigger\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"filterSelector\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"topic0\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"topic1\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"topic2\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"topic3\",\"type\":\"bytes32\"}],\"internalType\":\"structLogTriggerConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"_logTriggerConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"paymentPremiumPPB\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"flatFeeMicroLink\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"checkGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"stalenessSeconds\",\"type\":\"uint24\"},{\"internalType\":\"uint16\",\"name\":\"gasCeilingMultiplier\",\"type\":\"uint16\"},{\"internalType\":\"uint96\",\"name\":\"minUpkeepSpend\",\"type\":\"uint96\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxCheckDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxRevertDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"fallbackGasPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fallbackLinkPrice\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"transcoder\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"registrars\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"upkeepPrivilegeManager\",\"type\":\"address\"}],\"internalType\":\"structKeeperRegistryBase2_1.OnchainConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"_onChainConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"fastGasWei\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"linkNative\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"gasLimits\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes[]\",\"name\":\"triggers\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes[]\",\"name\":\"performDatas\",\"type\":\"bytes[]\"}],\"internalType\":\"structKeeperRegistryBase2_1.Report\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"_report\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]",
+ Bin: "0x608060405234801561001057600080fd5b506108ca806100206000396000f3fe608060405234801561001057600080fd5b50600436106100725760003560e01c8063776f306111610050578063776f3061146100a6578063e65d6546146100b4578063e9720a49146100c257600080fd5b806321f373d7146100775780632ff92a811461008a5780634b6df29414610098575b600080fd5b6100886100853660046101e8565b50565b005b610088610085366004610363565b6100886100853660046104bd565b610088610085366004610514565b6100886100853660046106fb565b6100886100853660046107e8565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516101e0810167ffffffffffffffff81118282101715610123576101236100d0565b60405290565b60405160c0810167ffffffffffffffff81118282101715610123576101236100d0565b604051610100810167ffffffffffffffff81118282101715610123576101236100d0565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156101b7576101b76100d0565b604052919050565b803573ffffffffffffffffffffffffffffffffffffffff811681146101e357600080fd5b919050565b600060c082840312156101fa57600080fd5b60405160c0810181811067ffffffffffffffff8211171561021d5761021d6100d0565b604052610229836101bf565b8152602083013560ff8116811461023f57600080fd5b8060208301525060408301356040820152606083013560608201526080830135608082015260a083013560a08201528091505092915050565b803563ffffffff811681146101e357600080fd5b803562ffffff811681146101e357600080fd5b803561ffff811681146101e357600080fd5b80356bffffffffffffffffffffffff811681146101e357600080fd5b600067ffffffffffffffff8211156102e7576102e76100d0565b5060051b60200190565b600082601f83011261030257600080fd5b81356020610317610312836102cd565b610170565b82815260059290921b8401810191818101908684111561033657600080fd5b8286015b848110156103585761034b816101bf565b835291830191830161033a565b509695505050505050565b60006020828403121561037557600080fd5b813567ffffffffffffffff8082111561038d57600080fd5b908301906101e082860312156103a257600080fd5b6103aa6100ff565b6103b383610278565b81526103c160208401610278565b60208201526103d260408401610278565b60408201526103e36060840161028c565b60608201526103f46080840161029f565b608082015261040560a084016102b1565b60a082015261041660c08401610278565b60c082015261042760e08401610278565b60e082015261010061043a818501610278565b9082015261012061044c848201610278565b90820152610140838101359082015261016080840135908201526101806104748185016101bf565b908201526101a0838101358381111561048c57600080fd5b610498888287016102f1565b8284015250506101c091506104ae8284016101bf565b91810191909152949350505050565b6000604082840312156104cf57600080fd5b6040516040810181811067ffffffffffffffff821117156104f2576104f26100d0565b6040526104fe83610278565b8152602083013560208201528091505092915050565b600060a0828403121561052657600080fd5b60405160a0810181811067ffffffffffffffff82111715610549576105496100d0565b8060405250823581526020830135602082015261056860408401610278565b604082015261057960608401610278565b6060820152608083013560808201528091505092915050565b600082601f8301126105a357600080fd5b813560206105b3610312836102cd565b82815260059290921b840181019181810190868411156105d257600080fd5b8286015b8481101561035857803583529183019183016105d6565b600082601f8301126105fe57600080fd5b813567ffffffffffffffff811115610618576106186100d0565b61064960207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601610170565b81815284602083860101111561065e57600080fd5b816020850160208301376000918101602001919091529392505050565b600082601f83011261068c57600080fd5b8135602061069c610312836102cd565b82815260059290921b840181019181810190868411156106bb57600080fd5b8286015b8481101561035857803567ffffffffffffffff8111156106df5760008081fd5b6106ed8986838b01016105ed565b8452509183019183016106bf565b60006020828403121561070d57600080fd5b813567ffffffffffffffff8082111561072557600080fd5b9083019060c0828603121561073957600080fd5b610741610129565b823581526020830135602082015260408301358281111561076157600080fd5b61076d87828601610592565b60408301525060608301358281111561078557600080fd5b61079187828601610592565b6060830152506080830135828111156107a957600080fd5b6107b58782860161067b565b60808301525060a0830135828111156107cd57600080fd5b6107d98782860161067b565b60a08301525095945050505050565b6000602082840312156107fa57600080fd5b813567ffffffffffffffff8082111561081257600080fd5b90830190610100828603121561082757600080fd5b61082f61014c565b823581526020830135602082015260408301356040820152606083013560608201526080830135608082015261086760a084016101bf565b60a082015260c08301358281111561087e57600080fd5b61088a87828601610592565b60c08301525060e0830135828111156108a257600080fd5b6108ae878286016105ed565b60e0830152509594505050505056fea164736f6c6343000810000a",
}
var AutomationUtilsABI = AutomationUtilsMetaData.ABI
diff --git a/core/gethwrappers/generated/feed_lookup_compatible_interface/feed_lookup_compatible_interface.go b/core/gethwrappers/generated/feed_lookup_compatible_interface/feed_lookup_compatible_interface.go
deleted file mode 100644
index 31118ef4a4c..00000000000
--- a/core/gethwrappers/generated/feed_lookup_compatible_interface/feed_lookup_compatible_interface.go
+++ /dev/null
@@ -1,198 +0,0 @@
-// Code generated - DO NOT EDIT.
-// This file is a generated binding and any manual changes will be lost.
-
-package feed_lookup_compatible_interface
-
-import (
- "errors"
- "math/big"
- "strings"
-
- ethereum "github.com/ethereum/go-ethereum"
- "github.com/ethereum/go-ethereum/accounts/abi"
- "github.com/ethereum/go-ethereum/accounts/abi/bind"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/event"
-)
-
-var (
- _ = errors.New
- _ = big.NewInt
- _ = strings.NewReader
- _ = ethereum.NotFound
- _ = bind.Bind
- _ = common.Big1
- _ = types.BloomLookup
- _ = event.NewSubscription
- _ = abi.ConvertType
-)
-
-var FeedLookupCompatibleInterfaceMetaData = &bind.MetaData{
- ABI: "[{\"inputs\":[{\"internalType\":\"string\",\"name\":\"feedParamKey\",\"type\":\"string\"},{\"internalType\":\"string[]\",\"name\":\"feeds\",\"type\":\"string[]\"},{\"internalType\":\"string\",\"name\":\"timeParamKey\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"time\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"FeedLookup\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes[]\",\"name\":\"values\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"checkCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]",
-}
-
-var FeedLookupCompatibleInterfaceABI = FeedLookupCompatibleInterfaceMetaData.ABI
-
-type FeedLookupCompatibleInterface struct {
- address common.Address
- abi abi.ABI
- FeedLookupCompatibleInterfaceCaller
- FeedLookupCompatibleInterfaceTransactor
- FeedLookupCompatibleInterfaceFilterer
-}
-
-type FeedLookupCompatibleInterfaceCaller struct {
- contract *bind.BoundContract
-}
-
-type FeedLookupCompatibleInterfaceTransactor struct {
- contract *bind.BoundContract
-}
-
-type FeedLookupCompatibleInterfaceFilterer struct {
- contract *bind.BoundContract
-}
-
-type FeedLookupCompatibleInterfaceSession struct {
- Contract *FeedLookupCompatibleInterface
- CallOpts bind.CallOpts
- TransactOpts bind.TransactOpts
-}
-
-type FeedLookupCompatibleInterfaceCallerSession struct {
- Contract *FeedLookupCompatibleInterfaceCaller
- CallOpts bind.CallOpts
-}
-
-type FeedLookupCompatibleInterfaceTransactorSession struct {
- Contract *FeedLookupCompatibleInterfaceTransactor
- TransactOpts bind.TransactOpts
-}
-
-type FeedLookupCompatibleInterfaceRaw struct {
- Contract *FeedLookupCompatibleInterface
-}
-
-type FeedLookupCompatibleInterfaceCallerRaw struct {
- Contract *FeedLookupCompatibleInterfaceCaller
-}
-
-type FeedLookupCompatibleInterfaceTransactorRaw struct {
- Contract *FeedLookupCompatibleInterfaceTransactor
-}
-
-func NewFeedLookupCompatibleInterface(address common.Address, backend bind.ContractBackend) (*FeedLookupCompatibleInterface, error) {
- abi, err := abi.JSON(strings.NewReader(FeedLookupCompatibleInterfaceABI))
- if err != nil {
- return nil, err
- }
- contract, err := bindFeedLookupCompatibleInterface(address, backend, backend, backend)
- if err != nil {
- return nil, err
- }
- return &FeedLookupCompatibleInterface{address: address, abi: abi, FeedLookupCompatibleInterfaceCaller: FeedLookupCompatibleInterfaceCaller{contract: contract}, FeedLookupCompatibleInterfaceTransactor: FeedLookupCompatibleInterfaceTransactor{contract: contract}, FeedLookupCompatibleInterfaceFilterer: FeedLookupCompatibleInterfaceFilterer{contract: contract}}, nil
-}
-
-func NewFeedLookupCompatibleInterfaceCaller(address common.Address, caller bind.ContractCaller) (*FeedLookupCompatibleInterfaceCaller, error) {
- contract, err := bindFeedLookupCompatibleInterface(address, caller, nil, nil)
- if err != nil {
- return nil, err
- }
- return &FeedLookupCompatibleInterfaceCaller{contract: contract}, nil
-}
-
-func NewFeedLookupCompatibleInterfaceTransactor(address common.Address, transactor bind.ContractTransactor) (*FeedLookupCompatibleInterfaceTransactor, error) {
- contract, err := bindFeedLookupCompatibleInterface(address, nil, transactor, nil)
- if err != nil {
- return nil, err
- }
- return &FeedLookupCompatibleInterfaceTransactor{contract: contract}, nil
-}
-
-func NewFeedLookupCompatibleInterfaceFilterer(address common.Address, filterer bind.ContractFilterer) (*FeedLookupCompatibleInterfaceFilterer, error) {
- contract, err := bindFeedLookupCompatibleInterface(address, nil, nil, filterer)
- if err != nil {
- return nil, err
- }
- return &FeedLookupCompatibleInterfaceFilterer{contract: contract}, nil
-}
-
-func bindFeedLookupCompatibleInterface(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) {
- parsed, err := FeedLookupCompatibleInterfaceMetaData.GetAbi()
- if err != nil {
- return nil, err
- }
- return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil
-}
-
-func (_FeedLookupCompatibleInterface *FeedLookupCompatibleInterfaceRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
- return _FeedLookupCompatibleInterface.Contract.FeedLookupCompatibleInterfaceCaller.contract.Call(opts, result, method, params...)
-}
-
-func (_FeedLookupCompatibleInterface *FeedLookupCompatibleInterfaceRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
- return _FeedLookupCompatibleInterface.Contract.FeedLookupCompatibleInterfaceTransactor.contract.Transfer(opts)
-}
-
-func (_FeedLookupCompatibleInterface *FeedLookupCompatibleInterfaceRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
- return _FeedLookupCompatibleInterface.Contract.FeedLookupCompatibleInterfaceTransactor.contract.Transact(opts, method, params...)
-}
-
-func (_FeedLookupCompatibleInterface *FeedLookupCompatibleInterfaceCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
- return _FeedLookupCompatibleInterface.Contract.contract.Call(opts, result, method, params...)
-}
-
-func (_FeedLookupCompatibleInterface *FeedLookupCompatibleInterfaceTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
- return _FeedLookupCompatibleInterface.Contract.contract.Transfer(opts)
-}
-
-func (_FeedLookupCompatibleInterface *FeedLookupCompatibleInterfaceTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
- return _FeedLookupCompatibleInterface.Contract.contract.Transact(opts, method, params...)
-}
-
-func (_FeedLookupCompatibleInterface *FeedLookupCompatibleInterfaceCaller) CheckCallback(opts *bind.CallOpts, values [][]byte, extraData []byte) (CheckCallback,
-
- error) {
- var out []interface{}
- err := _FeedLookupCompatibleInterface.contract.Call(opts, &out, "checkCallback", values, extraData)
-
- outstruct := new(CheckCallback)
- if err != nil {
- return *outstruct, err
- }
-
- outstruct.UpkeepNeeded = *abi.ConvertType(out[0], new(bool)).(*bool)
- outstruct.PerformData = *abi.ConvertType(out[1], new([]byte)).(*[]byte)
-
- return *outstruct, err
-
-}
-
-func (_FeedLookupCompatibleInterface *FeedLookupCompatibleInterfaceSession) CheckCallback(values [][]byte, extraData []byte) (CheckCallback,
-
- error) {
- return _FeedLookupCompatibleInterface.Contract.CheckCallback(&_FeedLookupCompatibleInterface.CallOpts, values, extraData)
-}
-
-func (_FeedLookupCompatibleInterface *FeedLookupCompatibleInterfaceCallerSession) CheckCallback(values [][]byte, extraData []byte) (CheckCallback,
-
- error) {
- return _FeedLookupCompatibleInterface.Contract.CheckCallback(&_FeedLookupCompatibleInterface.CallOpts, values, extraData)
-}
-
-type CheckCallback struct {
- UpkeepNeeded bool
- PerformData []byte
-}
-
-func (_FeedLookupCompatibleInterface *FeedLookupCompatibleInterface) Address() common.Address {
- return _FeedLookupCompatibleInterface.address
-}
-
-type FeedLookupCompatibleInterfaceInterface interface {
- CheckCallback(opts *bind.CallOpts, values [][]byte, extraData []byte) (CheckCallback,
-
- error)
-
- Address() common.Address
-}
diff --git a/core/gethwrappers/generated/i_log_automation/i_log_automation.go b/core/gethwrappers/generated/i_log_automation/i_log_automation.go
index 122c7f2ce7d..e6345b74bf3 100644
--- a/core/gethwrappers/generated/i_log_automation/i_log_automation.go
+++ b/core/gethwrappers/generated/i_log_automation/i_log_automation.go
@@ -30,7 +30,7 @@ var (
type Log struct {
Index *big.Int
- TxIndex *big.Int
+ Timestamp *big.Int
TxHash [32]byte
BlockNumber *big.Int
BlockHash [32]byte
@@ -40,7 +40,7 @@ type Log struct {
}
var ILogAutomationMetaData = &bind.MetaData{
- ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"txIndex\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"txHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"source\",\"type\":\"address\"},{\"internalType\":\"bytes32[]\",\"name\":\"topics\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"structLog\",\"name\":\"log\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"}],\"name\":\"checkLog\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"}],\"name\":\"performUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]",
+ ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"txHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"source\",\"type\":\"address\"},{\"internalType\":\"bytes32[]\",\"name\":\"topics\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"structLog\",\"name\":\"log\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"}],\"name\":\"checkLog\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"}],\"name\":\"performUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]",
}
var ILogAutomationABI = ILogAutomationMetaData.ABI
diff --git a/core/gethwrappers/generated/keeper_registry_wrapper_2_1/keeper_registry_wrapper_2_1.go b/core/gethwrappers/generated/keeper_registry_wrapper_2_1/keeper_registry_wrapper_2_1.go
index 4bbd827dc52..1db34ca3953 100644
--- a/core/gethwrappers/generated/keeper_registry_wrapper_2_1/keeper_registry_wrapper_2_1.go
+++ b/core/gethwrappers/generated/keeper_registry_wrapper_2_1/keeper_registry_wrapper_2_1.go
@@ -50,7 +50,7 @@ type KeeperRegistryBase21OnchainConfig struct {
var KeeperRegistryMetaData = &bind.MetaData{
ABI: "[{\"inputs\":[{\"internalType\":\"contractKeeperRegistryLogicB2_1\",\"name\":\"logicA\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"ArrayHasNoEntries\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotCancel\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CheckDataExceedsLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateEntry\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DuplicateSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasLimitOutsideRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfFaultyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectNumberOfSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IndexOutOfRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientFunds\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDataLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRecipient\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTrigger\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTriggerType\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxCheckDataSizeCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxPerformDataSizeCanOnlyIncrease\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MigrationNotPermitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotAContract\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyActiveTransmitters\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByLINKToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrRegistrar\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByProposedPayee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByUpkeepPrivilegeManager\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyPausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlySimulatedBackend\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyUnpausedUpkeep\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ParameterLengthError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PaymentGreaterThanAllLINK\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrantCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RegistryPaused\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RepeatedTransmitter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"reason\",\"type\":\"bytes\"}],\"name\":\"TargetCheckReverted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyOracles\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TranscoderNotSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepAlreadyExists\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepCancelled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotCanceled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpkeepNotNeeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ValueNotChanged\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"AdminPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"CancelledUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"dedupKey\",\"type\":\"bytes32\"}],\"name\":\"DedupKeyAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"FundsAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"FundsWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"InsufficientFundsUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"OwnerFundsWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"payees\",\"type\":\"address[]\"}],\"name\":\"PayeesUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"PayeeshipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"payee\",\"type\":\"address\"}],\"name\":\"PaymentWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"ReorgedUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"StaleUpkeepReport\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"UpkeepAdminTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"atBlockHeight\",\"type\":\"uint64\"}],\"name\":\"UpkeepCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"newCheckData\",\"type\":\"bytes\"}],\"name\":\"UpkeepCheckDataSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"gasLimit\",\"type\":\"uint96\"}],\"name\":\"UpkeepGasLimitSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"remainingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"}],\"name\":\"UpkeepMigrated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepOffchainConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepPaused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"totalPayment\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"gasOverhead\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"trigger\",\"type\":\"bytes\"}],\"name\":\"UpkeepPerformed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"privilegeConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepPrivilegeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"startingBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"importedFrom\",\"type\":\"address\"}],\"name\":\"UpkeepReceived\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"performGas\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"}],\"name\":\"UpkeepRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"}],\"name\":\"UpkeepTriggerConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"UpkeepUnpaused\",\"type\":\"event\"},{\"stateMutability\":\"nonpayable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"fallbackTo\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"onTokenTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"onchainConfigBytes\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"paymentPremiumPPB\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"flatFeeMicroLink\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"checkGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"stalenessSeconds\",\"type\":\"uint24\"},{\"internalType\":\"uint16\",\"name\":\"gasCeilingMultiplier\",\"type\":\"uint16\"},{\"internalType\":\"uint96\",\"name\":\"minUpkeepSpend\",\"type\":\"uint96\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformGas\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxCheckDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxPerformDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxRevertDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"fallbackGasPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fallbackLinkPrice\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"transcoder\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"registrars\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"upkeepPrivilegeManager\",\"type\":\"address\"}],\"internalType\":\"structKeeperRegistryBase2_1.OnchainConfig\",\"name\":\"onchainConfig\",\"type\":\"tuple\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setConfigTypeSafe\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"}],\"name\":\"simulatePerformUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"gasUsed\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"rawReport\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]",
- Bin: "0x6101406040523480156200001257600080fd5b50604051620054b9380380620054b98339810160408190526200003591620003df565b80816001600160a01b0316634b4fd03b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000075573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200009b919062000406565b826001600160a01b031663ca30e6036040518163ffffffff1660e01b8152600401602060405180830381865afa158015620000da573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001009190620003df565b836001600160a01b031663b10b673c6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200013f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001659190620003df565b846001600160a01b0316636709d0e56040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001a4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001ca9190620003df565b856001600160a01b0316635425d8ac6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000209573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200022f9190620003df565b3380600081620002865760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620002b957620002b9816200031b565b505050846002811115620002d157620002d162000429565b60e0816002811115620002e857620002e862000429565b9052506001600160a01b0393841660805291831660a052821660c0528116610100529190911661012052506200043f9050565b336001600160a01b03821603620003755760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200027d565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6001600160a01b0381168114620003dc57600080fd5b50565b600060208284031215620003f257600080fd5b8151620003ff81620003c6565b9392505050565b6000602082840312156200041957600080fd5b815160038110620003ff57600080fd5b634e487b7160e01b600052602160045260246000fd5b60805160a05160c05160e0516101005161012051615018620004a16000396000818160d6015261016f01526000505060008181612eb701528181613220015281816133b30152613a3e01526000505060005050600061043b01526150186000f3fe608060405234801561001057600080fd5b50600436106100d45760003560e01c8063aed2e92911610081578063e29b753c1161005b578063e29b753c146102e8578063e3d0e712146102fb578063f2fde38b1461030e576100d4565b8063aed2e92914610262578063afcb95d71461028c578063b1dc65a4146102d5576100d4565b806381ff7048116100b257806381ff7048146101bc5780638da5cb5b14610231578063a4c0ed361461024f576100d4565b8063181f5a771461011b578063349e8cca1461016d57806379ba5097146101b4575b7f00000000000000000000000000000000000000000000000000000000000000003660008037600080366000845af43d6000803e808015610114573d6000f35b3d6000fd5b005b6101576040518060400160405280601481526020017f4b6565706572526567697374727920322e312e3000000000000000000000000081525081565b6040516101649190613cbd565b60405180910390f35b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610164565b610119610321565b61020e60145460115463ffffffff780100000000000000000000000000000000000000000000000083048116937c01000000000000000000000000000000000000000000000000000000009093041691565b6040805163ffffffff948516815293909216602084015290820152606001610164565b60005473ffffffffffffffffffffffffffffffffffffffff1661018f565b61011961025d366004613d46565b610423565b610275610270366004613da2565b61063f565b604080519215158352602083019190915201610164565b601154601254604080516000815260208101939093527c010000000000000000000000000000000000000000000000000000000090910463ffffffff1690820152606001610164565b6101196102e3366004613e33565b6107a7565b6101196102f63660046142ae565b6112ea565b61011961030936600461437b565b6121e6565b61011961031c36600461440a565b61220f565b60015473ffffffffffffffffffffffffffffffffffffffff1633146103a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610492576040517fc8bad78d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602081146104cc576040517fdfe9309000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006104da82840184614427565b60008181526004602052604090205490915065010000000000900463ffffffff90811614610534576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008181526004602052604090206001015461056f9085906c0100000000000000000000000090046bffffffffffffffffffffffff1661446f565b600082815260046020526040902060010180546bffffffffffffffffffffffff929092166c01000000000000000000000000027fffffffffffffffff000000000000000000000000ffffffffffffffffffffffff9092169190911790556018546105da908590614494565b6018556040516bffffffffffffffffffffffff8516815273ffffffffffffffffffffffffffffffffffffffff86169082907fafd24114486da8ebfc32f3626dada8863652e187461aa74d4bfa7348915062039060200160405180910390a35050505050565b60008061064a612223565b6012546e010000000000000000000000000000900460ff1615610699576040517f24522f3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600085815260046020908152604091829020825160e081018452815460ff811615158252610100810463ffffffff908116838601819052650100000000008304821684880152690100000000000000000090920473ffffffffffffffffffffffffffffffffffffffff16606084018190526001909401546bffffffffffffffffffffffff80821660808601526c0100000000000000000000000082041660a0850152780100000000000000000000000000000000000000000000000090041660c08301528451601f8901859004850281018501909552878552909361079893899089908190840183828082843760009201919091525061225d92505050565b9093509150505b935093915050565b60005a604080516101208101825260125460ff808216835261010080830463ffffffff90811660208601526501000000000084048116958501959095526901000000000000000000830462ffffff1660608501526c01000000000000000000000000830461ffff1660808501526e0100000000000000000000000000008304821615801560a08601526f010000000000000000000000000000008404909216151560c085015270010000000000000000000000000000000083046bffffffffffffffffffffffff1660e08501527c0100000000000000000000000000000000000000000000000000000000909204909316908201529192506108d5576040517f24522f3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152600b602052604090205460ff1661091e576040517f1099ed7500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6011548a351461095a576040517fdfdcf8e700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516109679060016144d6565b60ff16861415806109785750858414155b156109af576040517f0244f71a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6109bf8a8a8a8a8a8a8a8a612468565b60006109cb8a8a6126d1565b9050600081604001515167ffffffffffffffff8111156109ed576109ed613eea565b604051908082528060200260200182016040528015610ab157816020015b604080516101e0810182526000610100820181815261012083018290526101408301829052610160830182905261018083018290526101a083018290526101c0830182905282526020808301829052928201819052606082018190526080820181905260a0820181905260c0820181905260e082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909201910181610a0b5790505b5090506000805b836040015151811015610efa576004600085604001518381518110610adf57610adf6144a7565b6020908102919091018101518252818101929092526040908101600020815160e081018352815460ff811615158252610100810463ffffffff90811695830195909552650100000000008104851693820193909352690100000000000000000090920473ffffffffffffffffffffffffffffffffffffffff166060830152600101546bffffffffffffffffffffffff80821660808401526c0100000000000000000000000082041660a08301527801000000000000000000000000000000000000000000000000900490911660c08201528351849083908110610bc457610bc46144a7565b602002602001015160000181905250610bf984604001518281518110610bec57610bec6144a7565b602002602001015161278c565b838281518110610c0b57610c0b6144a7565b6020026020010151608001906001811115610c2857610c286144ef565b90816001811115610c3b57610c3b6144ef565b81525050610caf85848381518110610c5557610c556144a7565b60200260200101516080015186606001518481518110610c7757610c776144a7565b60200260200101518760a001518581518110610c9557610c956144a7565b602002602001015151886000015189602001516001612837565b838281518110610cc157610cc16144a7565b6020026020010151604001906bffffffffffffffffffffffff1690816bffffffffffffffffffffffff1681525050610d4d84604001518281518110610d0857610d086144a7565b602002602001015185608001518381518110610d2657610d266144a7565b6020026020010151858481518110610d4057610d406144a7565b6020026020010151612882565b848381518110610d5f57610d5f6144a7565b6020026020010151602001858481518110610d7c57610d7c6144a7565b602002602001015160e0018281525082151515158152505050828181518110610da757610da76144a7565b60200260200101516020015115610dca57610dc360018361451e565b9150610dcf565b610ee8565b610e35838281518110610de457610de46144a7565b6020026020010151600001516060015185606001518381518110610e0a57610e0a6144a7565b60200260200101518660a001518481518110610e2857610e286144a7565b602002602001015161225d565b848381518110610e4757610e476144a7565b6020026020010151606001858481518110610e6457610e646144a7565b602002602001015160a0018281525082151515158152505050828181518110610e8f57610e8f6144a7565b602002602001015160a0015186610ea69190614539565b9550610ee884604001518281518110610ec157610ec16144a7565b6020026020010151848381518110610edb57610edb6144a7565b6020026020010151612a01565b80610ef28161454c565b915050610ab8565b508061ffff16600003610f115750505050506112e0565b8351610f1e9060016144d6565b610f2d9060ff1661044c614584565b616b6c610f3b8d6010614584565b5a610f469089614539565b610f509190614494565b610f5a9190614494565b610f649190614494565b9450611b58610f7761ffff8316876145f0565b610f819190614494565b945060008060008060005b87604001515181101561118257868181518110610fab57610fab6144a7565b60200260200101516020015115611170576110078a888381518110610fd257610fd26144a7565b6020026020010151608001518a60a001518481518110610ff457610ff46144a7565b6020026020010151518c60000151612b13565b878281518110611019576110196144a7565b602002602001015160c00181815250506110758989604001518381518110611043576110436144a7565b602002602001015189848151811061105d5761105d6144a7565b60200260200101518b600001518c602001518b612b33565b9093509150611084828561446f565b9350611090838661446f565b94508681815181106110a4576110a46144a7565b6020026020010151606001511515886040015182815181106110c8576110c86144a7565b60200260200101517fad8cc9579b21dfe2c2f6ea35ba15b656e46b4f5b0cb424f52739b8ce5cac9c5b84866110fd919061446f565b8a858151811061110f5761110f6144a7565b602002602001015160a001518b868151811061112d5761112d6144a7565b602002602001015160c001518d60800151878151811061114f5761114f6144a7565b60200260200101516040516111679493929190614604565b60405180910390a35b8061117a8161454c565b915050610f8c565b5050336000908152600b6020526040902080548492506002906111ba9084906201000090046bffffffffffffffffffffffff1661446f565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555080601260000160108282829054906101000a90046bffffffffffffffffffffffff16611214919061446f565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555060008f600160038110611257576112576144a7565b602002013560001c9050600060088264ffffffffff16901c905087610100015163ffffffff168163ffffffff1611156112d657601280547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167c010000000000000000000000000000000000000000000000000000000063ffffffff8416021790555b5050505050505050505b5050505050505050565b6112f2612c26565b601f8651111561132e576040517f25d0209c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8360ff1660000361136b576040517fe77dba5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8451865114158061138a5750611382846003614641565b60ff16865111155b156113c1576040517f1d2d1c5800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601254600e547001000000000000000000000000000000009091046bffffffffffffffffffffffff169060005b816bffffffffffffffffffffffff1681101561145657611443600e828154811061141a5761141a6144a7565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff168484612ca7565b508061144e8161454c565b9150506113ee565b5060008060005b836bffffffffffffffffffffffff1681101561155f57600d8181548110611486576114866144a7565b600091825260209091200154600e805473ffffffffffffffffffffffffffffffffffffffff909216945090829081106114c1576114c16144a7565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff8681168452600c8352604080852080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690559116808452600b90925290912080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690559150806115578161454c565b91505061145d565b5061156c600d6000613b92565b611578600e6000613b92565b604080516080810182526000808252602082018190529181018290526060810182905290805b8c518110156119e157600c60008e83815181106115bd576115bd6144a7565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff1682528101919091526040016000205460ff1615611628576040517f77cea0fa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168d8281518110611652576116526144a7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16036116a7576040517f815e1d6400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405180604001604052806001151581526020018260ff16815250600c60008f84815181106116d8576116d86144a7565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff1682528181019290925260400160002082518154939092015160ff16610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909316929092171790558b518c9082908110611780576117806144a7565b60200260200101519150600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036117f0576040517f58a70a0a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff82166000908152600b60209081526040918290208251608081018452905460ff80821615801584526101008304909116938301939093526bffffffffffffffffffffffff6201000082048116948301949094526e010000000000000000000000000000900490921660608301529093506118ab576040517f6a7281ad00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001835260ff80821660208086019182526bffffffffffffffffffffffff808b166060880190815273ffffffffffffffffffffffffffffffffffffffff87166000908152600b909352604092839020885181549551948a0151925184166e010000000000000000000000000000027fffffffffffff000000000000000000000000ffffffffffffffffffffffffffff939094166201000002929092167fffffffffffff000000000000000000000000000000000000000000000000ffff94909616610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000090951694909417179190911692909217919091179055806119d98161454c565b91505061159e565b50508a516119f79150600d9060208d0190613bb0565b508851611a0b90600e9060208c0190613bb0565b506040518061012001604052808960ff168152602001886000015163ffffffff168152602001886020015163ffffffff168152602001886060015162ffffff168152602001886080015161ffff1681526020016012600001600e9054906101000a900460ff16151581526020016012600001600f9054906101000a900460ff1615158152602001856bffffffffffffffffffffffff168152602001600063ffffffff16815250601260008201518160000160006101000a81548160ff021916908360ff16021790555060208201518160000160016101000a81548163ffffffff021916908363ffffffff16021790555060408201518160000160056101000a81548163ffffffff021916908363ffffffff16021790555060608201518160000160096101000a81548162ffffff021916908362ffffff160217905550608082015181600001600c6101000a81548161ffff021916908361ffff16021790555060a082015181600001600e6101000a81548160ff02191690831515021790555060c082015181600001600f6101000a81548160ff02191690831515021790555060e08201518160000160106101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555061010082015181600001601c6101000a81548163ffffffff021916908363ffffffff1602179055509050506040518061018001604052808860a001516bffffffffffffffffffffffff16815260200188610180015173ffffffffffffffffffffffffffffffffffffffff168152602001601360010160009054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff168152602001886040015163ffffffff1681526020018860c0015163ffffffff168152602001601360010160149054906101000a900463ffffffff1663ffffffff168152602001601360010160189054906101000a900463ffffffff1663ffffffff1681526020016013600101601c9054906101000a900463ffffffff1663ffffffff1681526020018860e0015163ffffffff16815260200188610100015163ffffffff16815260200188610120015163ffffffff168152602001886101c0015173ffffffffffffffffffffffffffffffffffffffff16815250601360008201518160000160006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550602082015181600001600c6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060408201518160010160006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550606082015181600101600c6101000a81548163ffffffff021916908363ffffffff16021790555060808201518160010160106101000a81548163ffffffff021916908363ffffffff16021790555060a08201518160010160146101000a81548163ffffffff021916908363ffffffff16021790555060c08201518160010160186101000a81548163ffffffff021916908363ffffffff16021790555060e082015181600101601c6101000a81548163ffffffff021916908363ffffffff1602179055506101008201518160020160006101000a81548163ffffffff021916908363ffffffff1602179055506101208201518160020160046101000a81548163ffffffff021916908363ffffffff1602179055506101408201518160020160086101000a81548163ffffffff021916908363ffffffff16021790555061016082015181600201600c6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555090505086610140015160168190555086610160015160178190555060006013600101601c9054906101000a900463ffffffff169050611fcd612eb1565b601480547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167c010000000000000000000000000000000000000000000000000000000063ffffffff9384160217808255600192601891612048918591780100000000000000000000000000000000000000000000000090041661466a565b92506101000a81548163ffffffff021916908363ffffffff16021790555060008860405160200161207991906146d8565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00181529190526014549091506120e290469030907801000000000000000000000000000000000000000000000000900463ffffffff168f8f8f878f8f612f66565b60115560005b6120f26009613010565b8110156121225761210f61210760098361301a565b600990613026565b508061211a8161454c565b9150506120e8565b5060005b896101a0015151811015612179576121668a6101a00151828151811061214e5761214e6144a7565b6020026020010151600961304890919063ffffffff16565b50806121718161454c565b915050612126565b507f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0582601154601360010160189054906101000a900463ffffffff168f8f8f878f8f6040516121d09998979695949392919061483c565b60405180910390a1505050505050505050505050565b61220786868686806020019051810190612200919061496d565b86866112ea565b505050505050565b612217612c26565b6122208161306a565b50565b321561225b576040517fb60ac5db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b60125460009081906f01000000000000000000000000000000900460ff16156122b2576040517f37ed32e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601280547fffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffff166f010000000000000000000000000000001790556040517f4585e33b000000000000000000000000000000000000000000000000000000009061231f908590602401613cbd565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925290517f79188d1600000000000000000000000000000000000000000000000000000000815290935073ffffffffffffffffffffffffffffffffffffffff8616906379188d16906123f29087908790600401614ac7565b60408051808303816000875af1158015612410573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124349190614ae0565b601280547fffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffff16905590969095509350505050565b6000878760405161247a929190614b13565b604051908190038120612491918b90602001614b23565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201208383019092526000808452908301819052909250906000805b88811015612668576001858783602081106124fd576124fd6144a7565b61250a91901a601b6144d6565b8c8c8581811061251c5761251c6144a7565b905060200201358b8b86818110612535576125356144a7565b9050602002013560405160008152602001604052604051612572949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015612594573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff81166000908152600c602090815290849020838501909452925460ff8082161515808552610100909204169383019390935290955093509050612642576040517f0f4c073700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b826020015160080260ff166001901b8401935080806126609061454c565b9150506124e0565b50827e010101010101010101010101010101010101010101010101010101010101018416146126c3576040517fc103be2e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050505050565b61270a6040518060c001604052806000815260200160008152602001606081526020016060815260200160608152602001606081525090565b600061271883850185614c14565b604081015151606082015151919250908114158061273b57508082608001515114155b8061274b5750808260a001515114155b15612782576040517fb55ac75400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5090505b92915050565b6000818160045b600f811015612819577fff0000000000000000000000000000000000000000000000000000000000000082168382602081106127d1576127d16144a7565b1a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161461280757506000949350505050565b806128118161454c565b915050612793565b5081600f1a600181111561282f5761282f6144ef565b949350505050565b60008061284988878b6000015161315f565b90506000806128648b8a63ffffffff16858a8a60018b6131eb565b9092509050612873818361446f565b9b9a5050505050505050505050565b60008080808460800151600181111561289d5761289d6144ef565b036128c1576128ad868686613644565b6128bc5760009250905061079f565b612938565b6001846080015160018111156128d9576128d96144ef565b036129065760006128eb878787613738565b9250905080612900575060009250905061079f565b50612938565b6040517ff2b2d41200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612940612eb1565b84516040015163ffffffff161161299457857fc3237c8807c467c1b39b8d0395eff077313e691bf0a7388106792564ebfd5636866040516129819190613cbd565b60405180910390a260009250905061079f565b83604001516bffffffffffffffffffffffff16846000015160a001516bffffffffffffffffffffffff1610156129f457857f377c8b0c126ae5248d27aca1c76fac4608aff85673ee3caf09747e1044549e02866040516129819190613cbd565b6001969095509350505050565b600081608001516001811115612a1957612a196144ef565b03612a8b57612a26612eb1565b6000838152600460205260409020600101805463ffffffff929092167801000000000000000000000000000000000000000000000000027fffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffff9092169190911790555050565b600181608001516001811115612aa357612aa36144ef565b03612b0f5760e08101805160009081526008602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055915191517fa4a4e334c0e330143f9437484fe516c13bc560b86b5b0daf58e7084aaac228f29190a25b5050565b6000612b2084848461315f565b90508085101561282f5750929392505050565b600080612b4e888760a001518860c0015188888860016131eb565b90925090506000612b5f828461446f565b600089815260046020526040902060010180549192508291600c90612ba39084906c0100000000000000000000000090046bffffffffffffffffffffffff16614d01565b82546101009290920a6bffffffffffffffffffffffff81810219909316918316021790915560008a815260046020526040812060010180548594509092612bec9185911661446f565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555050965096945050505050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461225b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161039e565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600b602090815260408083208151608081018352905460ff80821615801584526101008304909116948301949094526bffffffffffffffffffffffff6201000082048116938301939093526e0100000000000000000000000000009004909116606082015290612ea3576000816060015185612d3f9190614d01565b90506000612d4d8583614d26565b90508083604001818151612d61919061446f565b6bffffffffffffffffffffffff16905250612d7c8582614d51565b83606001818151612d8d919061446f565b6bffffffffffffffffffffffff90811690915273ffffffffffffffffffffffffffffffffffffffff89166000908152600b602090815260409182902087518154928901519389015160608a015186166e010000000000000000000000000000027fffffffffffff000000000000000000000000ffffffffffffffffffffffffffff919096166201000002167fffffffffffff000000000000000000000000000000000000000000000000ffff60ff95909516610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909416939093171792909216179190911790555050505b6040015190505b9392505050565b600060017f00000000000000000000000000000000000000000000000000000000000000006002811115612ee757612ee76144ef565b03612f6157606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612f38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f5c9190614d85565b905090565b504390565b6000808a8a8a8a8a8a8a8a8a604051602001612f8a99989796959493929190614d9e565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179b9a5050505050505050505050565b6000612786825490565b6000612eaa83836138c5565b6000612eaa8373ffffffffffffffffffffffffffffffffffffffff84166138ef565b6000612eaa8373ffffffffffffffffffffffffffffffffffffffff84166139e9565b3373ffffffffffffffffffffffffffffffffffffffff8216036130e9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161039e565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008080856001811115613175576131756144ef565b03613184575062015f906131a3565b6001856001811115613198576131986144ef565b0361290657506201adb05b6131b463ffffffff85166014614584565b6131bf8460016144d6565b6131ce9060ff16611d4c614584565b6131d89083614494565b6131e29190614494565b95945050505050565b6000806000896080015161ffff16876132049190614584565b90508380156132125750803a105b1561321a57503a5b600060027f00000000000000000000000000000000000000000000000000000000000000006002811115613250576132506144ef565b036133af5760408051600081526020810190915285156132ae57600036604051806080016040528060488152602001614fc46048913960405160200161329893929190614e33565b6040516020818303038152906040529050613316565b6015546132ca90640100000000900463ffffffff166004614e5a565b63ffffffff1667ffffffffffffffff8111156132e8576132e8613eea565b6040519080825280601f01601f191660200182016040528015613312576020820181803683370190505b5090505b6040517f49948e0e00000000000000000000000000000000000000000000000000000000815273420000000000000000000000000000000000000f906349948e0e90613366908490600401613cbd565b602060405180830381865afa158015613383573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133a79190614d85565b915050613509565b60017f000000000000000000000000000000000000000000000000000000000000000060028111156133e3576133e36144ef565b0361350957841561346557606c73ffffffffffffffffffffffffffffffffffffffff1663c6f7de0e6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561343a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061345e9190614d85565b9050613509565b6000606c73ffffffffffffffffffffffffffffffffffffffff166341b247a86040518163ffffffff1660e01b815260040160c060405180830381865afa1580156134b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134d79190614e7d565b50506015549294506134fa93505050640100000000900463ffffffff1682614584565b613505906010614584565b9150505b8461352557808b6080015161ffff166135229190614584565b90505b61353361ffff8716826145f0565b9050600087826135438c8e614494565b61354d9086614584565b6135579190614494565b61356990670de0b6b3a7640000614584565b61357391906145f0565b905060008c6040015163ffffffff1664e8d4a510006135929190614584565b898e6020015163ffffffff16858f886135ab9190614584565b6135b59190614494565b6135c390633b9aca00614584565b6135cd9190614584565b6135d791906145f0565b6135e19190614494565b90506b033b2e3c9fd0803ce80000006135fa8284614494565b1115613632576040517f2ad7547a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b909c909b509950505050505050505050565b6000808380602001905181019061365b9190614ec7565b835160c00151815191925063ffffffff908116911610156136b857847f405288ea7be309e16cfdf481367f90a413e1d4634fcdaf8966546db9b93012e8856040516136a69190613cbd565b60405180910390a26000915050612eaa565b6020810151158015906136df5750602081015181516136dc9063ffffffff16613a38565b14155b806136f857506136ed612eb1565b815163ffffffff1610155b1561372d57847f6aa7f60c176da7af894b384daea2249497448137f5943c1237ada8bc92bdc301856040516136a69190613cbd565b506001949350505050565b6000806000848060200190518101906137519190614f1f565b9050600086826000015183602001516040516020016137a893929190928352602083019190915260e01b7fffffffff0000000000000000000000000000000000000000000000000000000016604082015260440190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052805160209091012060608301519091501580159061380a57508160600151613807836040015163ffffffff16613a38565b14155b806138265750613818612eb1565b826040015163ffffffff1610155b1561387057867f6aa7f60c176da7af894b384daea2249497448137f5943c1237ada8bc92bdc3018760405161385b9190613cbd565b60405180910390a260009350915061079f9050565b60008181526008602052604090205460ff16156138b757867f405288ea7be309e16cfdf481367f90a413e1d4634fcdaf8966546db9b93012e88760405161385b9190613cbd565b600197909650945050505050565b60008260000182815481106138dc576138dc6144a7565b9060005260206000200154905092915050565b600081815260018301602052604081205480156139d8576000613913600183614539565b855490915060009061392790600190614539565b905081811461398c576000866000018281548110613947576139476144a7565b906000526020600020015490508087600001848154811061396a5761396a6144a7565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061399d5761399d614f94565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050612786565b6000915050612786565b5092915050565b6000818152600183016020526040812054613a3057508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155612786565b506000612786565b600060017f00000000000000000000000000000000000000000000000000000000000000006002811115613a6e57613a6e6144ef565b03613b88576000606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613ac1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ae59190614d85565b90508083101580613b005750610100613afe8483614539565b115b15613b0e5750600092915050565b6040517f2b407a8200000000000000000000000000000000000000000000000000000000815260048101849052606490632b407a8290602401602060405180830381865afa158015613b64573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612eaa9190614d85565b504090565b919050565b50805460008255906000526020600020908101906122209190613c3a565b828054828255906000526020600020908101928215613c2a579160200282015b82811115613c2a57825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909116178255602090920191600190910190613bd0565b50613c36929150613c3a565b5090565b5b80821115613c365760008155600101613c3b565b60005b83811015613c6a578181015183820152602001613c52565b50506000910152565b60008151808452613c8b816020860160208601613c4f565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000612eaa6020830184613c73565b73ffffffffffffffffffffffffffffffffffffffff8116811461222057600080fd5b8035613b8d81613cd0565b60008083601f840112613d0f57600080fd5b50813567ffffffffffffffff811115613d2757600080fd5b602083019150836020828501011115613d3f57600080fd5b9250929050565b60008060008060608587031215613d5c57600080fd5b8435613d6781613cd0565b935060208501359250604085013567ffffffffffffffff811115613d8a57600080fd5b613d9687828801613cfd565b95989497509550505050565b600080600060408486031215613db757600080fd5b83359250602084013567ffffffffffffffff811115613dd557600080fd5b613de186828701613cfd565b9497909650939450505050565b60008083601f840112613e0057600080fd5b50813567ffffffffffffffff811115613e1857600080fd5b6020830191508360208260051b8501011115613d3f57600080fd5b60008060008060008060008060e0898b031215613e4f57600080fd5b606089018a811115613e6057600080fd5b8998503567ffffffffffffffff80821115613e7a57600080fd5b613e868c838d01613cfd565b909950975060808b0135915080821115613e9f57600080fd5b613eab8c838d01613dee565b909750955060a08b0135915080821115613ec457600080fd5b50613ed18b828c01613dee565b999c989b50969995989497949560c00135949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516101e0810167ffffffffffffffff81118282101715613f3d57613f3d613eea565b60405290565b60405160c0810167ffffffffffffffff81118282101715613f3d57613f3d613eea565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613fad57613fad613eea565b604052919050565b600067ffffffffffffffff821115613fcf57613fcf613eea565b5060051b60200190565b600082601f830112613fea57600080fd5b81356020613fff613ffa83613fb5565b613f66565b82815260059290921b8401810191818101908684111561401e57600080fd5b8286015b8481101561404257803561403581613cd0565b8352918301918301614022565b509695505050505050565b803560ff81168114613b8d57600080fd5b63ffffffff8116811461222057600080fd5b8035613b8d8161405e565b62ffffff8116811461222057600080fd5b8035613b8d8161407b565b61ffff8116811461222057600080fd5b8035613b8d81614097565b6bffffffffffffffffffffffff8116811461222057600080fd5b8035613b8d816140b2565b60006101e082840312156140ea57600080fd5b6140f2613f19565b90506140fd82614070565b815261410b60208301614070565b602082015261411c60408301614070565b604082015261412d6060830161408c565b606082015261413e608083016140a7565b608082015261414f60a083016140cc565b60a082015261416060c08301614070565b60c082015261417160e08301614070565b60e0820152610100614184818401614070565b90820152610120614196838201614070565b90820152610140828101359082015261016080830135908201526101806141be818401613cf2565b908201526101a08281013567ffffffffffffffff8111156141de57600080fd5b6141ea85828601613fd9565b8284015250506101c06141fe818401613cf2565b9082015292915050565b803567ffffffffffffffff81168114613b8d57600080fd5b600082601f83011261423157600080fd5b813567ffffffffffffffff81111561424b5761424b613eea565b61427c60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601613f66565b81815284602083860101111561429157600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060c087890312156142c757600080fd5b863567ffffffffffffffff808211156142df57600080fd5b6142eb8a838b01613fd9565b9750602089013591508082111561430157600080fd5b61430d8a838b01613fd9565b965061431b60408a0161404d565b9550606089013591508082111561433157600080fd5b61433d8a838b016140d7565b945061434b60808a01614208565b935060a089013591508082111561436157600080fd5b5061436e89828a01614220565b9150509295509295509295565b60008060008060008060c0878903121561439457600080fd5b863567ffffffffffffffff808211156143ac57600080fd5b6143b88a838b01613fd9565b975060208901359150808211156143ce57600080fd5b6143da8a838b01613fd9565b96506143e860408a0161404d565b955060608901359150808211156143fe57600080fd5b61433d8a838b01614220565b60006020828403121561441c57600080fd5b8135612eaa81613cd0565b60006020828403121561443957600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6bffffffffffffffffffffffff8181168382160190808211156139e2576139e2614440565b8082018082111561278657612786614440565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60ff818116838216019081111561278657612786614440565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b61ffff8181168382160190808211156139e2576139e2614440565b8181038181111561278657612786614440565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361457d5761457d614440565b5060010190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156145bc576145bc614440565b500290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826145ff576145ff6145c1565b500490565b6bffffffffffffffffffffffff851681528360208201528260408201526080606082015260006146376080830184613c73565b9695505050505050565b600060ff821660ff84168160ff048111821515161561466257614662614440565b029392505050565b63ffffffff8181168382160190808211156139e2576139e2614440565b600081518084526020808501945080840160005b838110156146cd57815173ffffffffffffffffffffffffffffffffffffffff168752958201959082019060010161469b565b509495945050505050565b602081526146ef60208201835163ffffffff169052565b60006020830151614708604084018263ffffffff169052565b50604083015163ffffffff8116606084015250606083015162ffffff8116608084015250608083015161ffff811660a08401525060a08301516bffffffffffffffffffffffff811660c08401525060c083015163ffffffff811660e08401525060e08301516101006147818185018363ffffffff169052565b840151905061012061479a8482018363ffffffff169052565b84015190506101406147b38482018363ffffffff169052565b840151610160848101919091528401516101808085019190915284015190506101a06147f68185018373ffffffffffffffffffffffffffffffffffffffff169052565b808501519150506101e06101c08181860152614816610200860184614687565b95015173ffffffffffffffffffffffffffffffffffffffff169301929092525090919050565b600061012063ffffffff808d1684528b6020850152808b1660408501525080606084015261486c8184018a614687565b905082810360808401526148808189614687565b905060ff871660a084015282810360c084015261489d8187613c73565b905067ffffffffffffffff851660e08401528281036101008401526148c28185613c73565b9c9b505050505050505050505050565b8051613b8d8161405e565b8051613b8d8161407b565b8051613b8d81614097565b8051613b8d816140b2565b8051613b8d81613cd0565b600082601f83011261491a57600080fd5b8151602061492a613ffa83613fb5565b82815260059290921b8401810191818101908684111561494957600080fd5b8286015b8481101561404257805161496081613cd0565b835291830191830161494d565b60006020828403121561497f57600080fd5b815167ffffffffffffffff8082111561499757600080fd5b908301906101e082860312156149ac57600080fd5b6149b4613f19565b6149bd836148d2565b81526149cb602084016148d2565b60208201526149dc604084016148d2565b60408201526149ed606084016148dd565b60608201526149fe608084016148e8565b6080820152614a0f60a084016148f3565b60a0820152614a2060c084016148d2565b60c0820152614a3160e084016148d2565b60e0820152610100614a448185016148d2565b90820152610120614a568482016148d2565b9082015261014083810151908201526101608084015190820152610180614a7e8185016148fe565b908201526101a08381015183811115614a9657600080fd5b614aa288828701614909565b8284015250506101c09150614ab88284016148fe565b91810191909152949350505050565b82815260406020820152600061282f6040830184613c73565b60008060408385031215614af357600080fd5b82518015158114614b0357600080fd5b6020939093015192949293505050565b8183823760009101908152919050565b8281526080810160608360208401379392505050565b600082601f830112614b4a57600080fd5b81356020614b5a613ffa83613fb5565b82815260059290921b84018101918181019086841115614b7957600080fd5b8286015b848110156140425780358352918301918301614b7d565b600082601f830112614ba557600080fd5b81356020614bb5613ffa83613fb5565b82815260059290921b84018101918181019086841115614bd457600080fd5b8286015b8481101561404257803567ffffffffffffffff811115614bf85760008081fd5b614c068986838b0101614220565b845250918301918301614bd8565b600060208284031215614c2657600080fd5b813567ffffffffffffffff80821115614c3e57600080fd5b9083019060c08286031215614c5257600080fd5b614c5a613f43565b8235815260208301356020820152604083013582811115614c7a57600080fd5b614c8687828601614b39565b604083015250606083013582811115614c9e57600080fd5b614caa87828601614b39565b606083015250608083013582811115614cc257600080fd5b614cce87828601614b94565b60808301525060a083013582811115614ce657600080fd5b614cf287828601614b94565b60a08301525095945050505050565b6bffffffffffffffffffffffff8281168282160390808211156139e2576139e2614440565b60006bffffffffffffffffffffffff80841680614d4557614d456145c1565b92169190910492915050565b60006bffffffffffffffffffffffff80831681851681830481118215151615614d7c57614d7c614440565b02949350505050565b600060208284031215614d9757600080fd5b5051919050565b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b166040850152816060850152614de58285018b614687565b91508382036080850152614df9828a614687565b915060ff881660a085015283820360c0850152614e168288613c73565b90861660e085015283810361010085015290506148c28185613c73565b828482376000838201600081528351614e50818360208801613c4f565b0195945050505050565b600063ffffffff80831681851681830481118215151615614d7c57614d7c614440565b60008060008060008060c08789031215614e9657600080fd5b865195506020870151945060408701519350606087015192506080870151915060a087015190509295509295509295565b600060408284031215614ed957600080fd5b6040516040810181811067ffffffffffffffff82111715614efc57614efc613eea565b6040528251614f0a8161405e565b81526020928301519281019290925250919050565b600060808284031215614f3157600080fd5b6040516080810181811067ffffffffffffffff82111715614f5457614f54613eea565b604052825181526020830151614f698161405e565b60208201526040830151614f7c8161405e565b60408201526060928301519281019290925250919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfe307866666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666a164736f6c6343000810000a",
+ Bin: "0x6101406040523480156200001257600080fd5b50604051620054d0380380620054d08339810160408190526200003591620003df565b80816001600160a01b0316634b4fd03b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000075573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200009b919062000406565b826001600160a01b031663ca30e6036040518163ffffffff1660e01b8152600401602060405180830381865afa158015620000da573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001009190620003df565b836001600160a01b031663b10b673c6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200013f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001659190620003df565b846001600160a01b0316636709d0e56040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001a4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001ca9190620003df565b856001600160a01b0316635425d8ac6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000209573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200022f9190620003df565b3380600081620002865760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620002b957620002b9816200031b565b505050846002811115620002d157620002d162000429565b60e0816002811115620002e857620002e862000429565b9052506001600160a01b0393841660805291831660a052821660c0528116610100529190911661012052506200043f9050565b336001600160a01b03821603620003755760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200027d565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6001600160a01b0381168114620003dc57600080fd5b50565b600060208284031215620003f257600080fd5b8151620003ff81620003c6565b9392505050565b6000602082840312156200041957600080fd5b815160038110620003ff57600080fd5b634e487b7160e01b600052602160045260246000fd5b60805160a05160c05160e051610100516101205161502f620004a16000396000818160d6015261016f01526000505060008181612eb701528181613220015281816133b30152613a4901526000505060005050600061043b015261502f6000f3fe608060405234801561001057600080fd5b50600436106100d45760003560e01c8063aed2e92911610081578063e29b753c1161005b578063e29b753c146102e8578063e3d0e712146102fb578063f2fde38b1461030e576100d4565b8063aed2e92914610262578063afcb95d71461028c578063b1dc65a4146102d5576100d4565b806381ff7048116100b257806381ff7048146101bc5780638da5cb5b14610231578063a4c0ed361461024f576100d4565b8063181f5a771461011b578063349e8cca1461016d57806379ba5097146101b4575b7f00000000000000000000000000000000000000000000000000000000000000003660008037600080366000845af43d6000803e808015610114573d6000f35b3d6000fd5b005b6101576040518060400160405280601481526020017f4b6565706572526567697374727920322e312e3000000000000000000000000081525081565b6040516101649190613cc8565b60405180910390f35b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610164565b610119610321565b61020e60145460115463ffffffff780100000000000000000000000000000000000000000000000083048116937c01000000000000000000000000000000000000000000000000000000009093041691565b6040805163ffffffff948516815293909216602084015290820152606001610164565b60005473ffffffffffffffffffffffffffffffffffffffff1661018f565b61011961025d366004613d51565b610423565b610275610270366004613dad565b61063f565b604080519215158352602083019190915201610164565b601154601254604080516000815260208101939093527c010000000000000000000000000000000000000000000000000000000090910463ffffffff1690820152606001610164565b6101196102e3366004613e3e565b6107a7565b6101196102f63660046142b9565b6112ea565b610119610309366004614386565b6121e6565b61011961031c366004614415565b61220f565b60015473ffffffffffffffffffffffffffffffffffffffff1633146103a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610492576040517fc8bad78d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602081146104cc576040517fdfe9309000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006104da82840184614432565b60008181526004602052604090205490915065010000000000900463ffffffff90811614610534576040517f9c0083a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008181526004602052604090206001015461056f9085906c0100000000000000000000000090046bffffffffffffffffffffffff1661447a565b600082815260046020526040902060010180546bffffffffffffffffffffffff929092166c01000000000000000000000000027fffffffffffffffff000000000000000000000000ffffffffffffffffffffffff9092169190911790556018546105da90859061449f565b6018556040516bffffffffffffffffffffffff8516815273ffffffffffffffffffffffffffffffffffffffff86169082907fafd24114486da8ebfc32f3626dada8863652e187461aa74d4bfa7348915062039060200160405180910390a35050505050565b60008061064a612223565b6012546e010000000000000000000000000000900460ff1615610699576040517f24522f3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600085815260046020908152604091829020825160e081018452815460ff811615158252610100810463ffffffff908116838601819052650100000000008304821684880152690100000000000000000090920473ffffffffffffffffffffffffffffffffffffffff16606084018190526001909401546bffffffffffffffffffffffff80821660808601526c0100000000000000000000000082041660a0850152780100000000000000000000000000000000000000000000000090041660c08301528451601f8901859004850281018501909552878552909361079893899089908190840183828082843760009201919091525061225d92505050565b9093509150505b935093915050565b60005a604080516101208101825260125460ff808216835261010080830463ffffffff90811660208601526501000000000084048116958501959095526901000000000000000000830462ffffff1660608501526c01000000000000000000000000830461ffff1660808501526e0100000000000000000000000000008304821615801560a08601526f010000000000000000000000000000008404909216151560c085015270010000000000000000000000000000000083046bffffffffffffffffffffffff1660e08501527c0100000000000000000000000000000000000000000000000000000000909204909316908201529192506108d5576040517f24522f3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152600b602052604090205460ff1661091e576040517f1099ed7500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6011548a351461095a576040517fdfdcf8e700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516109679060016144e1565b60ff16861415806109785750858414155b156109af576040517f0244f71a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6109bf8a8a8a8a8a8a8a8a612468565b60006109cb8a8a6126d1565b9050600081604001515167ffffffffffffffff8111156109ed576109ed613ef5565b604051908082528060200260200182016040528015610ab157816020015b604080516101e0810182526000610100820181815261012083018290526101408301829052610160830182905261018083018290526101a083018290526101c0830182905282526020808301829052928201819052606082018190526080820181905260a0820181905260c0820181905260e082015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909201910181610a0b5790505b5090506000805b836040015151811015610efa576004600085604001518381518110610adf57610adf6144b2565b6020908102919091018101518252818101929092526040908101600020815160e081018352815460ff811615158252610100810463ffffffff90811695830195909552650100000000008104851693820193909352690100000000000000000090920473ffffffffffffffffffffffffffffffffffffffff166060830152600101546bffffffffffffffffffffffff80821660808401526c0100000000000000000000000082041660a08301527801000000000000000000000000000000000000000000000000900490911660c08201528351849083908110610bc457610bc46144b2565b602002602001015160000181905250610bf984604001518281518110610bec57610bec6144b2565b602002602001015161278c565b838281518110610c0b57610c0b6144b2565b6020026020010151608001906001811115610c2857610c286144fa565b90816001811115610c3b57610c3b6144fa565b81525050610caf85848381518110610c5557610c556144b2565b60200260200101516080015186606001518481518110610c7757610c776144b2565b60200260200101518760a001518581518110610c9557610c956144b2565b602002602001015151886000015189602001516001612837565b838281518110610cc157610cc16144b2565b6020026020010151604001906bffffffffffffffffffffffff1690816bffffffffffffffffffffffff1681525050610d4d84604001518281518110610d0857610d086144b2565b602002602001015185608001518381518110610d2657610d266144b2565b6020026020010151858481518110610d4057610d406144b2565b6020026020010151612882565b848381518110610d5f57610d5f6144b2565b6020026020010151602001858481518110610d7c57610d7c6144b2565b602002602001015160e0018281525082151515158152505050828181518110610da757610da76144b2565b60200260200101516020015115610dca57610dc3600183614529565b9150610dcf565b610ee8565b610e35838281518110610de457610de46144b2565b6020026020010151600001516060015185606001518381518110610e0a57610e0a6144b2565b60200260200101518660a001518481518110610e2857610e286144b2565b602002602001015161225d565b848381518110610e4757610e476144b2565b6020026020010151606001858481518110610e6457610e646144b2565b602002602001015160a0018281525082151515158152505050828181518110610e8f57610e8f6144b2565b602002602001015160a0015186610ea69190614544565b9550610ee884604001518281518110610ec157610ec16144b2565b6020026020010151848381518110610edb57610edb6144b2565b6020026020010151612a01565b80610ef281614557565b915050610ab8565b508061ffff16600003610f115750505050506112e0565b8351610f1e9060016144e1565b610f2d9060ff1661044c61458f565b616b6c610f3b8d601061458f565b5a610f469089614544565b610f50919061449f565b610f5a919061449f565b610f64919061449f565b9450611b58610f7761ffff8316876145fb565b610f81919061449f565b945060008060008060005b87604001515181101561118257868181518110610fab57610fab6144b2565b60200260200101516020015115611170576110078a888381518110610fd257610fd26144b2565b6020026020010151608001518a60a001518481518110610ff457610ff46144b2565b6020026020010151518c60000151612b13565b878281518110611019576110196144b2565b602002602001015160c00181815250506110758989604001518381518110611043576110436144b2565b602002602001015189848151811061105d5761105d6144b2565b60200260200101518b600001518c602001518b612b33565b9093509150611084828561447a565b9350611090838661447a565b94508681815181106110a4576110a46144b2565b6020026020010151606001511515886040015182815181106110c8576110c86144b2565b60200260200101517fad8cc9579b21dfe2c2f6ea35ba15b656e46b4f5b0cb424f52739b8ce5cac9c5b84866110fd919061447a565b8a858151811061110f5761110f6144b2565b602002602001015160a001518b868151811061112d5761112d6144b2565b602002602001015160c001518d60800151878151811061114f5761114f6144b2565b6020026020010151604051611167949392919061460f565b60405180910390a35b8061117a81614557565b915050610f8c565b5050336000908152600b6020526040902080548492506002906111ba9084906201000090046bffffffffffffffffffffffff1661447a565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555080601260000160108282829054906101000a90046bffffffffffffffffffffffff16611214919061447a565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555060008f600160038110611257576112576144b2565b602002013560001c9050600060088264ffffffffff16901c905087610100015163ffffffff168163ffffffff1611156112d657601280547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167c010000000000000000000000000000000000000000000000000000000063ffffffff8416021790555b5050505050505050505b5050505050505050565b6112f2612c26565b601f8651111561132e576040517f25d0209c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8360ff1660000361136b576040517fe77dba5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8451865114158061138a575061138284600361464c565b60ff16865111155b156113c1576040517f1d2d1c5800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601254600e547001000000000000000000000000000000009091046bffffffffffffffffffffffff169060005b816bffffffffffffffffffffffff1681101561145657611443600e828154811061141a5761141a6144b2565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff168484612ca7565b508061144e81614557565b9150506113ee565b5060008060005b836bffffffffffffffffffffffff1681101561155f57600d8181548110611486576114866144b2565b600091825260209091200154600e805473ffffffffffffffffffffffffffffffffffffffff909216945090829081106114c1576114c16144b2565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff8681168452600c8352604080852080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690559116808452600b90925290912080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905591508061155781614557565b91505061145d565b5061156c600d6000613b9d565b611578600e6000613b9d565b604080516080810182526000808252602082018190529181018290526060810182905290805b8c518110156119e157600c60008e83815181106115bd576115bd6144b2565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff1682528101919091526040016000205460ff1615611628576040517f77cea0fa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168d8281518110611652576116526144b2565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16036116a7576040517f815e1d6400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405180604001604052806001151581526020018260ff16815250600c60008f84815181106116d8576116d86144b2565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff1682528181019290925260400160002082518154939092015160ff16610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909316929092171790558b518c9082908110611780576117806144b2565b60200260200101519150600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036117f0576040517f58a70a0a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff82166000908152600b60209081526040918290208251608081018452905460ff80821615801584526101008304909116938301939093526bffffffffffffffffffffffff6201000082048116948301949094526e010000000000000000000000000000900490921660608301529093506118ab576040517f6a7281ad00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001835260ff80821660208086019182526bffffffffffffffffffffffff808b166060880190815273ffffffffffffffffffffffffffffffffffffffff87166000908152600b909352604092839020885181549551948a0151925184166e010000000000000000000000000000027fffffffffffff000000000000000000000000ffffffffffffffffffffffffffff939094166201000002929092167fffffffffffff000000000000000000000000000000000000000000000000ffff94909616610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000090951694909417179190911692909217919091179055806119d981614557565b91505061159e565b50508a516119f79150600d9060208d0190613bbb565b508851611a0b90600e9060208c0190613bbb565b506040518061012001604052808960ff168152602001886000015163ffffffff168152602001886020015163ffffffff168152602001886060015162ffffff168152602001886080015161ffff1681526020016012600001600e9054906101000a900460ff16151581526020016012600001600f9054906101000a900460ff1615158152602001856bffffffffffffffffffffffff168152602001600063ffffffff16815250601260008201518160000160006101000a81548160ff021916908360ff16021790555060208201518160000160016101000a81548163ffffffff021916908363ffffffff16021790555060408201518160000160056101000a81548163ffffffff021916908363ffffffff16021790555060608201518160000160096101000a81548162ffffff021916908362ffffff160217905550608082015181600001600c6101000a81548161ffff021916908361ffff16021790555060a082015181600001600e6101000a81548160ff02191690831515021790555060c082015181600001600f6101000a81548160ff02191690831515021790555060e08201518160000160106101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555061010082015181600001601c6101000a81548163ffffffff021916908363ffffffff1602179055509050506040518061018001604052808860a001516bffffffffffffffffffffffff16815260200188610180015173ffffffffffffffffffffffffffffffffffffffff168152602001601360010160009054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff168152602001886040015163ffffffff1681526020018860c0015163ffffffff168152602001601360010160149054906101000a900463ffffffff1663ffffffff168152602001601360010160189054906101000a900463ffffffff1663ffffffff1681526020016013600101601c9054906101000a900463ffffffff1663ffffffff1681526020018860e0015163ffffffff16815260200188610100015163ffffffff16815260200188610120015163ffffffff168152602001886101c0015173ffffffffffffffffffffffffffffffffffffffff16815250601360008201518160000160006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550602082015181600001600c6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060408201518160010160006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550606082015181600101600c6101000a81548163ffffffff021916908363ffffffff16021790555060808201518160010160106101000a81548163ffffffff021916908363ffffffff16021790555060a08201518160010160146101000a81548163ffffffff021916908363ffffffff16021790555060c08201518160010160186101000a81548163ffffffff021916908363ffffffff16021790555060e082015181600101601c6101000a81548163ffffffff021916908363ffffffff1602179055506101008201518160020160006101000a81548163ffffffff021916908363ffffffff1602179055506101208201518160020160046101000a81548163ffffffff021916908363ffffffff1602179055506101408201518160020160086101000a81548163ffffffff021916908363ffffffff16021790555061016082015181600201600c6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555090505086610140015160168190555086610160015160178190555060006013600101601c9054906101000a900463ffffffff169050611fcd612eb1565b601480547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167c010000000000000000000000000000000000000000000000000000000063ffffffff93841602178082556001926018916120489185917801000000000000000000000000000000000000000000000000900416614675565b92506101000a81548163ffffffff021916908363ffffffff16021790555060008860405160200161207991906146e3565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00181529190526014549091506120e290469030907801000000000000000000000000000000000000000000000000900463ffffffff168f8f8f878f8f612f66565b60115560005b6120f26009613010565b8110156121225761210f61210760098361301a565b600990613026565b508061211a81614557565b9150506120e8565b5060005b896101a0015151811015612179576121668a6101a00151828151811061214e5761214e6144b2565b6020026020010151600961304890919063ffffffff16565b508061217181614557565b915050612126565b507f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0582601154601360010160189054906101000a900463ffffffff168f8f8f878f8f6040516121d099989796959493929190614847565b60405180910390a1505050505050505050505050565b612207868686868060200190518101906122009190614978565b86866112ea565b505050505050565b612217612c26565b6122208161306a565b50565b321561225b576040517fb60ac5db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b60125460009081906f01000000000000000000000000000000900460ff16156122b2576040517f37ed32e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601280547fffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffff166f010000000000000000000000000000001790556040517f4585e33b000000000000000000000000000000000000000000000000000000009061231f908590602401613cc8565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925290517f79188d1600000000000000000000000000000000000000000000000000000000815290935073ffffffffffffffffffffffffffffffffffffffff8616906379188d16906123f29087908790600401614ad2565b60408051808303816000875af1158015612410573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124349190614aeb565b601280547fffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffff16905590969095509350505050565b6000878760405161247a929190614b1e565b604051908190038120612491918b90602001614b2e565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201208383019092526000808452908301819052909250906000805b88811015612668576001858783602081106124fd576124fd6144b2565b61250a91901a601b6144e1565b8c8c8581811061251c5761251c6144b2565b905060200201358b8b86818110612535576125356144b2565b9050602002013560405160008152602001604052604051612572949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015612594573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff81166000908152600c602090815290849020838501909452925460ff8082161515808552610100909204169383019390935290955093509050612642576040517f0f4c073700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b826020015160080260ff166001901b84019350808061266090614557565b9150506124e0565b50827e010101010101010101010101010101010101010101010101010101010101018416146126c3576040517fc103be2e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050505050565b61270a6040518060c001604052806000815260200160008152602001606081526020016060815260200160608152602001606081525090565b600061271883850185614c1f565b604081015151606082015151919250908114158061273b57508082608001515114155b8061274b5750808260a001515114155b15612782576040517fb55ac75400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5090505b92915050565b6000818160045b600f811015612819577fff0000000000000000000000000000000000000000000000000000000000000082168382602081106127d1576127d16144b2565b1a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161461280757506000949350505050565b8061281181614557565b915050612793565b5081600f1a600181111561282f5761282f6144fa565b949350505050565b60008061284988878b6000015161315f565b90506000806128648b8a63ffffffff16858a8a60018b6131eb565b9092509050612873818361447a565b9b9a5050505050505050505050565b60008080808460800151600181111561289d5761289d6144fa565b036128c1576128ad868686613644565b6128bc5760009250905061079f565b612938565b6001846080015160018111156128d9576128d96144fa565b036129065760006128eb878787613738565b9250905080612900575060009250905061079f565b50612938565b6040517ff2b2d41200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612940612eb1565b84516040015163ffffffff161161299457857fc3237c8807c467c1b39b8d0395eff077313e691bf0a7388106792564ebfd5636866040516129819190613cc8565b60405180910390a260009250905061079f565b83604001516bffffffffffffffffffffffff16846000015160a001516bffffffffffffffffffffffff1610156129f457857f377c8b0c126ae5248d27aca1c76fac4608aff85673ee3caf09747e1044549e02866040516129819190613cc8565b6001969095509350505050565b600081608001516001811115612a1957612a196144fa565b03612a8b57612a26612eb1565b6000838152600460205260409020600101805463ffffffff929092167801000000000000000000000000000000000000000000000000027fffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffff9092169190911790555050565b600181608001516001811115612aa357612aa36144fa565b03612b0f5760e08101805160009081526008602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055915191517fa4a4e334c0e330143f9437484fe516c13bc560b86b5b0daf58e7084aaac228f29190a25b5050565b6000612b2084848461315f565b90508085101561282f5750929392505050565b600080612b4e888760a001518860c0015188888860016131eb565b90925090506000612b5f828461447a565b600089815260046020526040902060010180549192508291600c90612ba39084906c0100000000000000000000000090046bffffffffffffffffffffffff16614d0c565b82546101009290920a6bffffffffffffffffffffffff81810219909316918316021790915560008a815260046020526040812060010180548594509092612bec9185911661447a565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555050965096945050505050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461225b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161039e565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600b602090815260408083208151608081018352905460ff80821615801584526101008304909116948301949094526bffffffffffffffffffffffff6201000082048116938301939093526e0100000000000000000000000000009004909116606082015290612ea3576000816060015185612d3f9190614d0c565b90506000612d4d8583614d31565b90508083604001818151612d61919061447a565b6bffffffffffffffffffffffff16905250612d7c8582614d5c565b83606001818151612d8d919061447a565b6bffffffffffffffffffffffff90811690915273ffffffffffffffffffffffffffffffffffffffff89166000908152600b602090815260409182902087518154928901519389015160608a015186166e010000000000000000000000000000027fffffffffffff000000000000000000000000ffffffffffffffffffffffffffff919096166201000002167fffffffffffff000000000000000000000000000000000000000000000000ffff60ff95909516610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff921515929092167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909416939093171792909216179190911790555050505b6040015190505b9392505050565b600060017f00000000000000000000000000000000000000000000000000000000000000006002811115612ee757612ee76144fa565b03612f6157606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612f38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f5c9190614d90565b905090565b504390565b6000808a8a8a8a8a8a8a8a8a604051602001612f8a99989796959493929190614da9565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179b9a5050505050505050505050565b6000612786825490565b6000612eaa83836138d0565b6000612eaa8373ffffffffffffffffffffffffffffffffffffffff84166138fa565b6000612eaa8373ffffffffffffffffffffffffffffffffffffffff84166139f4565b3373ffffffffffffffffffffffffffffffffffffffff8216036130e9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161039e565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008080856001811115613175576131756144fa565b03613184575062015f906131a3565b6001856001811115613198576131986144fa565b0361290657506201adb05b6131b463ffffffff8516601461458f565b6131bf8460016144e1565b6131ce9060ff16611d4c61458f565b6131d8908361449f565b6131e2919061449f565b95945050505050565b6000806000896080015161ffff1687613204919061458f565b90508380156132125750803a105b1561321a57503a5b600060027f00000000000000000000000000000000000000000000000000000000000000006002811115613250576132506144fa565b036133af5760408051600081526020810190915285156132ae57600036604051806080016040528060488152602001614fdb6048913960405160200161329893929190614e3e565b6040516020818303038152906040529050613316565b6015546132ca90640100000000900463ffffffff166004614e65565b63ffffffff1667ffffffffffffffff8111156132e8576132e8613ef5565b6040519080825280601f01601f191660200182016040528015613312576020820181803683370190505b5090505b6040517f49948e0e00000000000000000000000000000000000000000000000000000000815273420000000000000000000000000000000000000f906349948e0e90613366908490600401613cc8565b602060405180830381865afa158015613383573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133a79190614d90565b915050613509565b60017f000000000000000000000000000000000000000000000000000000000000000060028111156133e3576133e36144fa565b0361350957841561346557606c73ffffffffffffffffffffffffffffffffffffffff1663c6f7de0e6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561343a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061345e9190614d90565b9050613509565b6000606c73ffffffffffffffffffffffffffffffffffffffff166341b247a86040518163ffffffff1660e01b815260040160c060405180830381865afa1580156134b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134d79190614e88565b50506015549294506134fa93505050640100000000900463ffffffff168261458f565b61350590601061458f565b9150505b8461352557808b6080015161ffff16613522919061458f565b90505b61353361ffff8716826145fb565b9050600087826135438c8e61449f565b61354d908661458f565b613557919061449f565b61356990670de0b6b3a764000061458f565b61357391906145fb565b905060008c6040015163ffffffff1664e8d4a51000613592919061458f565b898e6020015163ffffffff16858f886135ab919061458f565b6135b5919061449f565b6135c390633b9aca0061458f565b6135cd919061458f565b6135d791906145fb565b6135e1919061449f565b90506b033b2e3c9fd0803ce80000006135fa828461449f565b1115613632576040517f2ad7547a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b909c909b509950505050505050505050565b6000808380602001905181019061365b9190614ed2565b835160c00151815191925063ffffffff908116911610156136b857847f405288ea7be309e16cfdf481367f90a413e1d4634fcdaf8966546db9b93012e8856040516136a69190613cc8565b60405180910390a26000915050612eaa565b6020810151158015906136df5750602081015181516136dc9063ffffffff16613a43565b14155b806136f857506136ed612eb1565b815163ffffffff1610155b1561372d57847f6aa7f60c176da7af894b384daea2249497448137f5943c1237ada8bc92bdc301856040516136a69190613cc8565b506001949350505050565b6000806000848060200190518101906137519190614f2a565b90506000868260000151836020015184604001516040516020016137b394939291909384526020840192909252604083015260e01b7fffffffff0000000000000000000000000000000000000000000000000000000016606082015260640190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052805160209091012060808301519091501580159061381557508160800151613812836060015163ffffffff16613a43565b14155b806138315750613823612eb1565b826060015163ffffffff1610155b1561387b57867f6aa7f60c176da7af894b384daea2249497448137f5943c1237ada8bc92bdc301876040516138669190613cc8565b60405180910390a260009350915061079f9050565b60008181526008602052604090205460ff16156138c257867f405288ea7be309e16cfdf481367f90a413e1d4634fcdaf8966546db9b93012e8876040516138669190613cc8565b600197909650945050505050565b60008260000182815481106138e7576138e76144b2565b9060005260206000200154905092915050565b600081815260018301602052604081205480156139e357600061391e600183614544565b855490915060009061393290600190614544565b9050818114613997576000866000018281548110613952576139526144b2565b9060005260206000200154905080876000018481548110613975576139756144b2565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806139a8576139a8614fab565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050612786565b6000915050612786565b5092915050565b6000818152600183016020526040812054613a3b57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155612786565b506000612786565b600060017f00000000000000000000000000000000000000000000000000000000000000006002811115613a7957613a796144fa565b03613b93576000606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613acc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613af09190614d90565b90508083101580613b0b5750610100613b098483614544565b115b15613b195750600092915050565b6040517f2b407a8200000000000000000000000000000000000000000000000000000000815260048101849052606490632b407a8290602401602060405180830381865afa158015613b6f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612eaa9190614d90565b504090565b919050565b50805460008255906000526020600020908101906122209190613c45565b828054828255906000526020600020908101928215613c35579160200282015b82811115613c3557825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909116178255602090920191600190910190613bdb565b50613c41929150613c45565b5090565b5b80821115613c415760008155600101613c46565b60005b83811015613c75578181015183820152602001613c5d565b50506000910152565b60008151808452613c96816020860160208601613c5a565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000612eaa6020830184613c7e565b73ffffffffffffffffffffffffffffffffffffffff8116811461222057600080fd5b8035613b9881613cdb565b60008083601f840112613d1a57600080fd5b50813567ffffffffffffffff811115613d3257600080fd5b602083019150836020828501011115613d4a57600080fd5b9250929050565b60008060008060608587031215613d6757600080fd5b8435613d7281613cdb565b935060208501359250604085013567ffffffffffffffff811115613d9557600080fd5b613da187828801613d08565b95989497509550505050565b600080600060408486031215613dc257600080fd5b83359250602084013567ffffffffffffffff811115613de057600080fd5b613dec86828701613d08565b9497909650939450505050565b60008083601f840112613e0b57600080fd5b50813567ffffffffffffffff811115613e2357600080fd5b6020830191508360208260051b8501011115613d4a57600080fd5b60008060008060008060008060e0898b031215613e5a57600080fd5b606089018a811115613e6b57600080fd5b8998503567ffffffffffffffff80821115613e8557600080fd5b613e918c838d01613d08565b909950975060808b0135915080821115613eaa57600080fd5b613eb68c838d01613df9565b909750955060a08b0135915080821115613ecf57600080fd5b50613edc8b828c01613df9565b999c989b50969995989497949560c00135949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516101e0810167ffffffffffffffff81118282101715613f4857613f48613ef5565b60405290565b60405160c0810167ffffffffffffffff81118282101715613f4857613f48613ef5565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613fb857613fb8613ef5565b604052919050565b600067ffffffffffffffff821115613fda57613fda613ef5565b5060051b60200190565b600082601f830112613ff557600080fd5b8135602061400a61400583613fc0565b613f71565b82815260059290921b8401810191818101908684111561402957600080fd5b8286015b8481101561404d57803561404081613cdb565b835291830191830161402d565b509695505050505050565b803560ff81168114613b9857600080fd5b63ffffffff8116811461222057600080fd5b8035613b9881614069565b62ffffff8116811461222057600080fd5b8035613b9881614086565b61ffff8116811461222057600080fd5b8035613b98816140a2565b6bffffffffffffffffffffffff8116811461222057600080fd5b8035613b98816140bd565b60006101e082840312156140f557600080fd5b6140fd613f24565b90506141088261407b565b81526141166020830161407b565b60208201526141276040830161407b565b604082015261413860608301614097565b6060820152614149608083016140b2565b608082015261415a60a083016140d7565b60a082015261416b60c0830161407b565b60c082015261417c60e0830161407b565b60e082015261010061418f81840161407b565b908201526101206141a183820161407b565b90820152610140828101359082015261016080830135908201526101806141c9818401613cfd565b908201526101a08281013567ffffffffffffffff8111156141e957600080fd5b6141f585828601613fe4565b8284015250506101c0614209818401613cfd565b9082015292915050565b803567ffffffffffffffff81168114613b9857600080fd5b600082601f83011261423c57600080fd5b813567ffffffffffffffff81111561425657614256613ef5565b61428760207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601613f71565b81815284602083860101111561429c57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060c087890312156142d257600080fd5b863567ffffffffffffffff808211156142ea57600080fd5b6142f68a838b01613fe4565b9750602089013591508082111561430c57600080fd5b6143188a838b01613fe4565b965061432660408a01614058565b9550606089013591508082111561433c57600080fd5b6143488a838b016140e2565b945061435660808a01614213565b935060a089013591508082111561436c57600080fd5b5061437989828a0161422b565b9150509295509295509295565b60008060008060008060c0878903121561439f57600080fd5b863567ffffffffffffffff808211156143b757600080fd5b6143c38a838b01613fe4565b975060208901359150808211156143d957600080fd5b6143e58a838b01613fe4565b96506143f360408a01614058565b9550606089013591508082111561440957600080fd5b6143488a838b0161422b565b60006020828403121561442757600080fd5b8135612eaa81613cdb565b60006020828403121561444457600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6bffffffffffffffffffffffff8181168382160190808211156139ed576139ed61444b565b808201808211156127865761278661444b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60ff81811683821601908111156127865761278661444b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b61ffff8181168382160190808211156139ed576139ed61444b565b818103818111156127865761278661444b565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036145885761458861444b565b5060010190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156145c7576145c761444b565b500290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261460a5761460a6145cc565b500490565b6bffffffffffffffffffffffff851681528360208201528260408201526080606082015260006146426080830184613c7e565b9695505050505050565b600060ff821660ff84168160ff048111821515161561466d5761466d61444b565b029392505050565b63ffffffff8181168382160190808211156139ed576139ed61444b565b600081518084526020808501945080840160005b838110156146d857815173ffffffffffffffffffffffffffffffffffffffff16875295820195908201906001016146a6565b509495945050505050565b602081526146fa60208201835163ffffffff169052565b60006020830151614713604084018263ffffffff169052565b50604083015163ffffffff8116606084015250606083015162ffffff8116608084015250608083015161ffff811660a08401525060a08301516bffffffffffffffffffffffff811660c08401525060c083015163ffffffff811660e08401525060e083015161010061478c8185018363ffffffff169052565b84015190506101206147a58482018363ffffffff169052565b84015190506101406147be8482018363ffffffff169052565b840151610160848101919091528401516101808085019190915284015190506101a06148018185018373ffffffffffffffffffffffffffffffffffffffff169052565b808501519150506101e06101c08181860152614821610200860184614692565b95015173ffffffffffffffffffffffffffffffffffffffff169301929092525090919050565b600061012063ffffffff808d1684528b6020850152808b166040850152508060608401526148778184018a614692565b9050828103608084015261488b8189614692565b905060ff871660a084015282810360c08401526148a88187613c7e565b905067ffffffffffffffff851660e08401528281036101008401526148cd8185613c7e565b9c9b505050505050505050505050565b8051613b9881614069565b8051613b9881614086565b8051613b98816140a2565b8051613b98816140bd565b8051613b9881613cdb565b600082601f83011261492557600080fd5b8151602061493561400583613fc0565b82815260059290921b8401810191818101908684111561495457600080fd5b8286015b8481101561404d57805161496b81613cdb565b8352918301918301614958565b60006020828403121561498a57600080fd5b815167ffffffffffffffff808211156149a257600080fd5b908301906101e082860312156149b757600080fd5b6149bf613f24565b6149c8836148dd565b81526149d6602084016148dd565b60208201526149e7604084016148dd565b60408201526149f8606084016148e8565b6060820152614a09608084016148f3565b6080820152614a1a60a084016148fe565b60a0820152614a2b60c084016148dd565b60c0820152614a3c60e084016148dd565b60e0820152610100614a4f8185016148dd565b90820152610120614a618482016148dd565b9082015261014083810151908201526101608084015190820152610180614a89818501614909565b908201526101a08381015183811115614aa157600080fd5b614aad88828701614914565b8284015250506101c09150614ac3828401614909565b91810191909152949350505050565b82815260406020820152600061282f6040830184613c7e565b60008060408385031215614afe57600080fd5b82518015158114614b0e57600080fd5b6020939093015192949293505050565b8183823760009101908152919050565b8281526080810160608360208401379392505050565b600082601f830112614b5557600080fd5b81356020614b6561400583613fc0565b82815260059290921b84018101918181019086841115614b8457600080fd5b8286015b8481101561404d5780358352918301918301614b88565b600082601f830112614bb057600080fd5b81356020614bc061400583613fc0565b82815260059290921b84018101918181019086841115614bdf57600080fd5b8286015b8481101561404d57803567ffffffffffffffff811115614c035760008081fd5b614c118986838b010161422b565b845250918301918301614be3565b600060208284031215614c3157600080fd5b813567ffffffffffffffff80821115614c4957600080fd5b9083019060c08286031215614c5d57600080fd5b614c65613f4e565b8235815260208301356020820152604083013582811115614c8557600080fd5b614c9187828601614b44565b604083015250606083013582811115614ca957600080fd5b614cb587828601614b44565b606083015250608083013582811115614ccd57600080fd5b614cd987828601614b9f565b60808301525060a083013582811115614cf157600080fd5b614cfd87828601614b9f565b60a08301525095945050505050565b6bffffffffffffffffffffffff8281168282160390808211156139ed576139ed61444b565b60006bffffffffffffffffffffffff80841680614d5057614d506145cc565b92169190910492915050565b60006bffffffffffffffffffffffff80831681851681830481118215151615614d8757614d8761444b565b02949350505050565b600060208284031215614da257600080fd5b5051919050565b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b166040850152816060850152614df08285018b614692565b91508382036080850152614e04828a614692565b915060ff881660a085015283820360c0850152614e218288613c7e565b90861660e085015283810361010085015290506148cd8185613c7e565b828482376000838201600081528351614e5b818360208801613c5a565b0195945050505050565b600063ffffffff80831681851681830481118215151615614d8757614d8761444b565b60008060008060008060c08789031215614ea157600080fd5b865195506020870151945060408701519350606087015192506080870151915060a087015190509295509295509295565b600060408284031215614ee457600080fd5b6040516040810181811067ffffffffffffffff82111715614f0757614f07613ef5565b6040528251614f1581614069565b81526020928301519281019290925250919050565b600060a08284031215614f3c57600080fd5b60405160a0810181811067ffffffffffffffff82111715614f5f57614f5f613ef5565b806040525082518152602083015160208201526040830151614f8081614069565b60408201526060830151614f9381614069565b60608201526080928301519281019290925250919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfe307866666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666a164736f6c6343000810000a",
}
var KeeperRegistryABI = KeeperRegistryMetaData.ABI
diff --git a/core/gethwrappers/generated/log_triggered_feed_lookup_wrapper/log_triggered_feed_lookup_wrapper.go b/core/gethwrappers/generated/log_triggered_feed_lookup_wrapper/log_triggered_feed_lookup_wrapper.go
deleted file mode 100644
index 21bc8fa80bf..00000000000
--- a/core/gethwrappers/generated/log_triggered_feed_lookup_wrapper/log_triggered_feed_lookup_wrapper.go
+++ /dev/null
@@ -1,561 +0,0 @@
-// Code generated - DO NOT EDIT.
-// This file is a generated binding and any manual changes will be lost.
-
-package log_triggered_feed_lookup_wrapper
-
-import (
- "errors"
- "fmt"
- "math/big"
- "strings"
-
- ethereum "github.com/ethereum/go-ethereum"
- "github.com/ethereum/go-ethereum/accounts/abi"
- "github.com/ethereum/go-ethereum/accounts/abi/bind"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/event"
- "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated"
-)
-
-var (
- _ = errors.New
- _ = big.NewInt
- _ = strings.NewReader
- _ = ethereum.NotFound
- _ = bind.Bind
- _ = common.Big1
- _ = types.BloomLookup
- _ = event.NewSubscription
- _ = abi.ConvertType
-)
-
-type Log struct {
- Index *big.Int
- TxIndex *big.Int
- TxHash [32]byte
- BlockNumber *big.Int
- BlockHash [32]byte
- Source common.Address
- Topics [][32]byte
- Data []byte
-}
-
-var LogTriggeredFeedLookupMetaData = &bind.MetaData{
- ABI: "[{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"_useArbitrumBlockNum\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"_verify\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"feedParamKey\",\"type\":\"string\"},{\"internalType\":\"string[]\",\"name\":\"feeds\",\"type\":\"string[]\"},{\"internalType\":\"string\",\"name\":\"timeParamKey\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"time\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"FeedLookup\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"orderId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"exchange\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"blob\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"verified\",\"type\":\"bytes\"}],\"name\":\"PerformingLogTriggerUpkeep\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes[]\",\"name\":\"values\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"checkCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"txIndex\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"txHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"source\",\"type\":\"address\"},{\"internalType\":\"bytes32[]\",\"name\":\"topics\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"structLog\",\"name\":\"log\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"checkLog\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"feedParamKey\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"feedsHex\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"}],\"name\":\"performUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"feedParam\",\"type\":\"string\"}],\"name\":\"setFeedParamKey\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string[]\",\"name\":\"newFeeds\",\"type\":\"string[]\"}],\"name\":\"setFeedsHex\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"timeParam\",\"type\":\"string\"}],\"name\":\"setTimeParamKey\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"timeParamKey\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"useArbitrumBlockNum\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]",
- Bin: "0x610120604052604260a08181526080918291906200164e60c03990526200002a9060019081620000e5565b506040805180820190915260098152680cccacac892c890caf60bb1b60208201526002906200005a908262000261565b5060408051808201909152600b81526a313637b1b5a73ab6b132b960a91b60208201526003906200008c908262000261565b503480156200009a57600080fd5b506040516200169038038062001690833981016040819052620000bd9162000343565b6000805461ffff191692151561ff00191692909217610100911515919091021790556200037b565b82805482825590600052602060002090810192821562000130579160200282015b828111156200013057825182906200011f908262000261565b509160200191906001019062000106565b506200013e92915062000142565b5090565b808211156200013e57600062000159828262000163565b5060010162000142565b5080546200017190620001d2565b6000825580601f1062000182575050565b601f016020900490600052602060002090810190620001a29190620001a5565b50565b5b808211156200013e5760008155600101620001a6565b634e487b7160e01b600052604160045260246000fd5b600181811c90821680620001e757607f821691505b6020821081036200020857634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200025c57600081815260208120601f850160051c81016020861015620002375750805b601f850160051c820191505b81811015620002585782815560010162000243565b5050505b505050565b81516001600160401b038111156200027d576200027d620001bc565b62000295816200028e8454620001d2565b846200020e565b602080601f831160018114620002cd5760008415620002b45750858301515b600019600386901b1c1916600185901b17855562000258565b600085815260208120601f198616915b82811015620002fe57888601518255948401946001909101908401620002dd565b50858210156200031d5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b805180151581146200033e57600080fd5b919050565b600080604083850312156200035757600080fd5b62000362836200032d565b915062000372602084016200032d565b90509250929050565b6112c3806200038b6000396000f3fe608060405234801561001057600080fd5b50600436106100c95760003560e01c8063642f6cef11610081578063afb28d1f1161005b578063afb28d1f14610196578063c98f10b01461019e578063fc735e99146101a657600080fd5b8063642f6cef146101465780639525d574146101635780639d6f1cc71461017657600080fd5b80634585e33b116100b25780634585e33b1461010d5780634b56a42e14610120578063601d5a711461013357600080fd5b806305e25131146100ce57806340691db4146100e3575b600080fd5b6100e16100dc3660046109cb565b6101b8565b005b6100f66100f1366004610a7c565b6101cf565b604051610104929190610b57565b60405180910390f35b6100e161011b366004610b7a565b61047f565b6100f661012e366004610bec565b61060e565b6100e1610141366004610ca9565b610664565b6000546101539060ff1681565b6040519015158152602001610104565b6100e1610171366004610ca9565b610670565b610189610184366004610cde565b61067c565b6040516101049190610cf7565b610189610728565b610189610735565b60005461015390610100900460ff1681565b80516101cb9060019060208401906107c8565b5050565b6000606060006101dd610742565b90507fd1ffe9e45581c11d7d9f2ed5f75217cd4be9f8b7eee6af0f6d03f46de53956cd61020d60c0870187610d11565b600081811061021e5761021e610d79565b90506020020135036103f757600061023960c0870187610d11565b600181811061024a5761024a610d79565b9050602002013560405160200161026391815260200190565b604051602081830303815290604052905060008180602001905181019061028a9190610da8565b9050600061029b60c0890189610d11565b60028181106102ac576102ac610d79565b905060200201356040516020016102c591815260200190565b60405160208183030381529060405290506000818060200190518101906102ec9190610da8565b905060006102fd60c08b018b610d11565b600381811061030e5761030e610d79565b9050602002013560405160200161032791815260200190565b604051602081830303815290604052905060008180602001905181019061034e9190610dea565b604080516020810188905290810185905273ffffffffffffffffffffffffffffffffffffffff821660608201529091506002906001906003908a90608001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527f7ddd933e0000000000000000000000000000000000000000000000000000000082526103ee9594939291600401610ef3565b60405180910390fd5b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f636f756c64206e6f742066696e64206d61746368696e67206576656e7420736960448201527f670000000000000000000000000000000000000000000000000000000000000060648201526084016103ee565b60008061048e83850185610bec565b915091506000806000838060200190518101906104ab9190610fb6565b6040805160208101909152600080825254939650919450925090610100900460ff16156105a1577309dff56a4ff44e0f4436260a04f5cfa65636a48173ffffffffffffffffffffffffffffffffffffffff16638e760afe8760008151811061051557610515610d79565b60200260200101516040518263ffffffff1660e01b81526004016105399190610cf7565b6000604051808303816000875af1158015610558573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261059e9190810190610feb565b90505b327f299a03817e683a32b21e29e3ae3c31f1c9c773f7d532836d116b62a9281fbc9d8585856105ce610742565b8b6000815181106105e1576105e1610d79565b6020026020010151876040516105fc96959493929190611062565b60405180910390a25050505050505050565b60006060600084846040516020016106279291906110c2565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052600193509150505b9250929050565b60036101cb828261119c565b60026101cb828261119c565b6001818154811061068c57600080fd5b9060005260206000200160009150905080546106a790610e05565b80601f01602080910402602001604051908101604052809291908181526020018280546106d390610e05565b80156107205780601f106106f557610100808354040283529160200191610720565b820191906000526020600020905b81548152906001019060200180831161070357829003601f168201915b505050505081565b600280546106a790610e05565b600380546106a790610e05565b6000805460ff16156107c357606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561079a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107be9190610da8565b905090565b504390565b82805482825590600052602060002090810192821561080e579160200282015b8281111561080e57825182906107fe908261119c565b50916020019190600101906107e8565b5061081a92915061081e565b5090565b8082111561081a576000610832828261083b565b5060010161081e565b50805461084790610e05565b6000825580601f10610857575050565b601f0160209004906000526020600020908101906108759190610878565b50565b5b8082111561081a5760008155600101610879565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156109035761090361088d565b604052919050565b600067ffffffffffffffff8211156109255761092561088d565b5060051b60200190565b600067ffffffffffffffff8211156109495761094961088d565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261098657600080fd5b81356109996109948261092f565b6108bc565b8181528460208386010111156109ae57600080fd5b816020850160208301376000918101602001919091529392505050565b600060208083850312156109de57600080fd5b823567ffffffffffffffff808211156109f657600080fd5b818501915085601f830112610a0a57600080fd5b8135610a186109948261090b565b81815260059190911b83018401908481019088831115610a3757600080fd5b8585015b83811015610a6f57803585811115610a535760008081fd5b610a618b89838a0101610975565b845250918601918601610a3b565b5098975050505050505050565b60008060408385031215610a8f57600080fd5b823567ffffffffffffffff80821115610aa757600080fd5b908401906101008287031215610abc57600080fd5b90925060208401359080821115610ad257600080fd5b50610adf85828601610975565b9150509250929050565b60005b83811015610b04578181015183820152602001610aec565b50506000910152565b60008151808452610b25816020860160208601610ae9565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b8215158152604060208201526000610b726040830184610b0d565b949350505050565b60008060208385031215610b8d57600080fd5b823567ffffffffffffffff80821115610ba557600080fd5b818501915085601f830112610bb957600080fd5b813581811115610bc857600080fd5b866020828501011115610bda57600080fd5b60209290920196919550909350505050565b60008060408385031215610bff57600080fd5b823567ffffffffffffffff80821115610c1757600080fd5b818501915085601f830112610c2b57600080fd5b81356020610c3b6109948361090b565b82815260059290921b84018101918181019089841115610c5a57600080fd5b8286015b84811015610c9257803586811115610c765760008081fd5b610c848c86838b0101610975565b845250918301918301610c5e565b5096505086013592505080821115610ad257600080fd5b600060208284031215610cbb57600080fd5b813567ffffffffffffffff811115610cd257600080fd5b610b7284828501610975565b600060208284031215610cf057600080fd5b5035919050565b602081526000610d0a6020830184610b0d565b9392505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112610d4657600080fd5b83018035915067ffffffffffffffff821115610d6157600080fd5b6020019150600581901b360382131561065d57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060208284031215610dba57600080fd5b5051919050565b805173ffffffffffffffffffffffffffffffffffffffff81168114610de557600080fd5b919050565b600060208284031215610dfc57600080fd5b610d0a82610dc1565b600181811c90821680610e1957607f821691505b602082108103610e52577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b60008154610e6581610e05565b808552602060018381168015610e825760018114610eba57610ee8565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008516838901528284151560051b8901019550610ee8565b866000528260002060005b85811015610ee05781548a8201860152908301908401610ec5565b890184019650505b505050505092915050565b60a081526000610f0660a0830188610e58565b6020838203818501528188548084528284019150828160051b8501018a6000528360002060005b83811015610f78577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0878403018552610f668383610e58565b94860194925060019182019101610f2d565b50508681036040880152610f8c818b610e58565b9450505050508460608401528281036080840152610faa8185610b0d565b98975050505050505050565b600080600060608486031215610fcb57600080fd5b8351925060208401519150610fe260408501610dc1565b90509250925092565b600060208284031215610ffd57600080fd5b815167ffffffffffffffff81111561101457600080fd5b8201601f8101841361102557600080fd5b80516110336109948261092f565b81815285602083850101111561104857600080fd5b611059826020830160208601610ae9565b95945050505050565b86815285602082015273ffffffffffffffffffffffffffffffffffffffff8516604082015283606082015260c0608082015260006110a360c0830185610b0d565b82810360a08401526110b58185610b0d565b9998505050505050505050565b6000604082016040835280855180835260608501915060608160051b8601019250602080880160005b83811015611137577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0888703018552611125868351610b0d565b955093820193908201906001016110eb565b5050858403818701525050506110598185610b0d565b601f82111561119757600081815260208120601f850160051c810160208610156111745750805b601f850160051c820191505b8181101561119357828155600101611180565b5050505b505050565b815167ffffffffffffffff8111156111b6576111b661088d565b6111ca816111c48454610e05565b8461114d565b602080601f83116001811461121d57600084156111e75750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555611193565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561126a5788860151825594840194600190910190840161124b565b50858210156112a657878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b0190555056fea164736f6c6343000810000a307834353534343832643535353334343264343135323432343935343532353534643264353434353533353434653435353430303030303030303030303030303030",
-}
-
-var LogTriggeredFeedLookupABI = LogTriggeredFeedLookupMetaData.ABI
-
-var LogTriggeredFeedLookupBin = LogTriggeredFeedLookupMetaData.Bin
-
-func DeployLogTriggeredFeedLookup(auth *bind.TransactOpts, backend bind.ContractBackend, _useArbitrumBlockNum bool, _verify bool) (common.Address, *types.Transaction, *LogTriggeredFeedLookup, error) {
- parsed, err := LogTriggeredFeedLookupMetaData.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(LogTriggeredFeedLookupBin), backend, _useArbitrumBlockNum, _verify)
- if err != nil {
- return common.Address{}, nil, nil, err
- }
- return address, tx, &LogTriggeredFeedLookup{LogTriggeredFeedLookupCaller: LogTriggeredFeedLookupCaller{contract: contract}, LogTriggeredFeedLookupTransactor: LogTriggeredFeedLookupTransactor{contract: contract}, LogTriggeredFeedLookupFilterer: LogTriggeredFeedLookupFilterer{contract: contract}}, nil
-}
-
-type LogTriggeredFeedLookup struct {
- address common.Address
- abi abi.ABI
- LogTriggeredFeedLookupCaller
- LogTriggeredFeedLookupTransactor
- LogTriggeredFeedLookupFilterer
-}
-
-type LogTriggeredFeedLookupCaller struct {
- contract *bind.BoundContract
-}
-
-type LogTriggeredFeedLookupTransactor struct {
- contract *bind.BoundContract
-}
-
-type LogTriggeredFeedLookupFilterer struct {
- contract *bind.BoundContract
-}
-
-type LogTriggeredFeedLookupSession struct {
- Contract *LogTriggeredFeedLookup
- CallOpts bind.CallOpts
- TransactOpts bind.TransactOpts
-}
-
-type LogTriggeredFeedLookupCallerSession struct {
- Contract *LogTriggeredFeedLookupCaller
- CallOpts bind.CallOpts
-}
-
-type LogTriggeredFeedLookupTransactorSession struct {
- Contract *LogTriggeredFeedLookupTransactor
- TransactOpts bind.TransactOpts
-}
-
-type LogTriggeredFeedLookupRaw struct {
- Contract *LogTriggeredFeedLookup
-}
-
-type LogTriggeredFeedLookupCallerRaw struct {
- Contract *LogTriggeredFeedLookupCaller
-}
-
-type LogTriggeredFeedLookupTransactorRaw struct {
- Contract *LogTriggeredFeedLookupTransactor
-}
-
-func NewLogTriggeredFeedLookup(address common.Address, backend bind.ContractBackend) (*LogTriggeredFeedLookup, error) {
- abi, err := abi.JSON(strings.NewReader(LogTriggeredFeedLookupABI))
- if err != nil {
- return nil, err
- }
- contract, err := bindLogTriggeredFeedLookup(address, backend, backend, backend)
- if err != nil {
- return nil, err
- }
- return &LogTriggeredFeedLookup{address: address, abi: abi, LogTriggeredFeedLookupCaller: LogTriggeredFeedLookupCaller{contract: contract}, LogTriggeredFeedLookupTransactor: LogTriggeredFeedLookupTransactor{contract: contract}, LogTriggeredFeedLookupFilterer: LogTriggeredFeedLookupFilterer{contract: contract}}, nil
-}
-
-func NewLogTriggeredFeedLookupCaller(address common.Address, caller bind.ContractCaller) (*LogTriggeredFeedLookupCaller, error) {
- contract, err := bindLogTriggeredFeedLookup(address, caller, nil, nil)
- if err != nil {
- return nil, err
- }
- return &LogTriggeredFeedLookupCaller{contract: contract}, nil
-}
-
-func NewLogTriggeredFeedLookupTransactor(address common.Address, transactor bind.ContractTransactor) (*LogTriggeredFeedLookupTransactor, error) {
- contract, err := bindLogTriggeredFeedLookup(address, nil, transactor, nil)
- if err != nil {
- return nil, err
- }
- return &LogTriggeredFeedLookupTransactor{contract: contract}, nil
-}
-
-func NewLogTriggeredFeedLookupFilterer(address common.Address, filterer bind.ContractFilterer) (*LogTriggeredFeedLookupFilterer, error) {
- contract, err := bindLogTriggeredFeedLookup(address, nil, nil, filterer)
- if err != nil {
- return nil, err
- }
- return &LogTriggeredFeedLookupFilterer{contract: contract}, nil
-}
-
-func bindLogTriggeredFeedLookup(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) {
- parsed, err := LogTriggeredFeedLookupMetaData.GetAbi()
- if err != nil {
- return nil, err
- }
- return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil
-}
-
-func (_LogTriggeredFeedLookup *LogTriggeredFeedLookupRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
- return _LogTriggeredFeedLookup.Contract.LogTriggeredFeedLookupCaller.contract.Call(opts, result, method, params...)
-}
-
-func (_LogTriggeredFeedLookup *LogTriggeredFeedLookupRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
- return _LogTriggeredFeedLookup.Contract.LogTriggeredFeedLookupTransactor.contract.Transfer(opts)
-}
-
-func (_LogTriggeredFeedLookup *LogTriggeredFeedLookupRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
- return _LogTriggeredFeedLookup.Contract.LogTriggeredFeedLookupTransactor.contract.Transact(opts, method, params...)
-}
-
-func (_LogTriggeredFeedLookup *LogTriggeredFeedLookupCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
- return _LogTriggeredFeedLookup.Contract.contract.Call(opts, result, method, params...)
-}
-
-func (_LogTriggeredFeedLookup *LogTriggeredFeedLookupTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
- return _LogTriggeredFeedLookup.Contract.contract.Transfer(opts)
-}
-
-func (_LogTriggeredFeedLookup *LogTriggeredFeedLookupTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
- return _LogTriggeredFeedLookup.Contract.contract.Transact(opts, method, params...)
-}
-
-func (_LogTriggeredFeedLookup *LogTriggeredFeedLookupCaller) CheckCallback(opts *bind.CallOpts, values [][]byte, extraData []byte) (bool, []byte, error) {
- var out []interface{}
- err := _LogTriggeredFeedLookup.contract.Call(opts, &out, "checkCallback", values, extraData)
-
- if err != nil {
- return *new(bool), *new([]byte), err
- }
-
- out0 := *abi.ConvertType(out[0], new(bool)).(*bool)
- out1 := *abi.ConvertType(out[1], new([]byte)).(*[]byte)
-
- return out0, out1, err
-
-}
-
-func (_LogTriggeredFeedLookup *LogTriggeredFeedLookupSession) CheckCallback(values [][]byte, extraData []byte) (bool, []byte, error) {
- return _LogTriggeredFeedLookup.Contract.CheckCallback(&_LogTriggeredFeedLookup.CallOpts, values, extraData)
-}
-
-func (_LogTriggeredFeedLookup *LogTriggeredFeedLookupCallerSession) CheckCallback(values [][]byte, extraData []byte) (bool, []byte, error) {
- return _LogTriggeredFeedLookup.Contract.CheckCallback(&_LogTriggeredFeedLookup.CallOpts, values, extraData)
-}
-
-func (_LogTriggeredFeedLookup *LogTriggeredFeedLookupCaller) FeedParamKey(opts *bind.CallOpts) (string, error) {
- var out []interface{}
- err := _LogTriggeredFeedLookup.contract.Call(opts, &out, "feedParamKey")
-
- if err != nil {
- return *new(string), err
- }
-
- out0 := *abi.ConvertType(out[0], new(string)).(*string)
-
- return out0, err
-
-}
-
-func (_LogTriggeredFeedLookup *LogTriggeredFeedLookupSession) FeedParamKey() (string, error) {
- return _LogTriggeredFeedLookup.Contract.FeedParamKey(&_LogTriggeredFeedLookup.CallOpts)
-}
-
-func (_LogTriggeredFeedLookup *LogTriggeredFeedLookupCallerSession) FeedParamKey() (string, error) {
- return _LogTriggeredFeedLookup.Contract.FeedParamKey(&_LogTriggeredFeedLookup.CallOpts)
-}
-
-func (_LogTriggeredFeedLookup *LogTriggeredFeedLookupCaller) FeedsHex(opts *bind.CallOpts, arg0 *big.Int) (string, error) {
- var out []interface{}
- err := _LogTriggeredFeedLookup.contract.Call(opts, &out, "feedsHex", arg0)
-
- if err != nil {
- return *new(string), err
- }
-
- out0 := *abi.ConvertType(out[0], new(string)).(*string)
-
- return out0, err
-
-}
-
-func (_LogTriggeredFeedLookup *LogTriggeredFeedLookupSession) FeedsHex(arg0 *big.Int) (string, error) {
- return _LogTriggeredFeedLookup.Contract.FeedsHex(&_LogTriggeredFeedLookup.CallOpts, arg0)
-}
-
-func (_LogTriggeredFeedLookup *LogTriggeredFeedLookupCallerSession) FeedsHex(arg0 *big.Int) (string, error) {
- return _LogTriggeredFeedLookup.Contract.FeedsHex(&_LogTriggeredFeedLookup.CallOpts, arg0)
-}
-
-func (_LogTriggeredFeedLookup *LogTriggeredFeedLookupCaller) TimeParamKey(opts *bind.CallOpts) (string, error) {
- var out []interface{}
- err := _LogTriggeredFeedLookup.contract.Call(opts, &out, "timeParamKey")
-
- if err != nil {
- return *new(string), err
- }
-
- out0 := *abi.ConvertType(out[0], new(string)).(*string)
-
- return out0, err
-
-}
-
-func (_LogTriggeredFeedLookup *LogTriggeredFeedLookupSession) TimeParamKey() (string, error) {
- return _LogTriggeredFeedLookup.Contract.TimeParamKey(&_LogTriggeredFeedLookup.CallOpts)
-}
-
-func (_LogTriggeredFeedLookup *LogTriggeredFeedLookupCallerSession) TimeParamKey() (string, error) {
- return _LogTriggeredFeedLookup.Contract.TimeParamKey(&_LogTriggeredFeedLookup.CallOpts)
-}
-
-func (_LogTriggeredFeedLookup *LogTriggeredFeedLookupCaller) UseArbitrumBlockNum(opts *bind.CallOpts) (bool, error) {
- var out []interface{}
- err := _LogTriggeredFeedLookup.contract.Call(opts, &out, "useArbitrumBlockNum")
-
- if err != nil {
- return *new(bool), err
- }
-
- out0 := *abi.ConvertType(out[0], new(bool)).(*bool)
-
- return out0, err
-
-}
-
-func (_LogTriggeredFeedLookup *LogTriggeredFeedLookupSession) UseArbitrumBlockNum() (bool, error) {
- return _LogTriggeredFeedLookup.Contract.UseArbitrumBlockNum(&_LogTriggeredFeedLookup.CallOpts)
-}
-
-func (_LogTriggeredFeedLookup *LogTriggeredFeedLookupCallerSession) UseArbitrumBlockNum() (bool, error) {
- return _LogTriggeredFeedLookup.Contract.UseArbitrumBlockNum(&_LogTriggeredFeedLookup.CallOpts)
-}
-
-func (_LogTriggeredFeedLookup *LogTriggeredFeedLookupCaller) Verify(opts *bind.CallOpts) (bool, error) {
- var out []interface{}
- err := _LogTriggeredFeedLookup.contract.Call(opts, &out, "verify")
-
- if err != nil {
- return *new(bool), err
- }
-
- out0 := *abi.ConvertType(out[0], new(bool)).(*bool)
-
- return out0, err
-
-}
-
-func (_LogTriggeredFeedLookup *LogTriggeredFeedLookupSession) Verify() (bool, error) {
- return _LogTriggeredFeedLookup.Contract.Verify(&_LogTriggeredFeedLookup.CallOpts)
-}
-
-func (_LogTriggeredFeedLookup *LogTriggeredFeedLookupCallerSession) Verify() (bool, error) {
- return _LogTriggeredFeedLookup.Contract.Verify(&_LogTriggeredFeedLookup.CallOpts)
-}
-
-func (_LogTriggeredFeedLookup *LogTriggeredFeedLookupTransactor) CheckLog(opts *bind.TransactOpts, log Log, arg1 []byte) (*types.Transaction, error) {
- return _LogTriggeredFeedLookup.contract.Transact(opts, "checkLog", log, arg1)
-}
-
-func (_LogTriggeredFeedLookup *LogTriggeredFeedLookupSession) CheckLog(log Log, arg1 []byte) (*types.Transaction, error) {
- return _LogTriggeredFeedLookup.Contract.CheckLog(&_LogTriggeredFeedLookup.TransactOpts, log, arg1)
-}
-
-func (_LogTriggeredFeedLookup *LogTriggeredFeedLookupTransactorSession) CheckLog(log Log, arg1 []byte) (*types.Transaction, error) {
- return _LogTriggeredFeedLookup.Contract.CheckLog(&_LogTriggeredFeedLookup.TransactOpts, log, arg1)
-}
-
-func (_LogTriggeredFeedLookup *LogTriggeredFeedLookupTransactor) PerformUpkeep(opts *bind.TransactOpts, performData []byte) (*types.Transaction, error) {
- return _LogTriggeredFeedLookup.contract.Transact(opts, "performUpkeep", performData)
-}
-
-func (_LogTriggeredFeedLookup *LogTriggeredFeedLookupSession) PerformUpkeep(performData []byte) (*types.Transaction, error) {
- return _LogTriggeredFeedLookup.Contract.PerformUpkeep(&_LogTriggeredFeedLookup.TransactOpts, performData)
-}
-
-func (_LogTriggeredFeedLookup *LogTriggeredFeedLookupTransactorSession) PerformUpkeep(performData []byte) (*types.Transaction, error) {
- return _LogTriggeredFeedLookup.Contract.PerformUpkeep(&_LogTriggeredFeedLookup.TransactOpts, performData)
-}
-
-func (_LogTriggeredFeedLookup *LogTriggeredFeedLookupTransactor) SetFeedParamKey(opts *bind.TransactOpts, feedParam string) (*types.Transaction, error) {
- return _LogTriggeredFeedLookup.contract.Transact(opts, "setFeedParamKey", feedParam)
-}
-
-func (_LogTriggeredFeedLookup *LogTriggeredFeedLookupSession) SetFeedParamKey(feedParam string) (*types.Transaction, error) {
- return _LogTriggeredFeedLookup.Contract.SetFeedParamKey(&_LogTriggeredFeedLookup.TransactOpts, feedParam)
-}
-
-func (_LogTriggeredFeedLookup *LogTriggeredFeedLookupTransactorSession) SetFeedParamKey(feedParam string) (*types.Transaction, error) {
- return _LogTriggeredFeedLookup.Contract.SetFeedParamKey(&_LogTriggeredFeedLookup.TransactOpts, feedParam)
-}
-
-func (_LogTriggeredFeedLookup *LogTriggeredFeedLookupTransactor) SetFeedsHex(opts *bind.TransactOpts, newFeeds []string) (*types.Transaction, error) {
- return _LogTriggeredFeedLookup.contract.Transact(opts, "setFeedsHex", newFeeds)
-}
-
-func (_LogTriggeredFeedLookup *LogTriggeredFeedLookupSession) SetFeedsHex(newFeeds []string) (*types.Transaction, error) {
- return _LogTriggeredFeedLookup.Contract.SetFeedsHex(&_LogTriggeredFeedLookup.TransactOpts, newFeeds)
-}
-
-func (_LogTriggeredFeedLookup *LogTriggeredFeedLookupTransactorSession) SetFeedsHex(newFeeds []string) (*types.Transaction, error) {
- return _LogTriggeredFeedLookup.Contract.SetFeedsHex(&_LogTriggeredFeedLookup.TransactOpts, newFeeds)
-}
-
-func (_LogTriggeredFeedLookup *LogTriggeredFeedLookupTransactor) SetTimeParamKey(opts *bind.TransactOpts, timeParam string) (*types.Transaction, error) {
- return _LogTriggeredFeedLookup.contract.Transact(opts, "setTimeParamKey", timeParam)
-}
-
-func (_LogTriggeredFeedLookup *LogTriggeredFeedLookupSession) SetTimeParamKey(timeParam string) (*types.Transaction, error) {
- return _LogTriggeredFeedLookup.Contract.SetTimeParamKey(&_LogTriggeredFeedLookup.TransactOpts, timeParam)
-}
-
-func (_LogTriggeredFeedLookup *LogTriggeredFeedLookupTransactorSession) SetTimeParamKey(timeParam string) (*types.Transaction, error) {
- return _LogTriggeredFeedLookup.Contract.SetTimeParamKey(&_LogTriggeredFeedLookup.TransactOpts, timeParam)
-}
-
-type LogTriggeredFeedLookupPerformingLogTriggerUpkeepIterator struct {
- Event *LogTriggeredFeedLookupPerformingLogTriggerUpkeep
-
- contract *bind.BoundContract
- event string
-
- logs chan types.Log
- sub ethereum.Subscription
- done bool
- fail error
-}
-
-func (it *LogTriggeredFeedLookupPerformingLogTriggerUpkeepIterator) Next() bool {
-
- if it.fail != nil {
- return false
- }
-
- if it.done {
- select {
- case log := <-it.logs:
- it.Event = new(LogTriggeredFeedLookupPerformingLogTriggerUpkeep)
- if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
- it.fail = err
- return false
- }
- it.Event.Raw = log
- return true
-
- default:
- return false
- }
- }
-
- select {
- case log := <-it.logs:
- it.Event = new(LogTriggeredFeedLookupPerformingLogTriggerUpkeep)
- if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
- it.fail = err
- return false
- }
- it.Event.Raw = log
- return true
-
- case err := <-it.sub.Err():
- it.done = true
- it.fail = err
- return it.Next()
- }
-}
-
-func (it *LogTriggeredFeedLookupPerformingLogTriggerUpkeepIterator) Error() error {
- return it.fail
-}
-
-func (it *LogTriggeredFeedLookupPerformingLogTriggerUpkeepIterator) Close() error {
- it.sub.Unsubscribe()
- return nil
-}
-
-type LogTriggeredFeedLookupPerformingLogTriggerUpkeep struct {
- From common.Address
- OrderId *big.Int
- Amount *big.Int
- Exchange common.Address
- BlockNumber *big.Int
- Blob []byte
- Verified []byte
- Raw types.Log
-}
-
-func (_LogTriggeredFeedLookup *LogTriggeredFeedLookupFilterer) FilterPerformingLogTriggerUpkeep(opts *bind.FilterOpts, from []common.Address) (*LogTriggeredFeedLookupPerformingLogTriggerUpkeepIterator, error) {
-
- var fromRule []interface{}
- for _, fromItem := range from {
- fromRule = append(fromRule, fromItem)
- }
-
- logs, sub, err := _LogTriggeredFeedLookup.contract.FilterLogs(opts, "PerformingLogTriggerUpkeep", fromRule)
- if err != nil {
- return nil, err
- }
- return &LogTriggeredFeedLookupPerformingLogTriggerUpkeepIterator{contract: _LogTriggeredFeedLookup.contract, event: "PerformingLogTriggerUpkeep", logs: logs, sub: sub}, nil
-}
-
-func (_LogTriggeredFeedLookup *LogTriggeredFeedLookupFilterer) WatchPerformingLogTriggerUpkeep(opts *bind.WatchOpts, sink chan<- *LogTriggeredFeedLookupPerformingLogTriggerUpkeep, from []common.Address) (event.Subscription, error) {
-
- var fromRule []interface{}
- for _, fromItem := range from {
- fromRule = append(fromRule, fromItem)
- }
-
- logs, sub, err := _LogTriggeredFeedLookup.contract.WatchLogs(opts, "PerformingLogTriggerUpkeep", fromRule)
- if err != nil {
- return nil, err
- }
- return event.NewSubscription(func(quit <-chan struct{}) error {
- defer sub.Unsubscribe()
- for {
- select {
- case log := <-logs:
-
- event := new(LogTriggeredFeedLookupPerformingLogTriggerUpkeep)
- if err := _LogTriggeredFeedLookup.contract.UnpackLog(event, "PerformingLogTriggerUpkeep", log); err != nil {
- return err
- }
- event.Raw = log
-
- select {
- case sink <- event:
- case err := <-sub.Err():
- return err
- case <-quit:
- return nil
- }
- case err := <-sub.Err():
- return err
- case <-quit:
- return nil
- }
- }
- }), nil
-}
-
-func (_LogTriggeredFeedLookup *LogTriggeredFeedLookupFilterer) ParsePerformingLogTriggerUpkeep(log types.Log) (*LogTriggeredFeedLookupPerformingLogTriggerUpkeep, error) {
- event := new(LogTriggeredFeedLookupPerformingLogTriggerUpkeep)
- if err := _LogTriggeredFeedLookup.contract.UnpackLog(event, "PerformingLogTriggerUpkeep", log); err != nil {
- return nil, err
- }
- event.Raw = log
- return event, nil
-}
-
-func (_LogTriggeredFeedLookup *LogTriggeredFeedLookup) ParseLog(log types.Log) (generated.AbigenLog, error) {
- switch log.Topics[0] {
- case _LogTriggeredFeedLookup.abi.Events["PerformingLogTriggerUpkeep"].ID:
- return _LogTriggeredFeedLookup.ParsePerformingLogTriggerUpkeep(log)
-
- default:
- return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0])
- }
-}
-
-func (LogTriggeredFeedLookupPerformingLogTriggerUpkeep) Topic() common.Hash {
- return common.HexToHash("0x299a03817e683a32b21e29e3ae3c31f1c9c773f7d532836d116b62a9281fbc9d")
-}
-
-func (_LogTriggeredFeedLookup *LogTriggeredFeedLookup) Address() common.Address {
- return _LogTriggeredFeedLookup.address
-}
-
-type LogTriggeredFeedLookupInterface interface {
- CheckCallback(opts *bind.CallOpts, values [][]byte, extraData []byte) (bool, []byte, error)
-
- FeedParamKey(opts *bind.CallOpts) (string, error)
-
- FeedsHex(opts *bind.CallOpts, arg0 *big.Int) (string, error)
-
- TimeParamKey(opts *bind.CallOpts) (string, error)
-
- UseArbitrumBlockNum(opts *bind.CallOpts) (bool, error)
-
- Verify(opts *bind.CallOpts) (bool, error)
-
- CheckLog(opts *bind.TransactOpts, log Log, arg1 []byte) (*types.Transaction, error)
-
- PerformUpkeep(opts *bind.TransactOpts, performData []byte) (*types.Transaction, error)
-
- SetFeedParamKey(opts *bind.TransactOpts, feedParam string) (*types.Transaction, error)
-
- SetFeedsHex(opts *bind.TransactOpts, newFeeds []string) (*types.Transaction, error)
-
- SetTimeParamKey(opts *bind.TransactOpts, timeParam string) (*types.Transaction, error)
-
- FilterPerformingLogTriggerUpkeep(opts *bind.FilterOpts, from []common.Address) (*LogTriggeredFeedLookupPerformingLogTriggerUpkeepIterator, error)
-
- WatchPerformingLogTriggerUpkeep(opts *bind.WatchOpts, sink chan<- *LogTriggeredFeedLookupPerformingLogTriggerUpkeep, from []common.Address) (event.Subscription, error)
-
- ParsePerformingLogTriggerUpkeep(log types.Log) (*LogTriggeredFeedLookupPerformingLogTriggerUpkeep, error)
-
- ParseLog(log types.Log) (generated.AbigenLog, error)
-
- Address() common.Address
-}
diff --git a/core/gethwrappers/generated/log_triggered_streams_lookup_wrapper/log_triggered_streams_lookup_wrapper.go b/core/gethwrappers/generated/log_triggered_streams_lookup_wrapper/log_triggered_streams_lookup_wrapper.go
new file mode 100644
index 00000000000..e3f5b3c3511
--- /dev/null
+++ b/core/gethwrappers/generated/log_triggered_streams_lookup_wrapper/log_triggered_streams_lookup_wrapper.go
@@ -0,0 +1,561 @@
+// Code generated - DO NOT EDIT.
+// This file is a generated binding and any manual changes will be lost.
+
+package log_triggered_streams_lookup_wrapper
+
+import (
+ "errors"
+ "fmt"
+ "math/big"
+ "strings"
+
+ ethereum "github.com/ethereum/go-ethereum"
+ "github.com/ethereum/go-ethereum/accounts/abi"
+ "github.com/ethereum/go-ethereum/accounts/abi/bind"
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/core/types"
+ "github.com/ethereum/go-ethereum/event"
+ "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated"
+)
+
+var (
+ _ = errors.New
+ _ = big.NewInt
+ _ = strings.NewReader
+ _ = ethereum.NotFound
+ _ = bind.Bind
+ _ = common.Big1
+ _ = types.BloomLookup
+ _ = event.NewSubscription
+ _ = abi.ConvertType
+)
+
+type Log struct {
+ Index *big.Int
+ Timestamp *big.Int
+ TxHash [32]byte
+ BlockNumber *big.Int
+ BlockHash [32]byte
+ Source common.Address
+ Topics [][32]byte
+ Data []byte
+}
+
+var LogTriggeredStreamsLookupMetaData = &bind.MetaData{
+ ABI: "[{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"_useArbitrumBlockNum\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"_verify\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"feedParamKey\",\"type\":\"string\"},{\"internalType\":\"string[]\",\"name\":\"feeds\",\"type\":\"string[]\"},{\"internalType\":\"string\",\"name\":\"timeParamKey\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"time\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"StreamsLookup\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"orderId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"exchange\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"blob\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"verified\",\"type\":\"bytes\"}],\"name\":\"PerformingLogTriggerUpkeep\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes[]\",\"name\":\"values\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"checkCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"txHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"source\",\"type\":\"address\"},{\"internalType\":\"bytes32[]\",\"name\":\"topics\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"structLog\",\"name\":\"log\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"checkLog\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"feedParamKey\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"feedsHex\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"}],\"name\":\"performUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"feedParam\",\"type\":\"string\"}],\"name\":\"setFeedParamKey\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string[]\",\"name\":\"newFeeds\",\"type\":\"string[]\"}],\"name\":\"setFeedsHex\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"timeParam\",\"type\":\"string\"}],\"name\":\"setTimeParamKey\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"timeParamKey\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"useArbitrumBlockNum\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]",
+ Bin: "0x610120604052604260a08181526080918291906200164e60c03990526200002a9060019081620000e5565b506040805180820190915260098152680cccacac892c890caf60bb1b60208201526002906200005a908262000261565b5060408051808201909152600b81526a313637b1b5a73ab6b132b960a91b60208201526003906200008c908262000261565b503480156200009a57600080fd5b506040516200169038038062001690833981016040819052620000bd9162000343565b6000805461ffff191692151561ff00191692909217610100911515919091021790556200037b565b82805482825590600052602060002090810192821562000130579160200282015b828111156200013057825182906200011f908262000261565b509160200191906001019062000106565b506200013e92915062000142565b5090565b808211156200013e57600062000159828262000163565b5060010162000142565b5080546200017190620001d2565b6000825580601f1062000182575050565b601f016020900490600052602060002090810190620001a29190620001a5565b50565b5b808211156200013e5760008155600101620001a6565b634e487b7160e01b600052604160045260246000fd5b600181811c90821680620001e757607f821691505b6020821081036200020857634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200025c57600081815260208120601f850160051c81016020861015620002375750805b601f850160051c820191505b81811015620002585782815560010162000243565b5050505b505050565b81516001600160401b038111156200027d576200027d620001bc565b62000295816200028e8454620001d2565b846200020e565b602080601f831160018114620002cd5760008415620002b45750858301515b600019600386901b1c1916600185901b17855562000258565b600085815260208120601f198616915b82811015620002fe57888601518255948401946001909101908401620002dd565b50858210156200031d5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b805180151581146200033e57600080fd5b919050565b600080604083850312156200035757600080fd5b62000362836200032d565b915062000372602084016200032d565b90509250929050565b6112c3806200038b6000396000f3fe608060405234801561001057600080fd5b50600436106100c95760003560e01c8063642f6cef11610081578063afb28d1f1161005b578063afb28d1f14610196578063c98f10b01461019e578063fc735e99146101a657600080fd5b8063642f6cef146101465780639525d574146101635780639d6f1cc71461017657600080fd5b80634585e33b116100b25780634585e33b1461010d5780634b56a42e14610120578063601d5a711461013357600080fd5b806305e25131146100ce57806340691db4146100e3575b600080fd5b6100e16100dc3660046109cb565b6101b8565b005b6100f66100f1366004610a7c565b6101cf565b604051610104929190610b57565b60405180910390f35b6100e161011b366004610b7a565b61047f565b6100f661012e366004610bec565b61060e565b6100e1610141366004610ca9565b610664565b6000546101539060ff1681565b6040519015158152602001610104565b6100e1610171366004610ca9565b610670565b610189610184366004610cde565b61067c565b6040516101049190610cf7565b610189610728565b610189610735565b60005461015390610100900460ff1681565b80516101cb9060019060208401906107c8565b5050565b6000606060006101dd610742565b90507fd1ffe9e45581c11d7d9f2ed5f75217cd4be9f8b7eee6af0f6d03f46de53956cd61020d60c0870187610d11565b600081811061021e5761021e610d79565b90506020020135036103f757600061023960c0870187610d11565b600181811061024a5761024a610d79565b9050602002013560405160200161026391815260200190565b604051602081830303815290604052905060008180602001905181019061028a9190610da8565b9050600061029b60c0890189610d11565b60028181106102ac576102ac610d79565b905060200201356040516020016102c591815260200190565b60405160208183030381529060405290506000818060200190518101906102ec9190610da8565b905060006102fd60c08b018b610d11565b600381811061030e5761030e610d79565b9050602002013560405160200161032791815260200190565b604051602081830303815290604052905060008180602001905181019061034e9190610dea565b604080516020810188905290810185905273ffffffffffffffffffffffffffffffffffffffff821660608201529091506002906001906003908a90608001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527ff055e4a20000000000000000000000000000000000000000000000000000000082526103ee9594939291600401610ef3565b60405180910390fd5b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f636f756c64206e6f742066696e64206d61746368696e67206576656e7420736960448201527f670000000000000000000000000000000000000000000000000000000000000060648201526084016103ee565b60008061048e83850185610bec565b915091506000806000838060200190518101906104ab9190610fb6565b6040805160208101909152600080825254939650919450925090610100900460ff16156105a1577309dff56a4ff44e0f4436260a04f5cfa65636a48173ffffffffffffffffffffffffffffffffffffffff16638e760afe8760008151811061051557610515610d79565b60200260200101516040518263ffffffff1660e01b81526004016105399190610cf7565b6000604051808303816000875af1158015610558573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261059e9190810190610feb565b90505b327f299a03817e683a32b21e29e3ae3c31f1c9c773f7d532836d116b62a9281fbc9d8585856105ce610742565b8b6000815181106105e1576105e1610d79565b6020026020010151876040516105fc96959493929190611062565b60405180910390a25050505050505050565b60006060600084846040516020016106279291906110c2565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052600193509150505b9250929050565b60036101cb828261119c565b60026101cb828261119c565b6001818154811061068c57600080fd5b9060005260206000200160009150905080546106a790610e05565b80601f01602080910402602001604051908101604052809291908181526020018280546106d390610e05565b80156107205780601f106106f557610100808354040283529160200191610720565b820191906000526020600020905b81548152906001019060200180831161070357829003601f168201915b505050505081565b600280546106a790610e05565b600380546106a790610e05565b6000805460ff16156107c357606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561079a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107be9190610da8565b905090565b504390565b82805482825590600052602060002090810192821561080e579160200282015b8281111561080e57825182906107fe908261119c565b50916020019190600101906107e8565b5061081a92915061081e565b5090565b8082111561081a576000610832828261083b565b5060010161081e565b50805461084790610e05565b6000825580601f10610857575050565b601f0160209004906000526020600020908101906108759190610878565b50565b5b8082111561081a5760008155600101610879565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156109035761090361088d565b604052919050565b600067ffffffffffffffff8211156109255761092561088d565b5060051b60200190565b600067ffffffffffffffff8211156109495761094961088d565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261098657600080fd5b81356109996109948261092f565b6108bc565b8181528460208386010111156109ae57600080fd5b816020850160208301376000918101602001919091529392505050565b600060208083850312156109de57600080fd5b823567ffffffffffffffff808211156109f657600080fd5b818501915085601f830112610a0a57600080fd5b8135610a186109948261090b565b81815260059190911b83018401908481019088831115610a3757600080fd5b8585015b83811015610a6f57803585811115610a535760008081fd5b610a618b89838a0101610975565b845250918601918601610a3b565b5098975050505050505050565b60008060408385031215610a8f57600080fd5b823567ffffffffffffffff80821115610aa757600080fd5b908401906101008287031215610abc57600080fd5b90925060208401359080821115610ad257600080fd5b50610adf85828601610975565b9150509250929050565b60005b83811015610b04578181015183820152602001610aec565b50506000910152565b60008151808452610b25816020860160208601610ae9565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b8215158152604060208201526000610b726040830184610b0d565b949350505050565b60008060208385031215610b8d57600080fd5b823567ffffffffffffffff80821115610ba557600080fd5b818501915085601f830112610bb957600080fd5b813581811115610bc857600080fd5b866020828501011115610bda57600080fd5b60209290920196919550909350505050565b60008060408385031215610bff57600080fd5b823567ffffffffffffffff80821115610c1757600080fd5b818501915085601f830112610c2b57600080fd5b81356020610c3b6109948361090b565b82815260059290921b84018101918181019089841115610c5a57600080fd5b8286015b84811015610c9257803586811115610c765760008081fd5b610c848c86838b0101610975565b845250918301918301610c5e565b5096505086013592505080821115610ad257600080fd5b600060208284031215610cbb57600080fd5b813567ffffffffffffffff811115610cd257600080fd5b610b7284828501610975565b600060208284031215610cf057600080fd5b5035919050565b602081526000610d0a6020830184610b0d565b9392505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112610d4657600080fd5b83018035915067ffffffffffffffff821115610d6157600080fd5b6020019150600581901b360382131561065d57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060208284031215610dba57600080fd5b5051919050565b805173ffffffffffffffffffffffffffffffffffffffff81168114610de557600080fd5b919050565b600060208284031215610dfc57600080fd5b610d0a82610dc1565b600181811c90821680610e1957607f821691505b602082108103610e52577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b60008154610e6581610e05565b808552602060018381168015610e825760018114610eba57610ee8565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008516838901528284151560051b8901019550610ee8565b866000528260002060005b85811015610ee05781548a8201860152908301908401610ec5565b890184019650505b505050505092915050565b60a081526000610f0660a0830188610e58565b6020838203818501528188548084528284019150828160051b8501018a6000528360002060005b83811015610f78577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0878403018552610f668383610e58565b94860194925060019182019101610f2d565b50508681036040880152610f8c818b610e58565b9450505050508460608401528281036080840152610faa8185610b0d565b98975050505050505050565b600080600060608486031215610fcb57600080fd5b8351925060208401519150610fe260408501610dc1565b90509250925092565b600060208284031215610ffd57600080fd5b815167ffffffffffffffff81111561101457600080fd5b8201601f8101841361102557600080fd5b80516110336109948261092f565b81815285602083850101111561104857600080fd5b611059826020830160208601610ae9565b95945050505050565b86815285602082015273ffffffffffffffffffffffffffffffffffffffff8516604082015283606082015260c0608082015260006110a360c0830185610b0d565b82810360a08401526110b58185610b0d565b9998505050505050505050565b6000604082016040835280855180835260608501915060608160051b8601019250602080880160005b83811015611137577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0888703018552611125868351610b0d565b955093820193908201906001016110eb565b5050858403818701525050506110598185610b0d565b601f82111561119757600081815260208120601f850160051c810160208610156111745750805b601f850160051c820191505b8181101561119357828155600101611180565b5050505b505050565b815167ffffffffffffffff8111156111b6576111b661088d565b6111ca816111c48454610e05565b8461114d565b602080601f83116001811461121d57600084156111e75750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555611193565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561126a5788860151825594840194600190910190840161124b565b50858210156112a657878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b0190555056fea164736f6c6343000810000a307834353534343832643535353334343264343135323432343935343532353534643264353434353533353434653435353430303030303030303030303030303030",
+}
+
+var LogTriggeredStreamsLookupABI = LogTriggeredStreamsLookupMetaData.ABI
+
+var LogTriggeredStreamsLookupBin = LogTriggeredStreamsLookupMetaData.Bin
+
+func DeployLogTriggeredStreamsLookup(auth *bind.TransactOpts, backend bind.ContractBackend, _useArbitrumBlockNum bool, _verify bool) (common.Address, *types.Transaction, *LogTriggeredStreamsLookup, error) {
+ parsed, err := LogTriggeredStreamsLookupMetaData.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(LogTriggeredStreamsLookupBin), backend, _useArbitrumBlockNum, _verify)
+ if err != nil {
+ return common.Address{}, nil, nil, err
+ }
+ return address, tx, &LogTriggeredStreamsLookup{LogTriggeredStreamsLookupCaller: LogTriggeredStreamsLookupCaller{contract: contract}, LogTriggeredStreamsLookupTransactor: LogTriggeredStreamsLookupTransactor{contract: contract}, LogTriggeredStreamsLookupFilterer: LogTriggeredStreamsLookupFilterer{contract: contract}}, nil
+}
+
+type LogTriggeredStreamsLookup struct {
+ address common.Address
+ abi abi.ABI
+ LogTriggeredStreamsLookupCaller
+ LogTriggeredStreamsLookupTransactor
+ LogTriggeredStreamsLookupFilterer
+}
+
+type LogTriggeredStreamsLookupCaller struct {
+ contract *bind.BoundContract
+}
+
+type LogTriggeredStreamsLookupTransactor struct {
+ contract *bind.BoundContract
+}
+
+type LogTriggeredStreamsLookupFilterer struct {
+ contract *bind.BoundContract
+}
+
+type LogTriggeredStreamsLookupSession struct {
+ Contract *LogTriggeredStreamsLookup
+ CallOpts bind.CallOpts
+ TransactOpts bind.TransactOpts
+}
+
+type LogTriggeredStreamsLookupCallerSession struct {
+ Contract *LogTriggeredStreamsLookupCaller
+ CallOpts bind.CallOpts
+}
+
+type LogTriggeredStreamsLookupTransactorSession struct {
+ Contract *LogTriggeredStreamsLookupTransactor
+ TransactOpts bind.TransactOpts
+}
+
+type LogTriggeredStreamsLookupRaw struct {
+ Contract *LogTriggeredStreamsLookup
+}
+
+type LogTriggeredStreamsLookupCallerRaw struct {
+ Contract *LogTriggeredStreamsLookupCaller
+}
+
+type LogTriggeredStreamsLookupTransactorRaw struct {
+ Contract *LogTriggeredStreamsLookupTransactor
+}
+
+func NewLogTriggeredStreamsLookup(address common.Address, backend bind.ContractBackend) (*LogTriggeredStreamsLookup, error) {
+ abi, err := abi.JSON(strings.NewReader(LogTriggeredStreamsLookupABI))
+ if err != nil {
+ return nil, err
+ }
+ contract, err := bindLogTriggeredStreamsLookup(address, backend, backend, backend)
+ if err != nil {
+ return nil, err
+ }
+ return &LogTriggeredStreamsLookup{address: address, abi: abi, LogTriggeredStreamsLookupCaller: LogTriggeredStreamsLookupCaller{contract: contract}, LogTriggeredStreamsLookupTransactor: LogTriggeredStreamsLookupTransactor{contract: contract}, LogTriggeredStreamsLookupFilterer: LogTriggeredStreamsLookupFilterer{contract: contract}}, nil
+}
+
+func NewLogTriggeredStreamsLookupCaller(address common.Address, caller bind.ContractCaller) (*LogTriggeredStreamsLookupCaller, error) {
+ contract, err := bindLogTriggeredStreamsLookup(address, caller, nil, nil)
+ if err != nil {
+ return nil, err
+ }
+ return &LogTriggeredStreamsLookupCaller{contract: contract}, nil
+}
+
+func NewLogTriggeredStreamsLookupTransactor(address common.Address, transactor bind.ContractTransactor) (*LogTriggeredStreamsLookupTransactor, error) {
+ contract, err := bindLogTriggeredStreamsLookup(address, nil, transactor, nil)
+ if err != nil {
+ return nil, err
+ }
+ return &LogTriggeredStreamsLookupTransactor{contract: contract}, nil
+}
+
+func NewLogTriggeredStreamsLookupFilterer(address common.Address, filterer bind.ContractFilterer) (*LogTriggeredStreamsLookupFilterer, error) {
+ contract, err := bindLogTriggeredStreamsLookup(address, nil, nil, filterer)
+ if err != nil {
+ return nil, err
+ }
+ return &LogTriggeredStreamsLookupFilterer{contract: contract}, nil
+}
+
+func bindLogTriggeredStreamsLookup(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) {
+ parsed, err := LogTriggeredStreamsLookupMetaData.GetAbi()
+ if err != nil {
+ return nil, err
+ }
+ return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil
+}
+
+func (_LogTriggeredStreamsLookup *LogTriggeredStreamsLookupRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
+ return _LogTriggeredStreamsLookup.Contract.LogTriggeredStreamsLookupCaller.contract.Call(opts, result, method, params...)
+}
+
+func (_LogTriggeredStreamsLookup *LogTriggeredStreamsLookupRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _LogTriggeredStreamsLookup.Contract.LogTriggeredStreamsLookupTransactor.contract.Transfer(opts)
+}
+
+func (_LogTriggeredStreamsLookup *LogTriggeredStreamsLookupRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+ return _LogTriggeredStreamsLookup.Contract.LogTriggeredStreamsLookupTransactor.contract.Transact(opts, method, params...)
+}
+
+func (_LogTriggeredStreamsLookup *LogTriggeredStreamsLookupCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
+ return _LogTriggeredStreamsLookup.Contract.contract.Call(opts, result, method, params...)
+}
+
+func (_LogTriggeredStreamsLookup *LogTriggeredStreamsLookupTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _LogTriggeredStreamsLookup.Contract.contract.Transfer(opts)
+}
+
+func (_LogTriggeredStreamsLookup *LogTriggeredStreamsLookupTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+ return _LogTriggeredStreamsLookup.Contract.contract.Transact(opts, method, params...)
+}
+
+func (_LogTriggeredStreamsLookup *LogTriggeredStreamsLookupCaller) CheckCallback(opts *bind.CallOpts, values [][]byte, extraData []byte) (bool, []byte, error) {
+ var out []interface{}
+ err := _LogTriggeredStreamsLookup.contract.Call(opts, &out, "checkCallback", values, extraData)
+
+ if err != nil {
+ return *new(bool), *new([]byte), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(bool)).(*bool)
+ out1 := *abi.ConvertType(out[1], new([]byte)).(*[]byte)
+
+ return out0, out1, err
+
+}
+
+func (_LogTriggeredStreamsLookup *LogTriggeredStreamsLookupSession) CheckCallback(values [][]byte, extraData []byte) (bool, []byte, error) {
+ return _LogTriggeredStreamsLookup.Contract.CheckCallback(&_LogTriggeredStreamsLookup.CallOpts, values, extraData)
+}
+
+func (_LogTriggeredStreamsLookup *LogTriggeredStreamsLookupCallerSession) CheckCallback(values [][]byte, extraData []byte) (bool, []byte, error) {
+ return _LogTriggeredStreamsLookup.Contract.CheckCallback(&_LogTriggeredStreamsLookup.CallOpts, values, extraData)
+}
+
+func (_LogTriggeredStreamsLookup *LogTriggeredStreamsLookupCaller) FeedParamKey(opts *bind.CallOpts) (string, error) {
+ var out []interface{}
+ err := _LogTriggeredStreamsLookup.contract.Call(opts, &out, "feedParamKey")
+
+ if err != nil {
+ return *new(string), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(string)).(*string)
+
+ return out0, err
+
+}
+
+func (_LogTriggeredStreamsLookup *LogTriggeredStreamsLookupSession) FeedParamKey() (string, error) {
+ return _LogTriggeredStreamsLookup.Contract.FeedParamKey(&_LogTriggeredStreamsLookup.CallOpts)
+}
+
+func (_LogTriggeredStreamsLookup *LogTriggeredStreamsLookupCallerSession) FeedParamKey() (string, error) {
+ return _LogTriggeredStreamsLookup.Contract.FeedParamKey(&_LogTriggeredStreamsLookup.CallOpts)
+}
+
+func (_LogTriggeredStreamsLookup *LogTriggeredStreamsLookupCaller) FeedsHex(opts *bind.CallOpts, arg0 *big.Int) (string, error) {
+ var out []interface{}
+ err := _LogTriggeredStreamsLookup.contract.Call(opts, &out, "feedsHex", arg0)
+
+ if err != nil {
+ return *new(string), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(string)).(*string)
+
+ return out0, err
+
+}
+
+func (_LogTriggeredStreamsLookup *LogTriggeredStreamsLookupSession) FeedsHex(arg0 *big.Int) (string, error) {
+ return _LogTriggeredStreamsLookup.Contract.FeedsHex(&_LogTriggeredStreamsLookup.CallOpts, arg0)
+}
+
+func (_LogTriggeredStreamsLookup *LogTriggeredStreamsLookupCallerSession) FeedsHex(arg0 *big.Int) (string, error) {
+ return _LogTriggeredStreamsLookup.Contract.FeedsHex(&_LogTriggeredStreamsLookup.CallOpts, arg0)
+}
+
+func (_LogTriggeredStreamsLookup *LogTriggeredStreamsLookupCaller) TimeParamKey(opts *bind.CallOpts) (string, error) {
+ var out []interface{}
+ err := _LogTriggeredStreamsLookup.contract.Call(opts, &out, "timeParamKey")
+
+ if err != nil {
+ return *new(string), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(string)).(*string)
+
+ return out0, err
+
+}
+
+func (_LogTriggeredStreamsLookup *LogTriggeredStreamsLookupSession) TimeParamKey() (string, error) {
+ return _LogTriggeredStreamsLookup.Contract.TimeParamKey(&_LogTriggeredStreamsLookup.CallOpts)
+}
+
+func (_LogTriggeredStreamsLookup *LogTriggeredStreamsLookupCallerSession) TimeParamKey() (string, error) {
+ return _LogTriggeredStreamsLookup.Contract.TimeParamKey(&_LogTriggeredStreamsLookup.CallOpts)
+}
+
+func (_LogTriggeredStreamsLookup *LogTriggeredStreamsLookupCaller) UseArbitrumBlockNum(opts *bind.CallOpts) (bool, error) {
+ var out []interface{}
+ err := _LogTriggeredStreamsLookup.contract.Call(opts, &out, "useArbitrumBlockNum")
+
+ if err != nil {
+ return *new(bool), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(bool)).(*bool)
+
+ return out0, err
+
+}
+
+func (_LogTriggeredStreamsLookup *LogTriggeredStreamsLookupSession) UseArbitrumBlockNum() (bool, error) {
+ return _LogTriggeredStreamsLookup.Contract.UseArbitrumBlockNum(&_LogTriggeredStreamsLookup.CallOpts)
+}
+
+func (_LogTriggeredStreamsLookup *LogTriggeredStreamsLookupCallerSession) UseArbitrumBlockNum() (bool, error) {
+ return _LogTriggeredStreamsLookup.Contract.UseArbitrumBlockNum(&_LogTriggeredStreamsLookup.CallOpts)
+}
+
+func (_LogTriggeredStreamsLookup *LogTriggeredStreamsLookupCaller) Verify(opts *bind.CallOpts) (bool, error) {
+ var out []interface{}
+ err := _LogTriggeredStreamsLookup.contract.Call(opts, &out, "verify")
+
+ if err != nil {
+ return *new(bool), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(bool)).(*bool)
+
+ return out0, err
+
+}
+
+func (_LogTriggeredStreamsLookup *LogTriggeredStreamsLookupSession) Verify() (bool, error) {
+ return _LogTriggeredStreamsLookup.Contract.Verify(&_LogTriggeredStreamsLookup.CallOpts)
+}
+
+func (_LogTriggeredStreamsLookup *LogTriggeredStreamsLookupCallerSession) Verify() (bool, error) {
+ return _LogTriggeredStreamsLookup.Contract.Verify(&_LogTriggeredStreamsLookup.CallOpts)
+}
+
+func (_LogTriggeredStreamsLookup *LogTriggeredStreamsLookupTransactor) CheckLog(opts *bind.TransactOpts, log Log, arg1 []byte) (*types.Transaction, error) {
+ return _LogTriggeredStreamsLookup.contract.Transact(opts, "checkLog", log, arg1)
+}
+
+func (_LogTriggeredStreamsLookup *LogTriggeredStreamsLookupSession) CheckLog(log Log, arg1 []byte) (*types.Transaction, error) {
+ return _LogTriggeredStreamsLookup.Contract.CheckLog(&_LogTriggeredStreamsLookup.TransactOpts, log, arg1)
+}
+
+func (_LogTriggeredStreamsLookup *LogTriggeredStreamsLookupTransactorSession) CheckLog(log Log, arg1 []byte) (*types.Transaction, error) {
+ return _LogTriggeredStreamsLookup.Contract.CheckLog(&_LogTriggeredStreamsLookup.TransactOpts, log, arg1)
+}
+
+func (_LogTriggeredStreamsLookup *LogTriggeredStreamsLookupTransactor) PerformUpkeep(opts *bind.TransactOpts, performData []byte) (*types.Transaction, error) {
+ return _LogTriggeredStreamsLookup.contract.Transact(opts, "performUpkeep", performData)
+}
+
+func (_LogTriggeredStreamsLookup *LogTriggeredStreamsLookupSession) PerformUpkeep(performData []byte) (*types.Transaction, error) {
+ return _LogTriggeredStreamsLookup.Contract.PerformUpkeep(&_LogTriggeredStreamsLookup.TransactOpts, performData)
+}
+
+func (_LogTriggeredStreamsLookup *LogTriggeredStreamsLookupTransactorSession) PerformUpkeep(performData []byte) (*types.Transaction, error) {
+ return _LogTriggeredStreamsLookup.Contract.PerformUpkeep(&_LogTriggeredStreamsLookup.TransactOpts, performData)
+}
+
+func (_LogTriggeredStreamsLookup *LogTriggeredStreamsLookupTransactor) SetFeedParamKey(opts *bind.TransactOpts, feedParam string) (*types.Transaction, error) {
+ return _LogTriggeredStreamsLookup.contract.Transact(opts, "setFeedParamKey", feedParam)
+}
+
+func (_LogTriggeredStreamsLookup *LogTriggeredStreamsLookupSession) SetFeedParamKey(feedParam string) (*types.Transaction, error) {
+ return _LogTriggeredStreamsLookup.Contract.SetFeedParamKey(&_LogTriggeredStreamsLookup.TransactOpts, feedParam)
+}
+
+func (_LogTriggeredStreamsLookup *LogTriggeredStreamsLookupTransactorSession) SetFeedParamKey(feedParam string) (*types.Transaction, error) {
+ return _LogTriggeredStreamsLookup.Contract.SetFeedParamKey(&_LogTriggeredStreamsLookup.TransactOpts, feedParam)
+}
+
+func (_LogTriggeredStreamsLookup *LogTriggeredStreamsLookupTransactor) SetFeedsHex(opts *bind.TransactOpts, newFeeds []string) (*types.Transaction, error) {
+ return _LogTriggeredStreamsLookup.contract.Transact(opts, "setFeedsHex", newFeeds)
+}
+
+func (_LogTriggeredStreamsLookup *LogTriggeredStreamsLookupSession) SetFeedsHex(newFeeds []string) (*types.Transaction, error) {
+ return _LogTriggeredStreamsLookup.Contract.SetFeedsHex(&_LogTriggeredStreamsLookup.TransactOpts, newFeeds)
+}
+
+func (_LogTriggeredStreamsLookup *LogTriggeredStreamsLookupTransactorSession) SetFeedsHex(newFeeds []string) (*types.Transaction, error) {
+ return _LogTriggeredStreamsLookup.Contract.SetFeedsHex(&_LogTriggeredStreamsLookup.TransactOpts, newFeeds)
+}
+
+func (_LogTriggeredStreamsLookup *LogTriggeredStreamsLookupTransactor) SetTimeParamKey(opts *bind.TransactOpts, timeParam string) (*types.Transaction, error) {
+ return _LogTriggeredStreamsLookup.contract.Transact(opts, "setTimeParamKey", timeParam)
+}
+
+func (_LogTriggeredStreamsLookup *LogTriggeredStreamsLookupSession) SetTimeParamKey(timeParam string) (*types.Transaction, error) {
+ return _LogTriggeredStreamsLookup.Contract.SetTimeParamKey(&_LogTriggeredStreamsLookup.TransactOpts, timeParam)
+}
+
+func (_LogTriggeredStreamsLookup *LogTriggeredStreamsLookupTransactorSession) SetTimeParamKey(timeParam string) (*types.Transaction, error) {
+ return _LogTriggeredStreamsLookup.Contract.SetTimeParamKey(&_LogTriggeredStreamsLookup.TransactOpts, timeParam)
+}
+
+type LogTriggeredStreamsLookupPerformingLogTriggerUpkeepIterator struct {
+ Event *LogTriggeredStreamsLookupPerformingLogTriggerUpkeep
+
+ contract *bind.BoundContract
+ event string
+
+ logs chan types.Log
+ sub ethereum.Subscription
+ done bool
+ fail error
+}
+
+func (it *LogTriggeredStreamsLookupPerformingLogTriggerUpkeepIterator) Next() bool {
+
+ if it.fail != nil {
+ return false
+ }
+
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(LogTriggeredStreamsLookupPerformingLogTriggerUpkeep)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+
+ select {
+ case log := <-it.logs:
+ it.Event = new(LogTriggeredStreamsLookupPerformingLogTriggerUpkeep)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+func (it *LogTriggeredStreamsLookupPerformingLogTriggerUpkeepIterator) Error() error {
+ return it.fail
+}
+
+func (it *LogTriggeredStreamsLookupPerformingLogTriggerUpkeepIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+type LogTriggeredStreamsLookupPerformingLogTriggerUpkeep struct {
+ From common.Address
+ OrderId *big.Int
+ Amount *big.Int
+ Exchange common.Address
+ BlockNumber *big.Int
+ Blob []byte
+ Verified []byte
+ Raw types.Log
+}
+
+func (_LogTriggeredStreamsLookup *LogTriggeredStreamsLookupFilterer) FilterPerformingLogTriggerUpkeep(opts *bind.FilterOpts, from []common.Address) (*LogTriggeredStreamsLookupPerformingLogTriggerUpkeepIterator, error) {
+
+ var fromRule []interface{}
+ for _, fromItem := range from {
+ fromRule = append(fromRule, fromItem)
+ }
+
+ logs, sub, err := _LogTriggeredStreamsLookup.contract.FilterLogs(opts, "PerformingLogTriggerUpkeep", fromRule)
+ if err != nil {
+ return nil, err
+ }
+ return &LogTriggeredStreamsLookupPerformingLogTriggerUpkeepIterator{contract: _LogTriggeredStreamsLookup.contract, event: "PerformingLogTriggerUpkeep", logs: logs, sub: sub}, nil
+}
+
+func (_LogTriggeredStreamsLookup *LogTriggeredStreamsLookupFilterer) WatchPerformingLogTriggerUpkeep(opts *bind.WatchOpts, sink chan<- *LogTriggeredStreamsLookupPerformingLogTriggerUpkeep, from []common.Address) (event.Subscription, error) {
+
+ var fromRule []interface{}
+ for _, fromItem := range from {
+ fromRule = append(fromRule, fromItem)
+ }
+
+ logs, sub, err := _LogTriggeredStreamsLookup.contract.WatchLogs(opts, "PerformingLogTriggerUpkeep", fromRule)
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+
+ event := new(LogTriggeredStreamsLookupPerformingLogTriggerUpkeep)
+ if err := _LogTriggeredStreamsLookup.contract.UnpackLog(event, "PerformingLogTriggerUpkeep", log); err != nil {
+ return err
+ }
+ event.Raw = log
+
+ select {
+ case sink <- event:
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ }
+ }), nil
+}
+
+func (_LogTriggeredStreamsLookup *LogTriggeredStreamsLookupFilterer) ParsePerformingLogTriggerUpkeep(log types.Log) (*LogTriggeredStreamsLookupPerformingLogTriggerUpkeep, error) {
+ event := new(LogTriggeredStreamsLookupPerformingLogTriggerUpkeep)
+ if err := _LogTriggeredStreamsLookup.contract.UnpackLog(event, "PerformingLogTriggerUpkeep", log); err != nil {
+ return nil, err
+ }
+ event.Raw = log
+ return event, nil
+}
+
+func (_LogTriggeredStreamsLookup *LogTriggeredStreamsLookup) ParseLog(log types.Log) (generated.AbigenLog, error) {
+ switch log.Topics[0] {
+ case _LogTriggeredStreamsLookup.abi.Events["PerformingLogTriggerUpkeep"].ID:
+ return _LogTriggeredStreamsLookup.ParsePerformingLogTriggerUpkeep(log)
+
+ default:
+ return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0])
+ }
+}
+
+func (LogTriggeredStreamsLookupPerformingLogTriggerUpkeep) Topic() common.Hash {
+ return common.HexToHash("0x299a03817e683a32b21e29e3ae3c31f1c9c773f7d532836d116b62a9281fbc9d")
+}
+
+func (_LogTriggeredStreamsLookup *LogTriggeredStreamsLookup) Address() common.Address {
+ return _LogTriggeredStreamsLookup.address
+}
+
+type LogTriggeredStreamsLookupInterface interface {
+ CheckCallback(opts *bind.CallOpts, values [][]byte, extraData []byte) (bool, []byte, error)
+
+ FeedParamKey(opts *bind.CallOpts) (string, error)
+
+ FeedsHex(opts *bind.CallOpts, arg0 *big.Int) (string, error)
+
+ TimeParamKey(opts *bind.CallOpts) (string, error)
+
+ UseArbitrumBlockNum(opts *bind.CallOpts) (bool, error)
+
+ Verify(opts *bind.CallOpts) (bool, error)
+
+ CheckLog(opts *bind.TransactOpts, log Log, arg1 []byte) (*types.Transaction, error)
+
+ PerformUpkeep(opts *bind.TransactOpts, performData []byte) (*types.Transaction, error)
+
+ SetFeedParamKey(opts *bind.TransactOpts, feedParam string) (*types.Transaction, error)
+
+ SetFeedsHex(opts *bind.TransactOpts, newFeeds []string) (*types.Transaction, error)
+
+ SetTimeParamKey(opts *bind.TransactOpts, timeParam string) (*types.Transaction, error)
+
+ FilterPerformingLogTriggerUpkeep(opts *bind.FilterOpts, from []common.Address) (*LogTriggeredStreamsLookupPerformingLogTriggerUpkeepIterator, error)
+
+ WatchPerformingLogTriggerUpkeep(opts *bind.WatchOpts, sink chan<- *LogTriggeredStreamsLookupPerformingLogTriggerUpkeep, from []common.Address) (event.Subscription, error)
+
+ ParsePerformingLogTriggerUpkeep(log types.Log) (*LogTriggeredStreamsLookupPerformingLogTriggerUpkeep, error)
+
+ ParseLog(log types.Log) (generated.AbigenLog, error)
+
+ Address() common.Address
+}
diff --git a/core/gethwrappers/generated/log_upkeep_counter_wrapper/log_upkeep_counter_wrapper.go b/core/gethwrappers/generated/log_upkeep_counter_wrapper/log_upkeep_counter_wrapper.go
index 1a6f58fe6b1..fd55349b126 100644
--- a/core/gethwrappers/generated/log_upkeep_counter_wrapper/log_upkeep_counter_wrapper.go
+++ b/core/gethwrappers/generated/log_upkeep_counter_wrapper/log_upkeep_counter_wrapper.go
@@ -32,7 +32,7 @@ var (
type Log struct {
Index *big.Int
- TxIndex *big.Int
+ Timestamp *big.Int
TxHash [32]byte
BlockNumber *big.Int
BlockHash [32]byte
@@ -42,7 +42,7 @@ type Log struct {
}
var LogUpkeepCounterMetaData = &bind.MetaData{
- ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_testRange\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"initialBlock\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"lastBlock\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"previousBlock\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"counter\",\"type\":\"uint256\"}],\"name\":\"PerformingUpkeep\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"Trigger\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"a\",\"type\":\"uint256\"}],\"name\":\"Trigger\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"a\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"b\",\"type\":\"uint256\"}],\"name\":\"Trigger\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"a\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"b\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"c\",\"type\":\"uint256\"}],\"name\":\"Trigger\",\"type\":\"event\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"txIndex\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"txHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"source\",\"type\":\"address\"},{\"internalType\":\"bytes32[]\",\"name\":\"topics\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"structLog\",\"name\":\"log\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"checkLog\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"counter\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"eligible\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initialBlock\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lastBlock\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"}],\"name\":\"performUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"previousPerformBlock\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_testRange\",\"type\":\"uint256\"}],\"name\":\"setSpread\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"start\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"testRange\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]",
+ ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_testRange\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"initialBlock\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"lastBlock\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"previousBlock\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"counter\",\"type\":\"uint256\"}],\"name\":\"PerformingUpkeep\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"Trigger\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"a\",\"type\":\"uint256\"}],\"name\":\"Trigger\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"a\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"b\",\"type\":\"uint256\"}],\"name\":\"Trigger\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"a\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"b\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"c\",\"type\":\"uint256\"}],\"name\":\"Trigger\",\"type\":\"event\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"txHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"source\",\"type\":\"address\"},{\"internalType\":\"bytes32[]\",\"name\":\"topics\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"structLog\",\"name\":\"log\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"checkLog\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"counter\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"eligible\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initialBlock\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lastBlock\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"}],\"name\":\"performUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"previousPerformBlock\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_testRange\",\"type\":\"uint256\"}],\"name\":\"setSpread\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"start\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"testRange\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]",
Bin: "0x60806040527f3d53a39550e04688065827f3bb86584cb007ab9ebca7ebd528e7301c9c31eb5d6000557f57b1de35764b0939dde00771c7069cdf8d6a65d6a175623f19aa18784fd4c6da6001557f1da9f70fe932e73fba9374396c5c0b02dbd170f951874b7b4afabe4dd029a9c86002557f5121119bad45ca7e58e0bdadf39045f5111e93ba4304a0f6457a3e7bc9791e716003553480156100a057600080fd5b50604051610f41380380610f418339810160408190526100bf916100da565b600455600060068190554360055560078190556008556100f3565b6000602082840312156100ec57600080fd5b5051919050565b610e3f806101026000396000f3fe608060405234801561001057600080fd5b50600436106100be5760003560e01c8063806b984f11610076578063b66a261c1161005b578063b66a261c14610139578063be9a655514610156578063d832d92f1461015e57600080fd5b8063806b984f14610127578063917d895f1461013057600080fd5b80634585e33b116100a75780634585e33b1461010057806361bc221a146101155780636250a13a1461011e57600080fd5b80632cb15864146100c357806340691db4146100df575b600080fd5b6100cc60075481565b6040519081526020015b60405180910390f35b6100f26100ed366004610889565b610176565b6040516100d6929190610a7c565b61011361010e366004610817565b610365565b005b6100cc60085481565b6100cc60045481565b6100cc60055481565b6100cc60065481565b6101136101473660046109cb565b60045560006007819055600855565b6101136105d7565b6101666106b1565b60405190151581526020016100d6565b600060606101826106b1565b6101ed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f6e6f7420656c696769626c65000000000000000000000000000000000000000060448201526064015b60405180910390fd5b6000546101fd60c0860186610bca565b600081811061020e5761020e610dd4565b905060200201351480610246575060015461022c60c0860186610bca565b600081811061023d5761023d610dd4565b90506020020135145b80610276575060025461025c60c0860186610bca565b600081811061026d5761026d610dd4565b90506020020135145b806102a6575060035461028c60c0860186610bca565b600081811061029d5761029d610dd4565b90506020020135145b156102d6576001846040516020016102be9190610af9565b6040516020818303038152906040529150915061035e565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f636f756c64206e6f742066696e64206d61746368696e67206576656e7420736960448201527f670000000000000000000000000000000000000000000000000000000000000060648201526084016101e4565b9250929050565b60075461037157436007555b43600555600854610383906001610d76565b600855600554600655600061039a828401846108f6565b90506000548160c001516000815181106103b6576103b6610dd4565b602002602001015114156103f2576040517f3d53a39550e04688065827f3bb86584cb007ab9ebca7ebd528e7301c9c31eb5d90600090a161057f565b6001548160c0015160008151811061040c5761040c610dd4565b6020026020010151141561045457604051600181527f57b1de35764b0939dde00771c7069cdf8d6a65d6a175623f19aa18784fd4c6da906020015b60405180910390a161057f565b6002548160c0015160008151811061046e5761046e610dd4565b602002602001015114156104b3576040805160018152600260208201527f1da9f70fe932e73fba9374396c5c0b02dbd170f951874b7b4afabe4dd029a9c89101610447565b6003548160c001516000815181106104cd576104cd610dd4565b6020026020010151141561051d576040805160018152600260208201526003918101919091527f5121119bad45ca7e58e0bdadf39045f5111e93ba4304a0f6457a3e7bc9791e7190606001610447565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f636f756c64206e6f742066696e64206d61746368696e6720736967000000000060448201526064016101e4565b60075460055460065460085460408051948552602085019390935291830152606082015232907f8e8112f20a2134e18e591d2cdd68cd86a95d06e6328ede501fc6314f4a5075fa9060800160405180910390a2505050565b6040517f3d53a39550e04688065827f3bb86584cb007ab9ebca7ebd528e7301c9c31eb5d90600090a1604051600181527f57b1de35764b0939dde00771c7069cdf8d6a65d6a175623f19aa18784fd4c6da9060200160405180910390a16040805160018152600260208201527f1da9f70fe932e73fba9374396c5c0b02dbd170f951874b7b4afabe4dd029a9c8910160405180910390a160408051600181526002602082015260038183015290517f5121119bad45ca7e58e0bdadf39045f5111e93ba4304a0f6457a3e7bc9791e719181900360600190a1565b6000600754600014156106c45750600190565b6004546007546106d49043610d8e565b10905090565b803573ffffffffffffffffffffffffffffffffffffffff811681146106fe57600080fd5b919050565b600082601f83011261071457600080fd5b8135602067ffffffffffffffff82111561073057610730610e03565b8160051b61073f828201610c5c565b83815282810190868401838801850189101561075a57600080fd5b600093505b8584101561077d57803583526001939093019291840191840161075f565b50979650505050505050565b600082601f83011261079a57600080fd5b813567ffffffffffffffff8111156107b4576107b4610e03565b6107e560207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601610c5c565b8181528460208386010111156107fa57600080fd5b816020850160208301376000918101602001919091529392505050565b6000806020838503121561082a57600080fd5b823567ffffffffffffffff8082111561084257600080fd5b818501915085601f83011261085657600080fd5b81358181111561086557600080fd5b86602082850101111561087757600080fd5b60209290920196919550909350505050565b6000806040838503121561089c57600080fd5b823567ffffffffffffffff808211156108b457600080fd5b9084019061010082870312156108c957600080fd5b909250602084013590808211156108df57600080fd5b506108ec85828601610789565b9150509250929050565b60006020828403121561090857600080fd5b813567ffffffffffffffff8082111561092057600080fd5b90830190610100828603121561093557600080fd5b61093d610c32565b823581526020830135602082015260408301356040820152606083013560608201526080830135608082015261097560a084016106da565b60a082015260c08301358281111561098c57600080fd5b61099887828601610703565b60c08301525060e0830135828111156109b057600080fd5b6109bc87828601610789565b60e08301525095945050505050565b6000602082840312156109dd57600080fd5b5035919050565b81835260007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831115610a1657600080fd5b8260051b8083602087013760009401602001938452509192915050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b821515815260006020604081840152835180604085015260005b81811015610ab257858101830151858201606001528201610a96565b81811115610ac4576000606083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01692909201606001949350505050565b6020815281356020820152602082013560408201526040820135606082015260608201356080820152608082013560a082015273ffffffffffffffffffffffffffffffffffffffff610b4d60a084016106da565b1660c08201526000610b6260c0840184610cab565b6101008060e0860152610b7a610120860183856109e4565b9250610b8960e0870187610d12565b92507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08685030182870152610bbf848483610a33565b979650505050505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112610bff57600080fd5b83018035915067ffffffffffffffff821115610c1a57600080fd5b6020019150600581901b360382131561035e57600080fd5b604051610100810167ffffffffffffffff81118282101715610c5657610c56610e03565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610ca357610ca3610e03565b604052919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112610ce057600080fd5b830160208101925035905067ffffffffffffffff811115610d0057600080fd5b8060051b360383131561035e57600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112610d4757600080fd5b830160208101925035905067ffffffffffffffff811115610d6757600080fd5b80360383131561035e57600080fd5b60008219821115610d8957610d89610da5565b500190565b600082821015610da057610da0610da5565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fdfea164736f6c6343000806000a",
}
diff --git a/core/gethwrappers/generated/mercury_upkeep_wrapper/mercury_upkeep_wrapper.go b/core/gethwrappers/generated/mercury_upkeep_wrapper/mercury_upkeep_wrapper.go
deleted file mode 100644
index 3233012fb7c..00000000000
--- a/core/gethwrappers/generated/mercury_upkeep_wrapper/mercury_upkeep_wrapper.go
+++ /dev/null
@@ -1,730 +0,0 @@
-// Code generated - DO NOT EDIT.
-// This file is a generated binding and any manual changes will be lost.
-
-package mercury_upkeep_wrapper
-
-import (
- "errors"
- "fmt"
- "math/big"
- "strings"
-
- ethereum "github.com/ethereum/go-ethereum"
- "github.com/ethereum/go-ethereum/accounts/abi"
- "github.com/ethereum/go-ethereum/accounts/abi/bind"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/event"
- "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated"
-)
-
-var (
- _ = errors.New
- _ = big.NewInt
- _ = strings.NewReader
- _ = ethereum.NotFound
- _ = bind.Bind
- _ = common.Big1
- _ = types.BloomLookup
- _ = event.NewSubscription
- _ = abi.ConvertType
-)
-
-var MercuryUpkeepMetaData = &bind.MetaData{
- ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_testRange\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_interval\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"_useL1BlockNumber\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"feedParamKey\",\"type\":\"string\"},{\"internalType\":\"string[]\",\"name\":\"feeds\",\"type\":\"string[]\"},{\"internalType\":\"string\",\"name\":\"timeParamKey\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"time\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"FeedLookup\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"origin\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"v0\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"v1\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"ed\",\"type\":\"bytes\"}],\"name\":\"MercuryPerformEvent\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"callbackReturnBool\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes[]\",\"name\":\"values\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"checkCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"checkUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"counter\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"eligible\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"feedParamKey\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"feeds\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initialBlock\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"interval\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"}],\"name\":\"performUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"previousPerformBlock\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"value\",\"type\":\"bool\"}],\"name\":\"setCallbackReturnBool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"value\",\"type\":\"bool\"}],\"name\":\"setShouldRevertCallback\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"shouldRevertCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"testRange\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"timeParamKey\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"useL1BlockNumber\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]",
- Bin: "0x60a06040523480156200001157600080fd5b5060405162001308380380620013088339810160408190526200003491620001f7565b60008381556001839055600281905560038190556004556040805180820190915260098152680cccacac892c890caf60bb1b60208201526006906200007a9082620002dc565b50604051806040016040528060405180608001604052806042815260200162001284604291398152602001604051806080016040528060428152602001620012c6604291399052620000d190600590600262000120565b5060408051808201909152600b81526a313637b1b5a73ab6b132b960a91b6020820152600790620001039082620002dc565b50151560805250506008805461ff001916610100179055620003a8565b8280548282559060005260206000209081019282156200016b579160200282015b828111156200016b57825182906200015a9082620002dc565b509160200191906001019062000141565b50620001799291506200017d565b5090565b80821115620001795760006200019482826200019e565b506001016200017d565b508054620001ac906200024d565b6000825580601f10620001bd575050565b601f016020900490600052602060002090810190620001dd9190620001e0565b50565b5b80821115620001795760008155600101620001e1565b6000806000606084860312156200020d57600080fd5b8351925060208401519150604084015180151581146200022c57600080fd5b809150509250925092565b634e487b7160e01b600052604160045260246000fd5b600181811c908216806200026257607f821691505b6020821081036200028357634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620002d757600081815260208120601f850160051c81016020861015620002b25750805b601f850160051c820191505b81811015620002d357828155600101620002be565b5050505b505050565b81516001600160401b03811115620002f857620002f862000237565b62000310816200030984546200024d565b8462000289565b602080601f8311600181146200034857600084156200032f5750858301515b600019600386901b1c1916600185901b178555620002d3565b600085815260208120601f198616915b82811015620003795788860151825594840194600190910190840162000358565b5085821015620003985787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b608051610eab620003d960003960008181610170015281816102bf015281816105ef01526107220152610eab6000f3fe608060405234801561001057600080fd5b506004361061011b5760003560e01c80635b48391a116100b2578063917d895f11610081578063afb28d1f11610066578063afb28d1f146102a3578063c98f10b0146102ab578063d832d92f146102b357600080fd5b8063917d895f14610291578063947a36fb1461029a57600080fd5b80635b48391a1461022757806361bc221a1461026c5780636250a13a146102755780636e04ff0d1461027e57600080fd5b80634585e33b116100ee5780634585e33b146101925780634a5479f3146101a75780634b56a42e146101c75780634bdb3862146101e857600080fd5b806302be021f14610120578063102d538b146101425780632cb15864146101545780632d02b93b1461016b575b600080fd5b60085461012d9060ff1681565b60405190151581526020015b60405180910390f35b60085461012d90610100900460ff1681565b61015d60035481565b604051908152602001610139565b61012d7f000000000000000000000000000000000000000000000000000000000000000081565b6101a56101a03660046107f1565b6102bb565b005b6101ba6101b5366004610863565b610414565b60405161013991906108e0565b6101da6101d5366004610a06565b6104c0565b604051610139929190610aec565b6101a56101f6366004610b0f565b600880547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055565b6101a5610235366004610b0f565b60088054911515610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff909216919091179055565b61015d60045481565b61015d60005481565b6101da61028c3660046107f1565b610593565b61015d60025481565b61015d60015481565b6101ba6106f2565b6101ba6106ff565b61012d61070c565b60007f0000000000000000000000000000000000000000000000000000000000000000156102ea57504361035d565b606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610336573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061035a9190610b31565b90505b60035460000361036d5760038190555b60008061037c84860186610a06565b60028590556004549193509150610394906001610b79565b60045581518390339032907fec3208363089f292bf230caa1cd39f9dc25d98a341b935d9ebd7a95e2ec82af19086906000906103d2576103d2610b92565b6020026020010151866001815181106103ed576103ed610b92565b60200260200101518660405161040593929190610bc1565b60405180910390a45050505050565b6005818154811061042457600080fd5b90600052602060002001600091509050805461043f90610c04565b80601f016020809104026020016040519081016040528092919081815260200182805461046b90610c04565b80156104b85780601f1061048d576101008083540402835291602001916104b8565b820191906000526020600020905b81548152906001019060200180831161049b57829003601f168201915b505050505081565b60085460009060609060ff1615610538576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f73686f756c6452657665727443616c6c6261636b20697320747275650000000060448201526064015b60405180910390fd5b6000848460405160200161054d929190610c57565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0018152919052600854610100900460ff1693509150505b9250929050565b6000606061059f61070c565b6105eb576000848481818080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525095975091955061058c945050505050565b60007f00000000000000000000000000000000000000000000000000000000000000001561061a57504361068d565b606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610666573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061068a9190610b31565b90505b604080516c6400000000000000000000000060208201528151601481830301815260348201928390527f7ddd933e0000000000000000000000000000000000000000000000000000000090925261052f91600691600591600791869190603801610dc8565b6006805461043f90610c04565b6007805461043f90610c04565b600060035460000361071e5750600190565b60007f00000000000000000000000000000000000000000000000000000000000000001561074d5750436107c0565b606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610799573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107bd9190610b31565b90505b6000546003546107d09083610e8b565b1080156107eb57506001546002546107e89083610e8b565b10155b91505090565b6000806020838503121561080457600080fd5b823567ffffffffffffffff8082111561081c57600080fd5b818501915085601f83011261083057600080fd5b81358181111561083f57600080fd5b86602082850101111561085157600080fd5b60209290920196919550909350505050565b60006020828403121561087557600080fd5b5035919050565b6000815180845260005b818110156108a257602081850181015186830182015201610886565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b6020815260006108f3602083018461087c565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610970576109706108fa565b604052919050565b600082601f83011261098957600080fd5b813567ffffffffffffffff8111156109a3576109a36108fa565b6109d460207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601610929565b8181528460208386010111156109e957600080fd5b816020850160208301376000918101602001919091529392505050565b60008060408385031215610a1957600080fd5b823567ffffffffffffffff80821115610a3157600080fd5b818501915085601f830112610a4557600080fd5b8135602082821115610a5957610a596108fa565b8160051b610a68828201610929565b928352848101820192828101908a851115610a8257600080fd5b83870192505b84831015610abe57823586811115610aa05760008081fd5b610aae8c86838b0101610978565b8352509183019190830190610a88565b9750505086013592505080821115610ad557600080fd5b50610ae285828601610978565b9150509250929050565b8215158152604060208201526000610b07604083018461087c565b949350505050565b600060208284031215610b2157600080fd5b813580151581146108f357600080fd5b600060208284031215610b4357600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610b8c57610b8c610b4a565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b606081526000610bd4606083018661087c565b8281036020840152610be6818661087c565b90508281036040840152610bfa818561087c565b9695505050505050565b600181811c90821680610c1857607f821691505b602082108103610c51577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b6000604082016040835280855180835260608501915060608160051b8601019250602080880160005b83811015610ccc577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0888703018552610cba86835161087c565b95509382019390820190600101610c80565b505085840381870152505050610ce2818561087c565b95945050505050565b8054600090600181811c9080831680610d0557607f831692505b60208084108203610d3f577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b838852818015610d565760018114610d8e57610dbc565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008616828a01528185151560051b8a01019650610dbc565b876000528160002060005b86811015610db45781548b8201850152908501908301610d99565b8a0183019750505b50505050505092915050565b60a081526000610ddb60a0830188610ceb565b6020838203818501528188548084528284019150828160051b8501018a6000528360002060005b83811015610e4d577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0878403018552610e3b8383610ceb565b94860194925060019182019101610e02565b50508681036040880152610e61818b610ceb565b9450505050508460608401528281036080840152610e7f818561087c565b98975050505050505050565b81810381811115610b8c57610b8c610b4a56fea164736f6c6343000810000a307834353534343832643535353334343264343135323432343935343532353534643264353434353533353434653435353430303030303030303030303030303030307834323534343332643535353334343264343135323432343935343532353534643264353434353533353434653435353430303030303030303030303030303030",
-}
-
-var MercuryUpkeepABI = MercuryUpkeepMetaData.ABI
-
-var MercuryUpkeepBin = MercuryUpkeepMetaData.Bin
-
-func DeployMercuryUpkeep(auth *bind.TransactOpts, backend bind.ContractBackend, _testRange *big.Int, _interval *big.Int, _useL1BlockNumber bool) (common.Address, *types.Transaction, *MercuryUpkeep, error) {
- parsed, err := MercuryUpkeepMetaData.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(MercuryUpkeepBin), backend, _testRange, _interval, _useL1BlockNumber)
- if err != nil {
- return common.Address{}, nil, nil, err
- }
- return address, tx, &MercuryUpkeep{MercuryUpkeepCaller: MercuryUpkeepCaller{contract: contract}, MercuryUpkeepTransactor: MercuryUpkeepTransactor{contract: contract}, MercuryUpkeepFilterer: MercuryUpkeepFilterer{contract: contract}}, nil
-}
-
-type MercuryUpkeep struct {
- address common.Address
- abi abi.ABI
- MercuryUpkeepCaller
- MercuryUpkeepTransactor
- MercuryUpkeepFilterer
-}
-
-type MercuryUpkeepCaller struct {
- contract *bind.BoundContract
-}
-
-type MercuryUpkeepTransactor struct {
- contract *bind.BoundContract
-}
-
-type MercuryUpkeepFilterer struct {
- contract *bind.BoundContract
-}
-
-type MercuryUpkeepSession struct {
- Contract *MercuryUpkeep
- CallOpts bind.CallOpts
- TransactOpts bind.TransactOpts
-}
-
-type MercuryUpkeepCallerSession struct {
- Contract *MercuryUpkeepCaller
- CallOpts bind.CallOpts
-}
-
-type MercuryUpkeepTransactorSession struct {
- Contract *MercuryUpkeepTransactor
- TransactOpts bind.TransactOpts
-}
-
-type MercuryUpkeepRaw struct {
- Contract *MercuryUpkeep
-}
-
-type MercuryUpkeepCallerRaw struct {
- Contract *MercuryUpkeepCaller
-}
-
-type MercuryUpkeepTransactorRaw struct {
- Contract *MercuryUpkeepTransactor
-}
-
-func NewMercuryUpkeep(address common.Address, backend bind.ContractBackend) (*MercuryUpkeep, error) {
- abi, err := abi.JSON(strings.NewReader(MercuryUpkeepABI))
- if err != nil {
- return nil, err
- }
- contract, err := bindMercuryUpkeep(address, backend, backend, backend)
- if err != nil {
- return nil, err
- }
- return &MercuryUpkeep{address: address, abi: abi, MercuryUpkeepCaller: MercuryUpkeepCaller{contract: contract}, MercuryUpkeepTransactor: MercuryUpkeepTransactor{contract: contract}, MercuryUpkeepFilterer: MercuryUpkeepFilterer{contract: contract}}, nil
-}
-
-func NewMercuryUpkeepCaller(address common.Address, caller bind.ContractCaller) (*MercuryUpkeepCaller, error) {
- contract, err := bindMercuryUpkeep(address, caller, nil, nil)
- if err != nil {
- return nil, err
- }
- return &MercuryUpkeepCaller{contract: contract}, nil
-}
-
-func NewMercuryUpkeepTransactor(address common.Address, transactor bind.ContractTransactor) (*MercuryUpkeepTransactor, error) {
- contract, err := bindMercuryUpkeep(address, nil, transactor, nil)
- if err != nil {
- return nil, err
- }
- return &MercuryUpkeepTransactor{contract: contract}, nil
-}
-
-func NewMercuryUpkeepFilterer(address common.Address, filterer bind.ContractFilterer) (*MercuryUpkeepFilterer, error) {
- contract, err := bindMercuryUpkeep(address, nil, nil, filterer)
- if err != nil {
- return nil, err
- }
- return &MercuryUpkeepFilterer{contract: contract}, nil
-}
-
-func bindMercuryUpkeep(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) {
- parsed, err := MercuryUpkeepMetaData.GetAbi()
- if err != nil {
- return nil, err
- }
- return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil
-}
-
-func (_MercuryUpkeep *MercuryUpkeepRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
- return _MercuryUpkeep.Contract.MercuryUpkeepCaller.contract.Call(opts, result, method, params...)
-}
-
-func (_MercuryUpkeep *MercuryUpkeepRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
- return _MercuryUpkeep.Contract.MercuryUpkeepTransactor.contract.Transfer(opts)
-}
-
-func (_MercuryUpkeep *MercuryUpkeepRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
- return _MercuryUpkeep.Contract.MercuryUpkeepTransactor.contract.Transact(opts, method, params...)
-}
-
-func (_MercuryUpkeep *MercuryUpkeepCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
- return _MercuryUpkeep.Contract.contract.Call(opts, result, method, params...)
-}
-
-func (_MercuryUpkeep *MercuryUpkeepTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
- return _MercuryUpkeep.Contract.contract.Transfer(opts)
-}
-
-func (_MercuryUpkeep *MercuryUpkeepTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
- return _MercuryUpkeep.Contract.contract.Transact(opts, method, params...)
-}
-
-func (_MercuryUpkeep *MercuryUpkeepCaller) CallbackReturnBool(opts *bind.CallOpts) (bool, error) {
- var out []interface{}
- err := _MercuryUpkeep.contract.Call(opts, &out, "callbackReturnBool")
-
- if err != nil {
- return *new(bool), err
- }
-
- out0 := *abi.ConvertType(out[0], new(bool)).(*bool)
-
- return out0, err
-
-}
-
-func (_MercuryUpkeep *MercuryUpkeepSession) CallbackReturnBool() (bool, error) {
- return _MercuryUpkeep.Contract.CallbackReturnBool(&_MercuryUpkeep.CallOpts)
-}
-
-func (_MercuryUpkeep *MercuryUpkeepCallerSession) CallbackReturnBool() (bool, error) {
- return _MercuryUpkeep.Contract.CallbackReturnBool(&_MercuryUpkeep.CallOpts)
-}
-
-func (_MercuryUpkeep *MercuryUpkeepCaller) CheckCallback(opts *bind.CallOpts, values [][]byte, extraData []byte) (bool, []byte, error) {
- var out []interface{}
- err := _MercuryUpkeep.contract.Call(opts, &out, "checkCallback", values, extraData)
-
- if err != nil {
- return *new(bool), *new([]byte), err
- }
-
- out0 := *abi.ConvertType(out[0], new(bool)).(*bool)
- out1 := *abi.ConvertType(out[1], new([]byte)).(*[]byte)
-
- return out0, out1, err
-
-}
-
-func (_MercuryUpkeep *MercuryUpkeepSession) CheckCallback(values [][]byte, extraData []byte) (bool, []byte, error) {
- return _MercuryUpkeep.Contract.CheckCallback(&_MercuryUpkeep.CallOpts, values, extraData)
-}
-
-func (_MercuryUpkeep *MercuryUpkeepCallerSession) CheckCallback(values [][]byte, extraData []byte) (bool, []byte, error) {
- return _MercuryUpkeep.Contract.CheckCallback(&_MercuryUpkeep.CallOpts, values, extraData)
-}
-
-func (_MercuryUpkeep *MercuryUpkeepCaller) CheckUpkeep(opts *bind.CallOpts, data []byte) (bool, []byte, error) {
- var out []interface{}
- err := _MercuryUpkeep.contract.Call(opts, &out, "checkUpkeep", data)
-
- if err != nil {
- return *new(bool), *new([]byte), err
- }
-
- out0 := *abi.ConvertType(out[0], new(bool)).(*bool)
- out1 := *abi.ConvertType(out[1], new([]byte)).(*[]byte)
-
- return out0, out1, err
-
-}
-
-func (_MercuryUpkeep *MercuryUpkeepSession) CheckUpkeep(data []byte) (bool, []byte, error) {
- return _MercuryUpkeep.Contract.CheckUpkeep(&_MercuryUpkeep.CallOpts, data)
-}
-
-func (_MercuryUpkeep *MercuryUpkeepCallerSession) CheckUpkeep(data []byte) (bool, []byte, error) {
- return _MercuryUpkeep.Contract.CheckUpkeep(&_MercuryUpkeep.CallOpts, data)
-}
-
-func (_MercuryUpkeep *MercuryUpkeepCaller) Counter(opts *bind.CallOpts) (*big.Int, error) {
- var out []interface{}
- err := _MercuryUpkeep.contract.Call(opts, &out, "counter")
-
- if err != nil {
- return *new(*big.Int), err
- }
-
- out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
-
- return out0, err
-
-}
-
-func (_MercuryUpkeep *MercuryUpkeepSession) Counter() (*big.Int, error) {
- return _MercuryUpkeep.Contract.Counter(&_MercuryUpkeep.CallOpts)
-}
-
-func (_MercuryUpkeep *MercuryUpkeepCallerSession) Counter() (*big.Int, error) {
- return _MercuryUpkeep.Contract.Counter(&_MercuryUpkeep.CallOpts)
-}
-
-func (_MercuryUpkeep *MercuryUpkeepCaller) Eligible(opts *bind.CallOpts) (bool, error) {
- var out []interface{}
- err := _MercuryUpkeep.contract.Call(opts, &out, "eligible")
-
- if err != nil {
- return *new(bool), err
- }
-
- out0 := *abi.ConvertType(out[0], new(bool)).(*bool)
-
- return out0, err
-
-}
-
-func (_MercuryUpkeep *MercuryUpkeepSession) Eligible() (bool, error) {
- return _MercuryUpkeep.Contract.Eligible(&_MercuryUpkeep.CallOpts)
-}
-
-func (_MercuryUpkeep *MercuryUpkeepCallerSession) Eligible() (bool, error) {
- return _MercuryUpkeep.Contract.Eligible(&_MercuryUpkeep.CallOpts)
-}
-
-func (_MercuryUpkeep *MercuryUpkeepCaller) FeedParamKey(opts *bind.CallOpts) (string, error) {
- var out []interface{}
- err := _MercuryUpkeep.contract.Call(opts, &out, "feedParamKey")
-
- if err != nil {
- return *new(string), err
- }
-
- out0 := *abi.ConvertType(out[0], new(string)).(*string)
-
- return out0, err
-
-}
-
-func (_MercuryUpkeep *MercuryUpkeepSession) FeedParamKey() (string, error) {
- return _MercuryUpkeep.Contract.FeedParamKey(&_MercuryUpkeep.CallOpts)
-}
-
-func (_MercuryUpkeep *MercuryUpkeepCallerSession) FeedParamKey() (string, error) {
- return _MercuryUpkeep.Contract.FeedParamKey(&_MercuryUpkeep.CallOpts)
-}
-
-func (_MercuryUpkeep *MercuryUpkeepCaller) Feeds(opts *bind.CallOpts, arg0 *big.Int) (string, error) {
- var out []interface{}
- err := _MercuryUpkeep.contract.Call(opts, &out, "feeds", arg0)
-
- if err != nil {
- return *new(string), err
- }
-
- out0 := *abi.ConvertType(out[0], new(string)).(*string)
-
- return out0, err
-
-}
-
-func (_MercuryUpkeep *MercuryUpkeepSession) Feeds(arg0 *big.Int) (string, error) {
- return _MercuryUpkeep.Contract.Feeds(&_MercuryUpkeep.CallOpts, arg0)
-}
-
-func (_MercuryUpkeep *MercuryUpkeepCallerSession) Feeds(arg0 *big.Int) (string, error) {
- return _MercuryUpkeep.Contract.Feeds(&_MercuryUpkeep.CallOpts, arg0)
-}
-
-func (_MercuryUpkeep *MercuryUpkeepCaller) InitialBlock(opts *bind.CallOpts) (*big.Int, error) {
- var out []interface{}
- err := _MercuryUpkeep.contract.Call(opts, &out, "initialBlock")
-
- if err != nil {
- return *new(*big.Int), err
- }
-
- out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
-
- return out0, err
-
-}
-
-func (_MercuryUpkeep *MercuryUpkeepSession) InitialBlock() (*big.Int, error) {
- return _MercuryUpkeep.Contract.InitialBlock(&_MercuryUpkeep.CallOpts)
-}
-
-func (_MercuryUpkeep *MercuryUpkeepCallerSession) InitialBlock() (*big.Int, error) {
- return _MercuryUpkeep.Contract.InitialBlock(&_MercuryUpkeep.CallOpts)
-}
-
-func (_MercuryUpkeep *MercuryUpkeepCaller) Interval(opts *bind.CallOpts) (*big.Int, error) {
- var out []interface{}
- err := _MercuryUpkeep.contract.Call(opts, &out, "interval")
-
- if err != nil {
- return *new(*big.Int), err
- }
-
- out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
-
- return out0, err
-
-}
-
-func (_MercuryUpkeep *MercuryUpkeepSession) Interval() (*big.Int, error) {
- return _MercuryUpkeep.Contract.Interval(&_MercuryUpkeep.CallOpts)
-}
-
-func (_MercuryUpkeep *MercuryUpkeepCallerSession) Interval() (*big.Int, error) {
- return _MercuryUpkeep.Contract.Interval(&_MercuryUpkeep.CallOpts)
-}
-
-func (_MercuryUpkeep *MercuryUpkeepCaller) PreviousPerformBlock(opts *bind.CallOpts) (*big.Int, error) {
- var out []interface{}
- err := _MercuryUpkeep.contract.Call(opts, &out, "previousPerformBlock")
-
- if err != nil {
- return *new(*big.Int), err
- }
-
- out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
-
- return out0, err
-
-}
-
-func (_MercuryUpkeep *MercuryUpkeepSession) PreviousPerformBlock() (*big.Int, error) {
- return _MercuryUpkeep.Contract.PreviousPerformBlock(&_MercuryUpkeep.CallOpts)
-}
-
-func (_MercuryUpkeep *MercuryUpkeepCallerSession) PreviousPerformBlock() (*big.Int, error) {
- return _MercuryUpkeep.Contract.PreviousPerformBlock(&_MercuryUpkeep.CallOpts)
-}
-
-func (_MercuryUpkeep *MercuryUpkeepCaller) ShouldRevertCallback(opts *bind.CallOpts) (bool, error) {
- var out []interface{}
- err := _MercuryUpkeep.contract.Call(opts, &out, "shouldRevertCallback")
-
- if err != nil {
- return *new(bool), err
- }
-
- out0 := *abi.ConvertType(out[0], new(bool)).(*bool)
-
- return out0, err
-
-}
-
-func (_MercuryUpkeep *MercuryUpkeepSession) ShouldRevertCallback() (bool, error) {
- return _MercuryUpkeep.Contract.ShouldRevertCallback(&_MercuryUpkeep.CallOpts)
-}
-
-func (_MercuryUpkeep *MercuryUpkeepCallerSession) ShouldRevertCallback() (bool, error) {
- return _MercuryUpkeep.Contract.ShouldRevertCallback(&_MercuryUpkeep.CallOpts)
-}
-
-func (_MercuryUpkeep *MercuryUpkeepCaller) TestRange(opts *bind.CallOpts) (*big.Int, error) {
- var out []interface{}
- err := _MercuryUpkeep.contract.Call(opts, &out, "testRange")
-
- if err != nil {
- return *new(*big.Int), err
- }
-
- out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
-
- return out0, err
-
-}
-
-func (_MercuryUpkeep *MercuryUpkeepSession) TestRange() (*big.Int, error) {
- return _MercuryUpkeep.Contract.TestRange(&_MercuryUpkeep.CallOpts)
-}
-
-func (_MercuryUpkeep *MercuryUpkeepCallerSession) TestRange() (*big.Int, error) {
- return _MercuryUpkeep.Contract.TestRange(&_MercuryUpkeep.CallOpts)
-}
-
-func (_MercuryUpkeep *MercuryUpkeepCaller) TimeParamKey(opts *bind.CallOpts) (string, error) {
- var out []interface{}
- err := _MercuryUpkeep.contract.Call(opts, &out, "timeParamKey")
-
- if err != nil {
- return *new(string), err
- }
-
- out0 := *abi.ConvertType(out[0], new(string)).(*string)
-
- return out0, err
-
-}
-
-func (_MercuryUpkeep *MercuryUpkeepSession) TimeParamKey() (string, error) {
- return _MercuryUpkeep.Contract.TimeParamKey(&_MercuryUpkeep.CallOpts)
-}
-
-func (_MercuryUpkeep *MercuryUpkeepCallerSession) TimeParamKey() (string, error) {
- return _MercuryUpkeep.Contract.TimeParamKey(&_MercuryUpkeep.CallOpts)
-}
-
-func (_MercuryUpkeep *MercuryUpkeepCaller) UseL1BlockNumber(opts *bind.CallOpts) (bool, error) {
- var out []interface{}
- err := _MercuryUpkeep.contract.Call(opts, &out, "useL1BlockNumber")
-
- if err != nil {
- return *new(bool), err
- }
-
- out0 := *abi.ConvertType(out[0], new(bool)).(*bool)
-
- return out0, err
-
-}
-
-func (_MercuryUpkeep *MercuryUpkeepSession) UseL1BlockNumber() (bool, error) {
- return _MercuryUpkeep.Contract.UseL1BlockNumber(&_MercuryUpkeep.CallOpts)
-}
-
-func (_MercuryUpkeep *MercuryUpkeepCallerSession) UseL1BlockNumber() (bool, error) {
- return _MercuryUpkeep.Contract.UseL1BlockNumber(&_MercuryUpkeep.CallOpts)
-}
-
-func (_MercuryUpkeep *MercuryUpkeepTransactor) PerformUpkeep(opts *bind.TransactOpts, performData []byte) (*types.Transaction, error) {
- return _MercuryUpkeep.contract.Transact(opts, "performUpkeep", performData)
-}
-
-func (_MercuryUpkeep *MercuryUpkeepSession) PerformUpkeep(performData []byte) (*types.Transaction, error) {
- return _MercuryUpkeep.Contract.PerformUpkeep(&_MercuryUpkeep.TransactOpts, performData)
-}
-
-func (_MercuryUpkeep *MercuryUpkeepTransactorSession) PerformUpkeep(performData []byte) (*types.Transaction, error) {
- return _MercuryUpkeep.Contract.PerformUpkeep(&_MercuryUpkeep.TransactOpts, performData)
-}
-
-func (_MercuryUpkeep *MercuryUpkeepTransactor) SetCallbackReturnBool(opts *bind.TransactOpts, value bool) (*types.Transaction, error) {
- return _MercuryUpkeep.contract.Transact(opts, "setCallbackReturnBool", value)
-}
-
-func (_MercuryUpkeep *MercuryUpkeepSession) SetCallbackReturnBool(value bool) (*types.Transaction, error) {
- return _MercuryUpkeep.Contract.SetCallbackReturnBool(&_MercuryUpkeep.TransactOpts, value)
-}
-
-func (_MercuryUpkeep *MercuryUpkeepTransactorSession) SetCallbackReturnBool(value bool) (*types.Transaction, error) {
- return _MercuryUpkeep.Contract.SetCallbackReturnBool(&_MercuryUpkeep.TransactOpts, value)
-}
-
-func (_MercuryUpkeep *MercuryUpkeepTransactor) SetShouldRevertCallback(opts *bind.TransactOpts, value bool) (*types.Transaction, error) {
- return _MercuryUpkeep.contract.Transact(opts, "setShouldRevertCallback", value)
-}
-
-func (_MercuryUpkeep *MercuryUpkeepSession) SetShouldRevertCallback(value bool) (*types.Transaction, error) {
- return _MercuryUpkeep.Contract.SetShouldRevertCallback(&_MercuryUpkeep.TransactOpts, value)
-}
-
-func (_MercuryUpkeep *MercuryUpkeepTransactorSession) SetShouldRevertCallback(value bool) (*types.Transaction, error) {
- return _MercuryUpkeep.Contract.SetShouldRevertCallback(&_MercuryUpkeep.TransactOpts, value)
-}
-
-type MercuryUpkeepMercuryPerformEventIterator struct {
- Event *MercuryUpkeepMercuryPerformEvent
-
- contract *bind.BoundContract
- event string
-
- logs chan types.Log
- sub ethereum.Subscription
- done bool
- fail error
-}
-
-func (it *MercuryUpkeepMercuryPerformEventIterator) Next() bool {
-
- if it.fail != nil {
- return false
- }
-
- if it.done {
- select {
- case log := <-it.logs:
- it.Event = new(MercuryUpkeepMercuryPerformEvent)
- if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
- it.fail = err
- return false
- }
- it.Event.Raw = log
- return true
-
- default:
- return false
- }
- }
-
- select {
- case log := <-it.logs:
- it.Event = new(MercuryUpkeepMercuryPerformEvent)
- if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
- it.fail = err
- return false
- }
- it.Event.Raw = log
- return true
-
- case err := <-it.sub.Err():
- it.done = true
- it.fail = err
- return it.Next()
- }
-}
-
-func (it *MercuryUpkeepMercuryPerformEventIterator) Error() error {
- return it.fail
-}
-
-func (it *MercuryUpkeepMercuryPerformEventIterator) Close() error {
- it.sub.Unsubscribe()
- return nil
-}
-
-type MercuryUpkeepMercuryPerformEvent struct {
- Origin common.Address
- Sender common.Address
- BlockNumber *big.Int
- V0 []byte
- V1 []byte
- Ed []byte
- Raw types.Log
-}
-
-func (_MercuryUpkeep *MercuryUpkeepFilterer) FilterMercuryPerformEvent(opts *bind.FilterOpts, origin []common.Address, sender []common.Address, blockNumber []*big.Int) (*MercuryUpkeepMercuryPerformEventIterator, error) {
-
- var originRule []interface{}
- for _, originItem := range origin {
- originRule = append(originRule, originItem)
- }
- var senderRule []interface{}
- for _, senderItem := range sender {
- senderRule = append(senderRule, senderItem)
- }
- var blockNumberRule []interface{}
- for _, blockNumberItem := range blockNumber {
- blockNumberRule = append(blockNumberRule, blockNumberItem)
- }
-
- logs, sub, err := _MercuryUpkeep.contract.FilterLogs(opts, "MercuryPerformEvent", originRule, senderRule, blockNumberRule)
- if err != nil {
- return nil, err
- }
- return &MercuryUpkeepMercuryPerformEventIterator{contract: _MercuryUpkeep.contract, event: "MercuryPerformEvent", logs: logs, sub: sub}, nil
-}
-
-func (_MercuryUpkeep *MercuryUpkeepFilterer) WatchMercuryPerformEvent(opts *bind.WatchOpts, sink chan<- *MercuryUpkeepMercuryPerformEvent, origin []common.Address, sender []common.Address, blockNumber []*big.Int) (event.Subscription, error) {
-
- var originRule []interface{}
- for _, originItem := range origin {
- originRule = append(originRule, originItem)
- }
- var senderRule []interface{}
- for _, senderItem := range sender {
- senderRule = append(senderRule, senderItem)
- }
- var blockNumberRule []interface{}
- for _, blockNumberItem := range blockNumber {
- blockNumberRule = append(blockNumberRule, blockNumberItem)
- }
-
- logs, sub, err := _MercuryUpkeep.contract.WatchLogs(opts, "MercuryPerformEvent", originRule, senderRule, blockNumberRule)
- if err != nil {
- return nil, err
- }
- return event.NewSubscription(func(quit <-chan struct{}) error {
- defer sub.Unsubscribe()
- for {
- select {
- case log := <-logs:
-
- event := new(MercuryUpkeepMercuryPerformEvent)
- if err := _MercuryUpkeep.contract.UnpackLog(event, "MercuryPerformEvent", log); err != nil {
- return err
- }
- event.Raw = log
-
- select {
- case sink <- event:
- case err := <-sub.Err():
- return err
- case <-quit:
- return nil
- }
- case err := <-sub.Err():
- return err
- case <-quit:
- return nil
- }
- }
- }), nil
-}
-
-func (_MercuryUpkeep *MercuryUpkeepFilterer) ParseMercuryPerformEvent(log types.Log) (*MercuryUpkeepMercuryPerformEvent, error) {
- event := new(MercuryUpkeepMercuryPerformEvent)
- if err := _MercuryUpkeep.contract.UnpackLog(event, "MercuryPerformEvent", log); err != nil {
- return nil, err
- }
- event.Raw = log
- return event, nil
-}
-
-func (_MercuryUpkeep *MercuryUpkeep) ParseLog(log types.Log) (generated.AbigenLog, error) {
- switch log.Topics[0] {
- case _MercuryUpkeep.abi.Events["MercuryPerformEvent"].ID:
- return _MercuryUpkeep.ParseMercuryPerformEvent(log)
-
- default:
- return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0])
- }
-}
-
-func (MercuryUpkeepMercuryPerformEvent) Topic() common.Hash {
- return common.HexToHash("0xec3208363089f292bf230caa1cd39f9dc25d98a341b935d9ebd7a95e2ec82af1")
-}
-
-func (_MercuryUpkeep *MercuryUpkeep) Address() common.Address {
- return _MercuryUpkeep.address
-}
-
-type MercuryUpkeepInterface interface {
- CallbackReturnBool(opts *bind.CallOpts) (bool, error)
-
- CheckCallback(opts *bind.CallOpts, values [][]byte, extraData []byte) (bool, []byte, error)
-
- CheckUpkeep(opts *bind.CallOpts, data []byte) (bool, []byte, error)
-
- Counter(opts *bind.CallOpts) (*big.Int, error)
-
- Eligible(opts *bind.CallOpts) (bool, error)
-
- FeedParamKey(opts *bind.CallOpts) (string, error)
-
- Feeds(opts *bind.CallOpts, arg0 *big.Int) (string, error)
-
- InitialBlock(opts *bind.CallOpts) (*big.Int, error)
-
- Interval(opts *bind.CallOpts) (*big.Int, error)
-
- PreviousPerformBlock(opts *bind.CallOpts) (*big.Int, error)
-
- ShouldRevertCallback(opts *bind.CallOpts) (bool, error)
-
- TestRange(opts *bind.CallOpts) (*big.Int, error)
-
- TimeParamKey(opts *bind.CallOpts) (string, error)
-
- UseL1BlockNumber(opts *bind.CallOpts) (bool, error)
-
- PerformUpkeep(opts *bind.TransactOpts, performData []byte) (*types.Transaction, error)
-
- SetCallbackReturnBool(opts *bind.TransactOpts, value bool) (*types.Transaction, error)
-
- SetShouldRevertCallback(opts *bind.TransactOpts, value bool) (*types.Transaction, error)
-
- FilterMercuryPerformEvent(opts *bind.FilterOpts, origin []common.Address, sender []common.Address, blockNumber []*big.Int) (*MercuryUpkeepMercuryPerformEventIterator, error)
-
- WatchMercuryPerformEvent(opts *bind.WatchOpts, sink chan<- *MercuryUpkeepMercuryPerformEvent, origin []common.Address, sender []common.Address, blockNumber []*big.Int) (event.Subscription, error)
-
- ParseMercuryPerformEvent(log types.Log) (*MercuryUpkeepMercuryPerformEvent, error)
-
- ParseLog(log types.Log) (generated.AbigenLog, error)
-
- Address() common.Address
-}
diff --git a/core/gethwrappers/generated/streams_lookup_compatible_interface/streams_lookup_compatible_interface.go b/core/gethwrappers/generated/streams_lookup_compatible_interface/streams_lookup_compatible_interface.go
new file mode 100644
index 00000000000..41155618774
--- /dev/null
+++ b/core/gethwrappers/generated/streams_lookup_compatible_interface/streams_lookup_compatible_interface.go
@@ -0,0 +1,198 @@
+// Code generated - DO NOT EDIT.
+// This file is a generated binding and any manual changes will be lost.
+
+package streams_lookup_compatible_interface
+
+import (
+ "errors"
+ "math/big"
+ "strings"
+
+ ethereum "github.com/ethereum/go-ethereum"
+ "github.com/ethereum/go-ethereum/accounts/abi"
+ "github.com/ethereum/go-ethereum/accounts/abi/bind"
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/core/types"
+ "github.com/ethereum/go-ethereum/event"
+)
+
+var (
+ _ = errors.New
+ _ = big.NewInt
+ _ = strings.NewReader
+ _ = ethereum.NotFound
+ _ = bind.Bind
+ _ = common.Big1
+ _ = types.BloomLookup
+ _ = event.NewSubscription
+ _ = abi.ConvertType
+)
+
+var StreamsLookupCompatibleInterfaceMetaData = &bind.MetaData{
+ ABI: "[{\"inputs\":[{\"internalType\":\"string\",\"name\":\"feedParamKey\",\"type\":\"string\"},{\"internalType\":\"string[]\",\"name\":\"feeds\",\"type\":\"string[]\"},{\"internalType\":\"string\",\"name\":\"timeParamKey\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"time\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"StreamsLookup\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes[]\",\"name\":\"values\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"checkCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"upkeepNeeded\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]",
+}
+
+var StreamsLookupCompatibleInterfaceABI = StreamsLookupCompatibleInterfaceMetaData.ABI
+
+type StreamsLookupCompatibleInterface struct {
+ address common.Address
+ abi abi.ABI
+ StreamsLookupCompatibleInterfaceCaller
+ StreamsLookupCompatibleInterfaceTransactor
+ StreamsLookupCompatibleInterfaceFilterer
+}
+
+type StreamsLookupCompatibleInterfaceCaller struct {
+ contract *bind.BoundContract
+}
+
+type StreamsLookupCompatibleInterfaceTransactor struct {
+ contract *bind.BoundContract
+}
+
+type StreamsLookupCompatibleInterfaceFilterer struct {
+ contract *bind.BoundContract
+}
+
+type StreamsLookupCompatibleInterfaceSession struct {
+ Contract *StreamsLookupCompatibleInterface
+ CallOpts bind.CallOpts
+ TransactOpts bind.TransactOpts
+}
+
+type StreamsLookupCompatibleInterfaceCallerSession struct {
+ Contract *StreamsLookupCompatibleInterfaceCaller
+ CallOpts bind.CallOpts
+}
+
+type StreamsLookupCompatibleInterfaceTransactorSession struct {
+ Contract *StreamsLookupCompatibleInterfaceTransactor
+ TransactOpts bind.TransactOpts
+}
+
+type StreamsLookupCompatibleInterfaceRaw struct {
+ Contract *StreamsLookupCompatibleInterface
+}
+
+type StreamsLookupCompatibleInterfaceCallerRaw struct {
+ Contract *StreamsLookupCompatibleInterfaceCaller
+}
+
+type StreamsLookupCompatibleInterfaceTransactorRaw struct {
+ Contract *StreamsLookupCompatibleInterfaceTransactor
+}
+
+func NewStreamsLookupCompatibleInterface(address common.Address, backend bind.ContractBackend) (*StreamsLookupCompatibleInterface, error) {
+ abi, err := abi.JSON(strings.NewReader(StreamsLookupCompatibleInterfaceABI))
+ if err != nil {
+ return nil, err
+ }
+ contract, err := bindStreamsLookupCompatibleInterface(address, backend, backend, backend)
+ if err != nil {
+ return nil, err
+ }
+ return &StreamsLookupCompatibleInterface{address: address, abi: abi, StreamsLookupCompatibleInterfaceCaller: StreamsLookupCompatibleInterfaceCaller{contract: contract}, StreamsLookupCompatibleInterfaceTransactor: StreamsLookupCompatibleInterfaceTransactor{contract: contract}, StreamsLookupCompatibleInterfaceFilterer: StreamsLookupCompatibleInterfaceFilterer{contract: contract}}, nil
+}
+
+func NewStreamsLookupCompatibleInterfaceCaller(address common.Address, caller bind.ContractCaller) (*StreamsLookupCompatibleInterfaceCaller, error) {
+ contract, err := bindStreamsLookupCompatibleInterface(address, caller, nil, nil)
+ if err != nil {
+ return nil, err
+ }
+ return &StreamsLookupCompatibleInterfaceCaller{contract: contract}, nil
+}
+
+func NewStreamsLookupCompatibleInterfaceTransactor(address common.Address, transactor bind.ContractTransactor) (*StreamsLookupCompatibleInterfaceTransactor, error) {
+ contract, err := bindStreamsLookupCompatibleInterface(address, nil, transactor, nil)
+ if err != nil {
+ return nil, err
+ }
+ return &StreamsLookupCompatibleInterfaceTransactor{contract: contract}, nil
+}
+
+func NewStreamsLookupCompatibleInterfaceFilterer(address common.Address, filterer bind.ContractFilterer) (*StreamsLookupCompatibleInterfaceFilterer, error) {
+ contract, err := bindStreamsLookupCompatibleInterface(address, nil, nil, filterer)
+ if err != nil {
+ return nil, err
+ }
+ return &StreamsLookupCompatibleInterfaceFilterer{contract: contract}, nil
+}
+
+func bindStreamsLookupCompatibleInterface(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) {
+ parsed, err := StreamsLookupCompatibleInterfaceMetaData.GetAbi()
+ if err != nil {
+ return nil, err
+ }
+ return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil
+}
+
+func (_StreamsLookupCompatibleInterface *StreamsLookupCompatibleInterfaceRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
+ return _StreamsLookupCompatibleInterface.Contract.StreamsLookupCompatibleInterfaceCaller.contract.Call(opts, result, method, params...)
+}
+
+func (_StreamsLookupCompatibleInterface *StreamsLookupCompatibleInterfaceRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _StreamsLookupCompatibleInterface.Contract.StreamsLookupCompatibleInterfaceTransactor.contract.Transfer(opts)
+}
+
+func (_StreamsLookupCompatibleInterface *StreamsLookupCompatibleInterfaceRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+ return _StreamsLookupCompatibleInterface.Contract.StreamsLookupCompatibleInterfaceTransactor.contract.Transact(opts, method, params...)
+}
+
+func (_StreamsLookupCompatibleInterface *StreamsLookupCompatibleInterfaceCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
+ return _StreamsLookupCompatibleInterface.Contract.contract.Call(opts, result, method, params...)
+}
+
+func (_StreamsLookupCompatibleInterface *StreamsLookupCompatibleInterfaceTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _StreamsLookupCompatibleInterface.Contract.contract.Transfer(opts)
+}
+
+func (_StreamsLookupCompatibleInterface *StreamsLookupCompatibleInterfaceTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+ return _StreamsLookupCompatibleInterface.Contract.contract.Transact(opts, method, params...)
+}
+
+func (_StreamsLookupCompatibleInterface *StreamsLookupCompatibleInterfaceCaller) CheckCallback(opts *bind.CallOpts, values [][]byte, extraData []byte) (CheckCallback,
+
+ error) {
+ var out []interface{}
+ err := _StreamsLookupCompatibleInterface.contract.Call(opts, &out, "checkCallback", values, extraData)
+
+ outstruct := new(CheckCallback)
+ if err != nil {
+ return *outstruct, err
+ }
+
+ outstruct.UpkeepNeeded = *abi.ConvertType(out[0], new(bool)).(*bool)
+ outstruct.PerformData = *abi.ConvertType(out[1], new([]byte)).(*[]byte)
+
+ return *outstruct, err
+
+}
+
+func (_StreamsLookupCompatibleInterface *StreamsLookupCompatibleInterfaceSession) CheckCallback(values [][]byte, extraData []byte) (CheckCallback,
+
+ error) {
+ return _StreamsLookupCompatibleInterface.Contract.CheckCallback(&_StreamsLookupCompatibleInterface.CallOpts, values, extraData)
+}
+
+func (_StreamsLookupCompatibleInterface *StreamsLookupCompatibleInterfaceCallerSession) CheckCallback(values [][]byte, extraData []byte) (CheckCallback,
+
+ error) {
+ return _StreamsLookupCompatibleInterface.Contract.CheckCallback(&_StreamsLookupCompatibleInterface.CallOpts, values, extraData)
+}
+
+type CheckCallback struct {
+ UpkeepNeeded bool
+ PerformData []byte
+}
+
+func (_StreamsLookupCompatibleInterface *StreamsLookupCompatibleInterface) Address() common.Address {
+ return _StreamsLookupCompatibleInterface.address
+}
+
+type StreamsLookupCompatibleInterfaceInterface interface {
+ CheckCallback(opts *bind.CallOpts, values [][]byte, extraData []byte) (CheckCallback,
+
+ error)
+
+ Address() common.Address
+}
diff --git a/core/gethwrappers/generated/streams_lookup_upkeep_wrapper/streams_lookup_upkeep_wrapper.go b/core/gethwrappers/generated/streams_lookup_upkeep_wrapper/streams_lookup_upkeep_wrapper.go
new file mode 100644
index 00000000000..3332ac8215e
--- /dev/null
+++ b/core/gethwrappers/generated/streams_lookup_upkeep_wrapper/streams_lookup_upkeep_wrapper.go
@@ -0,0 +1,811 @@
+// Code generated - DO NOT EDIT.
+// This file is a generated binding and any manual changes will be lost.
+
+package streams_lookup_upkeep_wrapper
+
+import (
+ "errors"
+ "fmt"
+ "math/big"
+ "strings"
+
+ ethereum "github.com/ethereum/go-ethereum"
+ "github.com/ethereum/go-ethereum/accounts/abi"
+ "github.com/ethereum/go-ethereum/accounts/abi/bind"
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/core/types"
+ "github.com/ethereum/go-ethereum/event"
+ "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated"
+)
+
+var (
+ _ = errors.New
+ _ = big.NewInt
+ _ = strings.NewReader
+ _ = ethereum.NotFound
+ _ = bind.Bind
+ _ = common.Big1
+ _ = types.BloomLookup
+ _ = event.NewSubscription
+ _ = abi.ConvertType
+)
+
+var StreamsLookupUpkeepMetaData = &bind.MetaData{
+ ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_testRange\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_interval\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"_useArbBlock\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"_staging\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"_verify\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"feedParamKey\",\"type\":\"string\"},{\"internalType\":\"string[]\",\"name\":\"feeds\",\"type\":\"string[]\"},{\"internalType\":\"string\",\"name\":\"timeParamKey\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"time\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"StreamsLookup\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"v0\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"verifiedV0\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"ed\",\"type\":\"bytes\"}],\"name\":\"MercuryPerformEvent\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"callbackReturnBool\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes[]\",\"name\":\"values\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"checkCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"checkUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"counter\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"eligible\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"feedParamKey\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"feeds\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initialBlock\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"interval\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"}],\"name\":\"performUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"previousPerformBlock\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"reset\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"value\",\"type\":\"bool\"}],\"name\":\"setCallbackReturnBool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string[]\",\"name\":\"_feeds\",\"type\":\"string[]\"}],\"name\":\"setFeeds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_feedParamKey\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_timeParamKey\",\"type\":\"string\"}],\"name\":\"setParamKeys\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"value\",\"type\":\"bool\"}],\"name\":\"setShouldRevertCallback\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"shouldRevertCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"staging\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"testRange\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"timeParamKey\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"useArbBlock\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]",
+ Bin: "0x60a06040523480156200001157600080fd5b5060405162001a6a38038062001a6a83398101604081905262000034916200020f565b60008581556001859055600281905560038190556004558215156080526040805180820190915260078152666665656449447360c81b60208201526006906200007e908262000312565b50604080518082019091526009815268074696d657374616d760bc1b6020820152600790620000ae908262000312565b50604051806020016040528060405180608001604052806042815260200162001a28604291399052620000e690600590600162000122565b506008805463ff000000199215156101000261ff00199415159490941661ffff19909116179290921716630100000017905550620003de915050565b8280548282559060005260206000209081019282156200016d579160200282015b828111156200016d57825182906200015c908262000312565b509160200191906001019062000143565b506200017b9291506200017f565b5090565b808211156200017b576000620001968282620001a0565b506001016200017f565b508054620001ae9062000283565b6000825580601f10620001bf575050565b601f016020900490600052602060002090810190620001df9190620001e2565b50565b5b808211156200017b5760008155600101620001e3565b805180151581146200020a57600080fd5b919050565b600080600080600060a086880312156200022857600080fd5b85519450602086015193506200024160408701620001f9565b92506200025160608701620001f9565b91506200026160808701620001f9565b90509295509295909350565b634e487b7160e01b600052604160045260246000fd5b600181811c908216806200029857607f821691505b602082108103620002b957634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200030d57600081815260208120601f850160051c81016020861015620002e85750805b601f850160051c820191505b818110156200030957828155600101620002f4565b5050505b505050565b81516001600160401b038111156200032e576200032e6200026d565b62000346816200033f845462000283565b84620002bf565b602080601f8311600181146200037e5760008415620003655750858301515b600019600386901b1c1916600185901b17855562000309565b600085815260208120601f198616915b82811015620003af578886015182559484019460019091019084016200038e565b5085821015620003ce5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6080516116196200040f60003960008181610307015281816103900152818161090c0152610a7b01526116196000f3fe608060405234801561001057600080fd5b50600436106101825760003560e01c80636e04ff0d116100d8578063947a36fb1161008c578063d826f88f11610066578063d826f88f1461035e578063d832d92f14610372578063fc735e991461037a57600080fd5b8063947a36fb14610345578063afb28d1f1461034e578063c98f10b01461035657600080fd5b806386b728e2116100bd57806386b728e21461030257806386e330af14610329578063917d895f1461033c57600080fd5b80636e04ff0d146102dc5780638340507c146102ef57600080fd5b80634a5479f31161013a5780635b48391a116101145780635b48391a1461028357806361bc221a146102ca5780636250a13a146102d357600080fd5b80634a5479f3146101fc5780634b56a42e1461021c5780634bdb38621461023d57600080fd5b80631d1970b71161016b5780631d1970b7146101c35780632cb15864146101d05780634585e33b146101e757600080fd5b806302be021f14610187578063102d538b146101af575b600080fd5b60085461019a9062010000900460ff1681565b60405190151581526020015b60405180910390f35b60085461019a906301000000900460ff1681565b60085461019a9060ff1681565b6101d960035481565b6040519081526020016101a6565b6101fa6101f5366004610c0f565b61038c565b005b61020f61020a366004610c81565b6106b9565b6040516101a69190610d08565b61022f61022a366004610e60565b610765565b6040516101a6929190610f34565b6101fa61024b366004610f57565b6008805491151562010000027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff909216919091179055565b6101fa610291366004610f57565b600880549115156301000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffff909216919091179055565b6101d960045481565b6101d960005481565b61022f6102ea366004610c0f565b610840565b6101fa6102fd366004610f79565b610a16565b61019a7f000000000000000000000000000000000000000000000000000000000000000081565b6101fa610337366004610fc6565b610a34565b6101d960025481565b6101d960015481565b61020f610a4b565b61020f610a58565b6101fa600060028190556003819055600455565b61019a610a65565b60085461019a90610100900460ff1681565b60007f00000000000000000000000000000000000000000000000000000000000000001561042b57606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610400573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104249190611077565b905061042e565b50435b60035460000361043e5760038190555b60008061044d84860186610e60565b600285905560045491935091506104659060016110bf565b600455604080516020808201835260008083528351918201909352918252600854909190610100900460ff16156106435760085460ff1615610574577360448b880c9f3b501af3f343da9284148bd7d77c73ffffffffffffffffffffffffffffffffffffffff16638e760afe856000815181106104e4576104e46110d8565b60200260200101516040518263ffffffff1660e01b81526004016105089190610d08565b6000604051808303816000875af1158015610527573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261056d9190810190611107565b9150610643565b7309dff56a4ff44e0f4436260a04f5cfa65636a48173ffffffffffffffffffffffffffffffffffffffff16638e760afe856000815181106105b7576105b76110d8565b60200260200101516040518263ffffffff1660e01b81526004016105db9190610d08565b6000604051808303816000875af11580156105fa573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526106409190810190611107565b91505b843373ffffffffffffffffffffffffffffffffffffffff167ff0f72c0b235fc8687d6a67c02ca543473a3cef8a18b48490f10e475a8dda13908660008151811061068f5761068f6110d8565b602002602001015185876040516106a89392919061117e565b60405180910390a350505050505050565b600581815481106106c957600080fd5b9060005260206000200160009150905080546106e4906111c1565b80601f0160208091040260200160405190810160405280929190818152602001828054610710906111c1565b801561075d5780601f106107325761010080835404028352916020019161075d565b820191906000526020600020905b81548152906001019060200180831161074057829003601f168201915b505050505081565b60085460009060609062010000900460ff16156107e3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f73686f756c6452657665727443616c6c6261636b20697320747275650000000060448201526064015b60405180910390fd5b600084846040516020016107f8929190611214565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00181529190526008546301000000900460ff1693509150505b9250929050565b6000606061084c610a65565b610898576000848481818080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250959750919550610839945050505050565b6040517f666565644964486578000000000000000000000000000000000000000000000060208201526000906029016040516020818303038152906040528051906020012060066040516020016108ef919061129f565b60405160208183030381529060405280519060200120036109ae577f0000000000000000000000000000000000000000000000000000000000000000156109a757606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561097c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109a09190611077565b90506109b1565b50436109b1565b50425b604080516c6400000000000000000000000060208201528151601481830301815260348201928390527ff055e4a2000000000000000000000000000000000000000000000000000000009092526107da916006916005916007918691906038016113ce565b6006610a2283826114df565b506007610a2f82826114df565b505050565b8051610a47906005906020840190610b4a565b5050565b600680546106e4906111c1565b600780546106e4906111c1565b6000600354600003610a775750600190565b60007f000000000000000000000000000000000000000000000000000000000000000015610b1657606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610aeb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b0f9190611077565b9050610b19565b50435b600054600354610b2990836115f9565b108015610b445750600154600254610b4190836115f9565b10155b91505090565b828054828255906000526020600020908101928215610b90579160200282015b82811115610b905782518290610b8090826114df565b5091602001919060010190610b6a565b50610b9c929150610ba0565b5090565b80821115610b9c576000610bb48282610bbd565b50600101610ba0565b508054610bc9906111c1565b6000825580601f10610bd9575050565b601f016020900490600052602060002090810190610bf79190610bfa565b50565b5b80821115610b9c5760008155600101610bfb565b60008060208385031215610c2257600080fd5b823567ffffffffffffffff80821115610c3a57600080fd5b818501915085601f830112610c4e57600080fd5b813581811115610c5d57600080fd5b866020828501011115610c6f57600080fd5b60209290920196919550909350505050565b600060208284031215610c9357600080fd5b5035919050565b60005b83811015610cb5578181015183820152602001610c9d565b50506000910152565b60008151808452610cd6816020860160208601610c9a565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610d1b6020830184610cbe565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610d9857610d98610d22565b604052919050565b600067ffffffffffffffff821115610dba57610dba610d22565b5060051b60200190565b600067ffffffffffffffff821115610dde57610dde610d22565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f830112610e1b57600080fd5b8135610e2e610e2982610dc4565b610d51565b818152846020838601011115610e4357600080fd5b816020850160208301376000918101602001919091529392505050565b60008060408385031215610e7357600080fd5b823567ffffffffffffffff80821115610e8b57600080fd5b818501915085601f830112610e9f57600080fd5b81356020610eaf610e2983610da0565b82815260059290921b84018101918181019089841115610ece57600080fd5b8286015b84811015610f0657803586811115610eea5760008081fd5b610ef88c86838b0101610e0a565b845250918301918301610ed2565b5096505086013592505080821115610f1d57600080fd5b50610f2a85828601610e0a565b9150509250929050565b8215158152604060208201526000610f4f6040830184610cbe565b949350505050565b600060208284031215610f6957600080fd5b81358015158114610d1b57600080fd5b60008060408385031215610f8c57600080fd5b823567ffffffffffffffff80821115610fa457600080fd5b610fb086838701610e0a565b93506020850135915080821115610f1d57600080fd5b60006020808385031215610fd957600080fd5b823567ffffffffffffffff80821115610ff157600080fd5b818501915085601f83011261100557600080fd5b8135611013610e2982610da0565b81815260059190911b8301840190848101908883111561103257600080fd5b8585015b8381101561106a5780358581111561104e5760008081fd5b61105c8b89838a0101610e0a565b845250918601918601611036565b5098975050505050505050565b60006020828403121561108957600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808201808211156110d2576110d2611090565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561111957600080fd5b815167ffffffffffffffff81111561113057600080fd5b8201601f8101841361114157600080fd5b805161114f610e2982610dc4565b81815285602083850101111561116457600080fd5b611175826020830160208601610c9a565b95945050505050565b6060815260006111916060830186610cbe565b82810360208401526111a38186610cbe565b905082810360408401526111b78185610cbe565b9695505050505050565b600181811c908216806111d557607f821691505b60208210810361120e577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b6000604082016040835280855180835260608501915060608160051b8601019250602080880160005b83811015611289577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0888703018552611277868351610cbe565b9550938201939082019060010161123d565b5050858403818701525050506111758185610cbe565b60008083546112ad816111c1565b600182811680156112c557600181146112f857611327565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0084168752821515830287019450611327565b8760005260208060002060005b8581101561131e5781548a820152908401908201611305565b50505082870194505b50929695505050505050565b60008154611340816111c1565b80855260206001838116801561135d5760018114611395576113c3565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008516838901528284151560051b89010195506113c3565b866000528260002060005b858110156113bb5781548a82018601529083019084016113a0565b890184019650505b505050505092915050565b60a0815260006113e160a0830188611333565b6020838203818501528188548084528284019150828160051b8501018a6000528360002060005b83811015611453577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08784030185526114418383611333565b94860194925060019182019101611408565b50508681036040880152611467818b611333565b94505050505084606084015282810360808401526114858185610cbe565b98975050505050505050565b601f821115610a2f57600081815260208120601f850160051c810160208610156114b85750805b601f850160051c820191505b818110156114d7578281556001016114c4565b505050505050565b815167ffffffffffffffff8111156114f9576114f9610d22565b61150d8161150784546111c1565b84611491565b602080601f831160018114611560576000841561152a5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556114d7565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156115ad5788860151825594840194600190910190840161158e565b50858210156115e957878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b818103818111156110d2576110d261109056fea164736f6c6343000810000a307830303032386339313564366166306664363662626132643066633934303532323662636138643638303633333331323161376439383332313033643135363363",
+}
+
+var StreamsLookupUpkeepABI = StreamsLookupUpkeepMetaData.ABI
+
+var StreamsLookupUpkeepBin = StreamsLookupUpkeepMetaData.Bin
+
+func DeployStreamsLookupUpkeep(auth *bind.TransactOpts, backend bind.ContractBackend, _testRange *big.Int, _interval *big.Int, _useArbBlock bool, _staging bool, _verify bool) (common.Address, *types.Transaction, *StreamsLookupUpkeep, error) {
+ parsed, err := StreamsLookupUpkeepMetaData.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(StreamsLookupUpkeepBin), backend, _testRange, _interval, _useArbBlock, _staging, _verify)
+ if err != nil {
+ return common.Address{}, nil, nil, err
+ }
+ return address, tx, &StreamsLookupUpkeep{StreamsLookupUpkeepCaller: StreamsLookupUpkeepCaller{contract: contract}, StreamsLookupUpkeepTransactor: StreamsLookupUpkeepTransactor{contract: contract}, StreamsLookupUpkeepFilterer: StreamsLookupUpkeepFilterer{contract: contract}}, nil
+}
+
+type StreamsLookupUpkeep struct {
+ address common.Address
+ abi abi.ABI
+ StreamsLookupUpkeepCaller
+ StreamsLookupUpkeepTransactor
+ StreamsLookupUpkeepFilterer
+}
+
+type StreamsLookupUpkeepCaller struct {
+ contract *bind.BoundContract
+}
+
+type StreamsLookupUpkeepTransactor struct {
+ contract *bind.BoundContract
+}
+
+type StreamsLookupUpkeepFilterer struct {
+ contract *bind.BoundContract
+}
+
+type StreamsLookupUpkeepSession struct {
+ Contract *StreamsLookupUpkeep
+ CallOpts bind.CallOpts
+ TransactOpts bind.TransactOpts
+}
+
+type StreamsLookupUpkeepCallerSession struct {
+ Contract *StreamsLookupUpkeepCaller
+ CallOpts bind.CallOpts
+}
+
+type StreamsLookupUpkeepTransactorSession struct {
+ Contract *StreamsLookupUpkeepTransactor
+ TransactOpts bind.TransactOpts
+}
+
+type StreamsLookupUpkeepRaw struct {
+ Contract *StreamsLookupUpkeep
+}
+
+type StreamsLookupUpkeepCallerRaw struct {
+ Contract *StreamsLookupUpkeepCaller
+}
+
+type StreamsLookupUpkeepTransactorRaw struct {
+ Contract *StreamsLookupUpkeepTransactor
+}
+
+func NewStreamsLookupUpkeep(address common.Address, backend bind.ContractBackend) (*StreamsLookupUpkeep, error) {
+ abi, err := abi.JSON(strings.NewReader(StreamsLookupUpkeepABI))
+ if err != nil {
+ return nil, err
+ }
+ contract, err := bindStreamsLookupUpkeep(address, backend, backend, backend)
+ if err != nil {
+ return nil, err
+ }
+ return &StreamsLookupUpkeep{address: address, abi: abi, StreamsLookupUpkeepCaller: StreamsLookupUpkeepCaller{contract: contract}, StreamsLookupUpkeepTransactor: StreamsLookupUpkeepTransactor{contract: contract}, StreamsLookupUpkeepFilterer: StreamsLookupUpkeepFilterer{contract: contract}}, nil
+}
+
+func NewStreamsLookupUpkeepCaller(address common.Address, caller bind.ContractCaller) (*StreamsLookupUpkeepCaller, error) {
+ contract, err := bindStreamsLookupUpkeep(address, caller, nil, nil)
+ if err != nil {
+ return nil, err
+ }
+ return &StreamsLookupUpkeepCaller{contract: contract}, nil
+}
+
+func NewStreamsLookupUpkeepTransactor(address common.Address, transactor bind.ContractTransactor) (*StreamsLookupUpkeepTransactor, error) {
+ contract, err := bindStreamsLookupUpkeep(address, nil, transactor, nil)
+ if err != nil {
+ return nil, err
+ }
+ return &StreamsLookupUpkeepTransactor{contract: contract}, nil
+}
+
+func NewStreamsLookupUpkeepFilterer(address common.Address, filterer bind.ContractFilterer) (*StreamsLookupUpkeepFilterer, error) {
+ contract, err := bindStreamsLookupUpkeep(address, nil, nil, filterer)
+ if err != nil {
+ return nil, err
+ }
+ return &StreamsLookupUpkeepFilterer{contract: contract}, nil
+}
+
+func bindStreamsLookupUpkeep(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) {
+ parsed, err := StreamsLookupUpkeepMetaData.GetAbi()
+ if err != nil {
+ return nil, err
+ }
+ return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
+ return _StreamsLookupUpkeep.Contract.StreamsLookupUpkeepCaller.contract.Call(opts, result, method, params...)
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _StreamsLookupUpkeep.Contract.StreamsLookupUpkeepTransactor.contract.Transfer(opts)
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+ return _StreamsLookupUpkeep.Contract.StreamsLookupUpkeepTransactor.contract.Transact(opts, method, params...)
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
+ return _StreamsLookupUpkeep.Contract.contract.Call(opts, result, method, params...)
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _StreamsLookupUpkeep.Contract.contract.Transfer(opts)
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+ return _StreamsLookupUpkeep.Contract.contract.Transact(opts, method, params...)
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepCaller) CallbackReturnBool(opts *bind.CallOpts) (bool, error) {
+ var out []interface{}
+ err := _StreamsLookupUpkeep.contract.Call(opts, &out, "callbackReturnBool")
+
+ if err != nil {
+ return *new(bool), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(bool)).(*bool)
+
+ return out0, err
+
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepSession) CallbackReturnBool() (bool, error) {
+ return _StreamsLookupUpkeep.Contract.CallbackReturnBool(&_StreamsLookupUpkeep.CallOpts)
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepCallerSession) CallbackReturnBool() (bool, error) {
+ return _StreamsLookupUpkeep.Contract.CallbackReturnBool(&_StreamsLookupUpkeep.CallOpts)
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepCaller) CheckCallback(opts *bind.CallOpts, values [][]byte, extraData []byte) (bool, []byte, error) {
+ var out []interface{}
+ err := _StreamsLookupUpkeep.contract.Call(opts, &out, "checkCallback", values, extraData)
+
+ if err != nil {
+ return *new(bool), *new([]byte), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(bool)).(*bool)
+ out1 := *abi.ConvertType(out[1], new([]byte)).(*[]byte)
+
+ return out0, out1, err
+
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepSession) CheckCallback(values [][]byte, extraData []byte) (bool, []byte, error) {
+ return _StreamsLookupUpkeep.Contract.CheckCallback(&_StreamsLookupUpkeep.CallOpts, values, extraData)
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepCallerSession) CheckCallback(values [][]byte, extraData []byte) (bool, []byte, error) {
+ return _StreamsLookupUpkeep.Contract.CheckCallback(&_StreamsLookupUpkeep.CallOpts, values, extraData)
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepCaller) CheckUpkeep(opts *bind.CallOpts, data []byte) (bool, []byte, error) {
+ var out []interface{}
+ err := _StreamsLookupUpkeep.contract.Call(opts, &out, "checkUpkeep", data)
+
+ if err != nil {
+ return *new(bool), *new([]byte), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(bool)).(*bool)
+ out1 := *abi.ConvertType(out[1], new([]byte)).(*[]byte)
+
+ return out0, out1, err
+
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepSession) CheckUpkeep(data []byte) (bool, []byte, error) {
+ return _StreamsLookupUpkeep.Contract.CheckUpkeep(&_StreamsLookupUpkeep.CallOpts, data)
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepCallerSession) CheckUpkeep(data []byte) (bool, []byte, error) {
+ return _StreamsLookupUpkeep.Contract.CheckUpkeep(&_StreamsLookupUpkeep.CallOpts, data)
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepCaller) Counter(opts *bind.CallOpts) (*big.Int, error) {
+ var out []interface{}
+ err := _StreamsLookupUpkeep.contract.Call(opts, &out, "counter")
+
+ if err != nil {
+ return *new(*big.Int), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
+
+ return out0, err
+
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepSession) Counter() (*big.Int, error) {
+ return _StreamsLookupUpkeep.Contract.Counter(&_StreamsLookupUpkeep.CallOpts)
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepCallerSession) Counter() (*big.Int, error) {
+ return _StreamsLookupUpkeep.Contract.Counter(&_StreamsLookupUpkeep.CallOpts)
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepCaller) Eligible(opts *bind.CallOpts) (bool, error) {
+ var out []interface{}
+ err := _StreamsLookupUpkeep.contract.Call(opts, &out, "eligible")
+
+ if err != nil {
+ return *new(bool), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(bool)).(*bool)
+
+ return out0, err
+
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepSession) Eligible() (bool, error) {
+ return _StreamsLookupUpkeep.Contract.Eligible(&_StreamsLookupUpkeep.CallOpts)
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepCallerSession) Eligible() (bool, error) {
+ return _StreamsLookupUpkeep.Contract.Eligible(&_StreamsLookupUpkeep.CallOpts)
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepCaller) FeedParamKey(opts *bind.CallOpts) (string, error) {
+ var out []interface{}
+ err := _StreamsLookupUpkeep.contract.Call(opts, &out, "feedParamKey")
+
+ if err != nil {
+ return *new(string), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(string)).(*string)
+
+ return out0, err
+
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepSession) FeedParamKey() (string, error) {
+ return _StreamsLookupUpkeep.Contract.FeedParamKey(&_StreamsLookupUpkeep.CallOpts)
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepCallerSession) FeedParamKey() (string, error) {
+ return _StreamsLookupUpkeep.Contract.FeedParamKey(&_StreamsLookupUpkeep.CallOpts)
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepCaller) Feeds(opts *bind.CallOpts, arg0 *big.Int) (string, error) {
+ var out []interface{}
+ err := _StreamsLookupUpkeep.contract.Call(opts, &out, "feeds", arg0)
+
+ if err != nil {
+ return *new(string), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(string)).(*string)
+
+ return out0, err
+
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepSession) Feeds(arg0 *big.Int) (string, error) {
+ return _StreamsLookupUpkeep.Contract.Feeds(&_StreamsLookupUpkeep.CallOpts, arg0)
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepCallerSession) Feeds(arg0 *big.Int) (string, error) {
+ return _StreamsLookupUpkeep.Contract.Feeds(&_StreamsLookupUpkeep.CallOpts, arg0)
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepCaller) InitialBlock(opts *bind.CallOpts) (*big.Int, error) {
+ var out []interface{}
+ err := _StreamsLookupUpkeep.contract.Call(opts, &out, "initialBlock")
+
+ if err != nil {
+ return *new(*big.Int), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
+
+ return out0, err
+
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepSession) InitialBlock() (*big.Int, error) {
+ return _StreamsLookupUpkeep.Contract.InitialBlock(&_StreamsLookupUpkeep.CallOpts)
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepCallerSession) InitialBlock() (*big.Int, error) {
+ return _StreamsLookupUpkeep.Contract.InitialBlock(&_StreamsLookupUpkeep.CallOpts)
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepCaller) Interval(opts *bind.CallOpts) (*big.Int, error) {
+ var out []interface{}
+ err := _StreamsLookupUpkeep.contract.Call(opts, &out, "interval")
+
+ if err != nil {
+ return *new(*big.Int), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
+
+ return out0, err
+
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepSession) Interval() (*big.Int, error) {
+ return _StreamsLookupUpkeep.Contract.Interval(&_StreamsLookupUpkeep.CallOpts)
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepCallerSession) Interval() (*big.Int, error) {
+ return _StreamsLookupUpkeep.Contract.Interval(&_StreamsLookupUpkeep.CallOpts)
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepCaller) PreviousPerformBlock(opts *bind.CallOpts) (*big.Int, error) {
+ var out []interface{}
+ err := _StreamsLookupUpkeep.contract.Call(opts, &out, "previousPerformBlock")
+
+ if err != nil {
+ return *new(*big.Int), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
+
+ return out0, err
+
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepSession) PreviousPerformBlock() (*big.Int, error) {
+ return _StreamsLookupUpkeep.Contract.PreviousPerformBlock(&_StreamsLookupUpkeep.CallOpts)
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepCallerSession) PreviousPerformBlock() (*big.Int, error) {
+ return _StreamsLookupUpkeep.Contract.PreviousPerformBlock(&_StreamsLookupUpkeep.CallOpts)
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepCaller) ShouldRevertCallback(opts *bind.CallOpts) (bool, error) {
+ var out []interface{}
+ err := _StreamsLookupUpkeep.contract.Call(opts, &out, "shouldRevertCallback")
+
+ if err != nil {
+ return *new(bool), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(bool)).(*bool)
+
+ return out0, err
+
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepSession) ShouldRevertCallback() (bool, error) {
+ return _StreamsLookupUpkeep.Contract.ShouldRevertCallback(&_StreamsLookupUpkeep.CallOpts)
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepCallerSession) ShouldRevertCallback() (bool, error) {
+ return _StreamsLookupUpkeep.Contract.ShouldRevertCallback(&_StreamsLookupUpkeep.CallOpts)
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepCaller) Staging(opts *bind.CallOpts) (bool, error) {
+ var out []interface{}
+ err := _StreamsLookupUpkeep.contract.Call(opts, &out, "staging")
+
+ if err != nil {
+ return *new(bool), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(bool)).(*bool)
+
+ return out0, err
+
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepSession) Staging() (bool, error) {
+ return _StreamsLookupUpkeep.Contract.Staging(&_StreamsLookupUpkeep.CallOpts)
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepCallerSession) Staging() (bool, error) {
+ return _StreamsLookupUpkeep.Contract.Staging(&_StreamsLookupUpkeep.CallOpts)
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepCaller) TestRange(opts *bind.CallOpts) (*big.Int, error) {
+ var out []interface{}
+ err := _StreamsLookupUpkeep.contract.Call(opts, &out, "testRange")
+
+ if err != nil {
+ return *new(*big.Int), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
+
+ return out0, err
+
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepSession) TestRange() (*big.Int, error) {
+ return _StreamsLookupUpkeep.Contract.TestRange(&_StreamsLookupUpkeep.CallOpts)
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepCallerSession) TestRange() (*big.Int, error) {
+ return _StreamsLookupUpkeep.Contract.TestRange(&_StreamsLookupUpkeep.CallOpts)
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepCaller) TimeParamKey(opts *bind.CallOpts) (string, error) {
+ var out []interface{}
+ err := _StreamsLookupUpkeep.contract.Call(opts, &out, "timeParamKey")
+
+ if err != nil {
+ return *new(string), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(string)).(*string)
+
+ return out0, err
+
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepSession) TimeParamKey() (string, error) {
+ return _StreamsLookupUpkeep.Contract.TimeParamKey(&_StreamsLookupUpkeep.CallOpts)
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepCallerSession) TimeParamKey() (string, error) {
+ return _StreamsLookupUpkeep.Contract.TimeParamKey(&_StreamsLookupUpkeep.CallOpts)
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepCaller) UseArbBlock(opts *bind.CallOpts) (bool, error) {
+ var out []interface{}
+ err := _StreamsLookupUpkeep.contract.Call(opts, &out, "useArbBlock")
+
+ if err != nil {
+ return *new(bool), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(bool)).(*bool)
+
+ return out0, err
+
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepSession) UseArbBlock() (bool, error) {
+ return _StreamsLookupUpkeep.Contract.UseArbBlock(&_StreamsLookupUpkeep.CallOpts)
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepCallerSession) UseArbBlock() (bool, error) {
+ return _StreamsLookupUpkeep.Contract.UseArbBlock(&_StreamsLookupUpkeep.CallOpts)
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepCaller) Verify(opts *bind.CallOpts) (bool, error) {
+ var out []interface{}
+ err := _StreamsLookupUpkeep.contract.Call(opts, &out, "verify")
+
+ if err != nil {
+ return *new(bool), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(bool)).(*bool)
+
+ return out0, err
+
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepSession) Verify() (bool, error) {
+ return _StreamsLookupUpkeep.Contract.Verify(&_StreamsLookupUpkeep.CallOpts)
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepCallerSession) Verify() (bool, error) {
+ return _StreamsLookupUpkeep.Contract.Verify(&_StreamsLookupUpkeep.CallOpts)
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepTransactor) PerformUpkeep(opts *bind.TransactOpts, performData []byte) (*types.Transaction, error) {
+ return _StreamsLookupUpkeep.contract.Transact(opts, "performUpkeep", performData)
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepSession) PerformUpkeep(performData []byte) (*types.Transaction, error) {
+ return _StreamsLookupUpkeep.Contract.PerformUpkeep(&_StreamsLookupUpkeep.TransactOpts, performData)
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepTransactorSession) PerformUpkeep(performData []byte) (*types.Transaction, error) {
+ return _StreamsLookupUpkeep.Contract.PerformUpkeep(&_StreamsLookupUpkeep.TransactOpts, performData)
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepTransactor) Reset(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _StreamsLookupUpkeep.contract.Transact(opts, "reset")
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepSession) Reset() (*types.Transaction, error) {
+ return _StreamsLookupUpkeep.Contract.Reset(&_StreamsLookupUpkeep.TransactOpts)
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepTransactorSession) Reset() (*types.Transaction, error) {
+ return _StreamsLookupUpkeep.Contract.Reset(&_StreamsLookupUpkeep.TransactOpts)
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepTransactor) SetCallbackReturnBool(opts *bind.TransactOpts, value bool) (*types.Transaction, error) {
+ return _StreamsLookupUpkeep.contract.Transact(opts, "setCallbackReturnBool", value)
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepSession) SetCallbackReturnBool(value bool) (*types.Transaction, error) {
+ return _StreamsLookupUpkeep.Contract.SetCallbackReturnBool(&_StreamsLookupUpkeep.TransactOpts, value)
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepTransactorSession) SetCallbackReturnBool(value bool) (*types.Transaction, error) {
+ return _StreamsLookupUpkeep.Contract.SetCallbackReturnBool(&_StreamsLookupUpkeep.TransactOpts, value)
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepTransactor) SetFeeds(opts *bind.TransactOpts, _feeds []string) (*types.Transaction, error) {
+ return _StreamsLookupUpkeep.contract.Transact(opts, "setFeeds", _feeds)
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepSession) SetFeeds(_feeds []string) (*types.Transaction, error) {
+ return _StreamsLookupUpkeep.Contract.SetFeeds(&_StreamsLookupUpkeep.TransactOpts, _feeds)
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepTransactorSession) SetFeeds(_feeds []string) (*types.Transaction, error) {
+ return _StreamsLookupUpkeep.Contract.SetFeeds(&_StreamsLookupUpkeep.TransactOpts, _feeds)
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepTransactor) SetParamKeys(opts *bind.TransactOpts, _feedParamKey string, _timeParamKey string) (*types.Transaction, error) {
+ return _StreamsLookupUpkeep.contract.Transact(opts, "setParamKeys", _feedParamKey, _timeParamKey)
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepSession) SetParamKeys(_feedParamKey string, _timeParamKey string) (*types.Transaction, error) {
+ return _StreamsLookupUpkeep.Contract.SetParamKeys(&_StreamsLookupUpkeep.TransactOpts, _feedParamKey, _timeParamKey)
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepTransactorSession) SetParamKeys(_feedParamKey string, _timeParamKey string) (*types.Transaction, error) {
+ return _StreamsLookupUpkeep.Contract.SetParamKeys(&_StreamsLookupUpkeep.TransactOpts, _feedParamKey, _timeParamKey)
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepTransactor) SetShouldRevertCallback(opts *bind.TransactOpts, value bool) (*types.Transaction, error) {
+ return _StreamsLookupUpkeep.contract.Transact(opts, "setShouldRevertCallback", value)
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepSession) SetShouldRevertCallback(value bool) (*types.Transaction, error) {
+ return _StreamsLookupUpkeep.Contract.SetShouldRevertCallback(&_StreamsLookupUpkeep.TransactOpts, value)
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepTransactorSession) SetShouldRevertCallback(value bool) (*types.Transaction, error) {
+ return _StreamsLookupUpkeep.Contract.SetShouldRevertCallback(&_StreamsLookupUpkeep.TransactOpts, value)
+}
+
+type StreamsLookupUpkeepMercuryPerformEventIterator struct {
+ Event *StreamsLookupUpkeepMercuryPerformEvent
+
+ contract *bind.BoundContract
+ event string
+
+ logs chan types.Log
+ sub ethereum.Subscription
+ done bool
+ fail error
+}
+
+func (it *StreamsLookupUpkeepMercuryPerformEventIterator) Next() bool {
+
+ if it.fail != nil {
+ return false
+ }
+
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(StreamsLookupUpkeepMercuryPerformEvent)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+
+ select {
+ case log := <-it.logs:
+ it.Event = new(StreamsLookupUpkeepMercuryPerformEvent)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+func (it *StreamsLookupUpkeepMercuryPerformEventIterator) Error() error {
+ return it.fail
+}
+
+func (it *StreamsLookupUpkeepMercuryPerformEventIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+type StreamsLookupUpkeepMercuryPerformEvent struct {
+ Sender common.Address
+ BlockNumber *big.Int
+ V0 []byte
+ VerifiedV0 []byte
+ Ed []byte
+ Raw types.Log
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepFilterer) FilterMercuryPerformEvent(opts *bind.FilterOpts, sender []common.Address, blockNumber []*big.Int) (*StreamsLookupUpkeepMercuryPerformEventIterator, error) {
+
+ var senderRule []interface{}
+ for _, senderItem := range sender {
+ senderRule = append(senderRule, senderItem)
+ }
+ var blockNumberRule []interface{}
+ for _, blockNumberItem := range blockNumber {
+ blockNumberRule = append(blockNumberRule, blockNumberItem)
+ }
+
+ logs, sub, err := _StreamsLookupUpkeep.contract.FilterLogs(opts, "MercuryPerformEvent", senderRule, blockNumberRule)
+ if err != nil {
+ return nil, err
+ }
+ return &StreamsLookupUpkeepMercuryPerformEventIterator{contract: _StreamsLookupUpkeep.contract, event: "MercuryPerformEvent", logs: logs, sub: sub}, nil
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepFilterer) WatchMercuryPerformEvent(opts *bind.WatchOpts, sink chan<- *StreamsLookupUpkeepMercuryPerformEvent, sender []common.Address, blockNumber []*big.Int) (event.Subscription, error) {
+
+ var senderRule []interface{}
+ for _, senderItem := range sender {
+ senderRule = append(senderRule, senderItem)
+ }
+ var blockNumberRule []interface{}
+ for _, blockNumberItem := range blockNumber {
+ blockNumberRule = append(blockNumberRule, blockNumberItem)
+ }
+
+ logs, sub, err := _StreamsLookupUpkeep.contract.WatchLogs(opts, "MercuryPerformEvent", senderRule, blockNumberRule)
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+
+ event := new(StreamsLookupUpkeepMercuryPerformEvent)
+ if err := _StreamsLookupUpkeep.contract.UnpackLog(event, "MercuryPerformEvent", log); err != nil {
+ return err
+ }
+ event.Raw = log
+
+ select {
+ case sink <- event:
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ }
+ }), nil
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeepFilterer) ParseMercuryPerformEvent(log types.Log) (*StreamsLookupUpkeepMercuryPerformEvent, error) {
+ event := new(StreamsLookupUpkeepMercuryPerformEvent)
+ if err := _StreamsLookupUpkeep.contract.UnpackLog(event, "MercuryPerformEvent", log); err != nil {
+ return nil, err
+ }
+ event.Raw = log
+ return event, nil
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeep) ParseLog(log types.Log) (generated.AbigenLog, error) {
+ switch log.Topics[0] {
+ case _StreamsLookupUpkeep.abi.Events["MercuryPerformEvent"].ID:
+ return _StreamsLookupUpkeep.ParseMercuryPerformEvent(log)
+
+ default:
+ return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0])
+ }
+}
+
+func (StreamsLookupUpkeepMercuryPerformEvent) Topic() common.Hash {
+ return common.HexToHash("0xf0f72c0b235fc8687d6a67c02ca543473a3cef8a18b48490f10e475a8dda1390")
+}
+
+func (_StreamsLookupUpkeep *StreamsLookupUpkeep) Address() common.Address {
+ return _StreamsLookupUpkeep.address
+}
+
+type StreamsLookupUpkeepInterface interface {
+ CallbackReturnBool(opts *bind.CallOpts) (bool, error)
+
+ CheckCallback(opts *bind.CallOpts, values [][]byte, extraData []byte) (bool, []byte, error)
+
+ CheckUpkeep(opts *bind.CallOpts, data []byte) (bool, []byte, error)
+
+ Counter(opts *bind.CallOpts) (*big.Int, error)
+
+ Eligible(opts *bind.CallOpts) (bool, error)
+
+ FeedParamKey(opts *bind.CallOpts) (string, error)
+
+ Feeds(opts *bind.CallOpts, arg0 *big.Int) (string, error)
+
+ InitialBlock(opts *bind.CallOpts) (*big.Int, error)
+
+ Interval(opts *bind.CallOpts) (*big.Int, error)
+
+ PreviousPerformBlock(opts *bind.CallOpts) (*big.Int, error)
+
+ ShouldRevertCallback(opts *bind.CallOpts) (bool, error)
+
+ Staging(opts *bind.CallOpts) (bool, error)
+
+ TestRange(opts *bind.CallOpts) (*big.Int, error)
+
+ TimeParamKey(opts *bind.CallOpts) (string, error)
+
+ UseArbBlock(opts *bind.CallOpts) (bool, error)
+
+ Verify(opts *bind.CallOpts) (bool, error)
+
+ PerformUpkeep(opts *bind.TransactOpts, performData []byte) (*types.Transaction, error)
+
+ Reset(opts *bind.TransactOpts) (*types.Transaction, error)
+
+ SetCallbackReturnBool(opts *bind.TransactOpts, value bool) (*types.Transaction, error)
+
+ SetFeeds(opts *bind.TransactOpts, _feeds []string) (*types.Transaction, error)
+
+ SetParamKeys(opts *bind.TransactOpts, _feedParamKey string, _timeParamKey string) (*types.Transaction, error)
+
+ SetShouldRevertCallback(opts *bind.TransactOpts, value bool) (*types.Transaction, error)
+
+ FilterMercuryPerformEvent(opts *bind.FilterOpts, sender []common.Address, blockNumber []*big.Int) (*StreamsLookupUpkeepMercuryPerformEventIterator, error)
+
+ WatchMercuryPerformEvent(opts *bind.WatchOpts, sink chan<- *StreamsLookupUpkeepMercuryPerformEvent, sender []common.Address, blockNumber []*big.Int) (event.Subscription, error)
+
+ ParseMercuryPerformEvent(log types.Log) (*StreamsLookupUpkeepMercuryPerformEvent, error)
+
+ ParseLog(log types.Log) (generated.AbigenLog, error)
+
+ Address() common.Address
+}
diff --git a/core/gethwrappers/generated/trusted_blockhash_store/trusted_blockhash_store.go b/core/gethwrappers/generated/trusted_blockhash_store/trusted_blockhash_store.go
index 0ddddead4bd..27f7c4ebbb5 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: "0x60806040523480156200001157600080fd5b50604051620014db380380620014db8339810160408190526200003491620003e8565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000d9565b505050620000d2816200018560201b60201c565b5062000517565b6001600160a01b038116331415620001345760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6200018f620002ec565b60006004805480602002602001604051908101604052809291908181526020018280548015620001e957602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311620001ca575b5050855193945062000207936004935060208701925090506200034a565b5060005b81518110156200027757600060036000848481518110620002305762000230620004eb565b6020908102919091018101516001600160a01b03168252810191909152604001600020805460ff1916911515919091179055806200026e81620004c1565b9150506200020b565b5060005b8251811015620002e757600160036000858481518110620002a057620002a0620004eb565b6020908102919091018101516001600160a01b03168252810191909152604001600020805460ff191691151591909117905580620002de81620004c1565b9150506200027b565b505050565b6000546001600160a01b03163314620003485760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640162000082565b565b828054828255906000526020600020908101928215620003a2579160200282015b82811115620003a257825182546001600160a01b0319166001600160a01b039091161782556020909201916001909101906200036b565b50620003b0929150620003b4565b5090565b5b80821115620003b05760008155600101620003b5565b80516001600160a01b0381168114620003e357600080fd5b919050565b60006020808385031215620003fc57600080fd5b82516001600160401b03808211156200041457600080fd5b818501915085601f8301126200042957600080fd5b8151818111156200043e576200043e62000501565b8060051b604051601f19603f8301168101818110858211171562000466576200046662000501565b604052828152858101935084860182860187018a10156200048657600080fd5b600095505b83861015620004b4576200049f81620003cb565b8552600195909501949386019386016200048b565b5098975050505050505050565b6000600019821415620004e457634e487b7160e01b600052601160045260246000fd5b5060010190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b610fb480620005276000396000f3fe608060405234801561001057600080fd5b50600436106100c95760003560e01c80638da5cb5b11610081578063f2fde38b1161005b578063f2fde38b146101b5578063f4217648146101c8578063fadff0e1146101db57600080fd5b80638da5cb5b14610143578063e9413d3814610161578063e9ecc1541461018257600080fd5b80636057361d116100b25780636057361d1461012057806379ba50971461013357806383b6d6b71461013b57600080fd5b80633b69ad60146100ce5780635c7de309146100e3575b600080fd5b6100e16100dc366004610cf6565b6101ee565b005b6100f66100f1366004610d8d565b610326565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6100e161012e366004610d8d565b61035d565b6100e16103e8565b6100e16104e5565b60005473ffffffffffffffffffffffffffffffffffffffff166100f6565b61017461016f366004610d8d565b6104ff565b604051908152602001610117565b6101a5610190366004610c27565b60036020526000908152604090205460ff1681565b6040519015158152602001610117565b6100e16101c3366004610c27565b61057b565b6100e16101d6366004610c42565b61058f565b6100e16101e9366004610da6565b610745565b60006101f9836107e8565b9050818114610234576040517fd2f69c9500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360009081526003602052604090205460ff1661027d576040517f5b0aa2ba00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8584146102b6576040517fbd75093300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8681101561031c578585828181106102d3576102d3610f49565b90506020020135600260008a8a858181106102f0576102f0610f49565b90506020020135815260200190815260200160002081905550808061031490610ee1565b9150506102b9565b5050505050505050565b6004818154811061033657600080fd5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b6000610368826107e8565b9050806103d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f626c6f636b68617368286e29206661696c65640000000000000000000000000060448201526064015b60405180910390fd5b60009182526002602052604090912055565b60015473ffffffffffffffffffffffffffffffffffffffff163314610469576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016103cd565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6104fd6101006104f36108f6565b61012e9190610eca565b565b60008181526002602052604081205480610575576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f626c6f636b68617368206e6f7420666f756e6420696e2073746f72650000000060448201526064016103cd565b92915050565b61058361099c565b61058c81610a1d565b50565b61059761099c565b600060048054806020026020016040519081016040528092919081815260200182805480156105fc57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff1681526001909101906020018083116105d1575b5050855193945061061893600493506020870192509050610b13565b5060005b81518110156106ac5760006003600084848151811061063d5761063d610f49565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160002080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055806106a481610ee1565b91505061061c565b5060005b8251811015610740576001600360008584815181106106d1576106d1610f49565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160002080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169115159190911790558061073881610ee1565b9150506106b0565b505050565b60026000610754846001610eb2565b8152602001908152602001600020548180519060200120146107d2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f6865616465722068617320756e6b6e6f776e20626c6f636b686173680000000060448201526064016103cd565b6024015160009182526002602052604090912055565b60004661a4b18114806107fd575062066eed81145b156108e6576101008367ffffffffffffffff166108186108f6565b6108229190610eca565b118061083f57506108316108f6565b8367ffffffffffffffff1610155b1561084d5750600092915050565b6040517f2b407a8200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152606490632b407a829060240160206040518083038186803b1580156108a757600080fd5b505afa1580156108bb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108df9190610d74565b9392505050565b505067ffffffffffffffff164090565b60004661a4b181148061090b575062066eed81145b1561099557606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b815260040160206040518083038186803b15801561095757600080fd5b505afa15801561096b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061098f9190610d74565b91505090565b4391505090565b60005473ffffffffffffffffffffffffffffffffffffffff1633146104fd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016103cd565b73ffffffffffffffffffffffffffffffffffffffff8116331415610a9d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016103cd565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b828054828255906000526020600020908101928215610b8d579160200282015b82811115610b8d57825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909116178255602090920191600190910190610b33565b50610b99929150610b9d565b5090565b5b80821115610b995760008155600101610b9e565b803573ffffffffffffffffffffffffffffffffffffffff81168114610bd657600080fd5b919050565b60008083601f840112610bed57600080fd5b50813567ffffffffffffffff811115610c0557600080fd5b6020830191508360208260051b8501011115610c2057600080fd5b9250929050565b600060208284031215610c3957600080fd5b6108df82610bb2565b60006020808385031215610c5557600080fd5b823567ffffffffffffffff80821115610c6d57600080fd5b818501915085601f830112610c8157600080fd5b813581811115610c9357610c93610f78565b8060051b9150610ca4848301610e63565b8181528481019084860184860187018a1015610cbf57600080fd5b600095505b83861015610ce957610cd581610bb2565b835260019590950194918601918601610cc4565b5098975050505050505050565b60008060008060008060808789031215610d0f57600080fd5b863567ffffffffffffffff80821115610d2757600080fd5b610d338a838b01610bdb565b90985096506020890135915080821115610d4c57600080fd5b50610d5989828a01610bdb565b979a9699509760408101359660609091013595509350505050565b600060208284031215610d8657600080fd5b5051919050565b600060208284031215610d9f57600080fd5b5035919050565b60008060408385031215610db957600080fd5b8235915060208084013567ffffffffffffffff80821115610dd957600080fd5b818601915086601f830112610ded57600080fd5b813581811115610dff57610dff610f78565b610e2f847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601610e63565b91508082528784828501011115610e4557600080fd5b80848401858401376000848284010152508093505050509250929050565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610eaa57610eaa610f78565b604052919050565b60008219821115610ec557610ec5610f1a565b500190565b600082821015610edc57610edc610f1a565b500390565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415610f1357610f13610f1a565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fdfea164736f6c6343000806000a",
+ Bin: "0x60806040523480156200001157600080fd5b50604051620014e8380380620014e88339810160408190526200003491620003e8565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000d9565b505050620000d2816200018560201b60201c565b5062000517565b6001600160a01b038116331415620001345760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6200018f620002ec565b60006004805480602002602001604051908101604052809291908181526020018280548015620001e957602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311620001ca575b5050855193945062000207936004935060208701925090506200034a565b5060005b81518110156200027757600060036000848481518110620002305762000230620004eb565b6020908102919091018101516001600160a01b03168252810191909152604001600020805460ff1916911515919091179055806200026e81620004c1565b9150506200020b565b5060005b8251811015620002e757600160036000858481518110620002a057620002a0620004eb565b6020908102919091018101516001600160a01b03168252810191909152604001600020805460ff191691151591909117905580620002de81620004c1565b9150506200027b565b505050565b6000546001600160a01b03163314620003485760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640162000082565b565b828054828255906000526020600020908101928215620003a2579160200282015b82811115620003a257825182546001600160a01b0319166001600160a01b039091161782556020909201916001909101906200036b565b50620003b0929150620003b4565b5090565b5b80821115620003b05760008155600101620003b5565b80516001600160a01b0381168114620003e357600080fd5b919050565b60006020808385031215620003fc57600080fd5b82516001600160401b03808211156200041457600080fd5b818501915085601f8301126200042957600080fd5b8151818111156200043e576200043e62000501565b8060051b604051601f19603f8301168101818110858211171562000466576200046662000501565b604052828152858101935084860182860187018a10156200048657600080fd5b600095505b83861015620004b4576200049f81620003cb565b8552600195909501949386019386016200048b565b5098975050505050505050565b6000600019821415620004e457634e487b7160e01b600052601160045260246000fd5b5060010190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b610fc180620005276000396000f3fe608060405234801561001057600080fd5b50600436106100c95760003560e01c80638da5cb5b11610081578063f2fde38b1161005b578063f2fde38b146101b5578063f4217648146101c8578063fadff0e1146101db57600080fd5b80638da5cb5b14610143578063e9413d3814610161578063e9ecc1541461018257600080fd5b80636057361d116100b25780636057361d1461012057806379ba50971461013357806383b6d6b71461013b57600080fd5b80633b69ad60146100ce5780635c7de309146100e3575b600080fd5b6100e16100dc366004610d03565b6101ee565b005b6100f66100f1366004610d9a565b610326565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6100e161012e366004610d9a565b61035d565b6100e16103e8565b6100e16104e5565b60005473ffffffffffffffffffffffffffffffffffffffff166100f6565b61017461016f366004610d9a565b6104ff565b604051908152602001610117565b6101a5610190366004610c34565b60036020526000908152604090205460ff1681565b6040519015158152602001610117565b6100e16101c3366004610c34565b61057b565b6100e16101d6366004610c4f565b61058f565b6100e16101e9366004610db3565b610745565b60006101f9836107e8565b9050818114610234576040517fd2f69c9500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360009081526003602052604090205460ff1661027d576040517f5b0aa2ba00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8584146102b6576040517fbd75093300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8681101561031c578585828181106102d3576102d3610f56565b90506020020135600260008a8a858181106102f0576102f0610f56565b90506020020135815260200190815260200160002081905550808061031490610eee565b9150506102b9565b5050505050505050565b6004818154811061033657600080fd5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b6000610368826107e8565b9050806103d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f626c6f636b68617368286e29206661696c65640000000000000000000000000060448201526064015b60405180910390fd5b60009182526002602052604090912055565b60015473ffffffffffffffffffffffffffffffffffffffff163314610469576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016103cd565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6104fd6101006104f3610903565b61012e9190610ed7565b565b60008181526002602052604081205480610575576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f626c6f636b68617368206e6f7420666f756e6420696e2073746f72650000000060448201526064016103cd565b92915050565b6105836109a9565b61058c81610a2a565b50565b6105976109a9565b600060048054806020026020016040519081016040528092919081815260200182805480156105fc57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff1681526001909101906020018083116105d1575b5050855193945061061893600493506020870192509050610b20565b5060005b81518110156106ac5760006003600084848151811061063d5761063d610f56565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160002080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055806106a481610eee565b91505061061c565b5060005b8251811015610740576001600360008584815181106106d1576106d1610f56565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160002080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169115159190911790558061073881610eee565b9150506106b0565b505050565b60026000610754846001610ebf565b8152602001908152602001600020548180519060200120146107d2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f6865616465722068617320756e6b6e6f776e20626c6f636b686173680000000060448201526064016103cd565b6024015160009182526002602052604090912055565b60004661a4b18114806107fd575062066eed81145b8061080a575062066eee81145b156108f3576101008367ffffffffffffffff16610825610903565b61082f9190610ed7565b118061084c575061083e610903565b8367ffffffffffffffff1610155b1561085a5750600092915050565b6040517f2b407a8200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152606490632b407a829060240160206040518083038186803b1580156108b457600080fd5b505afa1580156108c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108ec9190610d81565b9392505050565b505067ffffffffffffffff164090565b60004661a4b1811480610918575062066eed81145b156109a257606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b815260040160206040518083038186803b15801561096457600080fd5b505afa158015610978573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061099c9190610d81565b91505090565b4391505090565b60005473ffffffffffffffffffffffffffffffffffffffff1633146104fd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016103cd565b73ffffffffffffffffffffffffffffffffffffffff8116331415610aaa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016103cd565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b828054828255906000526020600020908101928215610b9a579160200282015b82811115610b9a57825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909116178255602090920191600190910190610b40565b50610ba6929150610baa565b5090565b5b80821115610ba65760008155600101610bab565b803573ffffffffffffffffffffffffffffffffffffffff81168114610be357600080fd5b919050565b60008083601f840112610bfa57600080fd5b50813567ffffffffffffffff811115610c1257600080fd5b6020830191508360208260051b8501011115610c2d57600080fd5b9250929050565b600060208284031215610c4657600080fd5b6108ec82610bbf565b60006020808385031215610c6257600080fd5b823567ffffffffffffffff80821115610c7a57600080fd5b818501915085601f830112610c8e57600080fd5b813581811115610ca057610ca0610f85565b8060051b9150610cb1848301610e70565b8181528481019084860184860187018a1015610ccc57600080fd5b600095505b83861015610cf657610ce281610bbf565b835260019590950194918601918601610cd1565b5098975050505050505050565b60008060008060008060808789031215610d1c57600080fd5b863567ffffffffffffffff80821115610d3457600080fd5b610d408a838b01610be8565b90985096506020890135915080821115610d5957600080fd5b50610d6689828a01610be8565b979a9699509760408101359660609091013595509350505050565b600060208284031215610d9357600080fd5b5051919050565b600060208284031215610dac57600080fd5b5035919050565b60008060408385031215610dc657600080fd5b8235915060208084013567ffffffffffffffff80821115610de657600080fd5b818601915086601f830112610dfa57600080fd5b813581811115610e0c57610e0c610f85565b610e3c847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601610e70565b91508082528784828501011115610e5257600080fd5b80848401858401376000848284010152508093505050509250929050565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610eb757610eb7610f85565b604052919050565b60008219821115610ed257610ed2610f27565b500190565b600082821015610ee957610ee9610f27565b500390565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415610f2057610f20610f27565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fdfea164736f6c6343000806000a",
}
var TrustedBlockhashStoreABI = TrustedBlockhashStoreMetaData.ABI
diff --git a/core/gethwrappers/generated/verifiable_load_log_trigger_upkeep_wrapper/verifiable_load_log_trigger_upkeep_wrapper.go b/core/gethwrappers/generated/verifiable_load_log_trigger_upkeep_wrapper/verifiable_load_log_trigger_upkeep_wrapper.go
index 4840897e022..52e241965f8 100644
--- a/core/gethwrappers/generated/verifiable_load_log_trigger_upkeep_wrapper/verifiable_load_log_trigger_upkeep_wrapper.go
+++ b/core/gethwrappers/generated/verifiable_load_log_trigger_upkeep_wrapper/verifiable_load_log_trigger_upkeep_wrapper.go
@@ -30,9 +30,22 @@ var (
_ = abi.ConvertType
)
+type KeeperRegistryBase21UpkeepInfo struct {
+ Target common.Address
+ PerformGas uint32
+ CheckData []byte
+ Balance *big.Int
+ Admin common.Address
+ MaxValidBlocknumber uint64
+ LastPerformedBlockNumber uint32
+ AmountSpent *big.Int
+ Paused bool
+ OffchainConfig []byte
+}
+
type Log struct {
Index *big.Int
- TxIndex *big.Int
+ Timestamp *big.Int
TxHash [32]byte
BlockNumber *big.Int
BlockHash [32]byte
@@ -42,15 +55,15 @@ type Log struct {
}
var VerifiableLoadLogTriggerUpkeepMetaData = &bind.MetaData{
- ABI: "[{\"inputs\":[{\"internalType\":\"contractAutomationRegistrar2_1\",\"name\":\"_registrar\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_useArb\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"_autoLog\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"_useMercury\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"feedParamKey\",\"type\":\"string\"},{\"internalType\":\"string[]\",\"name\":\"feeds\",\"type\":\"string[]\"},{\"internalType\":\"string\",\"name\":\"timeParamKey\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"time\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"FeedLookup\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IndexOutOfRange\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"blockNum\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"LogEmitted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Received\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"blockNum\",\"type\":\"uint256\"}],\"name\":\"UpkeepTopUp\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"}],\"name\":\"UpkeepsRegistered\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BUCKET_SIZE\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"addFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"addLinkAmount\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"autoLog\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"}],\"name\":\"batchCancelUpkeeps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"number\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"},{\"internalType\":\"uint256\",\"name\":\"checkGasToBurn\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"performGasToBurn\",\"type\":\"uint256\"}],\"name\":\"batchRegisterUpkeeps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"batchSendLogs\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"},{\"internalType\":\"uint32\",\"name\":\"interval\",\"type\":\"uint32\"}],\"name\":\"batchSetIntervals\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"}],\"name\":\"batchUpdatePipelineData\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"}],\"name\":\"batchWithdrawLinks\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"bucketedDelays\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"buckets\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"startGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"blockNum\",\"type\":\"uint256\"}],\"name\":\"burnPerformGas\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"cancelUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes[]\",\"name\":\"values\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"checkCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"checkGasToBurns\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"txIndex\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"txHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"source\",\"type\":\"address\"},{\"internalType\":\"bytes32[]\",\"name\":\"topics\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"structLog\",\"name\":\"log\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"}],\"name\":\"checkLog\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"counters\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"delays\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"dummyMap\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"eligible\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"emittedSig\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"feedParamKey\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"feedsHex\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"firstPerformBlocks\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"gasLimits\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"startIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxCount\",\"type\":\"uint256\"}],\"name\":\"getActiveUpkeepIDs\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"bucket\",\"type\":\"uint16\"}],\"name\":\"getBucketedDelays\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getBucketedDelaysLength\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getDelays\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getDelaysLength\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getLogTriggerConfig\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"logTrigger\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"p\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"n\",\"type\":\"uint256\"}],\"name\":\"getPxDelayLastNPerforms\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"bucket\",\"type\":\"uint16\"}],\"name\":\"getSumDelayInBucket\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"n\",\"type\":\"uint256\"}],\"name\":\"getSumDelayLastNPerforms\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"intervals\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"lastTopUpBlocks\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"linkToken\",\"outputs\":[{\"internalType\":\"contractLinkTokenInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"minBalanceThresholdMultiplier\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"performDataSizes\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"performGasToBurns\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"}],\"name\":\"performUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"previousPerformBlocks\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"registrar\",\"outputs\":[{\"internalType\":\"contractAutomationRegistrar2_1\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"registry\",\"outputs\":[{\"internalType\":\"contractIKeeperRegistryMaster\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"sendLog\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"setAddLinkAmount\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"_autoLog\",\"type\":\"bool\"}],\"name\":\"setAutoLog\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"setCheckGasToBurn\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractAutomationRegistrar2_1\",\"name\":\"newRegistrar\",\"type\":\"address\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string[]\",\"name\":\"newFeeds\",\"type\":\"string[]\"}],\"name\":\"setFeedsHex\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_interval\",\"type\":\"uint256\"}],\"name\":\"setInterval\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"newMinBalanceThresholdMultiplier\",\"type\":\"uint8\"}],\"name\":\"setMinBalanceThresholdMultiplier\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"setPerformDataSize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"setPerformGasToBurn\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"}],\"name\":\"setUpkeepGasLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"newInterval\",\"type\":\"uint256\"}],\"name\":\"setUpkeepTopUpCheckInterval\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"_useMercury\",\"type\":\"bool\"}],\"name\":\"setUseMercury\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"timeParamKey\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"blockNum\",\"type\":\"uint256\"}],\"name\":\"topUpFund\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"pipelineData\",\"type\":\"bytes\"}],\"name\":\"updateUpkeepPipelineData\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"upkeepTopUpCheckInterval\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"useArbitrumBlockNum\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"useMercury\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawLinks\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"withdrawLinks\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]",
- Bin: "0x7f97009585a4d2440f981ab6f6eec514343e1e6b2aa9b991a26998e6806f41bf086080526005601455601580546001600160681b0319166c140000000002c68af0bb140000179055606460c0526101a0604052604261012081815260e091829190620054fe6101403981526020016040518060800160405280604281526020016200554060429139905262000099906016906002620003c4565b506040805180820190915260098152680cccacac892c890caf60bb1b6020820152601790620000c9908262000540565b5060408051808201909152600b81526a313637b1b5a73ab6b132b960a91b6020820152601890620000fb908262000540565b503480156200010957600080fd5b5060405162005582380380620055828339810160408190526200012c9162000638565b83833380600081620001855760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620001b857620001b88162000319565b5050601180546001600160a01b0319166001600160a01b038516908117909155604080516330fe427560e21b815281516000945063c3f909d4926004808401939192918290030181865afa15801562000215573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200023b919062000697565b50601380546001600160a01b0319166001600160a01b038381169190911790915560115460408051631b6b6d2360e01b81529051939450911691631b6b6d23916004808201926020929091908290030181865afa158015620002a1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002c79190620006c8565b601280546001600160a01b0319166001600160a01b039290921691909117905550151560a052506019805461ffff191692151561ff001916929092176101009115159190910217905550620006ef9050565b336001600160a01b03821603620003735760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200017c565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b8280548282559060005260206000209081019282156200040f579160200282015b828111156200040f5782518290620003fe908262000540565b5091602001919060010190620003e5565b506200041d92915062000421565b5090565b808211156200041d57600062000438828262000442565b5060010162000421565b5080546200045090620004b1565b6000825580601f1062000461575050565b601f01602090049060005260206000209081019062000481919062000484565b50565b5b808211156200041d576000815560010162000485565b634e487b7160e01b600052604160045260246000fd5b600181811c90821680620004c657607f821691505b602082108103620004e757634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200053b57600081815260208120601f850160051c81016020861015620005165750805b601f850160051c820191505b81811015620005375782815560010162000522565b5050505b505050565b81516001600160401b038111156200055c576200055c6200049b565b62000574816200056d8454620004b1565b84620004ed565b602080601f831160018114620005ac5760008415620005935750858301515b600019600386901b1c1916600185901b17855562000537565b600085815260208120601f198616915b82811015620005dd57888601518255948401946001909101908401620005bc565b5085821015620005fc5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6001600160a01b03811681146200048157600080fd5b805180151581146200063357600080fd5b919050565b600080600080608085870312156200064f57600080fd5b84516200065c816200060c565b93506200066c6020860162000622565b92506200067c6040860162000622565b91506200068c6060860162000622565b905092959194509250565b60008060408385031215620006ab57600080fd5b8251620006b8816200060c565b6020939093015192949293505050565b600060208284031215620006db57600080fd5b8151620006e8816200060c565b9392505050565b60805160a05160c051614dc36200073b600039600081816105970152611e3e0152600081816108d301526130b3015260008181610c410152818161151c0152611a1c0152614dc36000f3fe60806040526004361061044e5760003560e01c806379ba509711610243578063af953a4a11610143578063d90c4a68116100bb578063e15e1b341161008a578063f2fde38b1161006f578063f2fde38b14610f5b578063fba7ffa314610f7b578063fcdc1f6314610fa857600080fd5b8063e15e1b3414610ef9578063e455308314610f4557600080fd5b8063d90c4a6814610e72578063daee1aeb14610e8c578063dbef701e14610eac578063e0114adb14610ecc57600080fd5b8063c41c815b11610112578063c98f10b0116100f7578063c98f10b014610dde578063d355852814610df3578063d6051a7214610e5257600080fd5b8063c41c815b14610d9f578063c804802214610dbe57600080fd5b8063af953a4a14610cf0578063afb28d1f14610d10578063becde0e114610d25578063c357f1f314610d4557600080fd5b80639b429354116101d6578063a6548248116101a5578063a6c60d891161018a578063a6c60d8914610c83578063a72aa27e14610ca3578063a79c404314610cc357600080fd5b8063a654824814610c2f578063a6b5947514610c6357600080fd5b80639b42935414610b915780639b51fb0d14610bbe5780639d385eaa14610bef5780639d6f1cc714610c0f57600080fd5b80638fcb3fba116102125780638fcb3fba14610ae8578063924ca57814610b15578063948108f714610b355780639ac542eb14610b5557600080fd5b806379ba509714610a5b5780637b10399914610a705780637e7a46dc14610a9d5780638da5cb5b14610abd57600080fd5b806346e7a63e1161034e578063636092e8116102e15780636b2120c6116102b057806373644cce1161029557806373644cce146109e15780637672130314610a0e578063776898c814610a3b57600080fd5b80636b2120c61461095f5780637145f11b146109b157600080fd5b8063636092e81461087f578063642f6cef146108c157806369cdbadb1461090557806369e9b7731461093257600080fd5b8063597109921161031d57806359710992146108085780635d4ee7f31461081d5780635f17e6161461083257806360457ff51461085257600080fd5b806346e7a63e1461076e5780634b56a42e1461079b57806351c98be3146107bb57806357970e93146107db57600080fd5b806320e3dbd4116103e1578063328ffd11116103b057806340691db41161039557806340691db4146107005780634585e33b1461072e57806345d2ec171461074e57600080fd5b8063328ffd11146106b35780633ebe8d6c146106e057600080fd5b806320e3dbd41461060157806328c4b57b146106215780632a9032d3146106415780632b20e3971461066157600080fd5b80630d4a4fb11161041d5780630d4a4fb1146105385780630e577d421461056557806312c5502714610585578063206c32e8146105cc57600080fd5b806305e251311461049257806306c1cc00146104b457806306e3b632146104d4578063077ac6211461050a57600080fd5b3661048d57604080513381523460208201527f88a5966d370b9919b20f3e2c13ff65706f196a4e32cc2c12bf57088f88525874910160405180910390a1005b600080fd5b34801561049e57600080fd5b506104b26104ad3660046139e0565b610fd5565b005b3480156104c057600080fd5b506104b26104cf366004613b01565b610fec565b3480156104e057600080fd5b506104f46104ef366004613b9d565b6113a8565b6040516105019190613bbf565b60405180910390f35b34801561051657600080fd5b5061052a610525366004613c1a565b6114a7565b604051908152602001610501565b34801561054457600080fd5b50610558610553366004613c4f565b6114e5565b6040516105019190613cd6565b34801561057157600080fd5b506104b2610580366004613c4f565b611602565b34801561059157600080fd5b506105b97f000000000000000000000000000000000000000000000000000000000000000081565b60405161ffff9091168152602001610501565b3480156105d857600080fd5b506105ec6105e7366004613ce9565b61164a565b60408051928352602083019190915201610501565b34801561060d57600080fd5b506104b261061c366004613d37565b6116cd565b34801561062d57600080fd5b5061052a61063c366004613d54565b611897565b34801561064d57600080fd5b506104b261065c366004613dc5565b611902565b34801561066d57600080fd5b5060115461068e9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610501565b3480156106bf57600080fd5b5061052a6106ce366004613c4f565b60036020526000908152604090205481565b3480156106ec57600080fd5b5061052a6106fb366004613c4f565b61199c565b34801561070c57600080fd5b5061072061071b366004613e07565b611a05565b604051610501929190613e74565b34801561073a57600080fd5b506104b2610749366004613ed1565b611d3d565b34801561075a57600080fd5b506104f4610769366004613ce9565b611f9a565b34801561077a57600080fd5b5061052a610789366004613c4f565b600a6020526000908152604090205481565b3480156107a757600080fd5b506107206107b6366004613f07565b612009565b3480156107c757600080fd5b506104b26107d6366004613fc4565b61205d565b3480156107e757600080fd5b5060125461068e9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561081457600080fd5b506104b2612101565b34801561082957600080fd5b506104b26122ec565b34801561083e57600080fd5b506104b261084d366004613b9d565b612423565b34801561085e57600080fd5b5061052a61086d366004613c4f565b60076020526000908152604090205481565b34801561088b57600080fd5b506015546108a4906bffffffffffffffffffffffff1681565b6040516bffffffffffffffffffffffff9091168152602001610501565b3480156108cd57600080fd5b506108f57f000000000000000000000000000000000000000000000000000000000000000081565b6040519015158152602001610501565b34801561091157600080fd5b5061052a610920366004613c4f565b60086020526000908152604090205481565b34801561093e57600080fd5b506104b261094d366004613b9d565b60009182526008602052604090912055565b34801561096b57600080fd5b506104b261097a366004614029565b60198054911515610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff909216919091179055565b3480156109bd57600080fd5b506108f56109cc366004613c4f565b600b6020526000908152604090205460ff1681565b3480156109ed57600080fd5b5061052a6109fc366004613c4f565b6000908152600c602052604090205490565b348015610a1a57600080fd5b5061052a610a29366004613c4f565b60046020526000908152604090205481565b348015610a4757600080fd5b506108f5610a56366004613c4f565b6124f0565b348015610a6757600080fd5b506104b2612542565b348015610a7c57600080fd5b5060135461068e9073ffffffffffffffffffffffffffffffffffffffff1681565b348015610aa957600080fd5b506104b2610ab8366004614046565b61263f565b348015610ac957600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff1661068e565b348015610af457600080fd5b5061052a610b03366004613c4f565b60056020526000908152604090205481565b348015610b2157600080fd5b506104b2610b30366004613b9d565b6126d0565b348015610b4157600080fd5b506104b2610b50366004614092565b612915565b348015610b6157600080fd5b50601554610b7f906c01000000000000000000000000900460ff1681565b60405160ff9091168152602001610501565b348015610b9d57600080fd5b506104b2610bac366004613b9d565b60009182526009602052604090912055565b348015610bca57600080fd5b506105b9610bd9366004613c4f565b600e6020526000908152604090205461ffff1681565b348015610bfb57600080fd5b506104f4610c0a366004613c4f565b612a5e565b348015610c1b57600080fd5b50610558610c2a366004613c4f565b612ac0565b348015610c3b57600080fd5b5061052a7f000000000000000000000000000000000000000000000000000000000000000081565b348015610c6f57600080fd5b506104b2610c7e366004613d54565b612b6c565b348015610c8f57600080fd5b506104b2610c9e366004613c4f565b601455565b348015610caf57600080fd5b506104b2610cbe3660046140c2565b612bd5565b348015610ccf57600080fd5b506104b2610cde366004613b9d565b60009182526007602052604090912055565b348015610cfc57600080fd5b506104b2610d0b366004613c4f565b612c80565b348015610d1c57600080fd5b50610558612d06565b348015610d3157600080fd5b506104b2610d40366004613dc5565b612d13565b348015610d5157600080fd5b506104b2610d603660046140e7565b601580547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff92909216919091179055565b348015610dab57600080fd5b506019546108f590610100900460ff1681565b348015610dca57600080fd5b506104b2610dd9366004613c4f565b612dad565b348015610dea57600080fd5b50610558612e45565b348015610dff57600080fd5b506104b2610e0e366004614104565b6015805460ff9092166c01000000000000000000000000027fffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffff909216919091179055565b348015610e5e57600080fd5b506105ec610e6d366004613b9d565b612e52565b348015610e7e57600080fd5b506019546108f59060ff1681565b348015610e9857600080fd5b506104b2610ea7366004613dc5565b612ebb565b348015610eb857600080fd5b5061052a610ec7366004613b9d565b612f86565b348015610ed857600080fd5b5061052a610ee7366004613c4f565b60096020526000908152604090205481565b348015610f0557600080fd5b506104b2610f14366004614029565b601980547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055565b348015610f5157600080fd5b5061052a60145481565b348015610f6757600080fd5b506104b2610f76366004613d37565b612fb7565b348015610f8757600080fd5b5061052a610f96366004613c4f565b60066020526000908152604090205481565b348015610fb457600080fd5b5061052a610fc3366004613c4f565b60026020526000908152604090205481565b8051610fe89060169060208401906137b0565b5050565b6040805161018081018252600461014082019081527f746573740000000000000000000000000000000000000000000000000000000061016083015281528151602081810184526000808352818401929092523083850181905263ffffffff8b166060850152608084015260ff808a1660a08501528451808301865283815260c085015260e0840189905284519182019094529081526101008201526bffffffffffffffffffffffff8516610120820152601254601154919273ffffffffffffffffffffffffffffffffffffffff9182169263095ea7b39216906110d2908c1688614150565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815273ffffffffffffffffffffffffffffffffffffffff90921660048301526bffffffffffffffffffffffff1660248201526044016020604051808303816000875af1158015611150573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611174919061418f565b5060008860ff1667ffffffffffffffff81111561119357611193613890565b6040519080825280602002602001820160405280156111bc578160200160208202803683370190505b50905060005b8960ff168160ff1610156113655760006111db84612fcb565b90508860ff16600103611313576040517f0d4a4fb1000000000000000000000000000000000000000000000000000000008152600481018290526000903090630d4a4fb190602401600060405180830381865afa158015611240573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261128691908101906141f9565b6013546040517f4ee88d3500000000000000000000000000000000000000000000000000000000815291925073ffffffffffffffffffffffffffffffffffffffff1690634ee88d35906112df908590859060040161422e565b600060405180830381600087803b1580156112f957600080fd5b505af115801561130d573d6000803e3d6000fd5b50505050505b80838360ff168151811061132957611329614247565b6020908102919091018101919091526000918252600881526040808320889055600790915290208490558061135d81614276565b9150506111c2565b507f2ee10f7eb180441fb9fbba75b10c0162b5390b557712c93426243ca8f383c711816040516113959190613bbf565b60405180910390a1505050505050505050565b606060006113b6600f613099565b90508084106113f1576040517f1390f2a100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82600003611406576114038482614295565b92505b60008367ffffffffffffffff81111561142157611421613890565b60405190808252806020026020018201604052801561144a578160200160208202803683370190505b50905060005b8481101561149c5761146d61146582886142a8565b600f906130a3565b82828151811061147f5761147f614247565b602090810291909101015280611494816142bb565b915050611450565b509150505b92915050565b600d60205282600052604060002060205281600052604060002081815481106114cf57600080fd5b9060005260206000200160009250925050505481565b606060006040518060c001604052803073ffffffffffffffffffffffffffffffffffffffff168152602001600160ff1681526020017f000000000000000000000000000000000000000000000000000000000000000081526020018460405160200161155391815260200190565b60405160208183030381529060405261156b906142f3565b81526020016000801b81526020016000801b8152509050806040516020016115eb9190600060c08201905073ffffffffffffffffffffffffffffffffffffffff835116825260ff602084015116602083015260408301516040830152606083015160608301526080830151608083015260a083015160a083015292915050565b604051602081830303815290604052915050919050565b600061160c6130af565b604051308152909150819083907f97009585a4d2440f981ab6f6eec514343e1e6b2aa9b991a26998e6806f41bf089060200160405180910390a35050565b6000828152600d6020908152604080832061ffff8516845282528083208054825181850281018501909352808352849384939291908301828280156116ae57602002820191906000526020600020905b81548152602001906001019080831161169a575b505050505090506116c0818251613151565b92509250505b9250929050565b601180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8316908117909155604080517fc3f909d400000000000000000000000000000000000000000000000000000000815281516000939263c3f909d492600480820193918290030181865afa158015611763573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117879190614343565b50601380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691909117909155601154604080517f1b6b6d230000000000000000000000000000000000000000000000000000000081529051939450911691631b6b6d23916004808201926020929091908290030181865afa15801561182a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061184e9190614371565b601280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff929092169190911790555050565b6000838152600c6020908152604080832080548251818502810185019093528083526118f8938301828280156118ec57602002820191906000526020600020905b8154815260200190600101908083116118d8575b505050505084846131d6565b90505b9392505050565b8060005b818160ff161015611996573063c8048022858560ff851681811061192c5761192c614247565b905060200201356040518263ffffffff1660e01b815260040161195191815260200190565b600060405180830381600087803b15801561196b57600080fd5b505af115801561197f573d6000803e3d6000fd5b50505050808061198e90614276565b915050611906565b50505050565b6000818152600e602052604081205461ffff1681805b8261ffff168161ffff16116119fd576000858152600d6020908152604080832061ffff851684529091529020546119e990836142a8565b9150806119f58161438e565b9150506119b2565b509392505050565b6000606060005a90506000611a186130af565b90507f0000000000000000000000000000000000000000000000000000000000000000611a4860c08801886143af565b6000818110611a5957611a59614247565b9050602002013503611cb5576000611a7460c08801886143af565b6001818110611a8557611a85614247565b90506020020135604051602001611a9e91815260200190565b6040516020818303038152906040529050600081806020019051810190611ac59190614417565b90506000611ad660c08a018a6143af565b6002818110611ae757611ae7614247565b90506020020135604051602001611b0091815260200190565b6040516020818303038152906040529050600081806020019051810190611b279190614417565b6000848152600860205260409020549091505b805a611b469089614295565b611b5290613a986142a8565b1015611b935781406000908152600b6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055611b3a565b601954610100900460ff1615611c3157601760166018848786604051602001611bc6929190918252602082015260400190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527f7ddd933e000000000000000000000000000000000000000000000000000000008252611c289594939291600401614518565b60405180910390fd5b604080516001808252818301909252600091816020015b6060815260200190600190039081611c4857505060408051602081018890528082018690528151808203830181526060820190925291925090600190611c9490849084906080016145db565b6040516020818303038152906040529a509a505050505050505050506116c6565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f636f756c64206e6f742066696e64206d61746368696e67206576656e7420736960448201527f67000000000000000000000000000000000000000000000000000000000000006064820152608401611c28565b60005a9050600080611d5184860186613f07565b9150915060008082806020019051810190611d6c919061466f565b6000828152600560209081526040808320546004909252822054939550919350909190611d976130af565b905082600003611db7576000858152600560205260409020819055611efb565b6000611dc38583614295565b6000878152600e6020908152604080832054600d835281842061ffff909116808552908352818420805483518186028101860190945280845295965090949192909190830182828015611e3557602002820191906000526020600020905b815481526020019060010190808311611e21575b505050505090507f000000000000000000000000000000000000000000000000000000000000000061ffff16815103611eb05781611e728161438e565b60008a8152600e6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff83161790559250505b506000878152600d6020908152604080832061ffff909416835292815282822080546001818101835591845282842001859055898352600c8252928220805493840181558252902001555b600085815260066020526040812054611f159060016142a8565b6000878152600660209081526040808320849055600490915290208390559050611f3f86836126d0565b60195460ff1615611f8257604051308152829087907f97009585a4d2440f981ab6f6eec514343e1e6b2aa9b991a26998e6806f41bf089060200160405180910390a35b611f8d868a84612b6c565b5050505050505050505050565b6000828152600d6020908152604080832061ffff85168452825291829020805483518184028101840190945280845260609392830182828015611ffc57602002820191906000526020600020905b815481526020019060010190808311611fe8575b5050505050905092915050565b60006060600084846040516020016120229291906145db565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00181529190526001969095509350505050565b8160005b818110156120fa5730635f17e61686868481811061208157612081614247565b90506020020135856040518363ffffffff1660e01b81526004016120b592919091825263ffffffff16602082015260400190565b600060405180830381600087803b1580156120cf57600080fd5b505af11580156120e3573d6000803e3d6000fd5b5050505080806120f2906142bb565b915050612061565b5050505050565b6013546040517f06e3b632000000000000000000000000000000000000000000000000000000008152600060048201819052602482018190529173ffffffffffffffffffffffffffffffffffffffff16906306e3b63290604401600060405180830381865afa158015612178573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526121be9190810190614693565b805190915060006121cd6130af565b905060005b828110156119965760008482815181106121ee576121ee614247565b60209081029190910101516013546040517f5147cd590000000000000000000000000000000000000000000000000000000081526004810183905291925060009173ffffffffffffffffffffffffffffffffffffffff90911690635147cd5990602401602060405180830381865afa15801561226e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122929190614724565b90508060ff166001036122d757604051308152849083907f97009585a4d2440f981ab6f6eec514343e1e6b2aa9b991a26998e6806f41bf089060200160405180910390a35b505080806122e4906142bb565b9150506121d2565b6122f4613335565b6012546040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612363573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123879190614417565b6012546040517fa9059cbb0000000000000000000000000000000000000000000000000000000081523360048201526024810183905291925073ffffffffffffffffffffffffffffffffffffffff169063a9059cbb906044016020604051808303816000875af11580156123ff573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fe8919061418f565b60008281526003602090815260408083208490556005825280832083905560068252808320839055600c909152812061245b91613806565b6000828152600e602052604081205461ffff16905b8161ffff168161ffff16116124b7576000848152600d6020908152604080832061ffff8516845290915281206124a591613806565b806124af8161438e565b915050612470565b5050506000908152600e6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000169055565b600081815260056020526040812054810361250d57506001919050565b6000828152600360209081526040808320546004909252909120546125306130af565b61253a9190614295565b101592915050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146125c3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401611c28565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6013546040517fcd7f71b500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063cd7f71b59061269990869086908690600401614741565b600060405180830381600087803b1580156126b357600080fd5b505af11580156126c7573d6000803e3d6000fd5b50505050505050565b6014546000838152600260205260409020546126ec9083614295565b1115610fe8576013546040517fc7c3a19a0000000000000000000000000000000000000000000000000000000081526004810184905260009173ffffffffffffffffffffffffffffffffffffffff169063c7c3a19a90602401600060405180830381865afa158015612762573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526127a891908101906147c3565b6013546040517fb657bc9c0000000000000000000000000000000000000000000000000000000081526004810186905291925060009173ffffffffffffffffffffffffffffffffffffffff9091169063b657bc9c90602401602060405180830381865afa15801561281d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061284191906148e2565b6015549091506128659082906c01000000000000000000000000900460ff16614150565b6bffffffffffffffffffffffff1682606001516bffffffffffffffffffffffff161015611996576015546128a89085906bffffffffffffffffffffffff16612915565b60008481526002602090815260409182902085905560155482518781526bffffffffffffffffffffffff909116918101919091529081018490527f49d4100ab0124eb4a9a65dc4ea08d6412a43f6f05c49194983f5b322bcc0a5c09060600160405180910390a150505050565b6012546013546040517f095ea7b300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff91821660048201526bffffffffffffffffffffffff8416602482015291169063095ea7b3906044016020604051808303816000875af115801561299d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129c1919061418f565b506013546040517f948108f7000000000000000000000000000000000000000000000000000000008152600481018490526bffffffffffffffffffffffff8316602482015273ffffffffffffffffffffffffffffffffffffffff9091169063948108f790604401600060405180830381600087803b158015612a4257600080fd5b505af1158015612a56573d6000803e3d6000fd5b505050505050565b6000818152600c6020908152604091829020805483518184028101840190945280845260609392830182828015612ab457602002820191906000526020600020905b815481526020019060010190808311612aa0575b50505050509050919050565b60168181548110612ad057600080fd5b906000526020600020016000915090508054612aeb90614430565b80601f0160208091040260200160405190810160405280929190818152602001828054612b1790614430565b8015612b645780601f10612b3957610100808354040283529160200191612b64565b820191906000526020600020905b815481529060010190602001808311612b4757829003601f168201915b505050505081565b6000838152600760205260409020545b805a612b889085614295565b612b94906127106142a8565b10156119965781406000908152600b6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055612b7c565b6013546040517fa72aa27e0000000000000000000000000000000000000000000000000000000081526004810184905263ffffffff8316602482015273ffffffffffffffffffffffffffffffffffffffff9091169063a72aa27e90604401600060405180830381600087803b158015612c4d57600080fd5b505af1158015612c61573d6000803e3d6000fd5b505050600092835250600a602052604090912063ffffffff9091169055565b6013546040517f744bfe610000000000000000000000000000000000000000000000000000000081526004810183905230602482015273ffffffffffffffffffffffffffffffffffffffff9091169063744bfe6190604401600060405180830381600087803b158015612cf257600080fd5b505af11580156120fa573d6000803e3d6000fd5b60178054612aeb90614430565b8060005b818163ffffffff161015611996573063af953a4a858563ffffffff8516818110612d4357612d43614247565b905060200201356040518263ffffffff1660e01b8152600401612d6891815260200190565b600060405180830381600087803b158015612d8257600080fd5b505af1158015612d96573d6000803e3d6000fd5b505050508080612da5906148ff565b915050612d17565b6013546040517fc80480220000000000000000000000000000000000000000000000000000000081526004810183905273ffffffffffffffffffffffffffffffffffffffff9091169063c804802290602401600060405180830381600087803b158015612e1957600080fd5b505af1158015612e2d573d6000803e3d6000fd5b50505050610fe881600f6133b890919063ffffffff16565b60188054612aeb90614430565b6000828152600c60209081526040808320805482518185028101850190935280835284938493929190830182828015612eaa57602002820191906000526020600020905b815481526020019060010190808311612e96575b505050505090506116c08185613151565b8060005b81811015611996576000848483818110612edb57612edb614247565b9050602002013590503073ffffffffffffffffffffffffffffffffffffffff16637e7a46dc8283604051602001612f1491815260200190565b6040516020818303038152906040526040518363ffffffff1660e01b8152600401612f4092919061422e565b600060405180830381600087803b158015612f5a57600080fd5b505af1158015612f6e573d6000803e3d6000fd5b50505050508080612f7e906142bb565b915050612ebf565b600c6020528160005260406000208181548110612fa257600080fd5b90600052602060002001600091509150505481565b612fbf613335565b612fc8816133c4565b50565b6011546040517f3f678e11000000000000000000000000000000000000000000000000000000008152600091829173ffffffffffffffffffffffffffffffffffffffff90911690633f678e1190613026908690600401614918565b6020604051808303816000875af1158015613045573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130699190614417565b9050613076600f826134b9565b506060909201516000838152600a6020526040902063ffffffff90911690555090565b60006114a1825490565b60006118fb83836134c5565b60007f00000000000000000000000000000000000000000000000000000000000000001561314c57606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613123573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131479190614417565b905090565b504390565b8151600090819081908415806131675750808510155b15613170578094505b60008092505b858310156131cc5786600161318b8585614295565b6131959190614295565b815181106131a5576131a5614247565b6020026020010151816131b891906142a8565b9050826131c4816142bb565b935050613176565b9694955050505050565b825160009081908315806131ea5750808410155b156131f3578093505b60008467ffffffffffffffff81111561320e5761320e613890565b604051908082528060200260200182016040528015613237578160200160208202803683370190505b509050600092505b848310156132a5578660016132548585614295565b61325e9190614295565b8151811061326e5761326e614247565b602002602001015181848151811061328857613288614247565b60209081029190910101528261329d816142bb565b93505061323f565b6132be816000600184516132b99190614295565b6134ef565b856064036132f75780600182516132d59190614295565b815181106132e5576132e5614247565b602002602001015193505050506118fb565b8060648251886133079190614a6a565b6133119190614ad6565b8151811061332157613321614247565b602002602001015193505050509392505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146133b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401611c28565b565b60006118fb8383613667565b3373ffffffffffffffffffffffffffffffffffffffff821603613443576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401611c28565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60006118fb8383613761565b60008260000182815481106134dc576134dc614247565b9060005260206000200154905092915050565b81818082036134ff575050505050565b600085600261350e8787614aea565b6135189190614b0a565b6135229087614b72565b8151811061353257613532614247565b602002602001015190505b818313613641575b8086848151811061355857613558614247565b60200260200101511015613578578261357081614b9a565b935050613545565b85828151811061358a5761358a614247565b60200260200101518110156135ab57816135a381614bcb565b925050613578565b81831361363c578582815181106135c4576135c4614247565b60200260200101518684815181106135de576135de614247565b60200260200101518785815181106135f8576135f8614247565b6020026020010188858151811061361157613611614247565b6020908102919091010191909152528261362a81614b9a565b935050818061363890614bcb565b9250505b61353d565b81851215613654576136548686846134ef565b83831215612a5657612a568684866134ef565b6000818152600183016020526040812054801561375057600061368b600183614295565b855490915060009061369f90600190614295565b90508181146137045760008660000182815481106136bf576136bf614247565b90600052602060002001549050808760000184815481106136e2576136e2614247565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061371557613715614c22565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506114a1565b60009150506114a1565b5092915050565b60008181526001830160205260408120546137a8575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556114a1565b5060006114a1565b8280548282559060005260206000209081019282156137f6579160200282015b828111156137f657825182906137e69082614c9c565b50916020019190600101906137d0565b50613802929150613824565b5090565b5080546000825590600052602060002090810190612fc89190613841565b808211156138025760006138388282613856565b50600101613824565b5b808211156138025760008155600101613842565b50805461386290614430565b6000825580601f10613872575050565b601f016020900490600052602060002090810190612fc89190613841565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff811182821017156138e3576138e3613890565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561393057613930613890565b604052919050565b600067ffffffffffffffff82111561395257613952613890565b5060051b60200190565b600067ffffffffffffffff82111561397657613976613890565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b60006139b56139b08461395c565b6138e9565b90508281528383830111156139c957600080fd5b828260208301376000602084830101529392505050565b600060208083850312156139f357600080fd5b823567ffffffffffffffff80821115613a0b57600080fd5b818501915085601f830112613a1f57600080fd5b8135613a2d6139b082613938565b81815260059190911b83018401908481019088831115613a4c57600080fd5b8585015b83811015613a9957803585811115613a685760008081fd5b8601603f81018b13613a7a5760008081fd5b613a8b8b89830135604084016139a2565b845250918601918601613a50565b5098975050505050505050565b60ff81168114612fc857600080fd5b63ffffffff81168114612fc857600080fd5b600082601f830112613ad857600080fd5b6118fb838335602085016139a2565b6bffffffffffffffffffffffff81168114612fc857600080fd5b600080600080600080600060e0888a031215613b1c57600080fd5b8735613b2781613aa6565b96506020880135613b3781613ab5565b95506040880135613b4781613aa6565b9450606088013567ffffffffffffffff811115613b6357600080fd5b613b6f8a828b01613ac7565b9450506080880135613b8081613ae7565b9699959850939692959460a0840135945060c09093013592915050565b60008060408385031215613bb057600080fd5b50508035926020909101359150565b6020808252825182820181905260009190848201906040850190845b81811015613bf757835183529284019291840191600101613bdb565b50909695505050505050565b803561ffff81168114613c1557600080fd5b919050565b600080600060608486031215613c2f57600080fd5b83359250613c3f60208501613c03565b9150604084013590509250925092565b600060208284031215613c6157600080fd5b5035919050565b60005b83811015613c83578181015183820152602001613c6b565b50506000910152565b60008151808452613ca4816020860160208601613c68565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006118fb6020830184613c8c565b60008060408385031215613cfc57600080fd5b82359150613d0c60208401613c03565b90509250929050565b73ffffffffffffffffffffffffffffffffffffffff81168114612fc857600080fd5b600060208284031215613d4957600080fd5b81356118fb81613d15565b600080600060608486031215613d6957600080fd5b505081359360208301359350604090920135919050565b60008083601f840112613d9257600080fd5b50813567ffffffffffffffff811115613daa57600080fd5b6020830191508360208260051b85010111156116c657600080fd5b60008060208385031215613dd857600080fd5b823567ffffffffffffffff811115613def57600080fd5b613dfb85828601613d80565b90969095509350505050565b60008060408385031215613e1a57600080fd5b823567ffffffffffffffff80821115613e3257600080fd5b908401906101008287031215613e4757600080fd5b90925060208401359080821115613e5d57600080fd5b50613e6a85828601613ac7565b9150509250929050565b82151581526040602082015260006118f86040830184613c8c565b60008083601f840112613ea157600080fd5b50813567ffffffffffffffff811115613eb957600080fd5b6020830191508360208285010111156116c657600080fd5b60008060208385031215613ee457600080fd5b823567ffffffffffffffff811115613efb57600080fd5b613dfb85828601613e8f565b60008060408385031215613f1a57600080fd5b823567ffffffffffffffff80821115613f3257600080fd5b818501915085601f830112613f4657600080fd5b81356020613f566139b083613938565b82815260059290921b84018101918181019089841115613f7557600080fd5b8286015b84811015613fad57803586811115613f915760008081fd5b613f9f8c86838b0101613ac7565b845250918301918301613f79565b5096505086013592505080821115613e5d57600080fd5b600080600060408486031215613fd957600080fd5b833567ffffffffffffffff811115613ff057600080fd5b613ffc86828701613d80565b909450925050602084013561401081613ab5565b809150509250925092565b8015158114612fc857600080fd5b60006020828403121561403b57600080fd5b81356118fb8161401b565b60008060006040848603121561405b57600080fd5b83359250602084013567ffffffffffffffff81111561407957600080fd5b61408586828701613e8f565b9497909650939450505050565b600080604083850312156140a557600080fd5b8235915060208301356140b781613ae7565b809150509250929050565b600080604083850312156140d557600080fd5b8235915060208301356140b781613ab5565b6000602082840312156140f957600080fd5b81356118fb81613ae7565b60006020828403121561411657600080fd5b81356118fb81613aa6565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006bffffffffffffffffffffffff8083168185168183048111821515161561417b5761417b614121565b02949350505050565b8051613c158161401b565b6000602082840312156141a157600080fd5b81516118fb8161401b565b600082601f8301126141bd57600080fd5b81516141cb6139b08261395c565b8181528460208386010111156141e057600080fd5b6141f1826020830160208701613c68565b949350505050565b60006020828403121561420b57600080fd5b815167ffffffffffffffff81111561422257600080fd5b6141f1848285016141ac565b8281526040602082015260006118f86040830184613c8c565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff821660ff810361428c5761428c614121565b60010192915050565b818103818111156114a1576114a1614121565b808201808211156114a1576114a1614121565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036142ec576142ec614121565b5060010190565b80516020808301519190811015614332577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8160200360031b1b821691505b50919050565b8051613c1581613d15565b6000806040838503121561435657600080fd5b825161436181613d15565b6020939093015192949293505050565b60006020828403121561438357600080fd5b81516118fb81613d15565b600061ffff8083168181036143a5576143a5614121565b6001019392505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126143e457600080fd5b83018035915067ffffffffffffffff8211156143ff57600080fd5b6020019150600581901b36038213156116c657600080fd5b60006020828403121561442957600080fd5b5051919050565b600181811c9082168061444457607f821691505b602082108103614332577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000815461448a81614430565b8085526020600183811680156144a757600181146144df5761450d565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008516838901528284151560051b890101955061450d565b866000528260002060005b858110156145055781548a82018601529083019084016144ea565b890184019650505b505050505092915050565b60a08152600061452b60a083018861447d565b6020838203818501528188548084528284019150828160051b8501018a6000528360002060005b8381101561459d577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe087840301855261458b838361447d565b94860194925060019182019101614552565b505086810360408801526145b1818b61447d565b94505050505084606084015282810360808401526145cf8185613c8c565b98975050505050505050565b6000604082016040835280855180835260608501915060608160051b8601019250602080880160005b83811015614650577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa088870301855261463e868351613c8c565b95509382019390820190600101614604565b5050858403818701525050506146668185613c8c565b95945050505050565b6000806040838503121561468257600080fd5b505080516020909101519092909150565b600060208083850312156146a657600080fd5b825167ffffffffffffffff8111156146bd57600080fd5b8301601f810185136146ce57600080fd5b80516146dc6139b082613938565b81815260059190911b820183019083810190878311156146fb57600080fd5b928401925b8284101561471957835182529284019290840190614700565b979650505050505050565b60006020828403121561473657600080fd5b81516118fb81613aa6565b83815260406020820152816040820152818360608301376000818301606090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016010192915050565b8051613c1581613ab5565b8051613c1581613ae7565b805167ffffffffffffffff81168114613c1557600080fd5b6000602082840312156147d557600080fd5b815167ffffffffffffffff808211156147ed57600080fd5b90830190610140828603121561480257600080fd5b61480a6138bf565b61481383614338565b815261482160208401614795565b602082015260408301518281111561483857600080fd5b614844878286016141ac565b604083015250614856606084016147a0565b606082015261486760808401614338565b608082015261487860a084016147ab565b60a082015261488960c08401614795565b60c082015261489a60e084016147a0565b60e08201526101006148ad818501614184565b9082015261012083810151838111156148c557600080fd5b6148d1888287016141ac565b918301919091525095945050505050565b6000602082840312156148f457600080fd5b81516118fb81613ae7565b600063ffffffff8083168181036143a5576143a5614121565b6020815260008251610140806020850152614937610160850183613c8c565b915060208501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0808685030160408701526149738483613c8c565b93506040870151915061499e606087018373ffffffffffffffffffffffffffffffffffffffff169052565b606087015163ffffffff811660808801529150608087015173ffffffffffffffffffffffffffffffffffffffff811660a0880152915060a087015160ff811660c0880152915060c08701519150808685030160e08701526149ff8483613c8c565b935060e08701519150610100818786030181880152614a1e8584613c8c565b945080880151925050610120818786030181880152614a3d8584613c8c565b94508088015192505050614a60828601826bffffffffffffffffffffffff169052565b5090949350505050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615614aa257614aa2614121565b500290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082614ae557614ae5614aa7565b500490565b818103600083128015838313168383128216171561375a5761375a614121565b600082614b1957614b19614aa7565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f800000000000000000000000000000000000000000000000000000000000000083141615614b6d57614b6d614121565b500590565b8082018281126000831280158216821582161715614b9257614b92614121565b505092915050565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036142ec576142ec614121565b60007f80000000000000000000000000000000000000000000000000000000000000008203614bfc57614bfc614121565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b601f821115614c9757600081815260208120601f850160051c81016020861015614c785750805b601f850160051c820191505b81811015612a5657828155600101614c84565b505050565b815167ffffffffffffffff811115614cb657614cb6613890565b614cca81614cc48454614430565b84614c51565b602080601f831160018114614d1d5760008415614ce75750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555612a56565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015614d6a57888601518255948401946001909101908401614d4b565b5085821015614da657878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b0190555056fea164736f6c6343000810000a307834353534343832643535353334343264343135323432343935343532353534643264353434353533353434653435353430303030303030303030303030303030307834323534343332643535353334343264343135323432343935343532353534643264353434353533353434653435353430303030303030303030303030303030",
+ ABI: "[{\"inputs\":[{\"internalType\":\"contractAutomationRegistrar2_1\",\"name\":\"_registrar\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_useArb\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"_useMercury\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"IndexOutOfRange\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"feedParamKey\",\"type\":\"string\"},{\"internalType\":\"string[]\",\"name\":\"feeds\",\"type\":\"string[]\"},{\"internalType\":\"string\",\"name\":\"timeParamKey\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"time\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"StreamsLookup\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"blockNum\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"LogEmitted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"blockNum\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"LogEmittedAgain\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"blockNum\",\"type\":\"uint256\"}],\"name\":\"UpkeepTopUp\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BUCKET_SIZE\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"addFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"addLinkAmount\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"}],\"name\":\"batchCancelUpkeeps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"},{\"internalType\":\"uint8\",\"name\":\"selector\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"topic0\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"topic1\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"topic2\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"topic3\",\"type\":\"bytes32\"}],\"name\":\"batchPreparingUpkeeps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"},{\"internalType\":\"uint8\",\"name\":\"log\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"selector\",\"type\":\"uint8\"}],\"name\":\"batchPreparingUpkeepsSimple\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"number\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"},{\"internalType\":\"uint256\",\"name\":\"checkGasToBurn\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"performGasToBurn\",\"type\":\"uint256\"}],\"name\":\"batchRegisterUpkeeps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"log\",\"type\":\"uint8\"}],\"name\":\"batchSendLogs\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"},{\"internalType\":\"uint32\",\"name\":\"interval\",\"type\":\"uint32\"}],\"name\":\"batchSetIntervals\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"}],\"name\":\"batchUpdatePipelineData\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"}],\"name\":\"batchWithdrawLinks\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"bucketedDelays\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"buckets\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"startGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"blockNum\",\"type\":\"uint256\"}],\"name\":\"burnPerformGas\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes[]\",\"name\":\"values\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"checkCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"checkGasToBurns\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"txHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"source\",\"type\":\"address\"},{\"internalType\":\"bytes32[]\",\"name\":\"topics\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"structLog\",\"name\":\"log\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"}],\"name\":\"checkLog\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"counters\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"delays\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"dummyMap\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"eligible\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"emittedAgainSig\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"emittedSig\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"feedParamKey\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"feedsHex\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"firstPerformBlocks\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"gasLimits\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"startIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxCount\",\"type\":\"uint256\"}],\"name\":\"getActiveUpkeepIDsDeployedByThisContract\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"startIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxCount\",\"type\":\"uint256\"}],\"name\":\"getAllActiveUpkeepIDsOnRegistry\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"getBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"bucket\",\"type\":\"uint16\"}],\"name\":\"getBucketedDelays\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getBucketedDelaysLength\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getDelays\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getDelaysLength\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepID\",\"type\":\"uint256\"}],\"name\":\"getForwarder\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"selector\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"topic0\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"topic1\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"topic2\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"topic3\",\"type\":\"bytes32\"}],\"name\":\"getLogTriggerConfig\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"logTrigger\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getMinBalanceForUpkeep\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"p\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"n\",\"type\":\"uint256\"}],\"name\":\"getPxDelayLastNPerforms\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"bucket\",\"type\":\"uint16\"}],\"name\":\"getSumDelayInBucket\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"n\",\"type\":\"uint256\"}],\"name\":\"getSumDelayLastNPerforms\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getTriggerType\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getUpkeepInfo\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"performGas\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"maxValidBlocknumber\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"lastPerformedBlockNumber\",\"type\":\"uint32\"},{\"internalType\":\"uint96\",\"name\":\"amountSpent\",\"type\":\"uint96\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"internalType\":\"structKeeperRegistryBase2_1.UpkeepInfo\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getUpkeepPrivilegeConfig\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getUpkeepTriggerConfig\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"intervals\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"lastTopUpBlocks\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"linkToken\",\"outputs\":[{\"internalType\":\"contractLinkTokenInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"logNum\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"minBalanceThresholdMultiplier\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"performDataSizes\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"performGasToBurns\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"}],\"name\":\"performUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"previousPerformBlocks\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"registrar\",\"outputs\":[{\"internalType\":\"contractAutomationRegistrar2_1\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"registry\",\"outputs\":[{\"internalType\":\"contractIKeeperRegistryMaster\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"log\",\"type\":\"uint8\"}],\"name\":\"sendLog\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractAutomationRegistrar2_1\",\"name\":\"newRegistrar\",\"type\":\"address\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string[]\",\"name\":\"_feeds\",\"type\":\"string[]\"}],\"name\":\"setFeeds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_interval\",\"type\":\"uint256\"}],\"name\":\"setInterval\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"_log\",\"type\":\"uint8\"}],\"name\":\"setLog\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_feedParamKey\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_timeParamKey\",\"type\":\"string\"}],\"name\":\"setParamKeys\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"setPerformDataSize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"}],\"name\":\"setUpkeepGasLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"cfg\",\"type\":\"bytes\"}],\"name\":\"setUpkeepPrivilegeConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"timeParamKey\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"blockNum\",\"type\":\"uint256\"}],\"name\":\"topUpFund\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"selector\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"topic0\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"topic1\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"topic2\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"topic3\",\"type\":\"bytes32\"}],\"name\":\"updateLogTriggerConfig1\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"cfg\",\"type\":\"bytes\"}],\"name\":\"updateLogTriggerConfig2\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"pipelineData\",\"type\":\"bytes\"}],\"name\":\"updateUpkeepPipelineData\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"upkeepTopUpCheckInterval\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"useArbitrumBlockNum\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"useMercury\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawLinks\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"withdrawLinks\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]",
+ Bin: "0x7f97009585a4d2440f981ab6f6eec514343e1e6b2aa9b991a26998e6806f41bf086080527fc76416badc8398ce17c93eab7b4f60f263241694cf503e4df24f233a8cc1c50d60a0526005601455601580546001600160681b0319166c140000000002c68af0bb140000179055606460e0526101c0604052604261014081815261010091829190620066ec6101603981526020016040518060800160405280604281526020016200672e604291399052620000be906016906002620003de565b506040805180820190915260098152680cccacac892c890caf60bb1b6020820152601790620000ee90826200055a565b5060408051808201909152600b81526a313637b1b5a73ab6b132b960a91b60208201526018906200012090826200055a565b503480156200012e57600080fd5b506040516200677038038062006770833981016040819052620001519162000652565b82823380600081620001aa5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620001dd57620001dd8162000333565b5050601180546001600160a01b0319166001600160a01b038516908117909155604080516330fe427560e21b815281516000945063c3f909d4926004808401939192918290030181865afa1580156200023a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200026091906200069e565b50601380546001600160a01b0319166001600160a01b038381169190911790915560115460408051631b6b6d2360e01b81529051939450911691631b6b6d23916004808201926020929091908290030181865afa158015620002c6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002ec9190620006cf565b601280546001600160a01b0319166001600160a01b039290921691909117905550151560c052506019805461ffff191691151561ff00191691909117905550620006f69050565b336001600160a01b038216036200038d5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401620001a1565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b82805482825590600052602060002090810192821562000429579160200282015b828111156200042957825182906200041890826200055a565b5091602001919060010190620003ff565b50620004379291506200043b565b5090565b80821115620004375760006200045282826200045c565b506001016200043b565b5080546200046a90620004cb565b6000825580601f106200047b575050565b601f0160209004906000526020600020908101906200049b91906200049e565b50565b5b808211156200043757600081556001016200049f565b634e487b7160e01b600052604160045260246000fd5b600181811c90821680620004e057607f821691505b6020821081036200050157634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200055557600081815260208120601f850160051c81016020861015620005305750805b601f850160051c820191505b8181101562000551578281556001016200053c565b5050505b505050565b81516001600160401b03811115620005765762000576620004b5565b6200058e81620005878454620004cb565b8462000507565b602080601f831160018114620005c65760008415620005ad5750858301515b600019600386901b1c1916600185901b17855562000551565b600085815260208120601f198616915b82811015620005f757888601518255948401946001909101908401620005d6565b5085821015620006165787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6001600160a01b03811681146200049b57600080fd5b805180151581146200064d57600080fd5b919050565b6000806000606084860312156200066857600080fd5b8351620006758162000626565b925062000685602085016200063c565b915062000695604085016200063c565b90509250925092565b60008060408385031215620006b257600080fd5b8251620006bf8162000626565b6020939093015192949293505050565b600060208284031215620006e257600080fd5b8151620006ef8162000626565b9392505050565b60805160a05160c05160e051615f926200075a600039600081816105b90152612551015260008181610a2d01526140920152600081816108a601528181611fa80152613ae0015260008181610dca01528181611f780152613ab50152615f926000f3fe6080604052600436106105265760003560e01c80637b103999116102af578063af953a4a11610179578063daee1aeb116100d6578063e83ce5581161008a578063fa333dfb1161006f578063fa333dfb14611066578063fba7ffa314611119578063fcdc1f631461114657600080fd5b8063e83ce55814611027578063f2fde38b1461104657600080fd5b8063de818253116100bb578063de81825314610f90578063e0114adb14610fe4578063e45530831461101157600080fd5b8063daee1aeb14610f50578063dbef701e14610f7057600080fd5b8063c41c815b1161012d578063d4c2490011610112578063d4c2490014610ef0578063d6051a7214610f10578063da6cba4714610f3057600080fd5b8063c41c815b14610ec1578063c98f10b014610edb57600080fd5b8063b657bc9c1161015e578063b657bc9c14610e61578063becde0e114610e81578063c041982214610ea157600080fd5b8063af953a4a14610e2c578063afb28d1f14610e4c57600080fd5b8063948108f7116102275780639d385eaa116101db578063a6548248116101c0578063a654824814610db8578063a6b5947514610dec578063a72aa27e14610e0c57600080fd5b80639d385eaa14610d785780639d6f1cc714610d9857600080fd5b80639ac542eb1161020c5780639ac542eb14610cf05780639b42935414610d1a5780639b51fb0d14610d4757600080fd5b8063948108f714610cb057806396cebc7c14610cd057600080fd5b806386e330af1161027e5780638da5cb5b116102635780638da5cb5b14610c385780638fcb3fba14610c63578063924ca57814610c9057600080fd5b806386e330af14610bf8578063873c758614610c1857600080fd5b80637b10399914610b6b5780637e7a46dc14610b985780638243444a14610bb85780638340507c14610bd857600080fd5b806345d2ec17116103f057806360457ff51161036857806373644cce1161031c578063776898c811610301578063776898c814610b1657806379ba509714610b3657806379ea994314610b4b57600080fd5b806373644cce14610abc5780637672130314610ae957600080fd5b8063642f6cef1161034d578063642f6cef14610a1b57806369cdbadb14610a5f5780637145f11b14610a8c57600080fd5b806360457ff5146109c9578063636092e8146109f657600080fd5b80635147cd59116103bf57806357970e93116103a457806357970e93146109675780635d4ee7f3146109945780635f17e616146109a957600080fd5b80635147cd591461091557806351c98be31461094757600080fd5b806345d2ec1714610867578063469820931461089457806346e7a63e146108c85780634b56a42e146108f557600080fd5b806320e3dbd41161049e5780632b20e397116104525780633ebe8d6c116104375780633ebe8d6c146107f957806340691db4146108195780634585e33b1461084757600080fd5b80632b20e3971461077a578063328ffd11146107cc57600080fd5b806328c4b57b1161048357806328c4b57b1461070d57806329e0a8411461072d5780632a9032d31461075a57600080fd5b806320e3dbd4146106cd5780632636aecf146106ed57600080fd5b806319d97a94116104f55780631e010439116104da5780631e0104391461063b578063206c32e814610678578063207b6516146106ad57600080fd5b806319d97a94146105ee5780631cdde2511461061b57600080fd5b806306c1cc0014610532578063077ac621146105545780630b7d33e61461058757806312c55027146105a757600080fd5b3661052d57005b600080fd5b34801561053e57600080fd5b5061055261054d366004614814565b611173565b005b34801561056057600080fd5b5061057461056f3660046148c7565b6113c2565b6040519081526020015b60405180910390f35b34801561059357600080fd5b506105526105a23660046148fc565b611400565b3480156105b357600080fd5b506105db7f000000000000000000000000000000000000000000000000000000000000000081565b60405161ffff909116815260200161057e565b3480156105fa57600080fd5b5061060e610609366004614943565b61148e565b60405161057e91906149ca565b34801561062757600080fd5b506105526106363660046149ff565b61154b565b34801561064757600080fd5b5061065b610656366004614943565b611688565b6040516bffffffffffffffffffffffff909116815260200161057e565b34801561068457600080fd5b50610698610693366004614a64565b61171d565b6040805192835260208301919091520161057e565b3480156106b957600080fd5b5061060e6106c8366004614943565b6117a0565b3480156106d957600080fd5b506105526106e8366004614a90565b6117f8565b3480156106f957600080fd5b50610552610708366004614af2565b6119c2565b34801561071957600080fd5b50610574610728366004614b6c565b611c8b565b34801561073957600080fd5b5061074d610748366004614943565b611cf6565b60405161057e9190614b98565b34801561076657600080fd5b50610552610775366004614cd9565b611dfb565b34801561078657600080fd5b506011546107a79073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161057e565b3480156107d857600080fd5b506105746107e7366004614943565b60036020526000908152604090205481565b34801561080557600080fd5b50610574610814366004614943565b611edc565b34801561082557600080fd5b50610839610834366004614d1b565b611f45565b60405161057e929190614d7e565b34801561085357600080fd5b50610552610862366004614ddb565b61244b565b34801561087357600080fd5b50610887610882366004614a64565b61269a565b60405161057e9190614e11565b3480156108a057600080fd5b506105747f000000000000000000000000000000000000000000000000000000000000000081565b3480156108d457600080fd5b506105746108e3366004614943565b600a6020526000908152604090205481565b34801561090157600080fd5b50610839610910366004614e79565b612709565b34801561092157600080fd5b50610935610930366004614943565b61275d565b60405160ff909116815260200161057e565b34801561095357600080fd5b50610552610962366004614f36565b6127f1565b34801561097357600080fd5b506012546107a79073ffffffffffffffffffffffffffffffffffffffff1681565b3480156109a057600080fd5b50610552612895565b3480156109b557600080fd5b506105526109c4366004614f8d565b6129d0565b3480156109d557600080fd5b506105746109e4366004614943565b60076020526000908152604090205481565b348015610a0257600080fd5b5060155461065b906bffffffffffffffffffffffff1681565b348015610a2757600080fd5b50610a4f7f000000000000000000000000000000000000000000000000000000000000000081565b604051901515815260200161057e565b348015610a6b57600080fd5b50610574610a7a366004614943565b60086020526000908152604090205481565b348015610a9857600080fd5b50610a4f610aa7366004614943565b600b6020526000908152604090205460ff1681565b348015610ac857600080fd5b50610574610ad7366004614943565b6000908152600c602052604090205490565b348015610af557600080fd5b50610574610b04366004614943565b60046020526000908152604090205481565b348015610b2257600080fd5b50610a4f610b31366004614943565b612a9d565b348015610b4257600080fd5b50610552612aef565b348015610b5757600080fd5b506107a7610b66366004614943565b612bec565b348015610b7757600080fd5b506013546107a79073ffffffffffffffffffffffffffffffffffffffff1681565b348015610ba457600080fd5b50610552610bb3366004614faf565b612c80565b348015610bc457600080fd5b50610552610bd3366004614faf565b612d11565b348015610be457600080fd5b50610552610bf3366004614ffb565b612d6b565b348015610c0457600080fd5b50610552610c13366004615048565b612d89565b348015610c2457600080fd5b50610887610c33366004614f8d565b612d9c565b348015610c4457600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff166107a7565b348015610c6f57600080fd5b50610574610c7e366004614943565b60056020526000908152604090205481565b348015610c9c57600080fd5b50610552610cab366004614f8d565b612e59565b348015610cbc57600080fd5b50610552610ccb3660046150f9565b61309e565b348015610cdc57600080fd5b50610552610ceb366004615129565b6131b6565b348015610cfc57600080fd5b50601554610935906c01000000000000000000000000900460ff1681565b348015610d2657600080fd5b50610552610d35366004614f8d565b60009182526009602052604090912055565b348015610d5357600080fd5b506105db610d62366004614943565b600e6020526000908152604090205461ffff1681565b348015610d8457600080fd5b50610887610d93366004614943565b6133c0565b348015610da457600080fd5b5061060e610db3366004614943565b613422565b348015610dc457600080fd5b506105747f000000000000000000000000000000000000000000000000000000000000000081565b348015610df857600080fd5b50610552610e07366004614b6c565b6134ce565b348015610e1857600080fd5b50610552610e27366004615146565b613537565b348015610e3857600080fd5b50610552610e47366004614943565b6135e2565b348015610e5857600080fd5b5061060e613668565b348015610e6d57600080fd5b5061065b610e7c366004614943565b613675565b348015610e8d57600080fd5b50610552610e9c366004614cd9565b6136cd565b348015610ead57600080fd5b50610887610ebc366004614f8d565b613767565b348015610ecd57600080fd5b50601954610a4f9060ff1681565b348015610ee757600080fd5b5061060e613864565b348015610efc57600080fd5b50610552610f0b36600461516b565b613871565b348015610f1c57600080fd5b50610698610f2b366004614f8d565b6138f0565b348015610f3c57600080fd5b50610552610f4b366004615190565b613959565b348015610f5c57600080fd5b50610552610f6b366004614cd9565b613cc0565b348015610f7c57600080fd5b50610574610f8b366004614f8d565b613d8b565b348015610f9c57600080fd5b50610552610fab366004615129565b6019805460ff909216610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff909216919091179055565b348015610ff057600080fd5b50610574610fff366004614943565b60096020526000908152604090205481565b34801561101d57600080fd5b5061057460145481565b34801561103357600080fd5b5060195461093590610100900460ff1681565b34801561105257600080fd5b50610552611061366004614a90565b613dbc565b34801561107257600080fd5b5061060e6110813660046151f8565b6040805160c0808201835273ffffffffffffffffffffffffffffffffffffffff9890981680825260ff97881660208084019182528385019889526060808501988952608080860198895260a095860197885286519283019490945291519099168985015296519688019690965293519486019490945290519184019190915251828401528051808303909301835260e0909101905290565b34801561112557600080fd5b50610574611134366004614943565b60066020526000908152604090205481565b34801561115257600080fd5b50610574611161366004614943565b60026020526000908152604090205481565b6040805161018081018252600461014082019081527f746573740000000000000000000000000000000000000000000000000000000061016083015281528151602081810184526000808352818401929092523083850181905263ffffffff8b166060850152608084015260ff808a1660a08501528451808301865283815260c085015260e0840189905284519182019094529081526101008201526bffffffffffffffffffffffff8516610120820152601254601154919273ffffffffffffffffffffffffffffffffffffffff9182169263095ea7b3921690611259908c1688615280565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815273ffffffffffffffffffffffffffffffffffffffff90921660048301526bffffffffffffffffffffffff1660248201526044016020604051808303816000875af11580156112d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112fb91906152c4565b5060008860ff1667ffffffffffffffff81111561131a5761131a6146b6565b604051908082528060200260200182016040528015611343578160200160208202803683370190505b50905060005b8960ff168160ff1610156113b657600061136284613dd0565b905080838360ff168151811061137a5761137a6152df565b602090810291909101810191909152600091825260088152604080832088905560079091529020849055806113ae8161530e565b915050611349565b50505050505050505050565b600d60205282600052604060002060205281600052604060002081815481106113ea57600080fd5b9060005260206000200160009250925050505481565b6013546040517f0b7d33e600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911690630b7d33e690611458908590859060040161532d565b600060405180830381600087803b15801561147257600080fd5b505af1158015611486573d6000803e3d6000fd5b505050505050565b6013546040517f19d97a940000000000000000000000000000000000000000000000000000000081526004810183905260609173ffffffffffffffffffffffffffffffffffffffff16906319d97a94906024015b600060405180830381865afa1580156114ff573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526115459190810190615393565b92915050565b6013546040517ffa333dfb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff888116600483015260ff8816602483015260448201879052606482018690526084820185905260a4820184905290911690634ee88d35908990309063fa333dfb9060c401600060405180830381865afa1580156115ea573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526116309190810190615393565b6040518363ffffffff1660e01b815260040161164d92919061532d565b600060405180830381600087803b15801561166757600080fd5b505af115801561167b573d6000803e3d6000fd5b5050505050505050505050565b6013546040517f1e0104390000000000000000000000000000000000000000000000000000000081526004810183905260009173ffffffffffffffffffffffffffffffffffffffff1690631e010439906024015b602060405180830381865afa1580156116f9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061154591906153d3565b6000828152600d6020908152604080832061ffff85168452825280832080548251818502810185019093528083528493849392919083018282801561178157602002820191906000526020600020905b81548152602001906001019080831161176d575b50505050509050611793818251613e9e565b92509250505b9250929050565b6013546040517f207b65160000000000000000000000000000000000000000000000000000000081526004810183905260609173ffffffffffffffffffffffffffffffffffffffff169063207b6516906024016114e2565b601180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8316908117909155604080517fc3f909d400000000000000000000000000000000000000000000000000000000815281516000939263c3f909d492600480820193918290030181865afa15801561188e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118b291906153fb565b50601380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691909117909155601154604080517f1b6b6d230000000000000000000000000000000000000000000000000000000081529051939450911691631b6b6d23916004808201926020929091908290030181865afa158015611955573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119799190615429565b601280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff929092169190911790555050565b8560005b81811015611c805760008989838181106119e2576119e26152df565b9050602002013590503073ffffffffffffffffffffffffffffffffffffffff16637e7a46dc8283604051602001611a1b91815260200190565b6040516020818303038152906040526040518363ffffffff1660e01b8152600401611a4792919061532d565b600060405180830381600087803b158015611a6157600080fd5b505af1158015611a75573d6000803e3d6000fd5b50506013546040517f5147cd59000000000000000000000000000000000000000000000000000000008152600481018590526000935073ffffffffffffffffffffffffffffffffffffffff9091169150635147cd5990602401602060405180830381865afa158015611aeb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b0f9190615446565b90508060ff16600103611c6b576040517ffa333dfb000000000000000000000000000000000000000000000000000000008152306004820181905260ff8b166024830152604482018a9052606482018890526084820188905260a4820187905260009163fa333dfb9060c401600060405180830381865afa158015611b98573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611bde9190810190615393565b6013546040517f4ee88d3500000000000000000000000000000000000000000000000000000000815291925073ffffffffffffffffffffffffffffffffffffffff1690634ee88d3590611c37908690859060040161532d565b600060405180830381600087803b158015611c5157600080fd5b505af1158015611c65573d6000803e3d6000fd5b50505050505b50508080611c7890615463565b9150506119c6565b505050505050505050565b6000838152600c602090815260408083208054825181850281018501909352808352611cec93830182828015611ce057602002820191906000526020600020905b815481526020019060010190808311611ccc575b50505050508484613f23565b90505b9392505050565b604080516101408101825260008082526020820181905260609282018390528282018190526080820181905260a0820181905260c0820181905260e082018190526101008201526101208101919091526013546040517fc7c3a19a0000000000000000000000000000000000000000000000000000000081526004810184905273ffffffffffffffffffffffffffffffffffffffff9091169063c7c3a19a90602401600060405180830381865afa158015611db5573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261154591908101906154be565b8060005b818160ff161015611ed65760135473ffffffffffffffffffffffffffffffffffffffff1663c8048022858560ff8516818110611e3d57611e3d6152df565b905060200201356040518263ffffffff1660e01b8152600401611e6291815260200190565b600060405180830381600087803b158015611e7c57600080fd5b505af1158015611e90573d6000803e3d6000fd5b50505050611ec384848360ff16818110611eac57611eac6152df565b90506020020135600f61408290919063ffffffff16565b5080611ece8161530e565b915050611dff565b50505050565b6000818152600e602052604081205461ffff1681805b8261ffff168161ffff1611611f3d576000858152600d6020908152604080832061ffff85168452909152902054611f2990836155dd565b915080611f35816155f0565b915050611ef2565b509392505050565b6000606060005a90506000611f5861408e565b9050600085806020019051810190611f709190615611565b6019549091507f000000000000000000000000000000000000000000000000000000000000000090610100900460ff1615611fc857507f00000000000000000000000000000000000000000000000000000000000000005b80611fd660c08a018a61562a565b6000818110611fe757611fe76152df565b90506020020135036123e957600061200260c08a018a61562a565b6001818110612013576120136152df565b9050602002013560405160200161202c91815260200190565b60405160208183030381529060405290506000818060200190518101906120539190615611565b90508381146120c3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f75706b6565702069647320646f6e2774206d617463680000000000000000000060448201526064015b60405180910390fd5b60006120d260c08c018c61562a565b60028181106120e3576120e36152df565b905060200201356040516020016120fc91815260200190565b60405160208183030381529060405290506000818060200190518101906121239190615611565b9050600061213460c08e018e61562a565b6003818110612145576121456152df565b9050602002013560405160200161215e91815260200190565b60405160208183030381529060405290506000818060200190518101906121859190615429565b6000868152600860205260409020549091505b805a6121a4908d615692565b6121b090613a986155dd565b10156121f15783406000908152600b6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055612198565b6040517f6665656449644865780000000000000000000000000000000000000000000000602082015260009060290160405160208183030381529060405280519060200120601760405160200161224891906156f8565b604051602081830303815290604052805190602001200361226a57508361226d565b50425b60195460ff161561231557604080516020810189905290810186905273ffffffffffffffffffffffffffffffffffffffff841660608201526017906016906018908490608001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527ff055e4a20000000000000000000000000000000000000000000000000000000082526120ba9594939291600401615827565b60165460009067ffffffffffffffff811115612333576123336146b6565b60405190808252806020026020018201604052801561236657816020015b60608152602001906001900390816123515790505b5060408051602081018b905290810188905273ffffffffffffffffffffffffffffffffffffffff861660608201529091506000906080016040516020818303038152906040529050600182826040516020016123c39291906158ea565b6040516020818303038152906040529f509f505050505050505050505050505050611799565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f756e6578706563746564206576656e742073696700000000000000000000000060448201526064016120ba565b60005a905060008061245f84860186614e79565b9150915060008060008380602001905181019061247c919061597e565b60008381526005602090815260408083205460049092528220549497509295509093509091906124aa61408e565b9050826000036124ca57600086815260056020526040902081905561260e565b60006124d68683615692565b6000888152600e6020908152604080832054600d835281842061ffff90911680855290835281842080548351818602810186019094528084529596509094919290919083018282801561254857602002820191906000526020600020905b815481526020019060010190808311612534575b505050505090507f000000000000000000000000000000000000000000000000000000000000000061ffff168151036125c35781612585816155f0565b60008b8152600e6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff83161790559250505b506000888152600d6020908152604080832061ffff9094168352928152828220805460018181018355918452828420018590558a8352600c8252928220805493840181558252902001555b6000868152600660205260408120546126289060016155dd565b60008881526006602090815260408083208490556004909152902083905590506126528783612e59565b6040513090839089907f97009585a4d2440f981ab6f6eec514343e1e6b2aa9b991a26998e6806f41bf0890600090a461268c878b846134ce565b505050505050505050505050565b6000828152600d6020908152604080832061ffff851684528252918290208054835181840281018401909452808452606093928301828280156126fc57602002820191906000526020600020905b8154815260200190600101908083116126e8575b5050505050905092915050565b60006060600084846040516020016127229291906158ea565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00181529190526001969095509350505050565b6013546040517f5147cd590000000000000000000000000000000000000000000000000000000081526004810183905260009173ffffffffffffffffffffffffffffffffffffffff1690635147cd5990602401602060405180830381865afa1580156127cd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115459190615446565b8160005b8181101561288e5730635f17e616868684818110612815576128156152df565b90506020020135856040518363ffffffff1660e01b815260040161284992919091825263ffffffff16602082015260400190565b600060405180830381600087803b15801561286357600080fd5b505af1158015612877573d6000803e3d6000fd5b50505050808061288690615463565b9150506127f5565b5050505050565b61289d614130565b6012546040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561290c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129309190615611565b6012546040517fa9059cbb0000000000000000000000000000000000000000000000000000000081523360048201526024810183905291925073ffffffffffffffffffffffffffffffffffffffff169063a9059cbb906044016020604051808303816000875af11580156129a8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129cc91906152c4565b5050565b60008281526003602090815260408083208490556005825280832083905560068252808320839055600c9091528120612a08916145b5565b6000828152600e602052604081205461ffff16905b8161ffff168161ffff1611612a64576000848152600d6020908152604080832061ffff851684529091528120612a52916145b5565b80612a5c816155f0565b915050612a1d565b5050506000908152600e6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000169055565b6000818152600560205260408120548103612aba57506001919050565b600082815260036020908152604080832054600490925290912054612add61408e565b612ae79190615692565b101592915050565b60015473ffffffffffffffffffffffffffffffffffffffff163314612b70576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016120ba565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6013546040517f79ea99430000000000000000000000000000000000000000000000000000000081526004810183905260009173ffffffffffffffffffffffffffffffffffffffff16906379ea994390602401602060405180830381865afa158015612c5c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115459190615429565b6013546040517fcd7f71b500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063cd7f71b590612cda908690869086906004016159ac565b600060405180830381600087803b158015612cf457600080fd5b505af1158015612d08573d6000803e3d6000fd5b50505050505050565b6013546040517f4ee88d3500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911690634ee88d3590612cda908690869086906004016159ac565b6017612d778382615a46565b506018612d848282615a46565b505050565b80516129cc9060169060208401906145d3565b6013546040517f06e3b632000000000000000000000000000000000000000000000000000000008152600481018490526024810183905260609173ffffffffffffffffffffffffffffffffffffffff16906306e3b63290604401600060405180830381865afa158015612e13573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611cef9190810190615b60565b601454600083815260026020526040902054612e759083615692565b11156129cc576013546040517fc7c3a19a0000000000000000000000000000000000000000000000000000000081526004810184905260009173ffffffffffffffffffffffffffffffffffffffff169063c7c3a19a90602401600060405180830381865afa158015612eeb573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052612f3191908101906154be565b6013546040517fb657bc9c0000000000000000000000000000000000000000000000000000000081526004810186905291925060009173ffffffffffffffffffffffffffffffffffffffff9091169063b657bc9c90602401602060405180830381865afa158015612fa6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fca91906153d3565b601554909150612fee9082906c01000000000000000000000000900460ff16615280565b6bffffffffffffffffffffffff1682606001516bffffffffffffffffffffffff161015611ed6576015546130319085906bffffffffffffffffffffffff1661309e565b60008481526002602090815260409182902085905560155482518781526bffffffffffffffffffffffff909116918101919091529081018490527f49d4100ab0124eb4a9a65dc4ea08d6412a43f6f05c49194983f5b322bcc0a5c09060600160405180910390a150505050565b6012546013546040517f095ea7b300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff91821660048201526bffffffffffffffffffffffff8416602482015291169063095ea7b3906044016020604051808303816000875af1158015613126573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061314a91906152c4565b506013546040517f948108f7000000000000000000000000000000000000000000000000000000008152600481018490526bffffffffffffffffffffffff8316602482015273ffffffffffffffffffffffffffffffffffffffff9091169063948108f790604401611458565b6040517fc04198220000000000000000000000000000000000000000000000000000000081526000600482018190526024820181905290309063c041982290604401600060405180830381865afa158015613215573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261325b9190810190615b60565b8051909150600061326a61408e565b905060005b8281101561288e57600084828151811061328b5761328b6152df565b60209081029190910101516013546040517f5147cd590000000000000000000000000000000000000000000000000000000081526004810183905291925060009173ffffffffffffffffffffffffffffffffffffffff90911690635147cd5990602401602060405180830381865afa15801561330b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061332f9190615446565b90508060ff166001036133ab578660ff1660000361337b576040513090859084907f97009585a4d2440f981ab6f6eec514343e1e6b2aa9b991a26998e6806f41bf0890600090a46133ab565b6040513090859084907fc76416badc8398ce17c93eab7b4f60f263241694cf503e4df24f233a8cc1c50d90600090a45b505080806133b890615463565b91505061326f565b6000818152600c602090815260409182902080548351818402810184019094528084526060939283018282801561341657602002820191906000526020600020905b815481526020019060010190808311613402575b50505050509050919050565b6016818154811061343257600080fd5b90600052602060002001600091509050805461344d906156a5565b80601f0160208091040260200160405190810160405280929190818152602001828054613479906156a5565b80156134c65780601f1061349b576101008083540402835291602001916134c6565b820191906000526020600020905b8154815290600101906020018083116134a957829003601f168201915b505050505081565b6000838152600760205260409020545b805a6134ea9085615692565b6134f6906127106155dd565b1015611ed65781406000908152600b6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690556134de565b6013546040517fa72aa27e0000000000000000000000000000000000000000000000000000000081526004810184905263ffffffff8316602482015273ffffffffffffffffffffffffffffffffffffffff9091169063a72aa27e90604401600060405180830381600087803b1580156135af57600080fd5b505af11580156135c3573d6000803e3d6000fd5b505050600092835250600a602052604090912063ffffffff9091169055565b6013546040517f744bfe610000000000000000000000000000000000000000000000000000000081526004810183905230602482015273ffffffffffffffffffffffffffffffffffffffff9091169063744bfe6190604401600060405180830381600087803b15801561365457600080fd5b505af115801561288e573d6000803e3d6000fd5b6017805461344d906156a5565b6013546040517fb657bc9c0000000000000000000000000000000000000000000000000000000081526004810183905260009173ffffffffffffffffffffffffffffffffffffffff169063b657bc9c906024016116dc565b8060005b818163ffffffff161015611ed6573063af953a4a858563ffffffff85168181106136fd576136fd6152df565b905060200201356040518263ffffffff1660e01b815260040161372291815260200190565b600060405180830381600087803b15801561373c57600080fd5b505af1158015613750573d6000803e3d6000fd5b50505050808061375f90615bf1565b9150506136d1565b60606000613775600f6141b3565b90508084106137b0576040517f1390f2a100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b826000036137c5576137c28482615692565b92505b60008367ffffffffffffffff8111156137e0576137e06146b6565b604051908082528060200260200182016040528015613809578160200160208202803683370190505b50905060005b8481101561385b5761382c61382482886155dd565b600f906141bd565b82828151811061383e5761383e6152df565b60209081029190910101528061385381615463565b91505061380f565b50949350505050565b6018805461344d906156a5565b600061387b61408e565b90508160ff166000036138bc576040513090829085907f97009585a4d2440f981ab6f6eec514343e1e6b2aa9b991a26998e6806f41bf0890600090a4505050565b6040513090829085907fc76416badc8398ce17c93eab7b4f60f263241694cf503e4df24f233a8cc1c50d90600090a4505050565b6000828152600c6020908152604080832080548251818502810185019093528083528493849392919083018282801561394857602002820191906000526020600020905b815481526020019060010190808311613934575b505050505090506117938185613e9e565b8260005b81811015611486576000868683818110613979576139796152df565b9050602002013590503073ffffffffffffffffffffffffffffffffffffffff16637e7a46dc82836040516020016139b291815260200190565b6040516020818303038152906040526040518363ffffffff1660e01b81526004016139de92919061532d565b600060405180830381600087803b1580156139f857600080fd5b505af1158015613a0c573d6000803e3d6000fd5b50506013546040517f5147cd59000000000000000000000000000000000000000000000000000000008152600481018590526000935073ffffffffffffffffffffffffffffffffffffffff9091169150635147cd5990602401602060405180830381865afa158015613a82573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613aa69190615446565b90508060ff16600103613cab577f000000000000000000000000000000000000000000000000000000000000000060ff871615613b0057507f00000000000000000000000000000000000000000000000000000000000000005b60003073ffffffffffffffffffffffffffffffffffffffff1663fa333dfb30898588604051602001613b3491815260200190565b604051602081830303815290604052613b4c90615c0a565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff909416600485015260ff90921660248401526044830152606482015260006084820181905260a482015260c401600060405180830381865afa158015613bd7573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052613c1d9190810190615393565b6013546040517f4ee88d3500000000000000000000000000000000000000000000000000000000815291925073ffffffffffffffffffffffffffffffffffffffff1690634ee88d3590613c76908790859060040161532d565b600060405180830381600087803b158015613c9057600080fd5b505af1158015613ca4573d6000803e3d6000fd5b5050505050505b50508080613cb890615463565b91505061395d565b8060005b81811015611ed6576000848483818110613ce057613ce06152df565b9050602002013590503073ffffffffffffffffffffffffffffffffffffffff16637e7a46dc8283604051602001613d1991815260200190565b6040516020818303038152906040526040518363ffffffff1660e01b8152600401613d4592919061532d565b600060405180830381600087803b158015613d5f57600080fd5b505af1158015613d73573d6000803e3d6000fd5b50505050508080613d8390615463565b915050613cc4565b600c6020528160005260406000208181548110613da757600080fd5b90600052602060002001600091509150505481565b613dc4614130565b613dcd816141c9565b50565b6011546040517f3f678e11000000000000000000000000000000000000000000000000000000008152600091829173ffffffffffffffffffffffffffffffffffffffff90911690633f678e1190613e2b908690600401615c4c565b6020604051808303816000875af1158015613e4a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613e6e9190615611565b9050613e7b600f826142be565b506060909201516000838152600a6020526040902063ffffffff90911690555090565b815160009081908190841580613eb45750808510155b15613ebd578094505b60008092505b85831015613f1957866001613ed88585615692565b613ee29190615692565b81518110613ef257613ef26152df565b602002602001015181613f0591906155dd565b905082613f1181615463565b935050613ec3565b9694955050505050565b82516000908190831580613f375750808410155b15613f40578093505b60008467ffffffffffffffff811115613f5b57613f5b6146b6565b604051908082528060200260200182016040528015613f84578160200160208202803683370190505b509050600092505b84831015613ff257866001613fa18585615692565b613fab9190615692565b81518110613fbb57613fbb6152df565b6020026020010151818481518110613fd557613fd56152df565b602090810291909101015282613fea81615463565b935050613f8c565b61400b816000600184516140069190615692565b6142ca565b856064036140445780600182516140229190615692565b81518110614032576140326152df565b60200260200101519350505050611cef565b8060648251886140549190615d9e565b61405e9190615e0a565b8151811061406e5761406e6152df565b602002602001015193505050509392505050565b6000611cef8383614442565b60007f00000000000000000000000000000000000000000000000000000000000000001561412b57606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015614102573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906141269190615611565b905090565b504390565b60005473ffffffffffffffffffffffffffffffffffffffff1633146141b1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016120ba565b565b6000611545825490565b6000611cef838361453c565b3373ffffffffffffffffffffffffffffffffffffffff821603614248576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016120ba565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000611cef8383614566565b81818082036142da575050505050565b60008560026142e98787615e1e565b6142f39190615e3e565b6142fd9087615ea6565b8151811061430d5761430d6152df565b602002602001015190505b81831361441c575b80868481518110614333576143336152df565b60200260200101511015614353578261434b81615ece565b935050614320565b858281518110614365576143656152df565b6020026020010151811015614386578161437e81615eff565b925050614353565b8183136144175785828151811061439f5761439f6152df565b60200260200101518684815181106143b9576143b96152df565b60200260200101518785815181106143d3576143d36152df565b602002602001018885815181106143ec576143ec6152df565b6020908102919091010191909152528261440581615ece565b935050818061441390615eff565b9250505b614318565b8185121561442f5761442f8686846142ca565b83831215611486576114868684866142ca565b6000818152600183016020526040812054801561452b576000614466600183615692565b855490915060009061447a90600190615692565b90508181146144df57600086600001828154811061449a5761449a6152df565b90600052602060002001549050808760000184815481106144bd576144bd6152df565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806144f0576144f0615f56565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050611545565b6000915050611545565b5092915050565b6000826000018281548110614553576145536152df565b9060005260206000200154905092915050565b60008181526001830160205260408120546145ad57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155611545565b506000611545565b5080546000825590600052602060002090810190613dcd9190614629565b828054828255906000526020600020908101928215614619579160200282015b8281111561461957825182906146099082615a46565b50916020019190600101906145f3565b5061462592915061463e565b5090565b5b80821115614625576000815560010161462a565b80821115614625576000614652828261465b565b5060010161463e565b508054614667906156a5565b6000825580601f10614677575050565b601f016020900490600052602060002090810190613dcd9190614629565b60ff81168114613dcd57600080fd5b63ffffffff81168114613dcd57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff81118282101715614709576147096146b6565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614756576147566146b6565b604052919050565b600067ffffffffffffffff821115614778576147786146b6565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f8301126147b557600080fd5b81356147c86147c38261475e565b61470f565b8181528460208386010111156147dd57600080fd5b816020850160208301376000918101602001919091529392505050565b6bffffffffffffffffffffffff81168114613dcd57600080fd5b600080600080600080600060e0888a03121561482f57600080fd5b873561483a81614695565b9650602088013561484a816146a4565b9550604088013561485a81614695565b9450606088013567ffffffffffffffff81111561487657600080fd5b6148828a828b016147a4565b9450506080880135614893816147fa565b9699959850939692959460a0840135945060c09093013592915050565b803561ffff811681146148c257600080fd5b919050565b6000806000606084860312156148dc57600080fd5b833592506148ec602085016148b0565b9150604084013590509250925092565b6000806040838503121561490f57600080fd5b82359150602083013567ffffffffffffffff81111561492d57600080fd5b614939858286016147a4565b9150509250929050565b60006020828403121561495557600080fd5b5035919050565b60005b8381101561497757818101518382015260200161495f565b50506000910152565b6000815180845261499881602086016020860161495c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611cef6020830184614980565b73ffffffffffffffffffffffffffffffffffffffff81168114613dcd57600080fd5b600080600080600080600060e0888a031215614a1a57600080fd5b873596506020880135614a2c816149dd565b95506040880135614a3c81614695565b969995985095966060810135965060808101359560a0820135955060c0909101359350915050565b60008060408385031215614a7757600080fd5b82359150614a87602084016148b0565b90509250929050565b600060208284031215614aa257600080fd5b8135611cef816149dd565b60008083601f840112614abf57600080fd5b50813567ffffffffffffffff811115614ad757600080fd5b6020830191508360208260051b850101111561179957600080fd5b600080600080600080600060c0888a031215614b0d57600080fd5b873567ffffffffffffffff811115614b2457600080fd5b614b308a828b01614aad565b9098509650506020880135614b4481614695565b96999598509596604081013596506060810135956080820135955060a0909101359350915050565b600080600060608486031215614b8157600080fd5b505081359360208301359350604090920135919050565b60208152614bbf60208201835173ffffffffffffffffffffffffffffffffffffffff169052565b60006020830151614bd8604084018263ffffffff169052565b506040830151610140806060850152614bf5610160850183614980565b91506060850151614c1660808601826bffffffffffffffffffffffff169052565b50608085015173ffffffffffffffffffffffffffffffffffffffff811660a08601525060a085015167ffffffffffffffff811660c08601525060c085015163ffffffff811660e08601525060e0850151610100614c82818701836bffffffffffffffffffffffff169052565b8601519050610120614c978682018315159052565b8601518584037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001838701529050614ccf8382614980565b9695505050505050565b60008060208385031215614cec57600080fd5b823567ffffffffffffffff811115614d0357600080fd5b614d0f85828601614aad565b90969095509350505050565b60008060408385031215614d2e57600080fd5b823567ffffffffffffffff80821115614d4657600080fd5b908401906101008287031215614d5b57600080fd5b90925060208401359080821115614d7157600080fd5b50614939858286016147a4565b8215158152604060208201526000611cec6040830184614980565b60008083601f840112614dab57600080fd5b50813567ffffffffffffffff811115614dc357600080fd5b60208301915083602082850101111561179957600080fd5b60008060208385031215614dee57600080fd5b823567ffffffffffffffff811115614e0557600080fd5b614d0f85828601614d99565b6020808252825182820181905260009190848201906040850190845b81811015614e4957835183529284019291840191600101614e2d565b50909695505050505050565b600067ffffffffffffffff821115614e6f57614e6f6146b6565b5060051b60200190565b60008060408385031215614e8c57600080fd5b823567ffffffffffffffff80821115614ea457600080fd5b818501915085601f830112614eb857600080fd5b81356020614ec86147c383614e55565b82815260059290921b84018101918181019089841115614ee757600080fd5b8286015b84811015614f1f57803586811115614f035760008081fd5b614f118c86838b01016147a4565b845250918301918301614eeb565b5096505086013592505080821115614d7157600080fd5b600080600060408486031215614f4b57600080fd5b833567ffffffffffffffff811115614f6257600080fd5b614f6e86828701614aad565b9094509250506020840135614f82816146a4565b809150509250925092565b60008060408385031215614fa057600080fd5b50508035926020909101359150565b600080600060408486031215614fc457600080fd5b83359250602084013567ffffffffffffffff811115614fe257600080fd5b614fee86828701614d99565b9497909650939450505050565b6000806040838503121561500e57600080fd5b823567ffffffffffffffff8082111561502657600080fd5b615032868387016147a4565b93506020850135915080821115614d7157600080fd5b6000602080838503121561505b57600080fd5b823567ffffffffffffffff8082111561507357600080fd5b818501915085601f83011261508757600080fd5b81356150956147c382614e55565b81815260059190911b830184019084810190888311156150b457600080fd5b8585015b838110156150ec578035858111156150d05760008081fd5b6150de8b89838a01016147a4565b8452509186019186016150b8565b5098975050505050505050565b6000806040838503121561510c57600080fd5b82359150602083013561511e816147fa565b809150509250929050565b60006020828403121561513b57600080fd5b8135611cef81614695565b6000806040838503121561515957600080fd5b82359150602083013561511e816146a4565b6000806040838503121561517e57600080fd5b82359150602083013561511e81614695565b600080600080606085870312156151a657600080fd5b843567ffffffffffffffff8111156151bd57600080fd5b6151c987828801614aad565b90955093505060208501356151dd81614695565b915060408501356151ed81614695565b939692955090935050565b60008060008060008060c0878903121561521157600080fd5b863561521c816149dd565b9550602087013561522c81614695565b95989597505050506040840135936060810135936080820135935060a0909101359150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006bffffffffffffffffffffffff808316818516818304811182151516156152ab576152ab615251565b02949350505050565b805180151581146148c257600080fd5b6000602082840312156152d657600080fd5b611cef826152b4565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff821660ff810361532457615324615251565b60010192915050565b828152604060208201526000611cec6040830184614980565b600082601f83011261535757600080fd5b81516153656147c38261475e565b81815284602083860101111561537a57600080fd5b61538b82602083016020870161495c565b949350505050565b6000602082840312156153a557600080fd5b815167ffffffffffffffff8111156153bc57600080fd5b61538b84828501615346565b80516148c2816147fa565b6000602082840312156153e557600080fd5b8151611cef816147fa565b80516148c2816149dd565b6000806040838503121561540e57600080fd5b8251615419816149dd565b6020939093015192949293505050565b60006020828403121561543b57600080fd5b8151611cef816149dd565b60006020828403121561545857600080fd5b8151611cef81614695565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361549457615494615251565b5060010190565b80516148c2816146a4565b805167ffffffffffffffff811681146148c257600080fd5b6000602082840312156154d057600080fd5b815167ffffffffffffffff808211156154e857600080fd5b9083019061014082860312156154fd57600080fd5b6155056146e5565b61550e836153f0565b815261551c6020840161549b565b602082015260408301518281111561553357600080fd5b61553f87828601615346565b604083015250615551606084016153c8565b6060820152615562608084016153f0565b608082015261557360a084016154a6565b60a082015261558460c0840161549b565b60c082015261559560e084016153c8565b60e08201526101006155a88185016152b4565b9082015261012083810151838111156155c057600080fd5b6155cc88828701615346565b918301919091525095945050505050565b8082018082111561154557611545615251565b600061ffff80831681810361560757615607615251565b6001019392505050565b60006020828403121561562357600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261565f57600080fd5b83018035915067ffffffffffffffff82111561567a57600080fd5b6020019150600581901b360382131561179957600080fd5b8181038181111561154557611545615251565b600181811c908216806156b957607f821691505b6020821081036156f2577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b6000808354615706816156a5565b6001828116801561571e576001811461575157615780565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0084168752821515830287019450615780565b8760005260208060002060005b858110156157775781548a82015290840190820161575e565b50505082870194505b50929695505050505050565b60008154615799816156a5565b8085526020600183811680156157b657600181146157ee5761581c565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008516838901528284151560051b890101955061581c565b866000528260002060005b858110156158145781548a82018601529083019084016157f9565b890184019650505b505050505092915050565b60a08152600061583a60a083018861578c565b6020838203818501528188548084528284019150828160051b8501018a6000528360002060005b838110156158ac577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe087840301855261589a838361578c565b94860194925060019182019101615861565b505086810360408801526158c0818b61578c565b94505050505084606084015282810360808401526158de8185614980565b98975050505050505050565b6000604082016040835280855180835260608501915060608160051b8601019250602080880160005b8381101561595f577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa088870301855261594d868351614980565b95509382019390820190600101615913565b5050858403818701525050506159758185614980565b95945050505050565b60008060006060848603121561599357600080fd5b83519250602084015191506040840151614f82816149dd565b83815260406020820152816040820152818360608301376000818301606090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016010192915050565b601f821115612d8457600081815260208120601f850160051c81016020861015615a275750805b601f850160051c820191505b8181101561148657828155600101615a33565b815167ffffffffffffffff811115615a6057615a606146b6565b615a7481615a6e84546156a5565b84615a00565b602080601f831160018114615ac75760008415615a915750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555611486565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015615b1457888601518255948401946001909101908401615af5565b5085821015615b5057878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b60006020808385031215615b7357600080fd5b825167ffffffffffffffff811115615b8a57600080fd5b8301601f81018513615b9b57600080fd5b8051615ba96147c382614e55565b81815260059190911b82018301908381019087831115615bc857600080fd5b928401925b82841015615be657835182529284019290840190615bcd565b979650505050505050565b600063ffffffff80831681810361560757615607615251565b805160208083015191908110156156f2577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60209190910360031b1b16919050565b6020815260008251610140806020850152615c6b610160850183614980565b915060208501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe080868503016040870152615ca78483614980565b935060408701519150615cd2606087018373ffffffffffffffffffffffffffffffffffffffff169052565b606087015163ffffffff811660808801529150608087015173ffffffffffffffffffffffffffffffffffffffff811660a0880152915060a087015160ff811660c0880152915060c08701519150808685030160e0870152615d338483614980565b935060e08701519150610100818786030181880152615d528584614980565b945080880151925050610120818786030181880152615d718584614980565b94508088015192505050615d94828601826bffffffffffffffffffffffff169052565b5090949350505050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615615dd657615dd6615251565b500290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082615e1957615e19615ddb565b500490565b818103600083128015838313168383128216171561453557614535615251565b600082615e4d57615e4d615ddb565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f800000000000000000000000000000000000000000000000000000000000000083141615615ea157615ea1615251565b500590565b8082018281126000831280158216821582161715615ec657615ec6615251565b505092915050565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361549457615494615251565b60007f80000000000000000000000000000000000000000000000000000000000000008203615f3057615f30615251565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000810000a307834353534343832643535353334343264343135323432343935343532353534643264353434353533353434653435353430303030303030303030303030303030307834323534343332643535353334343264343135323432343935343532353534643264353434353533353434653435353430303030303030303030303030303030",
}
var VerifiableLoadLogTriggerUpkeepABI = VerifiableLoadLogTriggerUpkeepMetaData.ABI
var VerifiableLoadLogTriggerUpkeepBin = VerifiableLoadLogTriggerUpkeepMetaData.Bin
-func DeployVerifiableLoadLogTriggerUpkeep(auth *bind.TransactOpts, backend bind.ContractBackend, _registrar common.Address, _useArb bool, _autoLog bool, _useMercury bool) (common.Address, *types.Transaction, *VerifiableLoadLogTriggerUpkeep, error) {
+func DeployVerifiableLoadLogTriggerUpkeep(auth *bind.TransactOpts, backend bind.ContractBackend, _registrar common.Address, _useArb bool, _useMercury bool) (common.Address, *types.Transaction, *VerifiableLoadLogTriggerUpkeep, error) {
parsed, err := VerifiableLoadLogTriggerUpkeepMetaData.GetAbi()
if err != nil {
return common.Address{}, nil, nil, err
@@ -59,7 +72,7 @@ func DeployVerifiableLoadLogTriggerUpkeep(auth *bind.TransactOpts, backend bind.
return common.Address{}, nil, nil, errors.New("GetABI returned nil")
}
- address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(VerifiableLoadLogTriggerUpkeepBin), backend, _registrar, _useArb, _autoLog, _useMercury)
+ address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(VerifiableLoadLogTriggerUpkeepBin), backend, _registrar, _useArb, _useMercury)
if err != nil {
return common.Address{}, nil, nil, err
}
@@ -226,28 +239,6 @@ func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCallerSessi
return _VerifiableLoadLogTriggerUpkeep.Contract.AddLinkAmount(&_VerifiableLoadLogTriggerUpkeep.CallOpts)
}
-func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCaller) AutoLog(opts *bind.CallOpts) (bool, error) {
- var out []interface{}
- err := _VerifiableLoadLogTriggerUpkeep.contract.Call(opts, &out, "autoLog")
-
- if err != nil {
- return *new(bool), err
- }
-
- out0 := *abi.ConvertType(out[0], new(bool)).(*bool)
-
- return out0, err
-
-}
-
-func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) AutoLog() (bool, error) {
- return _VerifiableLoadLogTriggerUpkeep.Contract.AutoLog(&_VerifiableLoadLogTriggerUpkeep.CallOpts)
-}
-
-func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCallerSession) AutoLog() (bool, error) {
- return _VerifiableLoadLogTriggerUpkeep.Contract.AutoLog(&_VerifiableLoadLogTriggerUpkeep.CallOpts)
-}
-
func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCaller) BucketedDelays(opts *bind.CallOpts, arg0 *big.Int, arg1 uint16, arg2 *big.Int) (*big.Int, error) {
var out []interface{}
err := _VerifiableLoadLogTriggerUpkeep.contract.Call(opts, &out, "bucketedDelays", arg0, arg1, arg2)
@@ -425,6 +416,28 @@ func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCallerSessi
return _VerifiableLoadLogTriggerUpkeep.Contract.Eligible(&_VerifiableLoadLogTriggerUpkeep.CallOpts, upkeepId)
}
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCaller) EmittedAgainSig(opts *bind.CallOpts) ([32]byte, error) {
+ var out []interface{}
+ err := _VerifiableLoadLogTriggerUpkeep.contract.Call(opts, &out, "emittedAgainSig")
+
+ if err != nil {
+ return *new([32]byte), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte)
+
+ return out0, err
+
+}
+
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) EmittedAgainSig() ([32]byte, error) {
+ return _VerifiableLoadLogTriggerUpkeep.Contract.EmittedAgainSig(&_VerifiableLoadLogTriggerUpkeep.CallOpts)
+}
+
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCallerSession) EmittedAgainSig() ([32]byte, error) {
+ return _VerifiableLoadLogTriggerUpkeep.Contract.EmittedAgainSig(&_VerifiableLoadLogTriggerUpkeep.CallOpts)
+}
+
func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCaller) EmittedSig(opts *bind.CallOpts) ([32]byte, error) {
var out []interface{}
err := _VerifiableLoadLogTriggerUpkeep.contract.Call(opts, &out, "emittedSig")
@@ -535,9 +548,9 @@ func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCallerSessi
return _VerifiableLoadLogTriggerUpkeep.Contract.GasLimits(&_VerifiableLoadLogTriggerUpkeep.CallOpts, arg0)
}
-func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCaller) GetActiveUpkeepIDs(opts *bind.CallOpts, startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error) {
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCaller) GetActiveUpkeepIDsDeployedByThisContract(opts *bind.CallOpts, startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error) {
var out []interface{}
- err := _VerifiableLoadLogTriggerUpkeep.contract.Call(opts, &out, "getActiveUpkeepIDs", startIndex, maxCount)
+ err := _VerifiableLoadLogTriggerUpkeep.contract.Call(opts, &out, "getActiveUpkeepIDsDeployedByThisContract", startIndex, maxCount)
if err != nil {
return *new([]*big.Int), err
@@ -549,12 +562,56 @@ func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCaller) Get
}
-func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) GetActiveUpkeepIDs(startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error) {
- return _VerifiableLoadLogTriggerUpkeep.Contract.GetActiveUpkeepIDs(&_VerifiableLoadLogTriggerUpkeep.CallOpts, startIndex, maxCount)
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) GetActiveUpkeepIDsDeployedByThisContract(startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error) {
+ return _VerifiableLoadLogTriggerUpkeep.Contract.GetActiveUpkeepIDsDeployedByThisContract(&_VerifiableLoadLogTriggerUpkeep.CallOpts, startIndex, maxCount)
+}
+
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCallerSession) GetActiveUpkeepIDsDeployedByThisContract(startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error) {
+ return _VerifiableLoadLogTriggerUpkeep.Contract.GetActiveUpkeepIDsDeployedByThisContract(&_VerifiableLoadLogTriggerUpkeep.CallOpts, startIndex, maxCount)
+}
+
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCaller) GetAllActiveUpkeepIDsOnRegistry(opts *bind.CallOpts, startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error) {
+ var out []interface{}
+ err := _VerifiableLoadLogTriggerUpkeep.contract.Call(opts, &out, "getAllActiveUpkeepIDsOnRegistry", startIndex, maxCount)
+
+ if err != nil {
+ return *new([]*big.Int), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new([]*big.Int)).(*[]*big.Int)
+
+ return out0, err
+
+}
+
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) GetAllActiveUpkeepIDsOnRegistry(startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error) {
+ return _VerifiableLoadLogTriggerUpkeep.Contract.GetAllActiveUpkeepIDsOnRegistry(&_VerifiableLoadLogTriggerUpkeep.CallOpts, startIndex, maxCount)
+}
+
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCallerSession) GetAllActiveUpkeepIDsOnRegistry(startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error) {
+ return _VerifiableLoadLogTriggerUpkeep.Contract.GetAllActiveUpkeepIDsOnRegistry(&_VerifiableLoadLogTriggerUpkeep.CallOpts, startIndex, maxCount)
+}
+
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCaller) GetBalance(opts *bind.CallOpts, id *big.Int) (*big.Int, error) {
+ var out []interface{}
+ err := _VerifiableLoadLogTriggerUpkeep.contract.Call(opts, &out, "getBalance", id)
+
+ if err != nil {
+ return *new(*big.Int), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
+
+ return out0, err
+
+}
+
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) GetBalance(id *big.Int) (*big.Int, error) {
+ return _VerifiableLoadLogTriggerUpkeep.Contract.GetBalance(&_VerifiableLoadLogTriggerUpkeep.CallOpts, id)
}
-func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCallerSession) GetActiveUpkeepIDs(startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error) {
- return _VerifiableLoadLogTriggerUpkeep.Contract.GetActiveUpkeepIDs(&_VerifiableLoadLogTriggerUpkeep.CallOpts, startIndex, maxCount)
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCallerSession) GetBalance(id *big.Int) (*big.Int, error) {
+ return _VerifiableLoadLogTriggerUpkeep.Contract.GetBalance(&_VerifiableLoadLogTriggerUpkeep.CallOpts, id)
}
func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCaller) GetBucketedDelays(opts *bind.CallOpts, upkeepId *big.Int, bucket uint16) ([]*big.Int, error) {
@@ -645,9 +702,31 @@ func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCallerSessi
return _VerifiableLoadLogTriggerUpkeep.Contract.GetDelaysLength(&_VerifiableLoadLogTriggerUpkeep.CallOpts, upkeepId)
}
-func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCaller) GetLogTriggerConfig(opts *bind.CallOpts, upkeepId *big.Int) ([]byte, error) {
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCaller) GetForwarder(opts *bind.CallOpts, upkeepID *big.Int) (common.Address, error) {
+ var out []interface{}
+ err := _VerifiableLoadLogTriggerUpkeep.contract.Call(opts, &out, "getForwarder", upkeepID)
+
+ if err != nil {
+ return *new(common.Address), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address)
+
+ return out0, err
+
+}
+
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) GetForwarder(upkeepID *big.Int) (common.Address, error) {
+ return _VerifiableLoadLogTriggerUpkeep.Contract.GetForwarder(&_VerifiableLoadLogTriggerUpkeep.CallOpts, upkeepID)
+}
+
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCallerSession) GetForwarder(upkeepID *big.Int) (common.Address, error) {
+ return _VerifiableLoadLogTriggerUpkeep.Contract.GetForwarder(&_VerifiableLoadLogTriggerUpkeep.CallOpts, upkeepID)
+}
+
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCaller) GetLogTriggerConfig(opts *bind.CallOpts, addr common.Address, selector uint8, topic0 [32]byte, topic1 [32]byte, topic2 [32]byte, topic3 [32]byte) ([]byte, error) {
var out []interface{}
- err := _VerifiableLoadLogTriggerUpkeep.contract.Call(opts, &out, "getLogTriggerConfig", upkeepId)
+ err := _VerifiableLoadLogTriggerUpkeep.contract.Call(opts, &out, "getLogTriggerConfig", addr, selector, topic0, topic1, topic2, topic3)
if err != nil {
return *new([]byte), err
@@ -659,12 +738,34 @@ func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCaller) Get
}
-func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) GetLogTriggerConfig(upkeepId *big.Int) ([]byte, error) {
- return _VerifiableLoadLogTriggerUpkeep.Contract.GetLogTriggerConfig(&_VerifiableLoadLogTriggerUpkeep.CallOpts, upkeepId)
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) GetLogTriggerConfig(addr common.Address, selector uint8, topic0 [32]byte, topic1 [32]byte, topic2 [32]byte, topic3 [32]byte) ([]byte, error) {
+ return _VerifiableLoadLogTriggerUpkeep.Contract.GetLogTriggerConfig(&_VerifiableLoadLogTriggerUpkeep.CallOpts, addr, selector, topic0, topic1, topic2, topic3)
+}
+
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCallerSession) GetLogTriggerConfig(addr common.Address, selector uint8, topic0 [32]byte, topic1 [32]byte, topic2 [32]byte, topic3 [32]byte) ([]byte, error) {
+ return _VerifiableLoadLogTriggerUpkeep.Contract.GetLogTriggerConfig(&_VerifiableLoadLogTriggerUpkeep.CallOpts, addr, selector, topic0, topic1, topic2, topic3)
}
-func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCallerSession) GetLogTriggerConfig(upkeepId *big.Int) ([]byte, error) {
- return _VerifiableLoadLogTriggerUpkeep.Contract.GetLogTriggerConfig(&_VerifiableLoadLogTriggerUpkeep.CallOpts, upkeepId)
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCaller) GetMinBalanceForUpkeep(opts *bind.CallOpts, upkeepId *big.Int) (*big.Int, error) {
+ var out []interface{}
+ err := _VerifiableLoadLogTriggerUpkeep.contract.Call(opts, &out, "getMinBalanceForUpkeep", upkeepId)
+
+ if err != nil {
+ return *new(*big.Int), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
+
+ return out0, err
+
+}
+
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) GetMinBalanceForUpkeep(upkeepId *big.Int) (*big.Int, error) {
+ return _VerifiableLoadLogTriggerUpkeep.Contract.GetMinBalanceForUpkeep(&_VerifiableLoadLogTriggerUpkeep.CallOpts, upkeepId)
+}
+
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCallerSession) GetMinBalanceForUpkeep(upkeepId *big.Int) (*big.Int, error) {
+ return _VerifiableLoadLogTriggerUpkeep.Contract.GetMinBalanceForUpkeep(&_VerifiableLoadLogTriggerUpkeep.CallOpts, upkeepId)
}
func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCaller) GetPxDelayLastNPerforms(opts *bind.CallOpts, upkeepId *big.Int, p *big.Int, n *big.Int) (*big.Int, error) {
@@ -735,6 +836,94 @@ func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCallerSessi
return _VerifiableLoadLogTriggerUpkeep.Contract.GetSumDelayLastNPerforms(&_VerifiableLoadLogTriggerUpkeep.CallOpts, upkeepId, n)
}
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCaller) GetTriggerType(opts *bind.CallOpts, upkeepId *big.Int) (uint8, error) {
+ var out []interface{}
+ err := _VerifiableLoadLogTriggerUpkeep.contract.Call(opts, &out, "getTriggerType", upkeepId)
+
+ if err != nil {
+ return *new(uint8), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8)
+
+ return out0, err
+
+}
+
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) GetTriggerType(upkeepId *big.Int) (uint8, error) {
+ return _VerifiableLoadLogTriggerUpkeep.Contract.GetTriggerType(&_VerifiableLoadLogTriggerUpkeep.CallOpts, upkeepId)
+}
+
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCallerSession) GetTriggerType(upkeepId *big.Int) (uint8, error) {
+ return _VerifiableLoadLogTriggerUpkeep.Contract.GetTriggerType(&_VerifiableLoadLogTriggerUpkeep.CallOpts, upkeepId)
+}
+
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCaller) GetUpkeepInfo(opts *bind.CallOpts, upkeepId *big.Int) (KeeperRegistryBase21UpkeepInfo, error) {
+ var out []interface{}
+ err := _VerifiableLoadLogTriggerUpkeep.contract.Call(opts, &out, "getUpkeepInfo", upkeepId)
+
+ if err != nil {
+ return *new(KeeperRegistryBase21UpkeepInfo), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(KeeperRegistryBase21UpkeepInfo)).(*KeeperRegistryBase21UpkeepInfo)
+
+ return out0, err
+
+}
+
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) GetUpkeepInfo(upkeepId *big.Int) (KeeperRegistryBase21UpkeepInfo, error) {
+ return _VerifiableLoadLogTriggerUpkeep.Contract.GetUpkeepInfo(&_VerifiableLoadLogTriggerUpkeep.CallOpts, upkeepId)
+}
+
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCallerSession) GetUpkeepInfo(upkeepId *big.Int) (KeeperRegistryBase21UpkeepInfo, error) {
+ return _VerifiableLoadLogTriggerUpkeep.Contract.GetUpkeepInfo(&_VerifiableLoadLogTriggerUpkeep.CallOpts, upkeepId)
+}
+
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCaller) GetUpkeepPrivilegeConfig(opts *bind.CallOpts, upkeepId *big.Int) ([]byte, error) {
+ var out []interface{}
+ err := _VerifiableLoadLogTriggerUpkeep.contract.Call(opts, &out, "getUpkeepPrivilegeConfig", upkeepId)
+
+ if err != nil {
+ return *new([]byte), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte)
+
+ return out0, err
+
+}
+
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) GetUpkeepPrivilegeConfig(upkeepId *big.Int) ([]byte, error) {
+ return _VerifiableLoadLogTriggerUpkeep.Contract.GetUpkeepPrivilegeConfig(&_VerifiableLoadLogTriggerUpkeep.CallOpts, upkeepId)
+}
+
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCallerSession) GetUpkeepPrivilegeConfig(upkeepId *big.Int) ([]byte, error) {
+ return _VerifiableLoadLogTriggerUpkeep.Contract.GetUpkeepPrivilegeConfig(&_VerifiableLoadLogTriggerUpkeep.CallOpts, upkeepId)
+}
+
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCaller) GetUpkeepTriggerConfig(opts *bind.CallOpts, upkeepId *big.Int) ([]byte, error) {
+ var out []interface{}
+ err := _VerifiableLoadLogTriggerUpkeep.contract.Call(opts, &out, "getUpkeepTriggerConfig", upkeepId)
+
+ if err != nil {
+ return *new([]byte), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte)
+
+ return out0, err
+
+}
+
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) GetUpkeepTriggerConfig(upkeepId *big.Int) ([]byte, error) {
+ return _VerifiableLoadLogTriggerUpkeep.Contract.GetUpkeepTriggerConfig(&_VerifiableLoadLogTriggerUpkeep.CallOpts, upkeepId)
+}
+
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCallerSession) GetUpkeepTriggerConfig(upkeepId *big.Int) ([]byte, error) {
+ return _VerifiableLoadLogTriggerUpkeep.Contract.GetUpkeepTriggerConfig(&_VerifiableLoadLogTriggerUpkeep.CallOpts, upkeepId)
+}
+
func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCaller) Intervals(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) {
var out []interface{}
err := _VerifiableLoadLogTriggerUpkeep.contract.Call(opts, &out, "intervals", arg0)
@@ -801,6 +990,28 @@ func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCallerSessi
return _VerifiableLoadLogTriggerUpkeep.Contract.LinkToken(&_VerifiableLoadLogTriggerUpkeep.CallOpts)
}
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCaller) LogNum(opts *bind.CallOpts) (uint8, error) {
+ var out []interface{}
+ err := _VerifiableLoadLogTriggerUpkeep.contract.Call(opts, &out, "logNum")
+
+ if err != nil {
+ return *new(uint8), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8)
+
+ return out0, err
+
+}
+
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) LogNum() (uint8, error) {
+ return _VerifiableLoadLogTriggerUpkeep.Contract.LogNum(&_VerifiableLoadLogTriggerUpkeep.CallOpts)
+}
+
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCallerSession) LogNum() (uint8, error) {
+ return _VerifiableLoadLogTriggerUpkeep.Contract.LogNum(&_VerifiableLoadLogTriggerUpkeep.CallOpts)
+}
+
func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepCaller) MinBalanceThresholdMultiplier(opts *bind.CallOpts) (uint8, error) {
var out []interface{}
err := _VerifiableLoadLogTriggerUpkeep.contract.Call(opts, &out, "minBalanceThresholdMultiplier")
@@ -1079,6 +1290,30 @@ func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactorS
return _VerifiableLoadLogTriggerUpkeep.Contract.BatchCancelUpkeeps(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, upkeepIds)
}
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactor) BatchPreparingUpkeeps(opts *bind.TransactOpts, upkeepIds []*big.Int, selector uint8, topic0 [32]byte, topic1 [32]byte, topic2 [32]byte, topic3 [32]byte) (*types.Transaction, error) {
+ return _VerifiableLoadLogTriggerUpkeep.contract.Transact(opts, "batchPreparingUpkeeps", upkeepIds, selector, topic0, topic1, topic2, topic3)
+}
+
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) BatchPreparingUpkeeps(upkeepIds []*big.Int, selector uint8, topic0 [32]byte, topic1 [32]byte, topic2 [32]byte, topic3 [32]byte) (*types.Transaction, error) {
+ return _VerifiableLoadLogTriggerUpkeep.Contract.BatchPreparingUpkeeps(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, upkeepIds, selector, topic0, topic1, topic2, topic3)
+}
+
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactorSession) BatchPreparingUpkeeps(upkeepIds []*big.Int, selector uint8, topic0 [32]byte, topic1 [32]byte, topic2 [32]byte, topic3 [32]byte) (*types.Transaction, error) {
+ return _VerifiableLoadLogTriggerUpkeep.Contract.BatchPreparingUpkeeps(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, upkeepIds, selector, topic0, topic1, topic2, topic3)
+}
+
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactor) BatchPreparingUpkeepsSimple(opts *bind.TransactOpts, upkeepIds []*big.Int, log uint8, selector uint8) (*types.Transaction, error) {
+ return _VerifiableLoadLogTriggerUpkeep.contract.Transact(opts, "batchPreparingUpkeepsSimple", upkeepIds, log, selector)
+}
+
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) BatchPreparingUpkeepsSimple(upkeepIds []*big.Int, log uint8, selector uint8) (*types.Transaction, error) {
+ return _VerifiableLoadLogTriggerUpkeep.Contract.BatchPreparingUpkeepsSimple(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, upkeepIds, log, selector)
+}
+
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactorSession) BatchPreparingUpkeepsSimple(upkeepIds []*big.Int, log uint8, selector uint8) (*types.Transaction, error) {
+ return _VerifiableLoadLogTriggerUpkeep.Contract.BatchPreparingUpkeepsSimple(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, upkeepIds, log, selector)
+}
+
func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactor) BatchRegisterUpkeeps(opts *bind.TransactOpts, number uint8, gasLimit uint32, triggerType uint8, triggerConfig []byte, amount *big.Int, checkGasToBurn *big.Int, performGasToBurn *big.Int) (*types.Transaction, error) {
return _VerifiableLoadLogTriggerUpkeep.contract.Transact(opts, "batchRegisterUpkeeps", number, gasLimit, triggerType, triggerConfig, amount, checkGasToBurn, performGasToBurn)
}
@@ -1091,16 +1326,16 @@ func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactorS
return _VerifiableLoadLogTriggerUpkeep.Contract.BatchRegisterUpkeeps(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, number, gasLimit, triggerType, triggerConfig, amount, checkGasToBurn, performGasToBurn)
}
-func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactor) BatchSendLogs(opts *bind.TransactOpts) (*types.Transaction, error) {
- return _VerifiableLoadLogTriggerUpkeep.contract.Transact(opts, "batchSendLogs")
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactor) BatchSendLogs(opts *bind.TransactOpts, log uint8) (*types.Transaction, error) {
+ return _VerifiableLoadLogTriggerUpkeep.contract.Transact(opts, "batchSendLogs", log)
}
-func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) BatchSendLogs() (*types.Transaction, error) {
- return _VerifiableLoadLogTriggerUpkeep.Contract.BatchSendLogs(&_VerifiableLoadLogTriggerUpkeep.TransactOpts)
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) BatchSendLogs(log uint8) (*types.Transaction, error) {
+ return _VerifiableLoadLogTriggerUpkeep.Contract.BatchSendLogs(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, log)
}
-func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactorSession) BatchSendLogs() (*types.Transaction, error) {
- return _VerifiableLoadLogTriggerUpkeep.Contract.BatchSendLogs(&_VerifiableLoadLogTriggerUpkeep.TransactOpts)
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactorSession) BatchSendLogs(log uint8) (*types.Transaction, error) {
+ return _VerifiableLoadLogTriggerUpkeep.Contract.BatchSendLogs(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, log)
}
func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactor) BatchSetIntervals(opts *bind.TransactOpts, upkeepIds []*big.Int, interval uint32) (*types.Transaction, error) {
@@ -1151,18 +1386,6 @@ func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactorS
return _VerifiableLoadLogTriggerUpkeep.Contract.BurnPerformGas(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, upkeepId, startGas, blockNum)
}
-func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactor) CancelUpkeep(opts *bind.TransactOpts, upkeepId *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadLogTriggerUpkeep.contract.Transact(opts, "cancelUpkeep", upkeepId)
-}
-
-func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) CancelUpkeep(upkeepId *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadLogTriggerUpkeep.Contract.CancelUpkeep(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, upkeepId)
-}
-
-func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactorSession) CancelUpkeep(upkeepId *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadLogTriggerUpkeep.Contract.CancelUpkeep(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, upkeepId)
-}
-
func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactor) CheckLog(opts *bind.TransactOpts, log Log, checkData []byte) (*types.Transaction, error) {
return _VerifiableLoadLogTriggerUpkeep.contract.Transact(opts, "checkLog", log, checkData)
}
@@ -1187,52 +1410,16 @@ func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactorS
return _VerifiableLoadLogTriggerUpkeep.Contract.PerformUpkeep(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, performData)
}
-func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactor) SendLog(opts *bind.TransactOpts, upkeepId *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadLogTriggerUpkeep.contract.Transact(opts, "sendLog", upkeepId)
-}
-
-func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) SendLog(upkeepId *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadLogTriggerUpkeep.Contract.SendLog(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, upkeepId)
-}
-
-func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactorSession) SendLog(upkeepId *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadLogTriggerUpkeep.Contract.SendLog(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, upkeepId)
-}
-
-func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactor) SetAddLinkAmount(opts *bind.TransactOpts, amount *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadLogTriggerUpkeep.contract.Transact(opts, "setAddLinkAmount", amount)
-}
-
-func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) SetAddLinkAmount(amount *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadLogTriggerUpkeep.Contract.SetAddLinkAmount(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, amount)
-}
-
-func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactorSession) SetAddLinkAmount(amount *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadLogTriggerUpkeep.Contract.SetAddLinkAmount(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, amount)
-}
-
-func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactor) SetAutoLog(opts *bind.TransactOpts, _autoLog bool) (*types.Transaction, error) {
- return _VerifiableLoadLogTriggerUpkeep.contract.Transact(opts, "setAutoLog", _autoLog)
-}
-
-func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) SetAutoLog(_autoLog bool) (*types.Transaction, error) {
- return _VerifiableLoadLogTriggerUpkeep.Contract.SetAutoLog(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, _autoLog)
-}
-
-func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactorSession) SetAutoLog(_autoLog bool) (*types.Transaction, error) {
- return _VerifiableLoadLogTriggerUpkeep.Contract.SetAutoLog(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, _autoLog)
-}
-
-func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactor) SetCheckGasToBurn(opts *bind.TransactOpts, upkeepId *big.Int, value *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadLogTriggerUpkeep.contract.Transact(opts, "setCheckGasToBurn", upkeepId, value)
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactor) SendLog(opts *bind.TransactOpts, upkeepId *big.Int, log uint8) (*types.Transaction, error) {
+ return _VerifiableLoadLogTriggerUpkeep.contract.Transact(opts, "sendLog", upkeepId, log)
}
-func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) SetCheckGasToBurn(upkeepId *big.Int, value *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadLogTriggerUpkeep.Contract.SetCheckGasToBurn(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, upkeepId, value)
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) SendLog(upkeepId *big.Int, log uint8) (*types.Transaction, error) {
+ return _VerifiableLoadLogTriggerUpkeep.Contract.SendLog(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, upkeepId, log)
}
-func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactorSession) SetCheckGasToBurn(upkeepId *big.Int, value *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadLogTriggerUpkeep.Contract.SetCheckGasToBurn(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, upkeepId, value)
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactorSession) SendLog(upkeepId *big.Int, log uint8) (*types.Transaction, error) {
+ return _VerifiableLoadLogTriggerUpkeep.Contract.SendLog(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, upkeepId, log)
}
func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactor) SetConfig(opts *bind.TransactOpts, newRegistrar common.Address) (*types.Transaction, error) {
@@ -1247,16 +1434,16 @@ func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactorS
return _VerifiableLoadLogTriggerUpkeep.Contract.SetConfig(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, newRegistrar)
}
-func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactor) SetFeedsHex(opts *bind.TransactOpts, newFeeds []string) (*types.Transaction, error) {
- return _VerifiableLoadLogTriggerUpkeep.contract.Transact(opts, "setFeedsHex", newFeeds)
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactor) SetFeeds(opts *bind.TransactOpts, _feeds []string) (*types.Transaction, error) {
+ return _VerifiableLoadLogTriggerUpkeep.contract.Transact(opts, "setFeeds", _feeds)
}
-func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) SetFeedsHex(newFeeds []string) (*types.Transaction, error) {
- return _VerifiableLoadLogTriggerUpkeep.Contract.SetFeedsHex(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, newFeeds)
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) SetFeeds(_feeds []string) (*types.Transaction, error) {
+ return _VerifiableLoadLogTriggerUpkeep.Contract.SetFeeds(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, _feeds)
}
-func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactorSession) SetFeedsHex(newFeeds []string) (*types.Transaction, error) {
- return _VerifiableLoadLogTriggerUpkeep.Contract.SetFeedsHex(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, newFeeds)
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactorSession) SetFeeds(_feeds []string) (*types.Transaction, error) {
+ return _VerifiableLoadLogTriggerUpkeep.Contract.SetFeeds(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, _feeds)
}
func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactor) SetInterval(opts *bind.TransactOpts, upkeepId *big.Int, _interval *big.Int) (*types.Transaction, error) {
@@ -1271,40 +1458,40 @@ func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactorS
return _VerifiableLoadLogTriggerUpkeep.Contract.SetInterval(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, upkeepId, _interval)
}
-func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactor) SetMinBalanceThresholdMultiplier(opts *bind.TransactOpts, newMinBalanceThresholdMultiplier uint8) (*types.Transaction, error) {
- return _VerifiableLoadLogTriggerUpkeep.contract.Transact(opts, "setMinBalanceThresholdMultiplier", newMinBalanceThresholdMultiplier)
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactor) SetLog(opts *bind.TransactOpts, _log uint8) (*types.Transaction, error) {
+ return _VerifiableLoadLogTriggerUpkeep.contract.Transact(opts, "setLog", _log)
}
-func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) SetMinBalanceThresholdMultiplier(newMinBalanceThresholdMultiplier uint8) (*types.Transaction, error) {
- return _VerifiableLoadLogTriggerUpkeep.Contract.SetMinBalanceThresholdMultiplier(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, newMinBalanceThresholdMultiplier)
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) SetLog(_log uint8) (*types.Transaction, error) {
+ return _VerifiableLoadLogTriggerUpkeep.Contract.SetLog(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, _log)
}
-func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactorSession) SetMinBalanceThresholdMultiplier(newMinBalanceThresholdMultiplier uint8) (*types.Transaction, error) {
- return _VerifiableLoadLogTriggerUpkeep.Contract.SetMinBalanceThresholdMultiplier(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, newMinBalanceThresholdMultiplier)
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactorSession) SetLog(_log uint8) (*types.Transaction, error) {
+ return _VerifiableLoadLogTriggerUpkeep.Contract.SetLog(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, _log)
}
-func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactor) SetPerformDataSize(opts *bind.TransactOpts, upkeepId *big.Int, value *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadLogTriggerUpkeep.contract.Transact(opts, "setPerformDataSize", upkeepId, value)
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactor) SetParamKeys(opts *bind.TransactOpts, _feedParamKey string, _timeParamKey string) (*types.Transaction, error) {
+ return _VerifiableLoadLogTriggerUpkeep.contract.Transact(opts, "setParamKeys", _feedParamKey, _timeParamKey)
}
-func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) SetPerformDataSize(upkeepId *big.Int, value *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadLogTriggerUpkeep.Contract.SetPerformDataSize(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, upkeepId, value)
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) SetParamKeys(_feedParamKey string, _timeParamKey string) (*types.Transaction, error) {
+ return _VerifiableLoadLogTriggerUpkeep.Contract.SetParamKeys(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, _feedParamKey, _timeParamKey)
}
-func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactorSession) SetPerformDataSize(upkeepId *big.Int, value *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadLogTriggerUpkeep.Contract.SetPerformDataSize(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, upkeepId, value)
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactorSession) SetParamKeys(_feedParamKey string, _timeParamKey string) (*types.Transaction, error) {
+ return _VerifiableLoadLogTriggerUpkeep.Contract.SetParamKeys(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, _feedParamKey, _timeParamKey)
}
-func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactor) SetPerformGasToBurn(opts *bind.TransactOpts, upkeepId *big.Int, value *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadLogTriggerUpkeep.contract.Transact(opts, "setPerformGasToBurn", upkeepId, value)
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactor) SetPerformDataSize(opts *bind.TransactOpts, upkeepId *big.Int, value *big.Int) (*types.Transaction, error) {
+ return _VerifiableLoadLogTriggerUpkeep.contract.Transact(opts, "setPerformDataSize", upkeepId, value)
}
-func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) SetPerformGasToBurn(upkeepId *big.Int, value *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadLogTriggerUpkeep.Contract.SetPerformGasToBurn(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, upkeepId, value)
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) SetPerformDataSize(upkeepId *big.Int, value *big.Int) (*types.Transaction, error) {
+ return _VerifiableLoadLogTriggerUpkeep.Contract.SetPerformDataSize(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, upkeepId, value)
}
-func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactorSession) SetPerformGasToBurn(upkeepId *big.Int, value *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadLogTriggerUpkeep.Contract.SetPerformGasToBurn(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, upkeepId, value)
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactorSession) SetPerformDataSize(upkeepId *big.Int, value *big.Int) (*types.Transaction, error) {
+ return _VerifiableLoadLogTriggerUpkeep.Contract.SetPerformDataSize(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, upkeepId, value)
}
func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactor) SetUpkeepGasLimit(opts *bind.TransactOpts, upkeepId *big.Int, gasLimit uint32) (*types.Transaction, error) {
@@ -1319,28 +1506,16 @@ func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactorS
return _VerifiableLoadLogTriggerUpkeep.Contract.SetUpkeepGasLimit(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, upkeepId, gasLimit)
}
-func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactor) SetUpkeepTopUpCheckInterval(opts *bind.TransactOpts, newInterval *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadLogTriggerUpkeep.contract.Transact(opts, "setUpkeepTopUpCheckInterval", newInterval)
-}
-
-func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) SetUpkeepTopUpCheckInterval(newInterval *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadLogTriggerUpkeep.Contract.SetUpkeepTopUpCheckInterval(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, newInterval)
-}
-
-func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactorSession) SetUpkeepTopUpCheckInterval(newInterval *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadLogTriggerUpkeep.Contract.SetUpkeepTopUpCheckInterval(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, newInterval)
-}
-
-func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactor) SetUseMercury(opts *bind.TransactOpts, _useMercury bool) (*types.Transaction, error) {
- return _VerifiableLoadLogTriggerUpkeep.contract.Transact(opts, "setUseMercury", _useMercury)
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactor) SetUpkeepPrivilegeConfig(opts *bind.TransactOpts, upkeepId *big.Int, cfg []byte) (*types.Transaction, error) {
+ return _VerifiableLoadLogTriggerUpkeep.contract.Transact(opts, "setUpkeepPrivilegeConfig", upkeepId, cfg)
}
-func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) SetUseMercury(_useMercury bool) (*types.Transaction, error) {
- return _VerifiableLoadLogTriggerUpkeep.Contract.SetUseMercury(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, _useMercury)
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) SetUpkeepPrivilegeConfig(upkeepId *big.Int, cfg []byte) (*types.Transaction, error) {
+ return _VerifiableLoadLogTriggerUpkeep.Contract.SetUpkeepPrivilegeConfig(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, upkeepId, cfg)
}
-func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactorSession) SetUseMercury(_useMercury bool) (*types.Transaction, error) {
- return _VerifiableLoadLogTriggerUpkeep.Contract.SetUseMercury(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, _useMercury)
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactorSession) SetUpkeepPrivilegeConfig(upkeepId *big.Int, cfg []byte) (*types.Transaction, error) {
+ return _VerifiableLoadLogTriggerUpkeep.Contract.SetUpkeepPrivilegeConfig(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, upkeepId, cfg)
}
func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactor) TopUpFund(opts *bind.TransactOpts, upkeepId *big.Int, blockNum *big.Int) (*types.Transaction, error) {
@@ -1367,6 +1542,30 @@ func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactorS
return _VerifiableLoadLogTriggerUpkeep.Contract.TransferOwnership(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, to)
}
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactor) UpdateLogTriggerConfig1(opts *bind.TransactOpts, upkeepId *big.Int, addr common.Address, selector uint8, topic0 [32]byte, topic1 [32]byte, topic2 [32]byte, topic3 [32]byte) (*types.Transaction, error) {
+ return _VerifiableLoadLogTriggerUpkeep.contract.Transact(opts, "updateLogTriggerConfig1", upkeepId, addr, selector, topic0, topic1, topic2, topic3)
+}
+
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) UpdateLogTriggerConfig1(upkeepId *big.Int, addr common.Address, selector uint8, topic0 [32]byte, topic1 [32]byte, topic2 [32]byte, topic3 [32]byte) (*types.Transaction, error) {
+ return _VerifiableLoadLogTriggerUpkeep.Contract.UpdateLogTriggerConfig1(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, upkeepId, addr, selector, topic0, topic1, topic2, topic3)
+}
+
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactorSession) UpdateLogTriggerConfig1(upkeepId *big.Int, addr common.Address, selector uint8, topic0 [32]byte, topic1 [32]byte, topic2 [32]byte, topic3 [32]byte) (*types.Transaction, error) {
+ return _VerifiableLoadLogTriggerUpkeep.Contract.UpdateLogTriggerConfig1(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, upkeepId, addr, selector, topic0, topic1, topic2, topic3)
+}
+
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactor) UpdateLogTriggerConfig2(opts *bind.TransactOpts, upkeepId *big.Int, cfg []byte) (*types.Transaction, error) {
+ return _VerifiableLoadLogTriggerUpkeep.contract.Transact(opts, "updateLogTriggerConfig2", upkeepId, cfg)
+}
+
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepSession) UpdateLogTriggerConfig2(upkeepId *big.Int, cfg []byte) (*types.Transaction, error) {
+ return _VerifiableLoadLogTriggerUpkeep.Contract.UpdateLogTriggerConfig2(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, upkeepId, cfg)
+}
+
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactorSession) UpdateLogTriggerConfig2(upkeepId *big.Int, cfg []byte) (*types.Transaction, error) {
+ return _VerifiableLoadLogTriggerUpkeep.Contract.UpdateLogTriggerConfig2(&_VerifiableLoadLogTriggerUpkeep.TransactOpts, upkeepId, cfg)
+}
+
func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepTransactor) UpdateUpkeepPipelineData(opts *bind.TransactOpts, upkeepId *big.Int, pipelineData []byte) (*types.Transaction, error) {
return _VerifiableLoadLogTriggerUpkeep.contract.Transact(opts, "updateUpkeepPipelineData", upkeepId, pipelineData)
}
@@ -1482,7 +1681,7 @@ type VerifiableLoadLogTriggerUpkeepLogEmitted struct {
Raw types.Log
}
-func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepFilterer) FilterLogEmitted(opts *bind.FilterOpts, upkeepId []*big.Int, blockNum []*big.Int) (*VerifiableLoadLogTriggerUpkeepLogEmittedIterator, error) {
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepFilterer) FilterLogEmitted(opts *bind.FilterOpts, upkeepId []*big.Int, blockNum []*big.Int, addr []common.Address) (*VerifiableLoadLogTriggerUpkeepLogEmittedIterator, error) {
var upkeepIdRule []interface{}
for _, upkeepIdItem := range upkeepId {
@@ -1492,15 +1691,19 @@ func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepFilterer) F
for _, blockNumItem := range blockNum {
blockNumRule = append(blockNumRule, blockNumItem)
}
+ var addrRule []interface{}
+ for _, addrItem := range addr {
+ addrRule = append(addrRule, addrItem)
+ }
- logs, sub, err := _VerifiableLoadLogTriggerUpkeep.contract.FilterLogs(opts, "LogEmitted", upkeepIdRule, blockNumRule)
+ logs, sub, err := _VerifiableLoadLogTriggerUpkeep.contract.FilterLogs(opts, "LogEmitted", upkeepIdRule, blockNumRule, addrRule)
if err != nil {
return nil, err
}
return &VerifiableLoadLogTriggerUpkeepLogEmittedIterator{contract: _VerifiableLoadLogTriggerUpkeep.contract, event: "LogEmitted", logs: logs, sub: sub}, nil
}
-func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepFilterer) WatchLogEmitted(opts *bind.WatchOpts, sink chan<- *VerifiableLoadLogTriggerUpkeepLogEmitted, upkeepId []*big.Int, blockNum []*big.Int) (event.Subscription, error) {
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepFilterer) WatchLogEmitted(opts *bind.WatchOpts, sink chan<- *VerifiableLoadLogTriggerUpkeepLogEmitted, upkeepId []*big.Int, blockNum []*big.Int, addr []common.Address) (event.Subscription, error) {
var upkeepIdRule []interface{}
for _, upkeepIdItem := range upkeepId {
@@ -1510,8 +1713,12 @@ func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepFilterer) W
for _, blockNumItem := range blockNum {
blockNumRule = append(blockNumRule, blockNumItem)
}
+ var addrRule []interface{}
+ for _, addrItem := range addr {
+ addrRule = append(addrRule, addrItem)
+ }
- logs, sub, err := _VerifiableLoadLogTriggerUpkeep.contract.WatchLogs(opts, "LogEmitted", upkeepIdRule, blockNumRule)
+ logs, sub, err := _VerifiableLoadLogTriggerUpkeep.contract.WatchLogs(opts, "LogEmitted", upkeepIdRule, blockNumRule, addrRule)
if err != nil {
return nil, err
}
@@ -1552,8 +1759,8 @@ func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepFilterer) P
return event, nil
}
-type VerifiableLoadLogTriggerUpkeepOwnershipTransferRequestedIterator struct {
- Event *VerifiableLoadLogTriggerUpkeepOwnershipTransferRequested
+type VerifiableLoadLogTriggerUpkeepLogEmittedAgainIterator struct {
+ Event *VerifiableLoadLogTriggerUpkeepLogEmittedAgain
contract *bind.BoundContract
event string
@@ -1564,7 +1771,7 @@ type VerifiableLoadLogTriggerUpkeepOwnershipTransferRequestedIterator struct {
fail error
}
-func (it *VerifiableLoadLogTriggerUpkeepOwnershipTransferRequestedIterator) Next() bool {
+func (it *VerifiableLoadLogTriggerUpkeepLogEmittedAgainIterator) Next() bool {
if it.fail != nil {
return false
@@ -1573,7 +1780,7 @@ func (it *VerifiableLoadLogTriggerUpkeepOwnershipTransferRequestedIterator) Next
if it.done {
select {
case log := <-it.logs:
- it.Event = new(VerifiableLoadLogTriggerUpkeepOwnershipTransferRequested)
+ it.Event = new(VerifiableLoadLogTriggerUpkeepLogEmittedAgain)
if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
it.fail = err
return false
@@ -1588,7 +1795,7 @@ func (it *VerifiableLoadLogTriggerUpkeepOwnershipTransferRequestedIterator) Next
select {
case log := <-it.logs:
- it.Event = new(VerifiableLoadLogTriggerUpkeepOwnershipTransferRequested)
+ it.Event = new(VerifiableLoadLogTriggerUpkeepLogEmittedAgain)
if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
it.fail = err
return false
@@ -1603,51 +1810,60 @@ func (it *VerifiableLoadLogTriggerUpkeepOwnershipTransferRequestedIterator) Next
}
}
-func (it *VerifiableLoadLogTriggerUpkeepOwnershipTransferRequestedIterator) Error() error {
+func (it *VerifiableLoadLogTriggerUpkeepLogEmittedAgainIterator) Error() error {
return it.fail
}
-func (it *VerifiableLoadLogTriggerUpkeepOwnershipTransferRequestedIterator) Close() error {
+func (it *VerifiableLoadLogTriggerUpkeepLogEmittedAgainIterator) Close() error {
it.sub.Unsubscribe()
return nil
}
-type VerifiableLoadLogTriggerUpkeepOwnershipTransferRequested struct {
- From common.Address
- To common.Address
- Raw types.Log
+type VerifiableLoadLogTriggerUpkeepLogEmittedAgain struct {
+ UpkeepId *big.Int
+ BlockNum *big.Int
+ Addr common.Address
+ Raw types.Log
}
-func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VerifiableLoadLogTriggerUpkeepOwnershipTransferRequestedIterator, error) {
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepFilterer) FilterLogEmittedAgain(opts *bind.FilterOpts, upkeepId []*big.Int, blockNum []*big.Int, addr []common.Address) (*VerifiableLoadLogTriggerUpkeepLogEmittedAgainIterator, error) {
- var fromRule []interface{}
- for _, fromItem := range from {
- fromRule = append(fromRule, fromItem)
+ var upkeepIdRule []interface{}
+ for _, upkeepIdItem := range upkeepId {
+ upkeepIdRule = append(upkeepIdRule, upkeepIdItem)
}
- var toRule []interface{}
- for _, toItem := range to {
- toRule = append(toRule, toItem)
+ var blockNumRule []interface{}
+ for _, blockNumItem := range blockNum {
+ blockNumRule = append(blockNumRule, blockNumItem)
+ }
+ var addrRule []interface{}
+ for _, addrItem := range addr {
+ addrRule = append(addrRule, addrItem)
}
- logs, sub, err := _VerifiableLoadLogTriggerUpkeep.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule)
+ logs, sub, err := _VerifiableLoadLogTriggerUpkeep.contract.FilterLogs(opts, "LogEmittedAgain", upkeepIdRule, blockNumRule, addrRule)
if err != nil {
return nil, err
}
- return &VerifiableLoadLogTriggerUpkeepOwnershipTransferRequestedIterator{contract: _VerifiableLoadLogTriggerUpkeep.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil
+ return &VerifiableLoadLogTriggerUpkeepLogEmittedAgainIterator{contract: _VerifiableLoadLogTriggerUpkeep.contract, event: "LogEmittedAgain", logs: logs, sub: sub}, nil
}
-func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *VerifiableLoadLogTriggerUpkeepOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) {
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepFilterer) WatchLogEmittedAgain(opts *bind.WatchOpts, sink chan<- *VerifiableLoadLogTriggerUpkeepLogEmittedAgain, upkeepId []*big.Int, blockNum []*big.Int, addr []common.Address) (event.Subscription, error) {
- var fromRule []interface{}
- for _, fromItem := range from {
- fromRule = append(fromRule, fromItem)
+ var upkeepIdRule []interface{}
+ for _, upkeepIdItem := range upkeepId {
+ upkeepIdRule = append(upkeepIdRule, upkeepIdItem)
}
- var toRule []interface{}
- for _, toItem := range to {
- toRule = append(toRule, toItem)
+ var blockNumRule []interface{}
+ for _, blockNumItem := range blockNum {
+ blockNumRule = append(blockNumRule, blockNumItem)
+ }
+ var addrRule []interface{}
+ for _, addrItem := range addr {
+ addrRule = append(addrRule, addrItem)
}
- logs, sub, err := _VerifiableLoadLogTriggerUpkeep.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule)
+ logs, sub, err := _VerifiableLoadLogTriggerUpkeep.contract.WatchLogs(opts, "LogEmittedAgain", upkeepIdRule, blockNumRule, addrRule)
if err != nil {
return nil, err
}
@@ -1657,8 +1873,8 @@ func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepFilterer) W
select {
case log := <-logs:
- event := new(VerifiableLoadLogTriggerUpkeepOwnershipTransferRequested)
- if err := _VerifiableLoadLogTriggerUpkeep.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil {
+ event := new(VerifiableLoadLogTriggerUpkeepLogEmittedAgain)
+ if err := _VerifiableLoadLogTriggerUpkeep.contract.UnpackLog(event, "LogEmittedAgain", log); err != nil {
return err
}
event.Raw = log
@@ -1679,17 +1895,17 @@ func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepFilterer) W
}), nil
}
-func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepFilterer) ParseOwnershipTransferRequested(log types.Log) (*VerifiableLoadLogTriggerUpkeepOwnershipTransferRequested, error) {
- event := new(VerifiableLoadLogTriggerUpkeepOwnershipTransferRequested)
- if err := _VerifiableLoadLogTriggerUpkeep.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil {
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepFilterer) ParseLogEmittedAgain(log types.Log) (*VerifiableLoadLogTriggerUpkeepLogEmittedAgain, error) {
+ event := new(VerifiableLoadLogTriggerUpkeepLogEmittedAgain)
+ if err := _VerifiableLoadLogTriggerUpkeep.contract.UnpackLog(event, "LogEmittedAgain", log); err != nil {
return nil, err
}
event.Raw = log
return event, nil
}
-type VerifiableLoadLogTriggerUpkeepOwnershipTransferredIterator struct {
- Event *VerifiableLoadLogTriggerUpkeepOwnershipTransferred
+type VerifiableLoadLogTriggerUpkeepOwnershipTransferRequestedIterator struct {
+ Event *VerifiableLoadLogTriggerUpkeepOwnershipTransferRequested
contract *bind.BoundContract
event string
@@ -1700,7 +1916,7 @@ type VerifiableLoadLogTriggerUpkeepOwnershipTransferredIterator struct {
fail error
}
-func (it *VerifiableLoadLogTriggerUpkeepOwnershipTransferredIterator) Next() bool {
+func (it *VerifiableLoadLogTriggerUpkeepOwnershipTransferRequestedIterator) Next() bool {
if it.fail != nil {
return false
@@ -1709,7 +1925,7 @@ func (it *VerifiableLoadLogTriggerUpkeepOwnershipTransferredIterator) Next() boo
if it.done {
select {
case log := <-it.logs:
- it.Event = new(VerifiableLoadLogTriggerUpkeepOwnershipTransferred)
+ it.Event = new(VerifiableLoadLogTriggerUpkeepOwnershipTransferRequested)
if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
it.fail = err
return false
@@ -1724,7 +1940,7 @@ func (it *VerifiableLoadLogTriggerUpkeepOwnershipTransferredIterator) Next() boo
select {
case log := <-it.logs:
- it.Event = new(VerifiableLoadLogTriggerUpkeepOwnershipTransferred)
+ it.Event = new(VerifiableLoadLogTriggerUpkeepOwnershipTransferRequested)
if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
it.fail = err
return false
@@ -1739,22 +1955,22 @@ func (it *VerifiableLoadLogTriggerUpkeepOwnershipTransferredIterator) Next() boo
}
}
-func (it *VerifiableLoadLogTriggerUpkeepOwnershipTransferredIterator) Error() error {
+func (it *VerifiableLoadLogTriggerUpkeepOwnershipTransferRequestedIterator) Error() error {
return it.fail
}
-func (it *VerifiableLoadLogTriggerUpkeepOwnershipTransferredIterator) Close() error {
+func (it *VerifiableLoadLogTriggerUpkeepOwnershipTransferRequestedIterator) Close() error {
it.sub.Unsubscribe()
return nil
}
-type VerifiableLoadLogTriggerUpkeepOwnershipTransferred struct {
+type VerifiableLoadLogTriggerUpkeepOwnershipTransferRequested struct {
From common.Address
To common.Address
Raw types.Log
}
-func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VerifiableLoadLogTriggerUpkeepOwnershipTransferredIterator, error) {
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VerifiableLoadLogTriggerUpkeepOwnershipTransferRequestedIterator, error) {
var fromRule []interface{}
for _, fromItem := range from {
@@ -1765,14 +1981,14 @@ func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepFilterer) F
toRule = append(toRule, toItem)
}
- logs, sub, err := _VerifiableLoadLogTriggerUpkeep.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule)
+ logs, sub, err := _VerifiableLoadLogTriggerUpkeep.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule)
if err != nil {
return nil, err
}
- return &VerifiableLoadLogTriggerUpkeepOwnershipTransferredIterator{contract: _VerifiableLoadLogTriggerUpkeep.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil
+ return &VerifiableLoadLogTriggerUpkeepOwnershipTransferRequestedIterator{contract: _VerifiableLoadLogTriggerUpkeep.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil
}
-func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *VerifiableLoadLogTriggerUpkeepOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) {
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *VerifiableLoadLogTriggerUpkeepOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) {
var fromRule []interface{}
for _, fromItem := range from {
@@ -1783,7 +1999,7 @@ func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepFilterer) W
toRule = append(toRule, toItem)
}
- logs, sub, err := _VerifiableLoadLogTriggerUpkeep.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule)
+ logs, sub, err := _VerifiableLoadLogTriggerUpkeep.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule)
if err != nil {
return nil, err
}
@@ -1793,8 +2009,8 @@ func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepFilterer) W
select {
case log := <-logs:
- event := new(VerifiableLoadLogTriggerUpkeepOwnershipTransferred)
- if err := _VerifiableLoadLogTriggerUpkeep.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil {
+ event := new(VerifiableLoadLogTriggerUpkeepOwnershipTransferRequested)
+ if err := _VerifiableLoadLogTriggerUpkeep.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil {
return err
}
event.Raw = log
@@ -1815,17 +2031,17 @@ func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepFilterer) W
}), nil
}
-func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepFilterer) ParseOwnershipTransferred(log types.Log) (*VerifiableLoadLogTriggerUpkeepOwnershipTransferred, error) {
- event := new(VerifiableLoadLogTriggerUpkeepOwnershipTransferred)
- if err := _VerifiableLoadLogTriggerUpkeep.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil {
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepFilterer) ParseOwnershipTransferRequested(log types.Log) (*VerifiableLoadLogTriggerUpkeepOwnershipTransferRequested, error) {
+ event := new(VerifiableLoadLogTriggerUpkeepOwnershipTransferRequested)
+ if err := _VerifiableLoadLogTriggerUpkeep.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil {
return nil, err
}
event.Raw = log
return event, nil
}
-type VerifiableLoadLogTriggerUpkeepReceivedIterator struct {
- Event *VerifiableLoadLogTriggerUpkeepReceived
+type VerifiableLoadLogTriggerUpkeepOwnershipTransferredIterator struct {
+ Event *VerifiableLoadLogTriggerUpkeepOwnershipTransferred
contract *bind.BoundContract
event string
@@ -1836,7 +2052,7 @@ type VerifiableLoadLogTriggerUpkeepReceivedIterator struct {
fail error
}
-func (it *VerifiableLoadLogTriggerUpkeepReceivedIterator) Next() bool {
+func (it *VerifiableLoadLogTriggerUpkeepOwnershipTransferredIterator) Next() bool {
if it.fail != nil {
return false
@@ -1845,7 +2061,7 @@ func (it *VerifiableLoadLogTriggerUpkeepReceivedIterator) Next() bool {
if it.done {
select {
case log := <-it.logs:
- it.Event = new(VerifiableLoadLogTriggerUpkeepReceived)
+ it.Event = new(VerifiableLoadLogTriggerUpkeepOwnershipTransferred)
if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
it.fail = err
return false
@@ -1860,7 +2076,7 @@ func (it *VerifiableLoadLogTriggerUpkeepReceivedIterator) Next() bool {
select {
case log := <-it.logs:
- it.Event = new(VerifiableLoadLogTriggerUpkeepReceived)
+ it.Event = new(VerifiableLoadLogTriggerUpkeepOwnershipTransferred)
if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
it.fail = err
return false
@@ -1875,33 +2091,51 @@ func (it *VerifiableLoadLogTriggerUpkeepReceivedIterator) Next() bool {
}
}
-func (it *VerifiableLoadLogTriggerUpkeepReceivedIterator) Error() error {
+func (it *VerifiableLoadLogTriggerUpkeepOwnershipTransferredIterator) Error() error {
return it.fail
}
-func (it *VerifiableLoadLogTriggerUpkeepReceivedIterator) Close() error {
+func (it *VerifiableLoadLogTriggerUpkeepOwnershipTransferredIterator) Close() error {
it.sub.Unsubscribe()
return nil
}
-type VerifiableLoadLogTriggerUpkeepReceived struct {
- Sender common.Address
- Value *big.Int
- Raw types.Log
+type VerifiableLoadLogTriggerUpkeepOwnershipTransferred struct {
+ From common.Address
+ To common.Address
+ Raw types.Log
}
-func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepFilterer) FilterReceived(opts *bind.FilterOpts) (*VerifiableLoadLogTriggerUpkeepReceivedIterator, error) {
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VerifiableLoadLogTriggerUpkeepOwnershipTransferredIterator, error) {
- logs, sub, err := _VerifiableLoadLogTriggerUpkeep.contract.FilterLogs(opts, "Received")
+ var fromRule []interface{}
+ for _, fromItem := range from {
+ fromRule = append(fromRule, fromItem)
+ }
+ var toRule []interface{}
+ for _, toItem := range to {
+ toRule = append(toRule, toItem)
+ }
+
+ logs, sub, err := _VerifiableLoadLogTriggerUpkeep.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule)
if err != nil {
return nil, err
}
- return &VerifiableLoadLogTriggerUpkeepReceivedIterator{contract: _VerifiableLoadLogTriggerUpkeep.contract, event: "Received", logs: logs, sub: sub}, nil
+ return &VerifiableLoadLogTriggerUpkeepOwnershipTransferredIterator{contract: _VerifiableLoadLogTriggerUpkeep.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil
}
-func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepFilterer) WatchReceived(opts *bind.WatchOpts, sink chan<- *VerifiableLoadLogTriggerUpkeepReceived) (event.Subscription, error) {
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *VerifiableLoadLogTriggerUpkeepOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) {
- logs, sub, err := _VerifiableLoadLogTriggerUpkeep.contract.WatchLogs(opts, "Received")
+ var fromRule []interface{}
+ for _, fromItem := range from {
+ fromRule = append(fromRule, fromItem)
+ }
+ var toRule []interface{}
+ for _, toItem := range to {
+ toRule = append(toRule, toItem)
+ }
+
+ logs, sub, err := _VerifiableLoadLogTriggerUpkeep.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule)
if err != nil {
return nil, err
}
@@ -1911,8 +2145,8 @@ func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepFilterer) W
select {
case log := <-logs:
- event := new(VerifiableLoadLogTriggerUpkeepReceived)
- if err := _VerifiableLoadLogTriggerUpkeep.contract.UnpackLog(event, "Received", log); err != nil {
+ event := new(VerifiableLoadLogTriggerUpkeepOwnershipTransferred)
+ if err := _VerifiableLoadLogTriggerUpkeep.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil {
return err
}
event.Raw = log
@@ -1933,9 +2167,9 @@ func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepFilterer) W
}), nil
}
-func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepFilterer) ParseReceived(log types.Log) (*VerifiableLoadLogTriggerUpkeepReceived, error) {
- event := new(VerifiableLoadLogTriggerUpkeepReceived)
- if err := _VerifiableLoadLogTriggerUpkeep.contract.UnpackLog(event, "Received", log); err != nil {
+func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepFilterer) ParseOwnershipTransferred(log types.Log) (*VerifiableLoadLogTriggerUpkeepOwnershipTransferred, error) {
+ event := new(VerifiableLoadLogTriggerUpkeepOwnershipTransferred)
+ if err := _VerifiableLoadLogTriggerUpkeep.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil {
return nil, err
}
event.Raw = log
@@ -2061,137 +2295,18 @@ func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepFilterer) P
return event, nil
}
-type VerifiableLoadLogTriggerUpkeepUpkeepsRegisteredIterator struct {
- Event *VerifiableLoadLogTriggerUpkeepUpkeepsRegistered
-
- contract *bind.BoundContract
- event string
-
- logs chan types.Log
- sub ethereum.Subscription
- done bool
- fail error
-}
-
-func (it *VerifiableLoadLogTriggerUpkeepUpkeepsRegisteredIterator) Next() bool {
-
- if it.fail != nil {
- return false
- }
-
- if it.done {
- select {
- case log := <-it.logs:
- it.Event = new(VerifiableLoadLogTriggerUpkeepUpkeepsRegistered)
- if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
- it.fail = err
- return false
- }
- it.Event.Raw = log
- return true
-
- default:
- return false
- }
- }
-
- select {
- case log := <-it.logs:
- it.Event = new(VerifiableLoadLogTriggerUpkeepUpkeepsRegistered)
- if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
- it.fail = err
- return false
- }
- it.Event.Raw = log
- return true
-
- case err := <-it.sub.Err():
- it.done = true
- it.fail = err
- return it.Next()
- }
-}
-
-func (it *VerifiableLoadLogTriggerUpkeepUpkeepsRegisteredIterator) Error() error {
- return it.fail
-}
-
-func (it *VerifiableLoadLogTriggerUpkeepUpkeepsRegisteredIterator) Close() error {
- it.sub.Unsubscribe()
- return nil
-}
-
-type VerifiableLoadLogTriggerUpkeepUpkeepsRegistered struct {
- UpkeepIds []*big.Int
- Raw types.Log
-}
-
-func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepFilterer) FilterUpkeepsRegistered(opts *bind.FilterOpts) (*VerifiableLoadLogTriggerUpkeepUpkeepsRegisteredIterator, error) {
-
- logs, sub, err := _VerifiableLoadLogTriggerUpkeep.contract.FilterLogs(opts, "UpkeepsRegistered")
- if err != nil {
- return nil, err
- }
- return &VerifiableLoadLogTriggerUpkeepUpkeepsRegisteredIterator{contract: _VerifiableLoadLogTriggerUpkeep.contract, event: "UpkeepsRegistered", logs: logs, sub: sub}, nil
-}
-
-func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepFilterer) WatchUpkeepsRegistered(opts *bind.WatchOpts, sink chan<- *VerifiableLoadLogTriggerUpkeepUpkeepsRegistered) (event.Subscription, error) {
-
- logs, sub, err := _VerifiableLoadLogTriggerUpkeep.contract.WatchLogs(opts, "UpkeepsRegistered")
- if err != nil {
- return nil, err
- }
- return event.NewSubscription(func(quit <-chan struct{}) error {
- defer sub.Unsubscribe()
- for {
- select {
- case log := <-logs:
-
- event := new(VerifiableLoadLogTriggerUpkeepUpkeepsRegistered)
- if err := _VerifiableLoadLogTriggerUpkeep.contract.UnpackLog(event, "UpkeepsRegistered", log); err != nil {
- return err
- }
- event.Raw = log
-
- select {
- case sink <- event:
- case err := <-sub.Err():
- return err
- case <-quit:
- return nil
- }
- case err := <-sub.Err():
- return err
- case <-quit:
- return nil
- }
- }
- }), nil
-}
-
-func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeepFilterer) ParseUpkeepsRegistered(log types.Log) (*VerifiableLoadLogTriggerUpkeepUpkeepsRegistered, error) {
- event := new(VerifiableLoadLogTriggerUpkeepUpkeepsRegistered)
- if err := _VerifiableLoadLogTriggerUpkeep.contract.UnpackLog(event, "UpkeepsRegistered", log); err != nil {
- return nil, err
- }
- event.Raw = log
- return event, nil
-}
-
func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeep) ParseLog(log types.Log) (generated.AbigenLog, error) {
switch log.Topics[0] {
case _VerifiableLoadLogTriggerUpkeep.abi.Events["LogEmitted"].ID:
return _VerifiableLoadLogTriggerUpkeep.ParseLogEmitted(log)
+ case _VerifiableLoadLogTriggerUpkeep.abi.Events["LogEmittedAgain"].ID:
+ return _VerifiableLoadLogTriggerUpkeep.ParseLogEmittedAgain(log)
case _VerifiableLoadLogTriggerUpkeep.abi.Events["OwnershipTransferRequested"].ID:
return _VerifiableLoadLogTriggerUpkeep.ParseOwnershipTransferRequested(log)
case _VerifiableLoadLogTriggerUpkeep.abi.Events["OwnershipTransferred"].ID:
return _VerifiableLoadLogTriggerUpkeep.ParseOwnershipTransferred(log)
- case _VerifiableLoadLogTriggerUpkeep.abi.Events["Received"].ID:
- return _VerifiableLoadLogTriggerUpkeep.ParseReceived(log)
case _VerifiableLoadLogTriggerUpkeep.abi.Events["UpkeepTopUp"].ID:
return _VerifiableLoadLogTriggerUpkeep.ParseUpkeepTopUp(log)
- case _VerifiableLoadLogTriggerUpkeep.abi.Events["UpkeepsRegistered"].ID:
- return _VerifiableLoadLogTriggerUpkeep.ParseUpkeepsRegistered(log)
default:
return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0])
@@ -2202,6 +2317,10 @@ func (VerifiableLoadLogTriggerUpkeepLogEmitted) Topic() common.Hash {
return common.HexToHash("0x97009585a4d2440f981ab6f6eec514343e1e6b2aa9b991a26998e6806f41bf08")
}
+func (VerifiableLoadLogTriggerUpkeepLogEmittedAgain) Topic() common.Hash {
+ return common.HexToHash("0xc76416badc8398ce17c93eab7b4f60f263241694cf503e4df24f233a8cc1c50d")
+}
+
func (VerifiableLoadLogTriggerUpkeepOwnershipTransferRequested) Topic() common.Hash {
return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278")
}
@@ -2210,18 +2329,10 @@ func (VerifiableLoadLogTriggerUpkeepOwnershipTransferred) Topic() common.Hash {
return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0")
}
-func (VerifiableLoadLogTriggerUpkeepReceived) Topic() common.Hash {
- return common.HexToHash("0x88a5966d370b9919b20f3e2c13ff65706f196a4e32cc2c12bf57088f88525874")
-}
-
func (VerifiableLoadLogTriggerUpkeepUpkeepTopUp) Topic() common.Hash {
return common.HexToHash("0x49d4100ab0124eb4a9a65dc4ea08d6412a43f6f05c49194983f5b322bcc0a5c0")
}
-func (VerifiableLoadLogTriggerUpkeepUpkeepsRegistered) Topic() common.Hash {
- return common.HexToHash("0x2ee10f7eb180441fb9fbba75b10c0162b5390b557712c93426243ca8f383c711")
-}
-
func (_VerifiableLoadLogTriggerUpkeep *VerifiableLoadLogTriggerUpkeep) Address() common.Address {
return _VerifiableLoadLogTriggerUpkeep.address
}
@@ -2231,8 +2342,6 @@ type VerifiableLoadLogTriggerUpkeepInterface interface {
AddLinkAmount(opts *bind.CallOpts) (*big.Int, error)
- AutoLog(opts *bind.CallOpts) (bool, error)
-
BucketedDelays(opts *bind.CallOpts, arg0 *big.Int, arg1 uint16, arg2 *big.Int) (*big.Int, error)
Buckets(opts *bind.CallOpts, arg0 *big.Int) (uint16, error)
@@ -2249,6 +2358,8 @@ type VerifiableLoadLogTriggerUpkeepInterface interface {
Eligible(opts *bind.CallOpts, upkeepId *big.Int) (bool, error)
+ EmittedAgainSig(opts *bind.CallOpts) ([32]byte, error)
+
EmittedSig(opts *bind.CallOpts) ([32]byte, error)
FeedParamKey(opts *bind.CallOpts) (string, error)
@@ -2259,7 +2370,11 @@ type VerifiableLoadLogTriggerUpkeepInterface interface {
GasLimits(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error)
- GetActiveUpkeepIDs(opts *bind.CallOpts, startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error)
+ GetActiveUpkeepIDsDeployedByThisContract(opts *bind.CallOpts, startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error)
+
+ GetAllActiveUpkeepIDsOnRegistry(opts *bind.CallOpts, startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error)
+
+ GetBalance(opts *bind.CallOpts, id *big.Int) (*big.Int, error)
GetBucketedDelays(opts *bind.CallOpts, upkeepId *big.Int, bucket uint16) ([]*big.Int, error)
@@ -2269,7 +2384,11 @@ type VerifiableLoadLogTriggerUpkeepInterface interface {
GetDelaysLength(opts *bind.CallOpts, upkeepId *big.Int) (*big.Int, error)
- GetLogTriggerConfig(opts *bind.CallOpts, upkeepId *big.Int) ([]byte, error)
+ GetForwarder(opts *bind.CallOpts, upkeepID *big.Int) (common.Address, error)
+
+ GetLogTriggerConfig(opts *bind.CallOpts, addr common.Address, selector uint8, topic0 [32]byte, topic1 [32]byte, topic2 [32]byte, topic3 [32]byte) ([]byte, error)
+
+ GetMinBalanceForUpkeep(opts *bind.CallOpts, upkeepId *big.Int) (*big.Int, error)
GetPxDelayLastNPerforms(opts *bind.CallOpts, upkeepId *big.Int, p *big.Int, n *big.Int) (*big.Int, error)
@@ -2277,12 +2396,22 @@ type VerifiableLoadLogTriggerUpkeepInterface interface {
GetSumDelayLastNPerforms(opts *bind.CallOpts, upkeepId *big.Int, n *big.Int) (*big.Int, *big.Int, error)
+ GetTriggerType(opts *bind.CallOpts, upkeepId *big.Int) (uint8, error)
+
+ GetUpkeepInfo(opts *bind.CallOpts, upkeepId *big.Int) (KeeperRegistryBase21UpkeepInfo, error)
+
+ GetUpkeepPrivilegeConfig(opts *bind.CallOpts, upkeepId *big.Int) ([]byte, error)
+
+ GetUpkeepTriggerConfig(opts *bind.CallOpts, upkeepId *big.Int) ([]byte, error)
+
Intervals(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error)
LastTopUpBlocks(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error)
LinkToken(opts *bind.CallOpts) (common.Address, error)
+ LogNum(opts *bind.CallOpts) (uint8, error)
+
MinBalanceThresholdMultiplier(opts *bind.CallOpts) (uint8, error)
Owner(opts *bind.CallOpts) (common.Address, error)
@@ -2311,9 +2440,13 @@ type VerifiableLoadLogTriggerUpkeepInterface interface {
BatchCancelUpkeeps(opts *bind.TransactOpts, upkeepIds []*big.Int) (*types.Transaction, error)
+ BatchPreparingUpkeeps(opts *bind.TransactOpts, upkeepIds []*big.Int, selector uint8, topic0 [32]byte, topic1 [32]byte, topic2 [32]byte, topic3 [32]byte) (*types.Transaction, error)
+
+ BatchPreparingUpkeepsSimple(opts *bind.TransactOpts, upkeepIds []*big.Int, log uint8, selector uint8) (*types.Transaction, error)
+
BatchRegisterUpkeeps(opts *bind.TransactOpts, number uint8, gasLimit uint32, triggerType uint8, triggerConfig []byte, amount *big.Int, checkGasToBurn *big.Int, performGasToBurn *big.Int) (*types.Transaction, error)
- BatchSendLogs(opts *bind.TransactOpts) (*types.Transaction, error)
+ BatchSendLogs(opts *bind.TransactOpts, log uint8) (*types.Transaction, error)
BatchSetIntervals(opts *bind.TransactOpts, upkeepIds []*big.Int, interval uint32) (*types.Transaction, error)
@@ -2323,42 +2456,36 @@ type VerifiableLoadLogTriggerUpkeepInterface interface {
BurnPerformGas(opts *bind.TransactOpts, upkeepId *big.Int, startGas *big.Int, blockNum *big.Int) (*types.Transaction, error)
- CancelUpkeep(opts *bind.TransactOpts, upkeepId *big.Int) (*types.Transaction, error)
-
CheckLog(opts *bind.TransactOpts, log Log, checkData []byte) (*types.Transaction, error)
PerformUpkeep(opts *bind.TransactOpts, performData []byte) (*types.Transaction, error)
- SendLog(opts *bind.TransactOpts, upkeepId *big.Int) (*types.Transaction, error)
-
- SetAddLinkAmount(opts *bind.TransactOpts, amount *big.Int) (*types.Transaction, error)
-
- SetAutoLog(opts *bind.TransactOpts, _autoLog bool) (*types.Transaction, error)
-
- SetCheckGasToBurn(opts *bind.TransactOpts, upkeepId *big.Int, value *big.Int) (*types.Transaction, error)
+ SendLog(opts *bind.TransactOpts, upkeepId *big.Int, log uint8) (*types.Transaction, error)
SetConfig(opts *bind.TransactOpts, newRegistrar common.Address) (*types.Transaction, error)
- SetFeedsHex(opts *bind.TransactOpts, newFeeds []string) (*types.Transaction, error)
+ SetFeeds(opts *bind.TransactOpts, _feeds []string) (*types.Transaction, error)
SetInterval(opts *bind.TransactOpts, upkeepId *big.Int, _interval *big.Int) (*types.Transaction, error)
- SetMinBalanceThresholdMultiplier(opts *bind.TransactOpts, newMinBalanceThresholdMultiplier uint8) (*types.Transaction, error)
+ SetLog(opts *bind.TransactOpts, _log uint8) (*types.Transaction, error)
- SetPerformDataSize(opts *bind.TransactOpts, upkeepId *big.Int, value *big.Int) (*types.Transaction, error)
+ SetParamKeys(opts *bind.TransactOpts, _feedParamKey string, _timeParamKey string) (*types.Transaction, error)
- SetPerformGasToBurn(opts *bind.TransactOpts, upkeepId *big.Int, value *big.Int) (*types.Transaction, error)
+ SetPerformDataSize(opts *bind.TransactOpts, upkeepId *big.Int, value *big.Int) (*types.Transaction, error)
SetUpkeepGasLimit(opts *bind.TransactOpts, upkeepId *big.Int, gasLimit uint32) (*types.Transaction, error)
- SetUpkeepTopUpCheckInterval(opts *bind.TransactOpts, newInterval *big.Int) (*types.Transaction, error)
-
- SetUseMercury(opts *bind.TransactOpts, _useMercury bool) (*types.Transaction, error)
+ SetUpkeepPrivilegeConfig(opts *bind.TransactOpts, upkeepId *big.Int, cfg []byte) (*types.Transaction, error)
TopUpFund(opts *bind.TransactOpts, upkeepId *big.Int, blockNum *big.Int) (*types.Transaction, error)
TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error)
+ UpdateLogTriggerConfig1(opts *bind.TransactOpts, upkeepId *big.Int, addr common.Address, selector uint8, topic0 [32]byte, topic1 [32]byte, topic2 [32]byte, topic3 [32]byte) (*types.Transaction, error)
+
+ UpdateLogTriggerConfig2(opts *bind.TransactOpts, upkeepId *big.Int, cfg []byte) (*types.Transaction, error)
+
UpdateUpkeepPipelineData(opts *bind.TransactOpts, upkeepId *big.Int, pipelineData []byte) (*types.Transaction, error)
WithdrawLinks(opts *bind.TransactOpts) (*types.Transaction, error)
@@ -2367,12 +2494,18 @@ type VerifiableLoadLogTriggerUpkeepInterface interface {
Receive(opts *bind.TransactOpts) (*types.Transaction, error)
- FilterLogEmitted(opts *bind.FilterOpts, upkeepId []*big.Int, blockNum []*big.Int) (*VerifiableLoadLogTriggerUpkeepLogEmittedIterator, error)
+ FilterLogEmitted(opts *bind.FilterOpts, upkeepId []*big.Int, blockNum []*big.Int, addr []common.Address) (*VerifiableLoadLogTriggerUpkeepLogEmittedIterator, error)
- WatchLogEmitted(opts *bind.WatchOpts, sink chan<- *VerifiableLoadLogTriggerUpkeepLogEmitted, upkeepId []*big.Int, blockNum []*big.Int) (event.Subscription, error)
+ WatchLogEmitted(opts *bind.WatchOpts, sink chan<- *VerifiableLoadLogTriggerUpkeepLogEmitted, upkeepId []*big.Int, blockNum []*big.Int, addr []common.Address) (event.Subscription, error)
ParseLogEmitted(log types.Log) (*VerifiableLoadLogTriggerUpkeepLogEmitted, error)
+ FilterLogEmittedAgain(opts *bind.FilterOpts, upkeepId []*big.Int, blockNum []*big.Int, addr []common.Address) (*VerifiableLoadLogTriggerUpkeepLogEmittedAgainIterator, error)
+
+ WatchLogEmittedAgain(opts *bind.WatchOpts, sink chan<- *VerifiableLoadLogTriggerUpkeepLogEmittedAgain, upkeepId []*big.Int, blockNum []*big.Int, addr []common.Address) (event.Subscription, error)
+
+ ParseLogEmittedAgain(log types.Log) (*VerifiableLoadLogTriggerUpkeepLogEmittedAgain, error)
+
FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VerifiableLoadLogTriggerUpkeepOwnershipTransferRequestedIterator, error)
WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *VerifiableLoadLogTriggerUpkeepOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error)
@@ -2385,24 +2518,12 @@ type VerifiableLoadLogTriggerUpkeepInterface interface {
ParseOwnershipTransferred(log types.Log) (*VerifiableLoadLogTriggerUpkeepOwnershipTransferred, error)
- FilterReceived(opts *bind.FilterOpts) (*VerifiableLoadLogTriggerUpkeepReceivedIterator, error)
-
- WatchReceived(opts *bind.WatchOpts, sink chan<- *VerifiableLoadLogTriggerUpkeepReceived) (event.Subscription, error)
-
- ParseReceived(log types.Log) (*VerifiableLoadLogTriggerUpkeepReceived, error)
-
FilterUpkeepTopUp(opts *bind.FilterOpts) (*VerifiableLoadLogTriggerUpkeepUpkeepTopUpIterator, error)
WatchUpkeepTopUp(opts *bind.WatchOpts, sink chan<- *VerifiableLoadLogTriggerUpkeepUpkeepTopUp) (event.Subscription, error)
ParseUpkeepTopUp(log types.Log) (*VerifiableLoadLogTriggerUpkeepUpkeepTopUp, error)
- FilterUpkeepsRegistered(opts *bind.FilterOpts) (*VerifiableLoadLogTriggerUpkeepUpkeepsRegisteredIterator, error)
-
- WatchUpkeepsRegistered(opts *bind.WatchOpts, sink chan<- *VerifiableLoadLogTriggerUpkeepUpkeepsRegistered) (event.Subscription, error)
-
- ParseUpkeepsRegistered(log types.Log) (*VerifiableLoadLogTriggerUpkeepUpkeepsRegistered, error)
-
ParseLog(log types.Log) (generated.AbigenLog, error)
Address() common.Address
diff --git a/core/gethwrappers/generated/verifiable_load_mercury_upkeep_wrapper/verifiable_load_mercury_upkeep_wrapper.go b/core/gethwrappers/generated/verifiable_load_mercury_upkeep_wrapper/verifiable_load_mercury_upkeep_wrapper.go
deleted file mode 100644
index 2d84e4c98b7..00000000000
--- a/core/gethwrappers/generated/verifiable_load_mercury_upkeep_wrapper/verifiable_load_mercury_upkeep_wrapper.go
+++ /dev/null
@@ -1,2322 +0,0 @@
-// Code generated - DO NOT EDIT.
-// This file is a generated binding and any manual changes will be lost.
-
-package verifiable_load_mercury_upkeep_wrapper
-
-import (
- "errors"
- "fmt"
- "math/big"
- "strings"
-
- ethereum "github.com/ethereum/go-ethereum"
- "github.com/ethereum/go-ethereum/accounts/abi"
- "github.com/ethereum/go-ethereum/accounts/abi/bind"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/event"
- "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated"
-)
-
-var (
- _ = errors.New
- _ = big.NewInt
- _ = strings.NewReader
- _ = ethereum.NotFound
- _ = bind.Bind
- _ = common.Big1
- _ = types.BloomLookup
- _ = event.NewSubscription
- _ = abi.ConvertType
-)
-
-var VerifiableLoadMercuryUpkeepMetaData = &bind.MetaData{
- ABI: "[{\"inputs\":[{\"internalType\":\"contractAutomationRegistrar2_1\",\"name\":\"_registrar\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_useArb\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"feedParamKey\",\"type\":\"string\"},{\"internalType\":\"string[]\",\"name\":\"feeds\",\"type\":\"string[]\"},{\"internalType\":\"string\",\"name\":\"timeParamKey\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"time\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"FeedLookup\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IndexOutOfRange\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"blockNum\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"LogEmitted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Received\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"blockNum\",\"type\":\"uint256\"}],\"name\":\"UpkeepTopUp\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"}],\"name\":\"UpkeepsRegistered\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BUCKET_SIZE\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"addFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"addLinkAmount\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"}],\"name\":\"batchCancelUpkeeps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"number\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"},{\"internalType\":\"uint256\",\"name\":\"checkGasToBurn\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"performGasToBurn\",\"type\":\"uint256\"}],\"name\":\"batchRegisterUpkeeps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"batchSendLogs\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"},{\"internalType\":\"uint32\",\"name\":\"interval\",\"type\":\"uint32\"}],\"name\":\"batchSetIntervals\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"}],\"name\":\"batchUpdatePipelineData\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"}],\"name\":\"batchWithdrawLinks\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"bucketedDelays\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"buckets\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"startGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"blockNum\",\"type\":\"uint256\"}],\"name\":\"burnPerformGas\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"cancelUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes[]\",\"name\":\"values\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"checkCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"checkGasToBurns\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"}],\"name\":\"checkUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"counters\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"delays\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"dummyMap\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"eligible\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"emittedSig\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"feedParamKey\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"feedsHex\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"firstPerformBlocks\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"gasLimits\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"startIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxCount\",\"type\":\"uint256\"}],\"name\":\"getActiveUpkeepIDs\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"bucket\",\"type\":\"uint16\"}],\"name\":\"getBucketedDelays\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getBucketedDelaysLength\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getDelays\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getDelaysLength\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getLogTriggerConfig\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"logTrigger\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"p\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"n\",\"type\":\"uint256\"}],\"name\":\"getPxDelayLastNPerforms\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"bucket\",\"type\":\"uint16\"}],\"name\":\"getSumDelayInBucket\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"n\",\"type\":\"uint256\"}],\"name\":\"getSumDelayLastNPerforms\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"intervals\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"lastTopUpBlocks\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"linkToken\",\"outputs\":[{\"internalType\":\"contractLinkTokenInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"minBalanceThresholdMultiplier\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"performDataSizes\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"performGasToBurns\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"}],\"name\":\"performUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"previousPerformBlocks\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"registrar\",\"outputs\":[{\"internalType\":\"contractAutomationRegistrar2_1\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"registry\",\"outputs\":[{\"internalType\":\"contractIKeeperRegistryMaster\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"sendLog\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"setAddLinkAmount\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"setCheckGasToBurn\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractAutomationRegistrar2_1\",\"name\":\"newRegistrar\",\"type\":\"address\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string[]\",\"name\":\"newFeeds\",\"type\":\"string[]\"}],\"name\":\"setFeedsHex\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_interval\",\"type\":\"uint256\"}],\"name\":\"setInterval\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"newMinBalanceThresholdMultiplier\",\"type\":\"uint8\"}],\"name\":\"setMinBalanceThresholdMultiplier\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"setPerformDataSize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"setPerformGasToBurn\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"}],\"name\":\"setUpkeepGasLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"newInterval\",\"type\":\"uint256\"}],\"name\":\"setUpkeepTopUpCheckInterval\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"timeParamKey\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"blockNum\",\"type\":\"uint256\"}],\"name\":\"topUpFund\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"pipelineData\",\"type\":\"bytes\"}],\"name\":\"updateUpkeepPipelineData\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"upkeepTopUpCheckInterval\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"useArbitrumBlockNum\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawLinks\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"withdrawLinks\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]",
- Bin: "0x7f97009585a4d2440f981ab6f6eec514343e1e6b2aa9b991a26998e6806f41bf086080526005601455601580546001600160681b0319166c140000000002c68af0bb140000179055606460c0526101c0604052604261014081815260e091829190620050fb6101603981526020016040518060800160405280604281526020016200513d6042913981526020016040518060800160405280604281526020016200517f604291399052620000b89060169060036200035f565b50348015620000c657600080fd5b50604051620051c1380380620051c1833981016040819052620000e9916200044c565b81813380600081620001425760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b038481169190911790915581161562000175576200017581620002b4565b5050601180546001600160a01b0319166001600160a01b038516908117909155604080516330fe427560e21b815281516000945063c3f909d4926004808401939192918290030181865afa158015620001d2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001f891906200048f565b50601380546001600160a01b0319166001600160a01b038381169190911790915560115460408051631b6b6d2360e01b81529051939450911691631b6b6d23916004808201926020929091908290030181865afa1580156200025e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002849190620004c0565b601280546001600160a01b0319166001600160a01b039290921691909117905550151560a0525062000658915050565b336001600160a01b038216036200030e5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000139565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b828054828255906000526020600020908101928215620003aa579160200282015b82811115620003aa57825182906200039990826200058c565b509160200191906001019062000380565b50620003b8929150620003bc565b5090565b80821115620003b8576000620003d38282620003dd565b50600101620003bc565b508054620003eb90620004fd565b6000825580601f10620003fc575050565b601f0160209004906000526020600020908101906200041c91906200041f565b50565b5b80821115620003b8576000815560010162000420565b6001600160a01b03811681146200041c57600080fd5b600080604083850312156200046057600080fd5b82516200046d8162000436565b602084015190925080151581146200048457600080fd5b809150509250929050565b60008060408385031215620004a357600080fd5b8251620004b08162000436565b6020939093015192949293505050565b600060208284031215620004d357600080fd5b8151620004e08162000436565b9392505050565b634e487b7160e01b600052604160045260246000fd5b600181811c908216806200051257607f821691505b6020821081036200053357634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200058757600081815260208120601f850160051c81016020861015620005625750805b601f850160051c820191505b8181101562000583578281556001016200056e565b5050505b505050565b81516001600160401b03811115620005a857620005a8620004e7565b620005c081620005b98454620004fd565b8462000539565b602080601f831160018114620005f85760008415620005df5750858301515b600019600386901b1c1916600185901b17855562000583565b600085815260208120601f198616915b82811015620006295788860151825594840194600190910190840162000608565b5085821015620006485787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a05160c051614a5e6200069d6000396000818161052b0152611a3d0152600081816108470152612e69015260008181610b8301526114410152614a5e6000f3fe6080604052600436106103e25760003560e01c8063776898c81161020d578063a72aa27e11610128578063d3558528116100bb578063e0114adb1161008a578063f2fde38b1161006f578063f2fde38b14610e80578063fba7ffa314610ea0578063fcdc1f6314610ecd57600080fd5b8063e0114adb14610e3d578063e455308314610e6a57600080fd5b8063d355852814610d7e578063d6051a7214610ddd578063daee1aeb14610dfd578063dbef701e14610e1d57600080fd5b8063becde0e1116100f7578063becde0e114610c9b578063c357f1f314610cbb578063c804802214610d15578063c98f10b014610d3557600080fd5b8063a72aa27e14610be5578063a79c404314610c05578063af953a4a14610c32578063afb28d1f14610c5257600080fd5b80639ac542eb116101a05780639d6f1cc71161016f5780639d6f1cc714610b51578063a654824814610b71578063a6b5947514610ba5578063a6c60d8914610bc557600080fd5b80639ac542eb14610a975780639b42935414610ad35780639b51fb0d14610b005780639d385eaa14610b3157600080fd5b80638da5cb5b116101dc5780638da5cb5b146109ff5780638fcb3fba14610a2a578063924ca57814610a57578063948108f714610a7757600080fd5b8063776898c81461097d57806379ba50971461099d5780637b103999146109b25780637e7a46dc146109df57600080fd5b806346e7a63e116102fd578063636092e8116102905780636e04ff0d1161025f5780636e04ff0d146108d35780637145f11b146108f357806373644cce14610923578063767213031461095057600080fd5b8063636092e8146107f3578063642f6cef1461083557806369cdbadb1461087957806369e9b773146108a657600080fd5b806359710992116102cc578063597109921461077c5780635d4ee7f3146107915780635f17e616146107a657806360457ff5146107c657600080fd5b806346e7a63e146106d45780634b56a42e1461070157806351c98be31461072f57806357970e931461074f57600080fd5b806320e3dbd411610375578063328ffd1111610344578063328ffd11146106475780633ebe8d6c146106745780634585e33b1461069457806345d2ec17146106b457600080fd5b806320e3dbd41461059557806328c4b57b146105b55780632a9032d3146105d55780632b20e397146105f557600080fd5b80630d4a4fb1116103b15780630d4a4fb1146104cc5780630e577d42146104f957806312c5502714610519578063206c32e81461056057600080fd5b806305e251311461042657806306c1cc001461044857806306e3b63214610468578063077ac6211461049e57600080fd5b3661042157604080513381523460208201527f88a5966d370b9919b20f3e2c13ff65706f196a4e32cc2c12bf57088f88525874910160405180910390a1005b600080fd5b34801561043257600080fd5b50610446610441366004613796565b610efa565b005b34801561045457600080fd5b506104466104633660046138b7565b610f11565b34801561047457600080fd5b50610488610483366004613953565b6112cd565b6040516104959190613975565b60405180910390f35b3480156104aa57600080fd5b506104be6104b93660046139d0565b6113cc565b604051908152602001610495565b3480156104d857600080fd5b506104ec6104e7366004613a05565b61140a565b6040516104959190613a8c565b34801561050557600080fd5b50610446610514366004613a05565b611527565b34801561052557600080fd5b5061054d7f000000000000000000000000000000000000000000000000000000000000000081565b60405161ffff9091168152602001610495565b34801561056c57600080fd5b5061058061057b366004613a9f565b61156f565b60408051928352602083019190915201610495565b3480156105a157600080fd5b506104466105b0366004613aed565b6115f2565b3480156105c157600080fd5b506104be6105d0366004613b0a565b6117bc565b3480156105e157600080fd5b506104466105f0366004613b7b565b611827565b34801561060157600080fd5b506011546106229073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610495565b34801561065357600080fd5b506104be610662366004613a05565b60036020526000908152604090205481565b34801561068057600080fd5b506104be61068f366004613a05565b6118c1565b3480156106a057600080fd5b506104466106af366004613bff565b61192a565b3480156106c057600080fd5b506104886106cf366004613a9f565b611b55565b3480156106e057600080fd5b506104be6106ef366004613a05565b600a6020526000908152604090205481565b34801561070d57600080fd5b5061072161071c366004613c35565b611bc4565b604051610495929190613d09565b34801561073b57600080fd5b5061044661074a366004613d24565b611c18565b34801561075b57600080fd5b506012546106229073ffffffffffffffffffffffffffffffffffffffff1681565b34801561078857600080fd5b50610446611cbc565b34801561079d57600080fd5b50610446611ea7565b3480156107b257600080fd5b506104466107c1366004613953565b611fde565b3480156107d257600080fd5b506104be6107e1366004613a05565b60076020526000908152604090205481565b3480156107ff57600080fd5b50601554610818906bffffffffffffffffffffffff1681565b6040516bffffffffffffffffffffffff9091168152602001610495565b34801561084157600080fd5b506108697f000000000000000000000000000000000000000000000000000000000000000081565b6040519015158152602001610495565b34801561088557600080fd5b506104be610894366004613a05565b60086020526000908152604090205481565b3480156108b257600080fd5b506104466108c1366004613953565b60009182526008602052604090912055565b3480156108df57600080fd5b506107216108ee366004613bff565b6120ab565b3480156108ff57600080fd5b5061086961090e366004613a05565b600b6020526000908152604090205460ff1681565b34801561092f57600080fd5b506104be61093e366004613a05565b6000908152600c602052604090205490565b34801561095c57600080fd5b506104be61096b366004613a05565b60046020526000908152604090205481565b34801561098957600080fd5b50610869610998366004613a05565b6122c0565b3480156109a957600080fd5b50610446612312565b3480156109be57600080fd5b506013546106229073ffffffffffffffffffffffffffffffffffffffff1681565b3480156109eb57600080fd5b506104466109fa366004613d7b565b61240f565b348015610a0b57600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff16610622565b348015610a3657600080fd5b506104be610a45366004613a05565b60056020526000908152604090205481565b348015610a6357600080fd5b50610446610a72366004613953565b6124a0565b348015610a8357600080fd5b50610446610a92366004613dc7565b6126e5565b348015610aa357600080fd5b50601554610ac1906c01000000000000000000000000900460ff1681565b60405160ff9091168152602001610495565b348015610adf57600080fd5b50610446610aee366004613953565b60009182526009602052604090912055565b348015610b0c57600080fd5b5061054d610b1b366004613a05565b600e6020526000908152604090205461ffff1681565b348015610b3d57600080fd5b50610488610b4c366004613a05565b61282e565b348015610b5d57600080fd5b506104ec610b6c366004613a05565b612890565b348015610b7d57600080fd5b506104be7f000000000000000000000000000000000000000000000000000000000000000081565b348015610bb157600080fd5b50610446610bc0366004613b0a565b61293c565b348015610bd157600080fd5b50610446610be0366004613a05565b601455565b348015610bf157600080fd5b50610446610c00366004613df7565b6129a5565b348015610c1157600080fd5b50610446610c20366004613953565b60009182526007602052604090912055565b348015610c3e57600080fd5b50610446610c4d366004613a05565b612a50565b348015610c5e57600080fd5b506104ec6040518060400160405280600981526020017f666565644964486578000000000000000000000000000000000000000000000081525081565b348015610ca757600080fd5b50610446610cb6366004613b7b565b612ad6565b348015610cc757600080fd5b50610446610cd6366004613e1c565b601580547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff92909216919091179055565b348015610d2157600080fd5b50610446610d30366004613a05565b612b70565b348015610d4157600080fd5b506104ec6040518060400160405280600b81526020017f626c6f636b4e756d62657200000000000000000000000000000000000000000081525081565b348015610d8a57600080fd5b50610446610d99366004613e39565b6015805460ff9092166c01000000000000000000000000027fffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffff909216919091179055565b348015610de957600080fd5b50610580610df8366004613953565b612c08565b348015610e0957600080fd5b50610446610e18366004613b7b565b612c71565b348015610e2957600080fd5b506104be610e38366004613953565b612d3c565b348015610e4957600080fd5b506104be610e58366004613a05565b60096020526000908152604090205481565b348015610e7657600080fd5b506104be60145481565b348015610e8c57600080fd5b50610446610e9b366004613aed565b612d6d565b348015610eac57600080fd5b506104be610ebb366004613a05565b60066020526000908152604090205481565b348015610ed957600080fd5b506104be610ee8366004613a05565b60026020526000908152604090205481565b8051610f0d906016906020840190613566565b5050565b6040805161018081018252600461014082019081527f746573740000000000000000000000000000000000000000000000000000000061016083015281528151602081810184526000808352818401929092523083850181905263ffffffff8b166060850152608084015260ff808a1660a08501528451808301865283815260c085015260e0840189905284519182019094529081526101008201526bffffffffffffffffffffffff8516610120820152601254601154919273ffffffffffffffffffffffffffffffffffffffff9182169263095ea7b3921690610ff7908c1688613e85565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815273ffffffffffffffffffffffffffffffffffffffff90921660048301526bffffffffffffffffffffffff1660248201526044016020604051808303816000875af1158015611075573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110999190613ec9565b5060008860ff1667ffffffffffffffff8111156110b8576110b8613646565b6040519080825280602002602001820160405280156110e1578160200160208202803683370190505b50905060005b8960ff168160ff16101561128a57600061110084612d81565b90508860ff16600103611238576040517f0d4a4fb1000000000000000000000000000000000000000000000000000000008152600481018290526000903090630d4a4fb190602401600060405180830381865afa158015611165573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526111ab9190810190613f31565b6013546040517f4ee88d3500000000000000000000000000000000000000000000000000000000815291925073ffffffffffffffffffffffffffffffffffffffff1690634ee88d35906112049085908590600401613f66565b600060405180830381600087803b15801561121e57600080fd5b505af1158015611232573d6000803e3d6000fd5b50505050505b80838360ff168151811061124e5761124e613f7f565b6020908102919091018101919091526000918252600881526040808320889055600790915290208490558061128281613fae565b9150506110e7565b507f2ee10f7eb180441fb9fbba75b10c0162b5390b557712c93426243ca8f383c711816040516112ba9190613975565b60405180910390a1505050505050505050565b606060006112db600f612e4f565b9050808410611316576040517f1390f2a100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8260000361132b576113288482613fcd565b92505b60008367ffffffffffffffff81111561134657611346613646565b60405190808252806020026020018201604052801561136f578160200160208202803683370190505b50905060005b848110156113c15761139261138a8288613fe0565b600f90612e59565b8282815181106113a4576113a4613f7f565b6020908102919091010152806113b981613ff3565b915050611375565b509150505b92915050565b600d60205282600052604060002060205281600052604060002081815481106113f457600080fd5b9060005260206000200160009250925050505481565b606060006040518060c001604052803073ffffffffffffffffffffffffffffffffffffffff168152602001600160ff1681526020017f000000000000000000000000000000000000000000000000000000000000000081526020018460405160200161147891815260200190565b6040516020818303038152906040526114909061402b565b81526020016000801b81526020016000801b8152509050806040516020016115109190600060c08201905073ffffffffffffffffffffffffffffffffffffffff835116825260ff602084015116602083015260408301516040830152606083015160608301526080830151608083015260a083015160a083015292915050565b604051602081830303815290604052915050919050565b6000611531612e65565b604051308152909150819083907f97009585a4d2440f981ab6f6eec514343e1e6b2aa9b991a26998e6806f41bf089060200160405180910390a35050565b6000828152600d6020908152604080832061ffff8516845282528083208054825181850281018501909352808352849384939291908301828280156115d357602002820191906000526020600020905b8154815260200190600101908083116115bf575b505050505090506115e5818251612f07565b92509250505b9250929050565b601180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8316908117909155604080517fc3f909d400000000000000000000000000000000000000000000000000000000815281516000939263c3f909d492600480820193918290030181865afa158015611688573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116ac919061407b565b50601380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691909117909155601154604080517f1b6b6d230000000000000000000000000000000000000000000000000000000081529051939450911691631b6b6d23916004808201926020929091908290030181865afa15801561174f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061177391906140a9565b601280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff929092169190911790555050565b6000838152600c60209081526040808320805482518185028101850190935280835261181d9383018282801561181157602002820191906000526020600020905b8154815260200190600101908083116117fd575b50505050508484612f8c565b90505b9392505050565b8060005b818160ff1610156118bb573063c8048022858560ff851681811061185157611851613f7f565b905060200201356040518263ffffffff1660e01b815260040161187691815260200190565b600060405180830381600087803b15801561189057600080fd5b505af11580156118a4573d6000803e3d6000fd5b5050505080806118b390613fae565b91505061182b565b50505050565b6000818152600e602052604081205461ffff1681805b8261ffff168161ffff1611611922576000858152600d6020908152604080832061ffff8516845290915290205461190e9083613fe0565b91508061191a816140c6565b9150506118d7565b509392505050565b60005a905060008061193e84860186613c35565b9150915060008180602001905181019061195891906140e7565b6000818152600560209081526040808320546004909252822054929350919061197f612e65565b90508260000361199f576000848152600560205260409020819055611afa565b6000848152600360205260408120546119b88484613fcd565b6119c29190613fcd565b6000868152600e6020908152604080832054600d835281842061ffff909116808552908352818420805483518186028101860190945280845295965090949192909190830182828015611a3457602002820191906000526020600020905b815481526020019060010190808311611a20575b505050505090507f000000000000000000000000000000000000000000000000000000000000000061ffff16815103611aaf5781611a71816140c6565b6000898152600e6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff83161790559250505b506000868152600d6020908152604080832061ffff909416835292815282822080546001818101835591845282842001859055888352600c8252928220805493840181558252902001555b600084815260066020526040812054611b14906001613fe0565b6000868152600660209081526040808320849055600490915290208390559050611b3e85836124a0565b611b4985898461293c565b50505050505050505050565b6000828152600d6020908152604080832061ffff85168452825291829020805483518184028101840190945280845260609392830182828015611bb757602002820191906000526020600020905b815481526020019060010190808311611ba3575b5050505050905092915050565b6000606060008484604051602001611bdd929190614100565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00181529190526001969095509350505050565b8160005b81811015611cb55730635f17e616868684818110611c3c57611c3c613f7f565b90506020020135856040518363ffffffff1660e01b8152600401611c7092919091825263ffffffff16602082015260400190565b600060405180830381600087803b158015611c8a57600080fd5b505af1158015611c9e573d6000803e3d6000fd5b505050508080611cad90613ff3565b915050611c1c565b5050505050565b6013546040517f06e3b632000000000000000000000000000000000000000000000000000000008152600060048201819052602482018190529173ffffffffffffffffffffffffffffffffffffffff16906306e3b63290604401600060405180830381865afa158015611d33573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611d799190810190614194565b80519091506000611d88612e65565b905060005b828110156118bb576000848281518110611da957611da9613f7f565b60209081029190910101516013546040517f5147cd590000000000000000000000000000000000000000000000000000000081526004810183905291925060009173ffffffffffffffffffffffffffffffffffffffff90911690635147cd5990602401602060405180830381865afa158015611e29573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e4d9190614225565b90508060ff16600103611e9257604051308152849083907f97009585a4d2440f981ab6f6eec514343e1e6b2aa9b991a26998e6806f41bf089060200160405180910390a35b50508080611e9f90613ff3565b915050611d8d565b611eaf6130eb565b6012546040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015611f1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f4291906140e7565b6012546040517fa9059cbb0000000000000000000000000000000000000000000000000000000081523360048201526024810183905291925073ffffffffffffffffffffffffffffffffffffffff169063a9059cbb906044016020604051808303816000875af1158015611fba573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f0d9190613ec9565b60008281526003602090815260408083208490556005825280832083905560068252808320839055600c9091528120612016916135bc565b6000828152600e602052604081205461ffff16905b8161ffff168161ffff1611612072576000848152600d6020908152604080832061ffff851684529091528120612060916135bc565b8061206a816140c6565b91505061202b565b5050506000908152600e6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000169055565b6000606060005a905060006120c285870187613a05565b60008181526009602090815260408083205460089092528220549293509190838367ffffffffffffffff8111156120fb576120fb613646565b6040519080825280601f01601f191660200182016040528015612125576020820181803683370190505b50604051602001612137929190613f66565b60405160208183030381529060405290506000612152612e65565b9050600061215f866122c0565b90505b835a61216e9089613fcd565b61217a90612710613fe0565b10156121bb5781406000908152600b6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055612162565b806121d35760008398509850505050505050506115eb565b6040518060400160405280600981526020017f666565644964486578000000000000000000000000000000000000000000000081525060166040518060400160405280600b81526020017f626c6f636b4e756d626572000000000000000000000000000000000000000000815250848960405160200161225591815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527f7ddd933e0000000000000000000000000000000000000000000000000000000082526122b7959493929160040161428f565b60405180910390fd5b60008181526005602052604081205481036122dd57506001919050565b600082815260036020908152604080832054600490925290912054612300612e65565b61230a9190613fcd565b101592915050565b60015473ffffffffffffffffffffffffffffffffffffffff163314612393576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016122b7565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6013546040517fcd7f71b500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063cd7f71b590612469908690869086906004016143dc565b600060405180830381600087803b15801561248357600080fd5b505af1158015612497573d6000803e3d6000fd5b50505050505050565b6014546000838152600260205260409020546124bc9083613fcd565b1115610f0d576013546040517fc7c3a19a0000000000000000000000000000000000000000000000000000000081526004810184905260009173ffffffffffffffffffffffffffffffffffffffff169063c7c3a19a90602401600060405180830381865afa158015612532573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052612578919081019061445e565b6013546040517fb657bc9c0000000000000000000000000000000000000000000000000000000081526004810186905291925060009173ffffffffffffffffffffffffffffffffffffffff9091169063b657bc9c90602401602060405180830381865afa1580156125ed573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612611919061457d565b6015549091506126359082906c01000000000000000000000000900460ff16613e85565b6bffffffffffffffffffffffff1682606001516bffffffffffffffffffffffff1610156118bb576015546126789085906bffffffffffffffffffffffff166126e5565b60008481526002602090815260409182902085905560155482518781526bffffffffffffffffffffffff909116918101919091529081018490527f49d4100ab0124eb4a9a65dc4ea08d6412a43f6f05c49194983f5b322bcc0a5c09060600160405180910390a150505050565b6012546013546040517f095ea7b300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff91821660048201526bffffffffffffffffffffffff8416602482015291169063095ea7b3906044016020604051808303816000875af115801561276d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127919190613ec9565b506013546040517f948108f7000000000000000000000000000000000000000000000000000000008152600481018490526bffffffffffffffffffffffff8316602482015273ffffffffffffffffffffffffffffffffffffffff9091169063948108f790604401600060405180830381600087803b15801561281257600080fd5b505af1158015612826573d6000803e3d6000fd5b505050505050565b6000818152600c602090815260409182902080548351818402810184019094528084526060939283018282801561288457602002820191906000526020600020905b815481526020019060010190808311612870575b50505050509050919050565b601681815481106128a057600080fd5b9060005260206000200160009150905080546128bb90614242565b80601f01602080910402602001604051908101604052809291908181526020018280546128e790614242565b80156129345780601f1061290957610100808354040283529160200191612934565b820191906000526020600020905b81548152906001019060200180831161291757829003601f168201915b505050505081565b6000838152600760205260409020545b805a6129589085613fcd565b61296490612710613fe0565b10156118bb5781406000908152600b6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905561294c565b6013546040517fa72aa27e0000000000000000000000000000000000000000000000000000000081526004810184905263ffffffff8316602482015273ffffffffffffffffffffffffffffffffffffffff9091169063a72aa27e90604401600060405180830381600087803b158015612a1d57600080fd5b505af1158015612a31573d6000803e3d6000fd5b505050600092835250600a602052604090912063ffffffff9091169055565b6013546040517f744bfe610000000000000000000000000000000000000000000000000000000081526004810183905230602482015273ffffffffffffffffffffffffffffffffffffffff9091169063744bfe6190604401600060405180830381600087803b158015612ac257600080fd5b505af1158015611cb5573d6000803e3d6000fd5b8060005b818163ffffffff1610156118bb573063af953a4a858563ffffffff8516818110612b0657612b06613f7f565b905060200201356040518263ffffffff1660e01b8152600401612b2b91815260200190565b600060405180830381600087803b158015612b4557600080fd5b505af1158015612b59573d6000803e3d6000fd5b505050508080612b689061459a565b915050612ada565b6013546040517fc80480220000000000000000000000000000000000000000000000000000000081526004810183905273ffffffffffffffffffffffffffffffffffffffff9091169063c804802290602401600060405180830381600087803b158015612bdc57600080fd5b505af1158015612bf0573d6000803e3d6000fd5b50505050610f0d81600f61316e90919063ffffffff16565b6000828152600c60209081526040808320805482518185028101850190935280835284938493929190830182828015612c6057602002820191906000526020600020905b815481526020019060010190808311612c4c575b505050505090506115e58185612f07565b8060005b818110156118bb576000848483818110612c9157612c91613f7f565b9050602002013590503073ffffffffffffffffffffffffffffffffffffffff16637e7a46dc8283604051602001612cca91815260200190565b6040516020818303038152906040526040518363ffffffff1660e01b8152600401612cf6929190613f66565b600060405180830381600087803b158015612d1057600080fd5b505af1158015612d24573d6000803e3d6000fd5b50505050508080612d3490613ff3565b915050612c75565b600c6020528160005260406000208181548110612d5857600080fd5b90600052602060002001600091509150505481565b612d756130eb565b612d7e8161317a565b50565b6011546040517f3f678e11000000000000000000000000000000000000000000000000000000008152600091829173ffffffffffffffffffffffffffffffffffffffff90911690633f678e1190612ddc9086906004016145b3565b6020604051808303816000875af1158015612dfb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e1f91906140e7565b9050612e2c600f8261326f565b506060909201516000838152600a6020526040902063ffffffff90911690555090565b60006113c6825490565b6000611820838361327b565b60007f000000000000000000000000000000000000000000000000000000000000000015612f0257606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612ed9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612efd91906140e7565b905090565b504390565b815160009081908190841580612f1d5750808510155b15612f26578094505b60008092505b85831015612f8257866001612f418585613fcd565b612f4b9190613fcd565b81518110612f5b57612f5b613f7f565b602002602001015181612f6e9190613fe0565b905082612f7a81613ff3565b935050612f2c565b9694955050505050565b82516000908190831580612fa05750808410155b15612fa9578093505b60008467ffffffffffffffff811115612fc457612fc4613646565b604051908082528060200260200182016040528015612fed578160200160208202803683370190505b509050600092505b8483101561305b5786600161300a8585613fcd565b6130149190613fcd565b8151811061302457613024613f7f565b602002602001015181848151811061303e5761303e613f7f565b60209081029190910101528261305381613ff3565b935050612ff5565b6130748160006001845161306f9190613fcd565b6132a5565b856064036130ad57806001825161308b9190613fcd565b8151811061309b5761309b613f7f565b60200260200101519350505050611820565b8060648251886130bd9190614705565b6130c79190614771565b815181106130d7576130d7613f7f565b602002602001015193505050509392505050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461316c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016122b7565b565b6000611820838361341d565b3373ffffffffffffffffffffffffffffffffffffffff8216036131f9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016122b7565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60006118208383613517565b600082600001828154811061329257613292613f7f565b9060005260206000200154905092915050565b81818082036132b5575050505050565b60008560026132c48787614785565b6132ce91906147a5565b6132d8908761480d565b815181106132e8576132e8613f7f565b602002602001015190505b8183136133f7575b8086848151811061330e5761330e613f7f565b6020026020010151101561332e578261332681614835565b9350506132fb565b85828151811061334057613340613f7f565b6020026020010151811015613361578161335981614866565b92505061332e565b8183136133f25785828151811061337a5761337a613f7f565b602002602001015186848151811061339457613394613f7f565b60200260200101518785815181106133ae576133ae613f7f565b602002602001018885815181106133c7576133c7613f7f565b602090810291909101019190915252826133e081614835565b93505081806133ee90614866565b9250505b6132f3565b8185121561340a5761340a8686846132a5565b83831215612826576128268684866132a5565b60008181526001830160205260408120548015613506576000613441600183613fcd565b855490915060009061345590600190613fcd565b90508181146134ba57600086600001828154811061347557613475613f7f565b906000526020600020015490508087600001848154811061349857613498613f7f565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806134cb576134cb6148bd565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506113c6565b60009150506113c6565b5092915050565b600081815260018301602052604081205461355e575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556113c6565b5060006113c6565b8280548282559060005260206000209081019282156135ac579160200282015b828111156135ac578251829061359c9082614937565b5091602001919060010190613586565b506135b89291506135da565b5090565b5080546000825590600052602060002090810190612d7e91906135f7565b808211156135b85760006135ee828261360c565b506001016135da565b5b808211156135b857600081556001016135f8565b50805461361890614242565b6000825580601f10613628575050565b601f016020900490600052602060002090810190612d7e91906135f7565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff8111828210171561369957613699613646565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156136e6576136e6613646565b604052919050565b600067ffffffffffffffff82111561370857613708613646565b5060051b60200190565b600067ffffffffffffffff82111561372c5761372c613646565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600061376b61376684613712565b61369f565b905082815283838301111561377f57600080fd5b828260208301376000602084830101529392505050565b600060208083850312156137a957600080fd5b823567ffffffffffffffff808211156137c157600080fd5b818501915085601f8301126137d557600080fd5b81356137e3613766826136ee565b81815260059190911b8301840190848101908883111561380257600080fd5b8585015b8381101561384f5780358581111561381e5760008081fd5b8601603f81018b136138305760008081fd5b6138418b8983013560408401613758565b845250918601918601613806565b5098975050505050505050565b60ff81168114612d7e57600080fd5b63ffffffff81168114612d7e57600080fd5b600082601f83011261388e57600080fd5b61182083833560208501613758565b6bffffffffffffffffffffffff81168114612d7e57600080fd5b600080600080600080600060e0888a0312156138d257600080fd5b87356138dd8161385c565b965060208801356138ed8161386b565b955060408801356138fd8161385c565b9450606088013567ffffffffffffffff81111561391957600080fd5b6139258a828b0161387d565b94505060808801356139368161389d565b9699959850939692959460a0840135945060c09093013592915050565b6000806040838503121561396657600080fd5b50508035926020909101359150565b6020808252825182820181905260009190848201906040850190845b818110156139ad57835183529284019291840191600101613991565b50909695505050505050565b803561ffff811681146139cb57600080fd5b919050565b6000806000606084860312156139e557600080fd5b833592506139f5602085016139b9565b9150604084013590509250925092565b600060208284031215613a1757600080fd5b5035919050565b60005b83811015613a39578181015183820152602001613a21565b50506000910152565b60008151808452613a5a816020860160208601613a1e565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006118206020830184613a42565b60008060408385031215613ab257600080fd5b82359150613ac2602084016139b9565b90509250929050565b73ffffffffffffffffffffffffffffffffffffffff81168114612d7e57600080fd5b600060208284031215613aff57600080fd5b813561182081613acb565b600080600060608486031215613b1f57600080fd5b505081359360208301359350604090920135919050565b60008083601f840112613b4857600080fd5b50813567ffffffffffffffff811115613b6057600080fd5b6020830191508360208260051b85010111156115eb57600080fd5b60008060208385031215613b8e57600080fd5b823567ffffffffffffffff811115613ba557600080fd5b613bb185828601613b36565b90969095509350505050565b60008083601f840112613bcf57600080fd5b50813567ffffffffffffffff811115613be757600080fd5b6020830191508360208285010111156115eb57600080fd5b60008060208385031215613c1257600080fd5b823567ffffffffffffffff811115613c2957600080fd5b613bb185828601613bbd565b60008060408385031215613c4857600080fd5b823567ffffffffffffffff80821115613c6057600080fd5b818501915085601f830112613c7457600080fd5b81356020613c84613766836136ee565b82815260059290921b84018101918181019089841115613ca357600080fd5b8286015b84811015613cdb57803586811115613cbf5760008081fd5b613ccd8c86838b010161387d565b845250918301918301613ca7565b5096505086013592505080821115613cf257600080fd5b50613cff8582860161387d565b9150509250929050565b821515815260406020820152600061181d6040830184613a42565b600080600060408486031215613d3957600080fd5b833567ffffffffffffffff811115613d5057600080fd5b613d5c86828701613b36565b9094509250506020840135613d708161386b565b809150509250925092565b600080600060408486031215613d9057600080fd5b83359250602084013567ffffffffffffffff811115613dae57600080fd5b613dba86828701613bbd565b9497909650939450505050565b60008060408385031215613dda57600080fd5b823591506020830135613dec8161389d565b809150509250929050565b60008060408385031215613e0a57600080fd5b823591506020830135613dec8161386b565b600060208284031215613e2e57600080fd5b81356118208161389d565b600060208284031215613e4b57600080fd5b81356118208161385c565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006bffffffffffffffffffffffff80831681851681830481118215151615613eb057613eb0613e56565b02949350505050565b805180151581146139cb57600080fd5b600060208284031215613edb57600080fd5b61182082613eb9565b600082601f830112613ef557600080fd5b8151613f0361376682613712565b818152846020838601011115613f1857600080fd5b613f29826020830160208701613a1e565b949350505050565b600060208284031215613f4357600080fd5b815167ffffffffffffffff811115613f5a57600080fd5b613f2984828501613ee4565b82815260406020820152600061181d6040830184613a42565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff821660ff8103613fc457613fc4613e56565b60010192915050565b818103818111156113c6576113c6613e56565b808201808211156113c6576113c6613e56565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361402457614024613e56565b5060010190565b8051602080830151919081101561406a577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8160200360031b1b821691505b50919050565b80516139cb81613acb565b6000806040838503121561408e57600080fd5b825161409981613acb565b6020939093015192949293505050565b6000602082840312156140bb57600080fd5b815161182081613acb565b600061ffff8083168181036140dd576140dd613e56565b6001019392505050565b6000602082840312156140f957600080fd5b5051919050565b6000604082016040835280855180835260608501915060608160051b8601019250602080880160005b83811015614175577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0888703018552614163868351613a42565b95509382019390820190600101614129565b50508584038187015250505061418b8185613a42565b95945050505050565b600060208083850312156141a757600080fd5b825167ffffffffffffffff8111156141be57600080fd5b8301601f810185136141cf57600080fd5b80516141dd613766826136ee565b81815260059190911b820183019083810190878311156141fc57600080fd5b928401925b8284101561421a57835182529284019290840190614201565b979650505050505050565b60006020828403121561423757600080fd5b81516118208161385c565b600181811c9082168061425657607f821691505b60208210810361406a577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60a0815260006142a260a0830188613a42565b602083820381850152818854808452828401915060058382821b86010160008c8152858120815b8581101561439c577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe089850301875282825461430481614242565b8087526001828116801561431f576001811461435657614385565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0084168d8a01528c8315158b1b8a01019450614385565b8688528c8820885b8481101561437d5781548f828d01015283820191508e8101905061435e565b8a018e019550505b50998b0199929650505091909101906001016142c9565b50505087810360408901526143b1818c613a42565b9550505050505084606084015282810360808401526143d08185613a42565b98975050505050505050565b83815260406020820152816040820152818360608301376000818301606090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016010192915050565b80516139cb8161386b565b80516139cb8161389d565b805167ffffffffffffffff811681146139cb57600080fd5b60006020828403121561447057600080fd5b815167ffffffffffffffff8082111561448857600080fd5b90830190610140828603121561449d57600080fd5b6144a5613675565b6144ae83614070565b81526144bc60208401614430565b60208201526040830151828111156144d357600080fd5b6144df87828601613ee4565b6040830152506144f16060840161443b565b606082015261450260808401614070565b608082015261451360a08401614446565b60a082015261452460c08401614430565b60c082015261453560e0840161443b565b60e0820152610100614548818501613eb9565b90820152610120838101518381111561456057600080fd5b61456c88828701613ee4565b918301919091525095945050505050565b60006020828403121561458f57600080fd5b81516118208161389d565b600063ffffffff8083168181036140dd576140dd613e56565b60208152600082516101408060208501526145d2610160850183613a42565b915060208501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08086850301604087015261460e8483613a42565b935060408701519150614639606087018373ffffffffffffffffffffffffffffffffffffffff169052565b606087015163ffffffff811660808801529150608087015173ffffffffffffffffffffffffffffffffffffffff811660a0880152915060a087015160ff811660c0880152915060c08701519150808685030160e087015261469a8483613a42565b935060e087015191506101008187860301818801526146b98584613a42565b9450808801519250506101208187860301818801526146d88584613a42565b945080880151925050506146fb828601826bffffffffffffffffffffffff169052565b5090949350505050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561473d5761473d613e56565b500290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261478057614780614742565b500490565b818103600083128015838313168383128216171561351057613510613e56565b6000826147b4576147b4614742565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f80000000000000000000000000000000000000000000000000000000000000008314161561480857614808613e56565b500590565b808201828112600083128015821682158216171561482d5761482d613e56565b505092915050565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361402457614024613e56565b60007f8000000000000000000000000000000000000000000000000000000000000000820361489757614897613e56565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b601f82111561493257600081815260208120601f850160051c810160208610156149135750805b601f850160051c820191505b818110156128265782815560010161491f565b505050565b815167ffffffffffffffff81111561495157614951613646565b6149658161495f8454614242565b846148ec565b602080601f8311600181146149b857600084156149825750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555612826565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015614a05578886015182559484019460019091019084016149e6565b5085821015614a4157878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b0190555056fea164736f6c6343000810000a307834353534343832643535353334343264343135323432343935343532353534643264353434353533353434653435353430303030303030303030303030303030307834323534343332643535353334343264343135323432343935343532353534643264353434353533353434653435353430303030303030303030303030303030307835353533343434333264353535333434326434313532343234393534353235353464326435343435353335343465343535343030303030303030303030303030",
-}
-
-var VerifiableLoadMercuryUpkeepABI = VerifiableLoadMercuryUpkeepMetaData.ABI
-
-var VerifiableLoadMercuryUpkeepBin = VerifiableLoadMercuryUpkeepMetaData.Bin
-
-func DeployVerifiableLoadMercuryUpkeep(auth *bind.TransactOpts, backend bind.ContractBackend, _registrar common.Address, _useArb bool) (common.Address, *types.Transaction, *VerifiableLoadMercuryUpkeep, error) {
- parsed, err := VerifiableLoadMercuryUpkeepMetaData.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(VerifiableLoadMercuryUpkeepBin), backend, _registrar, _useArb)
- if err != nil {
- return common.Address{}, nil, nil, err
- }
- return address, tx, &VerifiableLoadMercuryUpkeep{VerifiableLoadMercuryUpkeepCaller: VerifiableLoadMercuryUpkeepCaller{contract: contract}, VerifiableLoadMercuryUpkeepTransactor: VerifiableLoadMercuryUpkeepTransactor{contract: contract}, VerifiableLoadMercuryUpkeepFilterer: VerifiableLoadMercuryUpkeepFilterer{contract: contract}}, nil
-}
-
-type VerifiableLoadMercuryUpkeep struct {
- address common.Address
- abi abi.ABI
- VerifiableLoadMercuryUpkeepCaller
- VerifiableLoadMercuryUpkeepTransactor
- VerifiableLoadMercuryUpkeepFilterer
-}
-
-type VerifiableLoadMercuryUpkeepCaller struct {
- contract *bind.BoundContract
-}
-
-type VerifiableLoadMercuryUpkeepTransactor struct {
- contract *bind.BoundContract
-}
-
-type VerifiableLoadMercuryUpkeepFilterer struct {
- contract *bind.BoundContract
-}
-
-type VerifiableLoadMercuryUpkeepSession struct {
- Contract *VerifiableLoadMercuryUpkeep
- CallOpts bind.CallOpts
- TransactOpts bind.TransactOpts
-}
-
-type VerifiableLoadMercuryUpkeepCallerSession struct {
- Contract *VerifiableLoadMercuryUpkeepCaller
- CallOpts bind.CallOpts
-}
-
-type VerifiableLoadMercuryUpkeepTransactorSession struct {
- Contract *VerifiableLoadMercuryUpkeepTransactor
- TransactOpts bind.TransactOpts
-}
-
-type VerifiableLoadMercuryUpkeepRaw struct {
- Contract *VerifiableLoadMercuryUpkeep
-}
-
-type VerifiableLoadMercuryUpkeepCallerRaw struct {
- Contract *VerifiableLoadMercuryUpkeepCaller
-}
-
-type VerifiableLoadMercuryUpkeepTransactorRaw struct {
- Contract *VerifiableLoadMercuryUpkeepTransactor
-}
-
-func NewVerifiableLoadMercuryUpkeep(address common.Address, backend bind.ContractBackend) (*VerifiableLoadMercuryUpkeep, error) {
- abi, err := abi.JSON(strings.NewReader(VerifiableLoadMercuryUpkeepABI))
- if err != nil {
- return nil, err
- }
- contract, err := bindVerifiableLoadMercuryUpkeep(address, backend, backend, backend)
- if err != nil {
- return nil, err
- }
- return &VerifiableLoadMercuryUpkeep{address: address, abi: abi, VerifiableLoadMercuryUpkeepCaller: VerifiableLoadMercuryUpkeepCaller{contract: contract}, VerifiableLoadMercuryUpkeepTransactor: VerifiableLoadMercuryUpkeepTransactor{contract: contract}, VerifiableLoadMercuryUpkeepFilterer: VerifiableLoadMercuryUpkeepFilterer{contract: contract}}, nil
-}
-
-func NewVerifiableLoadMercuryUpkeepCaller(address common.Address, caller bind.ContractCaller) (*VerifiableLoadMercuryUpkeepCaller, error) {
- contract, err := bindVerifiableLoadMercuryUpkeep(address, caller, nil, nil)
- if err != nil {
- return nil, err
- }
- return &VerifiableLoadMercuryUpkeepCaller{contract: contract}, nil
-}
-
-func NewVerifiableLoadMercuryUpkeepTransactor(address common.Address, transactor bind.ContractTransactor) (*VerifiableLoadMercuryUpkeepTransactor, error) {
- contract, err := bindVerifiableLoadMercuryUpkeep(address, nil, transactor, nil)
- if err != nil {
- return nil, err
- }
- return &VerifiableLoadMercuryUpkeepTransactor{contract: contract}, nil
-}
-
-func NewVerifiableLoadMercuryUpkeepFilterer(address common.Address, filterer bind.ContractFilterer) (*VerifiableLoadMercuryUpkeepFilterer, error) {
- contract, err := bindVerifiableLoadMercuryUpkeep(address, nil, nil, filterer)
- if err != nil {
- return nil, err
- }
- return &VerifiableLoadMercuryUpkeepFilterer{contract: contract}, nil
-}
-
-func bindVerifiableLoadMercuryUpkeep(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) {
- parsed, err := VerifiableLoadMercuryUpkeepMetaData.GetAbi()
- if err != nil {
- return nil, err
- }
- return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
- return _VerifiableLoadMercuryUpkeep.Contract.VerifiableLoadMercuryUpkeepCaller.contract.Call(opts, result, method, params...)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.VerifiableLoadMercuryUpkeepTransactor.contract.Transfer(opts)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.VerifiableLoadMercuryUpkeepTransactor.contract.Transact(opts, method, params...)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
- return _VerifiableLoadMercuryUpkeep.Contract.contract.Call(opts, result, method, params...)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.contract.Transfer(opts)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.contract.Transact(opts, method, params...)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCaller) BUCKETSIZE(opts *bind.CallOpts) (uint16, error) {
- var out []interface{}
- err := _VerifiableLoadMercuryUpkeep.contract.Call(opts, &out, "BUCKET_SIZE")
-
- if err != nil {
- return *new(uint16), err
- }
-
- out0 := *abi.ConvertType(out[0], new(uint16)).(*uint16)
-
- return out0, err
-
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) BUCKETSIZE() (uint16, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.BUCKETSIZE(&_VerifiableLoadMercuryUpkeep.CallOpts)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCallerSession) BUCKETSIZE() (uint16, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.BUCKETSIZE(&_VerifiableLoadMercuryUpkeep.CallOpts)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCaller) AddLinkAmount(opts *bind.CallOpts) (*big.Int, error) {
- var out []interface{}
- err := _VerifiableLoadMercuryUpkeep.contract.Call(opts, &out, "addLinkAmount")
-
- if err != nil {
- return *new(*big.Int), err
- }
-
- out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
-
- return out0, err
-
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) AddLinkAmount() (*big.Int, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.AddLinkAmount(&_VerifiableLoadMercuryUpkeep.CallOpts)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCallerSession) AddLinkAmount() (*big.Int, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.AddLinkAmount(&_VerifiableLoadMercuryUpkeep.CallOpts)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCaller) BucketedDelays(opts *bind.CallOpts, arg0 *big.Int, arg1 uint16, arg2 *big.Int) (*big.Int, error) {
- var out []interface{}
- err := _VerifiableLoadMercuryUpkeep.contract.Call(opts, &out, "bucketedDelays", arg0, arg1, arg2)
-
- if err != nil {
- return *new(*big.Int), err
- }
-
- out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
-
- return out0, err
-
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) BucketedDelays(arg0 *big.Int, arg1 uint16, arg2 *big.Int) (*big.Int, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.BucketedDelays(&_VerifiableLoadMercuryUpkeep.CallOpts, arg0, arg1, arg2)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCallerSession) BucketedDelays(arg0 *big.Int, arg1 uint16, arg2 *big.Int) (*big.Int, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.BucketedDelays(&_VerifiableLoadMercuryUpkeep.CallOpts, arg0, arg1, arg2)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCaller) Buckets(opts *bind.CallOpts, arg0 *big.Int) (uint16, error) {
- var out []interface{}
- err := _VerifiableLoadMercuryUpkeep.contract.Call(opts, &out, "buckets", arg0)
-
- if err != nil {
- return *new(uint16), err
- }
-
- out0 := *abi.ConvertType(out[0], new(uint16)).(*uint16)
-
- return out0, err
-
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) Buckets(arg0 *big.Int) (uint16, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.Buckets(&_VerifiableLoadMercuryUpkeep.CallOpts, arg0)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCallerSession) Buckets(arg0 *big.Int) (uint16, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.Buckets(&_VerifiableLoadMercuryUpkeep.CallOpts, arg0)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCaller) CheckCallback(opts *bind.CallOpts, values [][]byte, extraData []byte) (bool, []byte, error) {
- var out []interface{}
- err := _VerifiableLoadMercuryUpkeep.contract.Call(opts, &out, "checkCallback", values, extraData)
-
- if err != nil {
- return *new(bool), *new([]byte), err
- }
-
- out0 := *abi.ConvertType(out[0], new(bool)).(*bool)
- out1 := *abi.ConvertType(out[1], new([]byte)).(*[]byte)
-
- return out0, out1, err
-
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) CheckCallback(values [][]byte, extraData []byte) (bool, []byte, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.CheckCallback(&_VerifiableLoadMercuryUpkeep.CallOpts, values, extraData)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCallerSession) CheckCallback(values [][]byte, extraData []byte) (bool, []byte, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.CheckCallback(&_VerifiableLoadMercuryUpkeep.CallOpts, values, extraData)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCaller) CheckGasToBurns(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) {
- var out []interface{}
- err := _VerifiableLoadMercuryUpkeep.contract.Call(opts, &out, "checkGasToBurns", arg0)
-
- if err != nil {
- return *new(*big.Int), err
- }
-
- out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
-
- return out0, err
-
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) CheckGasToBurns(arg0 *big.Int) (*big.Int, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.CheckGasToBurns(&_VerifiableLoadMercuryUpkeep.CallOpts, arg0)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCallerSession) CheckGasToBurns(arg0 *big.Int) (*big.Int, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.CheckGasToBurns(&_VerifiableLoadMercuryUpkeep.CallOpts, arg0)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCaller) Counters(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) {
- var out []interface{}
- err := _VerifiableLoadMercuryUpkeep.contract.Call(opts, &out, "counters", arg0)
-
- if err != nil {
- return *new(*big.Int), err
- }
-
- out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
-
- return out0, err
-
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) Counters(arg0 *big.Int) (*big.Int, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.Counters(&_VerifiableLoadMercuryUpkeep.CallOpts, arg0)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCallerSession) Counters(arg0 *big.Int) (*big.Int, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.Counters(&_VerifiableLoadMercuryUpkeep.CallOpts, arg0)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCaller) Delays(opts *bind.CallOpts, arg0 *big.Int, arg1 *big.Int) (*big.Int, error) {
- var out []interface{}
- err := _VerifiableLoadMercuryUpkeep.contract.Call(opts, &out, "delays", arg0, arg1)
-
- if err != nil {
- return *new(*big.Int), err
- }
-
- out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
-
- return out0, err
-
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) Delays(arg0 *big.Int, arg1 *big.Int) (*big.Int, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.Delays(&_VerifiableLoadMercuryUpkeep.CallOpts, arg0, arg1)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCallerSession) Delays(arg0 *big.Int, arg1 *big.Int) (*big.Int, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.Delays(&_VerifiableLoadMercuryUpkeep.CallOpts, arg0, arg1)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCaller) DummyMap(opts *bind.CallOpts, arg0 [32]byte) (bool, error) {
- var out []interface{}
- err := _VerifiableLoadMercuryUpkeep.contract.Call(opts, &out, "dummyMap", arg0)
-
- if err != nil {
- return *new(bool), err
- }
-
- out0 := *abi.ConvertType(out[0], new(bool)).(*bool)
-
- return out0, err
-
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) DummyMap(arg0 [32]byte) (bool, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.DummyMap(&_VerifiableLoadMercuryUpkeep.CallOpts, arg0)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCallerSession) DummyMap(arg0 [32]byte) (bool, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.DummyMap(&_VerifiableLoadMercuryUpkeep.CallOpts, arg0)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCaller) Eligible(opts *bind.CallOpts, upkeepId *big.Int) (bool, error) {
- var out []interface{}
- err := _VerifiableLoadMercuryUpkeep.contract.Call(opts, &out, "eligible", upkeepId)
-
- if err != nil {
- return *new(bool), err
- }
-
- out0 := *abi.ConvertType(out[0], new(bool)).(*bool)
-
- return out0, err
-
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) Eligible(upkeepId *big.Int) (bool, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.Eligible(&_VerifiableLoadMercuryUpkeep.CallOpts, upkeepId)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCallerSession) Eligible(upkeepId *big.Int) (bool, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.Eligible(&_VerifiableLoadMercuryUpkeep.CallOpts, upkeepId)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCaller) EmittedSig(opts *bind.CallOpts) ([32]byte, error) {
- var out []interface{}
- err := _VerifiableLoadMercuryUpkeep.contract.Call(opts, &out, "emittedSig")
-
- if err != nil {
- return *new([32]byte), err
- }
-
- out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte)
-
- return out0, err
-
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) EmittedSig() ([32]byte, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.EmittedSig(&_VerifiableLoadMercuryUpkeep.CallOpts)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCallerSession) EmittedSig() ([32]byte, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.EmittedSig(&_VerifiableLoadMercuryUpkeep.CallOpts)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCaller) FeedParamKey(opts *bind.CallOpts) (string, error) {
- var out []interface{}
- err := _VerifiableLoadMercuryUpkeep.contract.Call(opts, &out, "feedParamKey")
-
- if err != nil {
- return *new(string), err
- }
-
- out0 := *abi.ConvertType(out[0], new(string)).(*string)
-
- return out0, err
-
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) FeedParamKey() (string, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.FeedParamKey(&_VerifiableLoadMercuryUpkeep.CallOpts)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCallerSession) FeedParamKey() (string, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.FeedParamKey(&_VerifiableLoadMercuryUpkeep.CallOpts)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCaller) FeedsHex(opts *bind.CallOpts, arg0 *big.Int) (string, error) {
- var out []interface{}
- err := _VerifiableLoadMercuryUpkeep.contract.Call(opts, &out, "feedsHex", arg0)
-
- if err != nil {
- return *new(string), err
- }
-
- out0 := *abi.ConvertType(out[0], new(string)).(*string)
-
- return out0, err
-
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) FeedsHex(arg0 *big.Int) (string, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.FeedsHex(&_VerifiableLoadMercuryUpkeep.CallOpts, arg0)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCallerSession) FeedsHex(arg0 *big.Int) (string, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.FeedsHex(&_VerifiableLoadMercuryUpkeep.CallOpts, arg0)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCaller) FirstPerformBlocks(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) {
- var out []interface{}
- err := _VerifiableLoadMercuryUpkeep.contract.Call(opts, &out, "firstPerformBlocks", arg0)
-
- if err != nil {
- return *new(*big.Int), err
- }
-
- out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
-
- return out0, err
-
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) FirstPerformBlocks(arg0 *big.Int) (*big.Int, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.FirstPerformBlocks(&_VerifiableLoadMercuryUpkeep.CallOpts, arg0)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCallerSession) FirstPerformBlocks(arg0 *big.Int) (*big.Int, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.FirstPerformBlocks(&_VerifiableLoadMercuryUpkeep.CallOpts, arg0)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCaller) GasLimits(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) {
- var out []interface{}
- err := _VerifiableLoadMercuryUpkeep.contract.Call(opts, &out, "gasLimits", arg0)
-
- if err != nil {
- return *new(*big.Int), err
- }
-
- out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
-
- return out0, err
-
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) GasLimits(arg0 *big.Int) (*big.Int, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.GasLimits(&_VerifiableLoadMercuryUpkeep.CallOpts, arg0)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCallerSession) GasLimits(arg0 *big.Int) (*big.Int, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.GasLimits(&_VerifiableLoadMercuryUpkeep.CallOpts, arg0)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCaller) GetActiveUpkeepIDs(opts *bind.CallOpts, startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error) {
- var out []interface{}
- err := _VerifiableLoadMercuryUpkeep.contract.Call(opts, &out, "getActiveUpkeepIDs", startIndex, maxCount)
-
- if err != nil {
- return *new([]*big.Int), err
- }
-
- out0 := *abi.ConvertType(out[0], new([]*big.Int)).(*[]*big.Int)
-
- return out0, err
-
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) GetActiveUpkeepIDs(startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.GetActiveUpkeepIDs(&_VerifiableLoadMercuryUpkeep.CallOpts, startIndex, maxCount)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCallerSession) GetActiveUpkeepIDs(startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.GetActiveUpkeepIDs(&_VerifiableLoadMercuryUpkeep.CallOpts, startIndex, maxCount)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCaller) GetBucketedDelays(opts *bind.CallOpts, upkeepId *big.Int, bucket uint16) ([]*big.Int, error) {
- var out []interface{}
- err := _VerifiableLoadMercuryUpkeep.contract.Call(opts, &out, "getBucketedDelays", upkeepId, bucket)
-
- if err != nil {
- return *new([]*big.Int), err
- }
-
- out0 := *abi.ConvertType(out[0], new([]*big.Int)).(*[]*big.Int)
-
- return out0, err
-
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) GetBucketedDelays(upkeepId *big.Int, bucket uint16) ([]*big.Int, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.GetBucketedDelays(&_VerifiableLoadMercuryUpkeep.CallOpts, upkeepId, bucket)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCallerSession) GetBucketedDelays(upkeepId *big.Int, bucket uint16) ([]*big.Int, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.GetBucketedDelays(&_VerifiableLoadMercuryUpkeep.CallOpts, upkeepId, bucket)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCaller) GetBucketedDelaysLength(opts *bind.CallOpts, upkeepId *big.Int) (*big.Int, error) {
- var out []interface{}
- err := _VerifiableLoadMercuryUpkeep.contract.Call(opts, &out, "getBucketedDelaysLength", upkeepId)
-
- if err != nil {
- return *new(*big.Int), err
- }
-
- out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
-
- return out0, err
-
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) GetBucketedDelaysLength(upkeepId *big.Int) (*big.Int, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.GetBucketedDelaysLength(&_VerifiableLoadMercuryUpkeep.CallOpts, upkeepId)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCallerSession) GetBucketedDelaysLength(upkeepId *big.Int) (*big.Int, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.GetBucketedDelaysLength(&_VerifiableLoadMercuryUpkeep.CallOpts, upkeepId)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCaller) GetDelays(opts *bind.CallOpts, upkeepId *big.Int) ([]*big.Int, error) {
- var out []interface{}
- err := _VerifiableLoadMercuryUpkeep.contract.Call(opts, &out, "getDelays", upkeepId)
-
- if err != nil {
- return *new([]*big.Int), err
- }
-
- out0 := *abi.ConvertType(out[0], new([]*big.Int)).(*[]*big.Int)
-
- return out0, err
-
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) GetDelays(upkeepId *big.Int) ([]*big.Int, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.GetDelays(&_VerifiableLoadMercuryUpkeep.CallOpts, upkeepId)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCallerSession) GetDelays(upkeepId *big.Int) ([]*big.Int, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.GetDelays(&_VerifiableLoadMercuryUpkeep.CallOpts, upkeepId)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCaller) GetDelaysLength(opts *bind.CallOpts, upkeepId *big.Int) (*big.Int, error) {
- var out []interface{}
- err := _VerifiableLoadMercuryUpkeep.contract.Call(opts, &out, "getDelaysLength", upkeepId)
-
- if err != nil {
- return *new(*big.Int), err
- }
-
- out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
-
- return out0, err
-
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) GetDelaysLength(upkeepId *big.Int) (*big.Int, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.GetDelaysLength(&_VerifiableLoadMercuryUpkeep.CallOpts, upkeepId)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCallerSession) GetDelaysLength(upkeepId *big.Int) (*big.Int, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.GetDelaysLength(&_VerifiableLoadMercuryUpkeep.CallOpts, upkeepId)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCaller) GetLogTriggerConfig(opts *bind.CallOpts, upkeepId *big.Int) ([]byte, error) {
- var out []interface{}
- err := _VerifiableLoadMercuryUpkeep.contract.Call(opts, &out, "getLogTriggerConfig", upkeepId)
-
- if err != nil {
- return *new([]byte), err
- }
-
- out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte)
-
- return out0, err
-
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) GetLogTriggerConfig(upkeepId *big.Int) ([]byte, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.GetLogTriggerConfig(&_VerifiableLoadMercuryUpkeep.CallOpts, upkeepId)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCallerSession) GetLogTriggerConfig(upkeepId *big.Int) ([]byte, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.GetLogTriggerConfig(&_VerifiableLoadMercuryUpkeep.CallOpts, upkeepId)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCaller) GetPxDelayLastNPerforms(opts *bind.CallOpts, upkeepId *big.Int, p *big.Int, n *big.Int) (*big.Int, error) {
- var out []interface{}
- err := _VerifiableLoadMercuryUpkeep.contract.Call(opts, &out, "getPxDelayLastNPerforms", upkeepId, p, n)
-
- if err != nil {
- return *new(*big.Int), err
- }
-
- out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
-
- return out0, err
-
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) GetPxDelayLastNPerforms(upkeepId *big.Int, p *big.Int, n *big.Int) (*big.Int, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.GetPxDelayLastNPerforms(&_VerifiableLoadMercuryUpkeep.CallOpts, upkeepId, p, n)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCallerSession) GetPxDelayLastNPerforms(upkeepId *big.Int, p *big.Int, n *big.Int) (*big.Int, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.GetPxDelayLastNPerforms(&_VerifiableLoadMercuryUpkeep.CallOpts, upkeepId, p, n)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCaller) GetSumDelayInBucket(opts *bind.CallOpts, upkeepId *big.Int, bucket uint16) (*big.Int, *big.Int, error) {
- var out []interface{}
- err := _VerifiableLoadMercuryUpkeep.contract.Call(opts, &out, "getSumDelayInBucket", upkeepId, bucket)
-
- if err != nil {
- return *new(*big.Int), *new(*big.Int), err
- }
-
- out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
- out1 := *abi.ConvertType(out[1], new(*big.Int)).(**big.Int)
-
- return out0, out1, err
-
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) GetSumDelayInBucket(upkeepId *big.Int, bucket uint16) (*big.Int, *big.Int, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.GetSumDelayInBucket(&_VerifiableLoadMercuryUpkeep.CallOpts, upkeepId, bucket)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCallerSession) GetSumDelayInBucket(upkeepId *big.Int, bucket uint16) (*big.Int, *big.Int, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.GetSumDelayInBucket(&_VerifiableLoadMercuryUpkeep.CallOpts, upkeepId, bucket)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCaller) GetSumDelayLastNPerforms(opts *bind.CallOpts, upkeepId *big.Int, n *big.Int) (*big.Int, *big.Int, error) {
- var out []interface{}
- err := _VerifiableLoadMercuryUpkeep.contract.Call(opts, &out, "getSumDelayLastNPerforms", upkeepId, n)
-
- if err != nil {
- return *new(*big.Int), *new(*big.Int), err
- }
-
- out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
- out1 := *abi.ConvertType(out[1], new(*big.Int)).(**big.Int)
-
- return out0, out1, err
-
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) GetSumDelayLastNPerforms(upkeepId *big.Int, n *big.Int) (*big.Int, *big.Int, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.GetSumDelayLastNPerforms(&_VerifiableLoadMercuryUpkeep.CallOpts, upkeepId, n)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCallerSession) GetSumDelayLastNPerforms(upkeepId *big.Int, n *big.Int) (*big.Int, *big.Int, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.GetSumDelayLastNPerforms(&_VerifiableLoadMercuryUpkeep.CallOpts, upkeepId, n)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCaller) Intervals(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) {
- var out []interface{}
- err := _VerifiableLoadMercuryUpkeep.contract.Call(opts, &out, "intervals", arg0)
-
- if err != nil {
- return *new(*big.Int), err
- }
-
- out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
-
- return out0, err
-
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) Intervals(arg0 *big.Int) (*big.Int, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.Intervals(&_VerifiableLoadMercuryUpkeep.CallOpts, arg0)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCallerSession) Intervals(arg0 *big.Int) (*big.Int, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.Intervals(&_VerifiableLoadMercuryUpkeep.CallOpts, arg0)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCaller) LastTopUpBlocks(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) {
- var out []interface{}
- err := _VerifiableLoadMercuryUpkeep.contract.Call(opts, &out, "lastTopUpBlocks", arg0)
-
- if err != nil {
- return *new(*big.Int), err
- }
-
- out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
-
- return out0, err
-
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) LastTopUpBlocks(arg0 *big.Int) (*big.Int, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.LastTopUpBlocks(&_VerifiableLoadMercuryUpkeep.CallOpts, arg0)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCallerSession) LastTopUpBlocks(arg0 *big.Int) (*big.Int, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.LastTopUpBlocks(&_VerifiableLoadMercuryUpkeep.CallOpts, arg0)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCaller) LinkToken(opts *bind.CallOpts) (common.Address, error) {
- var out []interface{}
- err := _VerifiableLoadMercuryUpkeep.contract.Call(opts, &out, "linkToken")
-
- if err != nil {
- return *new(common.Address), err
- }
-
- out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address)
-
- return out0, err
-
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) LinkToken() (common.Address, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.LinkToken(&_VerifiableLoadMercuryUpkeep.CallOpts)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCallerSession) LinkToken() (common.Address, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.LinkToken(&_VerifiableLoadMercuryUpkeep.CallOpts)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCaller) MinBalanceThresholdMultiplier(opts *bind.CallOpts) (uint8, error) {
- var out []interface{}
- err := _VerifiableLoadMercuryUpkeep.contract.Call(opts, &out, "minBalanceThresholdMultiplier")
-
- if err != nil {
- return *new(uint8), err
- }
-
- out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8)
-
- return out0, err
-
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) MinBalanceThresholdMultiplier() (uint8, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.MinBalanceThresholdMultiplier(&_VerifiableLoadMercuryUpkeep.CallOpts)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCallerSession) MinBalanceThresholdMultiplier() (uint8, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.MinBalanceThresholdMultiplier(&_VerifiableLoadMercuryUpkeep.CallOpts)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCaller) Owner(opts *bind.CallOpts) (common.Address, error) {
- var out []interface{}
- err := _VerifiableLoadMercuryUpkeep.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 (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) Owner() (common.Address, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.Owner(&_VerifiableLoadMercuryUpkeep.CallOpts)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCallerSession) Owner() (common.Address, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.Owner(&_VerifiableLoadMercuryUpkeep.CallOpts)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCaller) PerformDataSizes(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) {
- var out []interface{}
- err := _VerifiableLoadMercuryUpkeep.contract.Call(opts, &out, "performDataSizes", arg0)
-
- if err != nil {
- return *new(*big.Int), err
- }
-
- out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
-
- return out0, err
-
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) PerformDataSizes(arg0 *big.Int) (*big.Int, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.PerformDataSizes(&_VerifiableLoadMercuryUpkeep.CallOpts, arg0)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCallerSession) PerformDataSizes(arg0 *big.Int) (*big.Int, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.PerformDataSizes(&_VerifiableLoadMercuryUpkeep.CallOpts, arg0)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCaller) PerformGasToBurns(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) {
- var out []interface{}
- err := _VerifiableLoadMercuryUpkeep.contract.Call(opts, &out, "performGasToBurns", arg0)
-
- if err != nil {
- return *new(*big.Int), err
- }
-
- out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
-
- return out0, err
-
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) PerformGasToBurns(arg0 *big.Int) (*big.Int, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.PerformGasToBurns(&_VerifiableLoadMercuryUpkeep.CallOpts, arg0)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCallerSession) PerformGasToBurns(arg0 *big.Int) (*big.Int, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.PerformGasToBurns(&_VerifiableLoadMercuryUpkeep.CallOpts, arg0)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCaller) PreviousPerformBlocks(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) {
- var out []interface{}
- err := _VerifiableLoadMercuryUpkeep.contract.Call(opts, &out, "previousPerformBlocks", arg0)
-
- if err != nil {
- return *new(*big.Int), err
- }
-
- out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
-
- return out0, err
-
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) PreviousPerformBlocks(arg0 *big.Int) (*big.Int, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.PreviousPerformBlocks(&_VerifiableLoadMercuryUpkeep.CallOpts, arg0)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCallerSession) PreviousPerformBlocks(arg0 *big.Int) (*big.Int, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.PreviousPerformBlocks(&_VerifiableLoadMercuryUpkeep.CallOpts, arg0)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCaller) Registrar(opts *bind.CallOpts) (common.Address, error) {
- var out []interface{}
- err := _VerifiableLoadMercuryUpkeep.contract.Call(opts, &out, "registrar")
-
- if err != nil {
- return *new(common.Address), err
- }
-
- out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address)
-
- return out0, err
-
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) Registrar() (common.Address, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.Registrar(&_VerifiableLoadMercuryUpkeep.CallOpts)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCallerSession) Registrar() (common.Address, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.Registrar(&_VerifiableLoadMercuryUpkeep.CallOpts)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCaller) Registry(opts *bind.CallOpts) (common.Address, error) {
- var out []interface{}
- err := _VerifiableLoadMercuryUpkeep.contract.Call(opts, &out, "registry")
-
- if err != nil {
- return *new(common.Address), err
- }
-
- out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address)
-
- return out0, err
-
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) Registry() (common.Address, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.Registry(&_VerifiableLoadMercuryUpkeep.CallOpts)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCallerSession) Registry() (common.Address, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.Registry(&_VerifiableLoadMercuryUpkeep.CallOpts)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCaller) TimeParamKey(opts *bind.CallOpts) (string, error) {
- var out []interface{}
- err := _VerifiableLoadMercuryUpkeep.contract.Call(opts, &out, "timeParamKey")
-
- if err != nil {
- return *new(string), err
- }
-
- out0 := *abi.ConvertType(out[0], new(string)).(*string)
-
- return out0, err
-
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) TimeParamKey() (string, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.TimeParamKey(&_VerifiableLoadMercuryUpkeep.CallOpts)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCallerSession) TimeParamKey() (string, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.TimeParamKey(&_VerifiableLoadMercuryUpkeep.CallOpts)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCaller) UpkeepTopUpCheckInterval(opts *bind.CallOpts) (*big.Int, error) {
- var out []interface{}
- err := _VerifiableLoadMercuryUpkeep.contract.Call(opts, &out, "upkeepTopUpCheckInterval")
-
- if err != nil {
- return *new(*big.Int), err
- }
-
- out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
-
- return out0, err
-
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) UpkeepTopUpCheckInterval() (*big.Int, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.UpkeepTopUpCheckInterval(&_VerifiableLoadMercuryUpkeep.CallOpts)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCallerSession) UpkeepTopUpCheckInterval() (*big.Int, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.UpkeepTopUpCheckInterval(&_VerifiableLoadMercuryUpkeep.CallOpts)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCaller) UseArbitrumBlockNum(opts *bind.CallOpts) (bool, error) {
- var out []interface{}
- err := _VerifiableLoadMercuryUpkeep.contract.Call(opts, &out, "useArbitrumBlockNum")
-
- if err != nil {
- return *new(bool), err
- }
-
- out0 := *abi.ConvertType(out[0], new(bool)).(*bool)
-
- return out0, err
-
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) UseArbitrumBlockNum() (bool, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.UseArbitrumBlockNum(&_VerifiableLoadMercuryUpkeep.CallOpts)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepCallerSession) UseArbitrumBlockNum() (bool, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.UseArbitrumBlockNum(&_VerifiableLoadMercuryUpkeep.CallOpts)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.contract.Transact(opts, "acceptOwnership")
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) AcceptOwnership() (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.AcceptOwnership(&_VerifiableLoadMercuryUpkeep.TransactOpts)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactorSession) AcceptOwnership() (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.AcceptOwnership(&_VerifiableLoadMercuryUpkeep.TransactOpts)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactor) AddFunds(opts *bind.TransactOpts, upkeepId *big.Int, amount *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.contract.Transact(opts, "addFunds", upkeepId, amount)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) AddFunds(upkeepId *big.Int, amount *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.AddFunds(&_VerifiableLoadMercuryUpkeep.TransactOpts, upkeepId, amount)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactorSession) AddFunds(upkeepId *big.Int, amount *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.AddFunds(&_VerifiableLoadMercuryUpkeep.TransactOpts, upkeepId, amount)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactor) BatchCancelUpkeeps(opts *bind.TransactOpts, upkeepIds []*big.Int) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.contract.Transact(opts, "batchCancelUpkeeps", upkeepIds)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) BatchCancelUpkeeps(upkeepIds []*big.Int) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.BatchCancelUpkeeps(&_VerifiableLoadMercuryUpkeep.TransactOpts, upkeepIds)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactorSession) BatchCancelUpkeeps(upkeepIds []*big.Int) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.BatchCancelUpkeeps(&_VerifiableLoadMercuryUpkeep.TransactOpts, upkeepIds)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactor) BatchRegisterUpkeeps(opts *bind.TransactOpts, number uint8, gasLimit uint32, triggerType uint8, triggerConfig []byte, amount *big.Int, checkGasToBurn *big.Int, performGasToBurn *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.contract.Transact(opts, "batchRegisterUpkeeps", number, gasLimit, triggerType, triggerConfig, amount, checkGasToBurn, performGasToBurn)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) BatchRegisterUpkeeps(number uint8, gasLimit uint32, triggerType uint8, triggerConfig []byte, amount *big.Int, checkGasToBurn *big.Int, performGasToBurn *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.BatchRegisterUpkeeps(&_VerifiableLoadMercuryUpkeep.TransactOpts, number, gasLimit, triggerType, triggerConfig, amount, checkGasToBurn, performGasToBurn)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactorSession) BatchRegisterUpkeeps(number uint8, gasLimit uint32, triggerType uint8, triggerConfig []byte, amount *big.Int, checkGasToBurn *big.Int, performGasToBurn *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.BatchRegisterUpkeeps(&_VerifiableLoadMercuryUpkeep.TransactOpts, number, gasLimit, triggerType, triggerConfig, amount, checkGasToBurn, performGasToBurn)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactor) BatchSendLogs(opts *bind.TransactOpts) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.contract.Transact(opts, "batchSendLogs")
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) BatchSendLogs() (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.BatchSendLogs(&_VerifiableLoadMercuryUpkeep.TransactOpts)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactorSession) BatchSendLogs() (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.BatchSendLogs(&_VerifiableLoadMercuryUpkeep.TransactOpts)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactor) BatchSetIntervals(opts *bind.TransactOpts, upkeepIds []*big.Int, interval uint32) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.contract.Transact(opts, "batchSetIntervals", upkeepIds, interval)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) BatchSetIntervals(upkeepIds []*big.Int, interval uint32) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.BatchSetIntervals(&_VerifiableLoadMercuryUpkeep.TransactOpts, upkeepIds, interval)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactorSession) BatchSetIntervals(upkeepIds []*big.Int, interval uint32) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.BatchSetIntervals(&_VerifiableLoadMercuryUpkeep.TransactOpts, upkeepIds, interval)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactor) BatchUpdatePipelineData(opts *bind.TransactOpts, upkeepIds []*big.Int) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.contract.Transact(opts, "batchUpdatePipelineData", upkeepIds)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) BatchUpdatePipelineData(upkeepIds []*big.Int) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.BatchUpdatePipelineData(&_VerifiableLoadMercuryUpkeep.TransactOpts, upkeepIds)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactorSession) BatchUpdatePipelineData(upkeepIds []*big.Int) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.BatchUpdatePipelineData(&_VerifiableLoadMercuryUpkeep.TransactOpts, upkeepIds)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactor) BatchWithdrawLinks(opts *bind.TransactOpts, upkeepIds []*big.Int) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.contract.Transact(opts, "batchWithdrawLinks", upkeepIds)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) BatchWithdrawLinks(upkeepIds []*big.Int) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.BatchWithdrawLinks(&_VerifiableLoadMercuryUpkeep.TransactOpts, upkeepIds)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactorSession) BatchWithdrawLinks(upkeepIds []*big.Int) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.BatchWithdrawLinks(&_VerifiableLoadMercuryUpkeep.TransactOpts, upkeepIds)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactor) BurnPerformGas(opts *bind.TransactOpts, upkeepId *big.Int, startGas *big.Int, blockNum *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.contract.Transact(opts, "burnPerformGas", upkeepId, startGas, blockNum)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) BurnPerformGas(upkeepId *big.Int, startGas *big.Int, blockNum *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.BurnPerformGas(&_VerifiableLoadMercuryUpkeep.TransactOpts, upkeepId, startGas, blockNum)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactorSession) BurnPerformGas(upkeepId *big.Int, startGas *big.Int, blockNum *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.BurnPerformGas(&_VerifiableLoadMercuryUpkeep.TransactOpts, upkeepId, startGas, blockNum)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactor) CancelUpkeep(opts *bind.TransactOpts, upkeepId *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.contract.Transact(opts, "cancelUpkeep", upkeepId)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) CancelUpkeep(upkeepId *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.CancelUpkeep(&_VerifiableLoadMercuryUpkeep.TransactOpts, upkeepId)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactorSession) CancelUpkeep(upkeepId *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.CancelUpkeep(&_VerifiableLoadMercuryUpkeep.TransactOpts, upkeepId)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactor) CheckUpkeep(opts *bind.TransactOpts, checkData []byte) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.contract.Transact(opts, "checkUpkeep", checkData)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) CheckUpkeep(checkData []byte) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.CheckUpkeep(&_VerifiableLoadMercuryUpkeep.TransactOpts, checkData)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactorSession) CheckUpkeep(checkData []byte) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.CheckUpkeep(&_VerifiableLoadMercuryUpkeep.TransactOpts, checkData)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactor) PerformUpkeep(opts *bind.TransactOpts, performData []byte) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.contract.Transact(opts, "performUpkeep", performData)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) PerformUpkeep(performData []byte) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.PerformUpkeep(&_VerifiableLoadMercuryUpkeep.TransactOpts, performData)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactorSession) PerformUpkeep(performData []byte) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.PerformUpkeep(&_VerifiableLoadMercuryUpkeep.TransactOpts, performData)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactor) SendLog(opts *bind.TransactOpts, upkeepId *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.contract.Transact(opts, "sendLog", upkeepId)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) SendLog(upkeepId *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.SendLog(&_VerifiableLoadMercuryUpkeep.TransactOpts, upkeepId)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactorSession) SendLog(upkeepId *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.SendLog(&_VerifiableLoadMercuryUpkeep.TransactOpts, upkeepId)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactor) SetAddLinkAmount(opts *bind.TransactOpts, amount *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.contract.Transact(opts, "setAddLinkAmount", amount)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) SetAddLinkAmount(amount *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.SetAddLinkAmount(&_VerifiableLoadMercuryUpkeep.TransactOpts, amount)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactorSession) SetAddLinkAmount(amount *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.SetAddLinkAmount(&_VerifiableLoadMercuryUpkeep.TransactOpts, amount)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactor) SetCheckGasToBurn(opts *bind.TransactOpts, upkeepId *big.Int, value *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.contract.Transact(opts, "setCheckGasToBurn", upkeepId, value)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) SetCheckGasToBurn(upkeepId *big.Int, value *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.SetCheckGasToBurn(&_VerifiableLoadMercuryUpkeep.TransactOpts, upkeepId, value)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactorSession) SetCheckGasToBurn(upkeepId *big.Int, value *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.SetCheckGasToBurn(&_VerifiableLoadMercuryUpkeep.TransactOpts, upkeepId, value)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactor) SetConfig(opts *bind.TransactOpts, newRegistrar common.Address) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.contract.Transact(opts, "setConfig", newRegistrar)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) SetConfig(newRegistrar common.Address) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.SetConfig(&_VerifiableLoadMercuryUpkeep.TransactOpts, newRegistrar)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactorSession) SetConfig(newRegistrar common.Address) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.SetConfig(&_VerifiableLoadMercuryUpkeep.TransactOpts, newRegistrar)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactor) SetFeedsHex(opts *bind.TransactOpts, newFeeds []string) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.contract.Transact(opts, "setFeedsHex", newFeeds)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) SetFeedsHex(newFeeds []string) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.SetFeedsHex(&_VerifiableLoadMercuryUpkeep.TransactOpts, newFeeds)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactorSession) SetFeedsHex(newFeeds []string) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.SetFeedsHex(&_VerifiableLoadMercuryUpkeep.TransactOpts, newFeeds)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactor) SetInterval(opts *bind.TransactOpts, upkeepId *big.Int, _interval *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.contract.Transact(opts, "setInterval", upkeepId, _interval)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) SetInterval(upkeepId *big.Int, _interval *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.SetInterval(&_VerifiableLoadMercuryUpkeep.TransactOpts, upkeepId, _interval)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactorSession) SetInterval(upkeepId *big.Int, _interval *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.SetInterval(&_VerifiableLoadMercuryUpkeep.TransactOpts, upkeepId, _interval)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactor) SetMinBalanceThresholdMultiplier(opts *bind.TransactOpts, newMinBalanceThresholdMultiplier uint8) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.contract.Transact(opts, "setMinBalanceThresholdMultiplier", newMinBalanceThresholdMultiplier)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) SetMinBalanceThresholdMultiplier(newMinBalanceThresholdMultiplier uint8) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.SetMinBalanceThresholdMultiplier(&_VerifiableLoadMercuryUpkeep.TransactOpts, newMinBalanceThresholdMultiplier)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactorSession) SetMinBalanceThresholdMultiplier(newMinBalanceThresholdMultiplier uint8) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.SetMinBalanceThresholdMultiplier(&_VerifiableLoadMercuryUpkeep.TransactOpts, newMinBalanceThresholdMultiplier)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactor) SetPerformDataSize(opts *bind.TransactOpts, upkeepId *big.Int, value *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.contract.Transact(opts, "setPerformDataSize", upkeepId, value)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) SetPerformDataSize(upkeepId *big.Int, value *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.SetPerformDataSize(&_VerifiableLoadMercuryUpkeep.TransactOpts, upkeepId, value)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactorSession) SetPerformDataSize(upkeepId *big.Int, value *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.SetPerformDataSize(&_VerifiableLoadMercuryUpkeep.TransactOpts, upkeepId, value)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactor) SetPerformGasToBurn(opts *bind.TransactOpts, upkeepId *big.Int, value *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.contract.Transact(opts, "setPerformGasToBurn", upkeepId, value)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) SetPerformGasToBurn(upkeepId *big.Int, value *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.SetPerformGasToBurn(&_VerifiableLoadMercuryUpkeep.TransactOpts, upkeepId, value)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactorSession) SetPerformGasToBurn(upkeepId *big.Int, value *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.SetPerformGasToBurn(&_VerifiableLoadMercuryUpkeep.TransactOpts, upkeepId, value)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactor) SetUpkeepGasLimit(opts *bind.TransactOpts, upkeepId *big.Int, gasLimit uint32) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.contract.Transact(opts, "setUpkeepGasLimit", upkeepId, gasLimit)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) SetUpkeepGasLimit(upkeepId *big.Int, gasLimit uint32) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.SetUpkeepGasLimit(&_VerifiableLoadMercuryUpkeep.TransactOpts, upkeepId, gasLimit)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactorSession) SetUpkeepGasLimit(upkeepId *big.Int, gasLimit uint32) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.SetUpkeepGasLimit(&_VerifiableLoadMercuryUpkeep.TransactOpts, upkeepId, gasLimit)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactor) SetUpkeepTopUpCheckInterval(opts *bind.TransactOpts, newInterval *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.contract.Transact(opts, "setUpkeepTopUpCheckInterval", newInterval)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) SetUpkeepTopUpCheckInterval(newInterval *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.SetUpkeepTopUpCheckInterval(&_VerifiableLoadMercuryUpkeep.TransactOpts, newInterval)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactorSession) SetUpkeepTopUpCheckInterval(newInterval *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.SetUpkeepTopUpCheckInterval(&_VerifiableLoadMercuryUpkeep.TransactOpts, newInterval)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactor) TopUpFund(opts *bind.TransactOpts, upkeepId *big.Int, blockNum *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.contract.Transact(opts, "topUpFund", upkeepId, blockNum)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) TopUpFund(upkeepId *big.Int, blockNum *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.TopUpFund(&_VerifiableLoadMercuryUpkeep.TransactOpts, upkeepId, blockNum)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactorSession) TopUpFund(upkeepId *big.Int, blockNum *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.TopUpFund(&_VerifiableLoadMercuryUpkeep.TransactOpts, upkeepId, blockNum)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.contract.Transact(opts, "transferOwnership", to)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) TransferOwnership(to common.Address) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.TransferOwnership(&_VerifiableLoadMercuryUpkeep.TransactOpts, to)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.TransferOwnership(&_VerifiableLoadMercuryUpkeep.TransactOpts, to)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactor) UpdateUpkeepPipelineData(opts *bind.TransactOpts, upkeepId *big.Int, pipelineData []byte) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.contract.Transact(opts, "updateUpkeepPipelineData", upkeepId, pipelineData)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) UpdateUpkeepPipelineData(upkeepId *big.Int, pipelineData []byte) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.UpdateUpkeepPipelineData(&_VerifiableLoadMercuryUpkeep.TransactOpts, upkeepId, pipelineData)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactorSession) UpdateUpkeepPipelineData(upkeepId *big.Int, pipelineData []byte) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.UpdateUpkeepPipelineData(&_VerifiableLoadMercuryUpkeep.TransactOpts, upkeepId, pipelineData)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactor) WithdrawLinks(opts *bind.TransactOpts) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.contract.Transact(opts, "withdrawLinks")
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) WithdrawLinks() (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.WithdrawLinks(&_VerifiableLoadMercuryUpkeep.TransactOpts)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactorSession) WithdrawLinks() (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.WithdrawLinks(&_VerifiableLoadMercuryUpkeep.TransactOpts)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactor) WithdrawLinks0(opts *bind.TransactOpts, upkeepId *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.contract.Transact(opts, "withdrawLinks0", upkeepId)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) WithdrawLinks0(upkeepId *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.WithdrawLinks0(&_VerifiableLoadMercuryUpkeep.TransactOpts, upkeepId)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactorSession) WithdrawLinks0(upkeepId *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.WithdrawLinks0(&_VerifiableLoadMercuryUpkeep.TransactOpts, upkeepId)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactor) Receive(opts *bind.TransactOpts) (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.contract.RawTransact(opts, nil)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepSession) Receive() (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.Receive(&_VerifiableLoadMercuryUpkeep.TransactOpts)
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepTransactorSession) Receive() (*types.Transaction, error) {
- return _VerifiableLoadMercuryUpkeep.Contract.Receive(&_VerifiableLoadMercuryUpkeep.TransactOpts)
-}
-
-type VerifiableLoadMercuryUpkeepLogEmittedIterator struct {
- Event *VerifiableLoadMercuryUpkeepLogEmitted
-
- contract *bind.BoundContract
- event string
-
- logs chan types.Log
- sub ethereum.Subscription
- done bool
- fail error
-}
-
-func (it *VerifiableLoadMercuryUpkeepLogEmittedIterator) Next() bool {
-
- if it.fail != nil {
- return false
- }
-
- if it.done {
- select {
- case log := <-it.logs:
- it.Event = new(VerifiableLoadMercuryUpkeepLogEmitted)
- if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
- it.fail = err
- return false
- }
- it.Event.Raw = log
- return true
-
- default:
- return false
- }
- }
-
- select {
- case log := <-it.logs:
- it.Event = new(VerifiableLoadMercuryUpkeepLogEmitted)
- if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
- it.fail = err
- return false
- }
- it.Event.Raw = log
- return true
-
- case err := <-it.sub.Err():
- it.done = true
- it.fail = err
- return it.Next()
- }
-}
-
-func (it *VerifiableLoadMercuryUpkeepLogEmittedIterator) Error() error {
- return it.fail
-}
-
-func (it *VerifiableLoadMercuryUpkeepLogEmittedIterator) Close() error {
- it.sub.Unsubscribe()
- return nil
-}
-
-type VerifiableLoadMercuryUpkeepLogEmitted struct {
- UpkeepId *big.Int
- BlockNum *big.Int
- Addr common.Address
- Raw types.Log
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) FilterLogEmitted(opts *bind.FilterOpts, upkeepId []*big.Int, blockNum []*big.Int) (*VerifiableLoadMercuryUpkeepLogEmittedIterator, error) {
-
- var upkeepIdRule []interface{}
- for _, upkeepIdItem := range upkeepId {
- upkeepIdRule = append(upkeepIdRule, upkeepIdItem)
- }
- var blockNumRule []interface{}
- for _, blockNumItem := range blockNum {
- blockNumRule = append(blockNumRule, blockNumItem)
- }
-
- logs, sub, err := _VerifiableLoadMercuryUpkeep.contract.FilterLogs(opts, "LogEmitted", upkeepIdRule, blockNumRule)
- if err != nil {
- return nil, err
- }
- return &VerifiableLoadMercuryUpkeepLogEmittedIterator{contract: _VerifiableLoadMercuryUpkeep.contract, event: "LogEmitted", logs: logs, sub: sub}, nil
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) WatchLogEmitted(opts *bind.WatchOpts, sink chan<- *VerifiableLoadMercuryUpkeepLogEmitted, upkeepId []*big.Int, blockNum []*big.Int) (event.Subscription, error) {
-
- var upkeepIdRule []interface{}
- for _, upkeepIdItem := range upkeepId {
- upkeepIdRule = append(upkeepIdRule, upkeepIdItem)
- }
- var blockNumRule []interface{}
- for _, blockNumItem := range blockNum {
- blockNumRule = append(blockNumRule, blockNumItem)
- }
-
- logs, sub, err := _VerifiableLoadMercuryUpkeep.contract.WatchLogs(opts, "LogEmitted", upkeepIdRule, blockNumRule)
- if err != nil {
- return nil, err
- }
- return event.NewSubscription(func(quit <-chan struct{}) error {
- defer sub.Unsubscribe()
- for {
- select {
- case log := <-logs:
-
- event := new(VerifiableLoadMercuryUpkeepLogEmitted)
- if err := _VerifiableLoadMercuryUpkeep.contract.UnpackLog(event, "LogEmitted", log); err != nil {
- return err
- }
- event.Raw = log
-
- select {
- case sink <- event:
- case err := <-sub.Err():
- return err
- case <-quit:
- return nil
- }
- case err := <-sub.Err():
- return err
- case <-quit:
- return nil
- }
- }
- }), nil
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) ParseLogEmitted(log types.Log) (*VerifiableLoadMercuryUpkeepLogEmitted, error) {
- event := new(VerifiableLoadMercuryUpkeepLogEmitted)
- if err := _VerifiableLoadMercuryUpkeep.contract.UnpackLog(event, "LogEmitted", log); err != nil {
- return nil, err
- }
- event.Raw = log
- return event, nil
-}
-
-type VerifiableLoadMercuryUpkeepOwnershipTransferRequestedIterator struct {
- Event *VerifiableLoadMercuryUpkeepOwnershipTransferRequested
-
- contract *bind.BoundContract
- event string
-
- logs chan types.Log
- sub ethereum.Subscription
- done bool
- fail error
-}
-
-func (it *VerifiableLoadMercuryUpkeepOwnershipTransferRequestedIterator) Next() bool {
-
- if it.fail != nil {
- return false
- }
-
- if it.done {
- select {
- case log := <-it.logs:
- it.Event = new(VerifiableLoadMercuryUpkeepOwnershipTransferRequested)
- if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
- it.fail = err
- return false
- }
- it.Event.Raw = log
- return true
-
- default:
- return false
- }
- }
-
- select {
- case log := <-it.logs:
- it.Event = new(VerifiableLoadMercuryUpkeepOwnershipTransferRequested)
- if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
- it.fail = err
- return false
- }
- it.Event.Raw = log
- return true
-
- case err := <-it.sub.Err():
- it.done = true
- it.fail = err
- return it.Next()
- }
-}
-
-func (it *VerifiableLoadMercuryUpkeepOwnershipTransferRequestedIterator) Error() error {
- return it.fail
-}
-
-func (it *VerifiableLoadMercuryUpkeepOwnershipTransferRequestedIterator) Close() error {
- it.sub.Unsubscribe()
- return nil
-}
-
-type VerifiableLoadMercuryUpkeepOwnershipTransferRequested struct {
- From common.Address
- To common.Address
- Raw types.Log
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VerifiableLoadMercuryUpkeepOwnershipTransferRequestedIterator, error) {
-
- var fromRule []interface{}
- for _, fromItem := range from {
- fromRule = append(fromRule, fromItem)
- }
- var toRule []interface{}
- for _, toItem := range to {
- toRule = append(toRule, toItem)
- }
-
- logs, sub, err := _VerifiableLoadMercuryUpkeep.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule)
- if err != nil {
- return nil, err
- }
- return &VerifiableLoadMercuryUpkeepOwnershipTransferRequestedIterator{contract: _VerifiableLoadMercuryUpkeep.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *VerifiableLoadMercuryUpkeepOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) {
-
- var fromRule []interface{}
- for _, fromItem := range from {
- fromRule = append(fromRule, fromItem)
- }
- var toRule []interface{}
- for _, toItem := range to {
- toRule = append(toRule, toItem)
- }
-
- logs, sub, err := _VerifiableLoadMercuryUpkeep.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule)
- if err != nil {
- return nil, err
- }
- return event.NewSubscription(func(quit <-chan struct{}) error {
- defer sub.Unsubscribe()
- for {
- select {
- case log := <-logs:
-
- event := new(VerifiableLoadMercuryUpkeepOwnershipTransferRequested)
- if err := _VerifiableLoadMercuryUpkeep.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil {
- return err
- }
- event.Raw = log
-
- select {
- case sink <- event:
- case err := <-sub.Err():
- return err
- case <-quit:
- return nil
- }
- case err := <-sub.Err():
- return err
- case <-quit:
- return nil
- }
- }
- }), nil
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) ParseOwnershipTransferRequested(log types.Log) (*VerifiableLoadMercuryUpkeepOwnershipTransferRequested, error) {
- event := new(VerifiableLoadMercuryUpkeepOwnershipTransferRequested)
- if err := _VerifiableLoadMercuryUpkeep.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil {
- return nil, err
- }
- event.Raw = log
- return event, nil
-}
-
-type VerifiableLoadMercuryUpkeepOwnershipTransferredIterator struct {
- Event *VerifiableLoadMercuryUpkeepOwnershipTransferred
-
- contract *bind.BoundContract
- event string
-
- logs chan types.Log
- sub ethereum.Subscription
- done bool
- fail error
-}
-
-func (it *VerifiableLoadMercuryUpkeepOwnershipTransferredIterator) Next() bool {
-
- if it.fail != nil {
- return false
- }
-
- if it.done {
- select {
- case log := <-it.logs:
- it.Event = new(VerifiableLoadMercuryUpkeepOwnershipTransferred)
- if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
- it.fail = err
- return false
- }
- it.Event.Raw = log
- return true
-
- default:
- return false
- }
- }
-
- select {
- case log := <-it.logs:
- it.Event = new(VerifiableLoadMercuryUpkeepOwnershipTransferred)
- if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
- it.fail = err
- return false
- }
- it.Event.Raw = log
- return true
-
- case err := <-it.sub.Err():
- it.done = true
- it.fail = err
- return it.Next()
- }
-}
-
-func (it *VerifiableLoadMercuryUpkeepOwnershipTransferredIterator) Error() error {
- return it.fail
-}
-
-func (it *VerifiableLoadMercuryUpkeepOwnershipTransferredIterator) Close() error {
- it.sub.Unsubscribe()
- return nil
-}
-
-type VerifiableLoadMercuryUpkeepOwnershipTransferred struct {
- From common.Address
- To common.Address
- Raw types.Log
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VerifiableLoadMercuryUpkeepOwnershipTransferredIterator, error) {
-
- var fromRule []interface{}
- for _, fromItem := range from {
- fromRule = append(fromRule, fromItem)
- }
- var toRule []interface{}
- for _, toItem := range to {
- toRule = append(toRule, toItem)
- }
-
- logs, sub, err := _VerifiableLoadMercuryUpkeep.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule)
- if err != nil {
- return nil, err
- }
- return &VerifiableLoadMercuryUpkeepOwnershipTransferredIterator{contract: _VerifiableLoadMercuryUpkeep.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *VerifiableLoadMercuryUpkeepOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) {
-
- var fromRule []interface{}
- for _, fromItem := range from {
- fromRule = append(fromRule, fromItem)
- }
- var toRule []interface{}
- for _, toItem := range to {
- toRule = append(toRule, toItem)
- }
-
- logs, sub, err := _VerifiableLoadMercuryUpkeep.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule)
- if err != nil {
- return nil, err
- }
- return event.NewSubscription(func(quit <-chan struct{}) error {
- defer sub.Unsubscribe()
- for {
- select {
- case log := <-logs:
-
- event := new(VerifiableLoadMercuryUpkeepOwnershipTransferred)
- if err := _VerifiableLoadMercuryUpkeep.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil {
- return err
- }
- event.Raw = log
-
- select {
- case sink <- event:
- case err := <-sub.Err():
- return err
- case <-quit:
- return nil
- }
- case err := <-sub.Err():
- return err
- case <-quit:
- return nil
- }
- }
- }), nil
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) ParseOwnershipTransferred(log types.Log) (*VerifiableLoadMercuryUpkeepOwnershipTransferred, error) {
- event := new(VerifiableLoadMercuryUpkeepOwnershipTransferred)
- if err := _VerifiableLoadMercuryUpkeep.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil {
- return nil, err
- }
- event.Raw = log
- return event, nil
-}
-
-type VerifiableLoadMercuryUpkeepReceivedIterator struct {
- Event *VerifiableLoadMercuryUpkeepReceived
-
- contract *bind.BoundContract
- event string
-
- logs chan types.Log
- sub ethereum.Subscription
- done bool
- fail error
-}
-
-func (it *VerifiableLoadMercuryUpkeepReceivedIterator) Next() bool {
-
- if it.fail != nil {
- return false
- }
-
- if it.done {
- select {
- case log := <-it.logs:
- it.Event = new(VerifiableLoadMercuryUpkeepReceived)
- if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
- it.fail = err
- return false
- }
- it.Event.Raw = log
- return true
-
- default:
- return false
- }
- }
-
- select {
- case log := <-it.logs:
- it.Event = new(VerifiableLoadMercuryUpkeepReceived)
- if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
- it.fail = err
- return false
- }
- it.Event.Raw = log
- return true
-
- case err := <-it.sub.Err():
- it.done = true
- it.fail = err
- return it.Next()
- }
-}
-
-func (it *VerifiableLoadMercuryUpkeepReceivedIterator) Error() error {
- return it.fail
-}
-
-func (it *VerifiableLoadMercuryUpkeepReceivedIterator) Close() error {
- it.sub.Unsubscribe()
- return nil
-}
-
-type VerifiableLoadMercuryUpkeepReceived struct {
- Sender common.Address
- Value *big.Int
- Raw types.Log
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) FilterReceived(opts *bind.FilterOpts) (*VerifiableLoadMercuryUpkeepReceivedIterator, error) {
-
- logs, sub, err := _VerifiableLoadMercuryUpkeep.contract.FilterLogs(opts, "Received")
- if err != nil {
- return nil, err
- }
- return &VerifiableLoadMercuryUpkeepReceivedIterator{contract: _VerifiableLoadMercuryUpkeep.contract, event: "Received", logs: logs, sub: sub}, nil
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) WatchReceived(opts *bind.WatchOpts, sink chan<- *VerifiableLoadMercuryUpkeepReceived) (event.Subscription, error) {
-
- logs, sub, err := _VerifiableLoadMercuryUpkeep.contract.WatchLogs(opts, "Received")
- if err != nil {
- return nil, err
- }
- return event.NewSubscription(func(quit <-chan struct{}) error {
- defer sub.Unsubscribe()
- for {
- select {
- case log := <-logs:
-
- event := new(VerifiableLoadMercuryUpkeepReceived)
- if err := _VerifiableLoadMercuryUpkeep.contract.UnpackLog(event, "Received", log); err != nil {
- return err
- }
- event.Raw = log
-
- select {
- case sink <- event:
- case err := <-sub.Err():
- return err
- case <-quit:
- return nil
- }
- case err := <-sub.Err():
- return err
- case <-quit:
- return nil
- }
- }
- }), nil
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) ParseReceived(log types.Log) (*VerifiableLoadMercuryUpkeepReceived, error) {
- event := new(VerifiableLoadMercuryUpkeepReceived)
- if err := _VerifiableLoadMercuryUpkeep.contract.UnpackLog(event, "Received", log); err != nil {
- return nil, err
- }
- event.Raw = log
- return event, nil
-}
-
-type VerifiableLoadMercuryUpkeepUpkeepTopUpIterator struct {
- Event *VerifiableLoadMercuryUpkeepUpkeepTopUp
-
- contract *bind.BoundContract
- event string
-
- logs chan types.Log
- sub ethereum.Subscription
- done bool
- fail error
-}
-
-func (it *VerifiableLoadMercuryUpkeepUpkeepTopUpIterator) Next() bool {
-
- if it.fail != nil {
- return false
- }
-
- if it.done {
- select {
- case log := <-it.logs:
- it.Event = new(VerifiableLoadMercuryUpkeepUpkeepTopUp)
- if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
- it.fail = err
- return false
- }
- it.Event.Raw = log
- return true
-
- default:
- return false
- }
- }
-
- select {
- case log := <-it.logs:
- it.Event = new(VerifiableLoadMercuryUpkeepUpkeepTopUp)
- if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
- it.fail = err
- return false
- }
- it.Event.Raw = log
- return true
-
- case err := <-it.sub.Err():
- it.done = true
- it.fail = err
- return it.Next()
- }
-}
-
-func (it *VerifiableLoadMercuryUpkeepUpkeepTopUpIterator) Error() error {
- return it.fail
-}
-
-func (it *VerifiableLoadMercuryUpkeepUpkeepTopUpIterator) Close() error {
- it.sub.Unsubscribe()
- return nil
-}
-
-type VerifiableLoadMercuryUpkeepUpkeepTopUp struct {
- UpkeepId *big.Int
- Amount *big.Int
- BlockNum *big.Int
- Raw types.Log
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) FilterUpkeepTopUp(opts *bind.FilterOpts) (*VerifiableLoadMercuryUpkeepUpkeepTopUpIterator, error) {
-
- logs, sub, err := _VerifiableLoadMercuryUpkeep.contract.FilterLogs(opts, "UpkeepTopUp")
- if err != nil {
- return nil, err
- }
- return &VerifiableLoadMercuryUpkeepUpkeepTopUpIterator{contract: _VerifiableLoadMercuryUpkeep.contract, event: "UpkeepTopUp", logs: logs, sub: sub}, nil
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) WatchUpkeepTopUp(opts *bind.WatchOpts, sink chan<- *VerifiableLoadMercuryUpkeepUpkeepTopUp) (event.Subscription, error) {
-
- logs, sub, err := _VerifiableLoadMercuryUpkeep.contract.WatchLogs(opts, "UpkeepTopUp")
- if err != nil {
- return nil, err
- }
- return event.NewSubscription(func(quit <-chan struct{}) error {
- defer sub.Unsubscribe()
- for {
- select {
- case log := <-logs:
-
- event := new(VerifiableLoadMercuryUpkeepUpkeepTopUp)
- if err := _VerifiableLoadMercuryUpkeep.contract.UnpackLog(event, "UpkeepTopUp", log); err != nil {
- return err
- }
- event.Raw = log
-
- select {
- case sink <- event:
- case err := <-sub.Err():
- return err
- case <-quit:
- return nil
- }
- case err := <-sub.Err():
- return err
- case <-quit:
- return nil
- }
- }
- }), nil
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) ParseUpkeepTopUp(log types.Log) (*VerifiableLoadMercuryUpkeepUpkeepTopUp, error) {
- event := new(VerifiableLoadMercuryUpkeepUpkeepTopUp)
- if err := _VerifiableLoadMercuryUpkeep.contract.UnpackLog(event, "UpkeepTopUp", log); err != nil {
- return nil, err
- }
- event.Raw = log
- return event, nil
-}
-
-type VerifiableLoadMercuryUpkeepUpkeepsRegisteredIterator struct {
- Event *VerifiableLoadMercuryUpkeepUpkeepsRegistered
-
- contract *bind.BoundContract
- event string
-
- logs chan types.Log
- sub ethereum.Subscription
- done bool
- fail error
-}
-
-func (it *VerifiableLoadMercuryUpkeepUpkeepsRegisteredIterator) Next() bool {
-
- if it.fail != nil {
- return false
- }
-
- if it.done {
- select {
- case log := <-it.logs:
- it.Event = new(VerifiableLoadMercuryUpkeepUpkeepsRegistered)
- if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
- it.fail = err
- return false
- }
- it.Event.Raw = log
- return true
-
- default:
- return false
- }
- }
-
- select {
- case log := <-it.logs:
- it.Event = new(VerifiableLoadMercuryUpkeepUpkeepsRegistered)
- if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
- it.fail = err
- return false
- }
- it.Event.Raw = log
- return true
-
- case err := <-it.sub.Err():
- it.done = true
- it.fail = err
- return it.Next()
- }
-}
-
-func (it *VerifiableLoadMercuryUpkeepUpkeepsRegisteredIterator) Error() error {
- return it.fail
-}
-
-func (it *VerifiableLoadMercuryUpkeepUpkeepsRegisteredIterator) Close() error {
- it.sub.Unsubscribe()
- return nil
-}
-
-type VerifiableLoadMercuryUpkeepUpkeepsRegistered struct {
- UpkeepIds []*big.Int
- Raw types.Log
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) FilterUpkeepsRegistered(opts *bind.FilterOpts) (*VerifiableLoadMercuryUpkeepUpkeepsRegisteredIterator, error) {
-
- logs, sub, err := _VerifiableLoadMercuryUpkeep.contract.FilterLogs(opts, "UpkeepsRegistered")
- if err != nil {
- return nil, err
- }
- return &VerifiableLoadMercuryUpkeepUpkeepsRegisteredIterator{contract: _VerifiableLoadMercuryUpkeep.contract, event: "UpkeepsRegistered", logs: logs, sub: sub}, nil
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) WatchUpkeepsRegistered(opts *bind.WatchOpts, sink chan<- *VerifiableLoadMercuryUpkeepUpkeepsRegistered) (event.Subscription, error) {
-
- logs, sub, err := _VerifiableLoadMercuryUpkeep.contract.WatchLogs(opts, "UpkeepsRegistered")
- if err != nil {
- return nil, err
- }
- return event.NewSubscription(func(quit <-chan struct{}) error {
- defer sub.Unsubscribe()
- for {
- select {
- case log := <-logs:
-
- event := new(VerifiableLoadMercuryUpkeepUpkeepsRegistered)
- if err := _VerifiableLoadMercuryUpkeep.contract.UnpackLog(event, "UpkeepsRegistered", log); err != nil {
- return err
- }
- event.Raw = log
-
- select {
- case sink <- event:
- case err := <-sub.Err():
- return err
- case <-quit:
- return nil
- }
- case err := <-sub.Err():
- return err
- case <-quit:
- return nil
- }
- }
- }), nil
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeepFilterer) ParseUpkeepsRegistered(log types.Log) (*VerifiableLoadMercuryUpkeepUpkeepsRegistered, error) {
- event := new(VerifiableLoadMercuryUpkeepUpkeepsRegistered)
- if err := _VerifiableLoadMercuryUpkeep.contract.UnpackLog(event, "UpkeepsRegistered", log); err != nil {
- return nil, err
- }
- event.Raw = log
- return event, nil
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeep) ParseLog(log types.Log) (generated.AbigenLog, error) {
- switch log.Topics[0] {
- case _VerifiableLoadMercuryUpkeep.abi.Events["LogEmitted"].ID:
- return _VerifiableLoadMercuryUpkeep.ParseLogEmitted(log)
- case _VerifiableLoadMercuryUpkeep.abi.Events["OwnershipTransferRequested"].ID:
- return _VerifiableLoadMercuryUpkeep.ParseOwnershipTransferRequested(log)
- case _VerifiableLoadMercuryUpkeep.abi.Events["OwnershipTransferred"].ID:
- return _VerifiableLoadMercuryUpkeep.ParseOwnershipTransferred(log)
- case _VerifiableLoadMercuryUpkeep.abi.Events["Received"].ID:
- return _VerifiableLoadMercuryUpkeep.ParseReceived(log)
- case _VerifiableLoadMercuryUpkeep.abi.Events["UpkeepTopUp"].ID:
- return _VerifiableLoadMercuryUpkeep.ParseUpkeepTopUp(log)
- case _VerifiableLoadMercuryUpkeep.abi.Events["UpkeepsRegistered"].ID:
- return _VerifiableLoadMercuryUpkeep.ParseUpkeepsRegistered(log)
-
- default:
- return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0])
- }
-}
-
-func (VerifiableLoadMercuryUpkeepLogEmitted) Topic() common.Hash {
- return common.HexToHash("0x97009585a4d2440f981ab6f6eec514343e1e6b2aa9b991a26998e6806f41bf08")
-}
-
-func (VerifiableLoadMercuryUpkeepOwnershipTransferRequested) Topic() common.Hash {
- return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278")
-}
-
-func (VerifiableLoadMercuryUpkeepOwnershipTransferred) Topic() common.Hash {
- return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0")
-}
-
-func (VerifiableLoadMercuryUpkeepReceived) Topic() common.Hash {
- return common.HexToHash("0x88a5966d370b9919b20f3e2c13ff65706f196a4e32cc2c12bf57088f88525874")
-}
-
-func (VerifiableLoadMercuryUpkeepUpkeepTopUp) Topic() common.Hash {
- return common.HexToHash("0x49d4100ab0124eb4a9a65dc4ea08d6412a43f6f05c49194983f5b322bcc0a5c0")
-}
-
-func (VerifiableLoadMercuryUpkeepUpkeepsRegistered) Topic() common.Hash {
- return common.HexToHash("0x2ee10f7eb180441fb9fbba75b10c0162b5390b557712c93426243ca8f383c711")
-}
-
-func (_VerifiableLoadMercuryUpkeep *VerifiableLoadMercuryUpkeep) Address() common.Address {
- return _VerifiableLoadMercuryUpkeep.address
-}
-
-type VerifiableLoadMercuryUpkeepInterface interface {
- BUCKETSIZE(opts *bind.CallOpts) (uint16, error)
-
- AddLinkAmount(opts *bind.CallOpts) (*big.Int, error)
-
- BucketedDelays(opts *bind.CallOpts, arg0 *big.Int, arg1 uint16, arg2 *big.Int) (*big.Int, error)
-
- Buckets(opts *bind.CallOpts, arg0 *big.Int) (uint16, error)
-
- CheckCallback(opts *bind.CallOpts, values [][]byte, extraData []byte) (bool, []byte, error)
-
- CheckGasToBurns(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error)
-
- Counters(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error)
-
- Delays(opts *bind.CallOpts, arg0 *big.Int, arg1 *big.Int) (*big.Int, error)
-
- DummyMap(opts *bind.CallOpts, arg0 [32]byte) (bool, error)
-
- Eligible(opts *bind.CallOpts, upkeepId *big.Int) (bool, error)
-
- EmittedSig(opts *bind.CallOpts) ([32]byte, error)
-
- FeedParamKey(opts *bind.CallOpts) (string, error)
-
- FeedsHex(opts *bind.CallOpts, arg0 *big.Int) (string, error)
-
- FirstPerformBlocks(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error)
-
- GasLimits(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error)
-
- GetActiveUpkeepIDs(opts *bind.CallOpts, startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error)
-
- GetBucketedDelays(opts *bind.CallOpts, upkeepId *big.Int, bucket uint16) ([]*big.Int, error)
-
- GetBucketedDelaysLength(opts *bind.CallOpts, upkeepId *big.Int) (*big.Int, error)
-
- GetDelays(opts *bind.CallOpts, upkeepId *big.Int) ([]*big.Int, error)
-
- GetDelaysLength(opts *bind.CallOpts, upkeepId *big.Int) (*big.Int, error)
-
- GetLogTriggerConfig(opts *bind.CallOpts, upkeepId *big.Int) ([]byte, error)
-
- GetPxDelayLastNPerforms(opts *bind.CallOpts, upkeepId *big.Int, p *big.Int, n *big.Int) (*big.Int, error)
-
- GetSumDelayInBucket(opts *bind.CallOpts, upkeepId *big.Int, bucket uint16) (*big.Int, *big.Int, error)
-
- GetSumDelayLastNPerforms(opts *bind.CallOpts, upkeepId *big.Int, n *big.Int) (*big.Int, *big.Int, error)
-
- Intervals(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error)
-
- LastTopUpBlocks(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error)
-
- LinkToken(opts *bind.CallOpts) (common.Address, error)
-
- MinBalanceThresholdMultiplier(opts *bind.CallOpts) (uint8, error)
-
- Owner(opts *bind.CallOpts) (common.Address, error)
-
- PerformDataSizes(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error)
-
- PerformGasToBurns(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error)
-
- PreviousPerformBlocks(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error)
-
- Registrar(opts *bind.CallOpts) (common.Address, error)
-
- Registry(opts *bind.CallOpts) (common.Address, error)
-
- TimeParamKey(opts *bind.CallOpts) (string, error)
-
- UpkeepTopUpCheckInterval(opts *bind.CallOpts) (*big.Int, error)
-
- UseArbitrumBlockNum(opts *bind.CallOpts) (bool, error)
-
- AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error)
-
- AddFunds(opts *bind.TransactOpts, upkeepId *big.Int, amount *big.Int) (*types.Transaction, error)
-
- BatchCancelUpkeeps(opts *bind.TransactOpts, upkeepIds []*big.Int) (*types.Transaction, error)
-
- BatchRegisterUpkeeps(opts *bind.TransactOpts, number uint8, gasLimit uint32, triggerType uint8, triggerConfig []byte, amount *big.Int, checkGasToBurn *big.Int, performGasToBurn *big.Int) (*types.Transaction, error)
-
- BatchSendLogs(opts *bind.TransactOpts) (*types.Transaction, error)
-
- BatchSetIntervals(opts *bind.TransactOpts, upkeepIds []*big.Int, interval uint32) (*types.Transaction, error)
-
- BatchUpdatePipelineData(opts *bind.TransactOpts, upkeepIds []*big.Int) (*types.Transaction, error)
-
- BatchWithdrawLinks(opts *bind.TransactOpts, upkeepIds []*big.Int) (*types.Transaction, error)
-
- BurnPerformGas(opts *bind.TransactOpts, upkeepId *big.Int, startGas *big.Int, blockNum *big.Int) (*types.Transaction, error)
-
- CancelUpkeep(opts *bind.TransactOpts, upkeepId *big.Int) (*types.Transaction, error)
-
- CheckUpkeep(opts *bind.TransactOpts, checkData []byte) (*types.Transaction, error)
-
- PerformUpkeep(opts *bind.TransactOpts, performData []byte) (*types.Transaction, error)
-
- SendLog(opts *bind.TransactOpts, upkeepId *big.Int) (*types.Transaction, error)
-
- SetAddLinkAmount(opts *bind.TransactOpts, amount *big.Int) (*types.Transaction, error)
-
- SetCheckGasToBurn(opts *bind.TransactOpts, upkeepId *big.Int, value *big.Int) (*types.Transaction, error)
-
- SetConfig(opts *bind.TransactOpts, newRegistrar common.Address) (*types.Transaction, error)
-
- SetFeedsHex(opts *bind.TransactOpts, newFeeds []string) (*types.Transaction, error)
-
- SetInterval(opts *bind.TransactOpts, upkeepId *big.Int, _interval *big.Int) (*types.Transaction, error)
-
- SetMinBalanceThresholdMultiplier(opts *bind.TransactOpts, newMinBalanceThresholdMultiplier uint8) (*types.Transaction, error)
-
- SetPerformDataSize(opts *bind.TransactOpts, upkeepId *big.Int, value *big.Int) (*types.Transaction, error)
-
- SetPerformGasToBurn(opts *bind.TransactOpts, upkeepId *big.Int, value *big.Int) (*types.Transaction, error)
-
- SetUpkeepGasLimit(opts *bind.TransactOpts, upkeepId *big.Int, gasLimit uint32) (*types.Transaction, error)
-
- SetUpkeepTopUpCheckInterval(opts *bind.TransactOpts, newInterval *big.Int) (*types.Transaction, error)
-
- TopUpFund(opts *bind.TransactOpts, upkeepId *big.Int, blockNum *big.Int) (*types.Transaction, error)
-
- TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error)
-
- UpdateUpkeepPipelineData(opts *bind.TransactOpts, upkeepId *big.Int, pipelineData []byte) (*types.Transaction, error)
-
- WithdrawLinks(opts *bind.TransactOpts) (*types.Transaction, error)
-
- WithdrawLinks0(opts *bind.TransactOpts, upkeepId *big.Int) (*types.Transaction, error)
-
- Receive(opts *bind.TransactOpts) (*types.Transaction, error)
-
- FilterLogEmitted(opts *bind.FilterOpts, upkeepId []*big.Int, blockNum []*big.Int) (*VerifiableLoadMercuryUpkeepLogEmittedIterator, error)
-
- WatchLogEmitted(opts *bind.WatchOpts, sink chan<- *VerifiableLoadMercuryUpkeepLogEmitted, upkeepId []*big.Int, blockNum []*big.Int) (event.Subscription, error)
-
- ParseLogEmitted(log types.Log) (*VerifiableLoadMercuryUpkeepLogEmitted, error)
-
- FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VerifiableLoadMercuryUpkeepOwnershipTransferRequestedIterator, error)
-
- WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *VerifiableLoadMercuryUpkeepOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error)
-
- ParseOwnershipTransferRequested(log types.Log) (*VerifiableLoadMercuryUpkeepOwnershipTransferRequested, error)
-
- FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VerifiableLoadMercuryUpkeepOwnershipTransferredIterator, error)
-
- WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *VerifiableLoadMercuryUpkeepOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error)
-
- ParseOwnershipTransferred(log types.Log) (*VerifiableLoadMercuryUpkeepOwnershipTransferred, error)
-
- FilterReceived(opts *bind.FilterOpts) (*VerifiableLoadMercuryUpkeepReceivedIterator, error)
-
- WatchReceived(opts *bind.WatchOpts, sink chan<- *VerifiableLoadMercuryUpkeepReceived) (event.Subscription, error)
-
- ParseReceived(log types.Log) (*VerifiableLoadMercuryUpkeepReceived, error)
-
- FilterUpkeepTopUp(opts *bind.FilterOpts) (*VerifiableLoadMercuryUpkeepUpkeepTopUpIterator, error)
-
- WatchUpkeepTopUp(opts *bind.WatchOpts, sink chan<- *VerifiableLoadMercuryUpkeepUpkeepTopUp) (event.Subscription, error)
-
- ParseUpkeepTopUp(log types.Log) (*VerifiableLoadMercuryUpkeepUpkeepTopUp, error)
-
- FilterUpkeepsRegistered(opts *bind.FilterOpts) (*VerifiableLoadMercuryUpkeepUpkeepsRegisteredIterator, error)
-
- WatchUpkeepsRegistered(opts *bind.WatchOpts, sink chan<- *VerifiableLoadMercuryUpkeepUpkeepsRegistered) (event.Subscription, error)
-
- ParseUpkeepsRegistered(log types.Log) (*VerifiableLoadMercuryUpkeepUpkeepsRegistered, error)
-
- ParseLog(log types.Log) (generated.AbigenLog, error)
-
- Address() common.Address
-}
diff --git a/core/gethwrappers/generated/verifiable_load_streams_lookup_upkeep_wrapper/verifiable_load_streams_lookup_upkeep_wrapper.go b/core/gethwrappers/generated/verifiable_load_streams_lookup_upkeep_wrapper/verifiable_load_streams_lookup_upkeep_wrapper.go
new file mode 100644
index 00000000000..e8a10d85dd1
--- /dev/null
+++ b/core/gethwrappers/generated/verifiable_load_streams_lookup_upkeep_wrapper/verifiable_load_streams_lookup_upkeep_wrapper.go
@@ -0,0 +1,2457 @@
+// Code generated - DO NOT EDIT.
+// This file is a generated binding and any manual changes will be lost.
+
+package verifiable_load_streams_lookup_upkeep_wrapper
+
+import (
+ "errors"
+ "fmt"
+ "math/big"
+ "strings"
+
+ ethereum "github.com/ethereum/go-ethereum"
+ "github.com/ethereum/go-ethereum/accounts/abi"
+ "github.com/ethereum/go-ethereum/accounts/abi/bind"
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/core/types"
+ "github.com/ethereum/go-ethereum/event"
+ "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated"
+)
+
+var (
+ _ = errors.New
+ _ = big.NewInt
+ _ = strings.NewReader
+ _ = ethereum.NotFound
+ _ = bind.Bind
+ _ = common.Big1
+ _ = types.BloomLookup
+ _ = event.NewSubscription
+ _ = abi.ConvertType
+)
+
+type KeeperRegistryBase21UpkeepInfo struct {
+ Target common.Address
+ PerformGas uint32
+ CheckData []byte
+ Balance *big.Int
+ Admin common.Address
+ MaxValidBlocknumber uint64
+ LastPerformedBlockNumber uint32
+ AmountSpent *big.Int
+ Paused bool
+ OffchainConfig []byte
+}
+
+var VerifiableLoadStreamsLookupUpkeepMetaData = &bind.MetaData{
+ ABI: "[{\"inputs\":[{\"internalType\":\"contractAutomationRegistrar2_1\",\"name\":\"_registrar\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_useArb\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"IndexOutOfRange\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"feedParamKey\",\"type\":\"string\"},{\"internalType\":\"string[]\",\"name\":\"feeds\",\"type\":\"string[]\"},{\"internalType\":\"string\",\"name\":\"timeParamKey\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"time\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"StreamsLookup\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"blockNum\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"LogEmitted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"blockNum\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"LogEmittedAgain\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"blockNum\",\"type\":\"uint256\"}],\"name\":\"UpkeepTopUp\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BUCKET_SIZE\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"addFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"addLinkAmount\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"}],\"name\":\"batchCancelUpkeeps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"},{\"internalType\":\"uint8\",\"name\":\"selector\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"topic0\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"topic1\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"topic2\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"topic3\",\"type\":\"bytes32\"}],\"name\":\"batchPreparingUpkeeps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"},{\"internalType\":\"uint8\",\"name\":\"log\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"selector\",\"type\":\"uint8\"}],\"name\":\"batchPreparingUpkeepsSimple\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"number\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"},{\"internalType\":\"uint256\",\"name\":\"checkGasToBurn\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"performGasToBurn\",\"type\":\"uint256\"}],\"name\":\"batchRegisterUpkeeps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"log\",\"type\":\"uint8\"}],\"name\":\"batchSendLogs\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"},{\"internalType\":\"uint32\",\"name\":\"interval\",\"type\":\"uint32\"}],\"name\":\"batchSetIntervals\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"}],\"name\":\"batchUpdatePipelineData\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"}],\"name\":\"batchWithdrawLinks\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"bucketedDelays\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"buckets\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"startGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"blockNum\",\"type\":\"uint256\"}],\"name\":\"burnPerformGas\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes[]\",\"name\":\"values\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"checkCallback\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"checkGasToBurns\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"}],\"name\":\"checkUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"counters\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"delays\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"dummyMap\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"eligible\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"emittedAgainSig\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"emittedSig\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"feedParamKey\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"feedsHex\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"firstPerformBlocks\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"gasLimits\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"startIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxCount\",\"type\":\"uint256\"}],\"name\":\"getActiveUpkeepIDsDeployedByThisContract\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"startIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxCount\",\"type\":\"uint256\"}],\"name\":\"getAllActiveUpkeepIDsOnRegistry\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"getBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"bucket\",\"type\":\"uint16\"}],\"name\":\"getBucketedDelays\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getBucketedDelaysLength\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getDelays\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getDelaysLength\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepID\",\"type\":\"uint256\"}],\"name\":\"getForwarder\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"selector\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"topic0\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"topic1\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"topic2\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"topic3\",\"type\":\"bytes32\"}],\"name\":\"getLogTriggerConfig\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"logTrigger\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getMinBalanceForUpkeep\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"p\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"n\",\"type\":\"uint256\"}],\"name\":\"getPxDelayLastNPerforms\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"bucket\",\"type\":\"uint16\"}],\"name\":\"getSumDelayInBucket\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"n\",\"type\":\"uint256\"}],\"name\":\"getSumDelayLastNPerforms\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getTriggerType\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getUpkeepInfo\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"performGas\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"maxValidBlocknumber\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"lastPerformedBlockNumber\",\"type\":\"uint32\"},{\"internalType\":\"uint96\",\"name\":\"amountSpent\",\"type\":\"uint96\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"internalType\":\"structKeeperRegistryBase2_1.UpkeepInfo\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getUpkeepPrivilegeConfig\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getUpkeepTriggerConfig\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"intervals\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"lastTopUpBlocks\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"linkToken\",\"outputs\":[{\"internalType\":\"contractLinkTokenInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"minBalanceThresholdMultiplier\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"performDataSizes\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"performGasToBurns\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"}],\"name\":\"performUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"previousPerformBlocks\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"registrar\",\"outputs\":[{\"internalType\":\"contractAutomationRegistrar2_1\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"registry\",\"outputs\":[{\"internalType\":\"contractIKeeperRegistryMaster\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"log\",\"type\":\"uint8\"}],\"name\":\"sendLog\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractAutomationRegistrar2_1\",\"name\":\"newRegistrar\",\"type\":\"address\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string[]\",\"name\":\"_feeds\",\"type\":\"string[]\"}],\"name\":\"setFeeds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_interval\",\"type\":\"uint256\"}],\"name\":\"setInterval\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_feedParamKey\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_timeParamKey\",\"type\":\"string\"}],\"name\":\"setParamKeys\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"setPerformDataSize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"}],\"name\":\"setUpkeepGasLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"cfg\",\"type\":\"bytes\"}],\"name\":\"setUpkeepPrivilegeConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"timeParamKey\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"blockNum\",\"type\":\"uint256\"}],\"name\":\"topUpFund\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"selector\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"topic0\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"topic1\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"topic2\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"topic3\",\"type\":\"bytes32\"}],\"name\":\"updateLogTriggerConfig1\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"cfg\",\"type\":\"bytes\"}],\"name\":\"updateLogTriggerConfig2\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"pipelineData\",\"type\":\"bytes\"}],\"name\":\"updateUpkeepPipelineData\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"upkeepTopUpCheckInterval\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"useArbitrumBlockNum\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawLinks\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"withdrawLinks\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]",
+ Bin: "0x7f97009585a4d2440f981ab6f6eec514343e1e6b2aa9b991a26998e6806f41bf086080527fc76416badc8398ce17c93eab7b4f60f263241694cf503e4df24f233a8cc1c50d60a0526005601455601580546001600160681b0319166c140000000002c68af0bb140000179055606460e0526101c0604052604261014081815261010091829190620061d161016039815260200160405180608001604052806042815260200162006213604291399052620000be906016906002620003c7565b506040805180820190915260098152680cccacac892c890caf60bb1b6020820152601790620000ee908262000543565b5060408051808201909152600b81526a313637b1b5a73ab6b132b960a91b602082015260189062000120908262000543565b503480156200012e57600080fd5b506040516200625538038062006255833981016040819052620001519162000625565b81813380600081620001aa5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620001dd57620001dd816200031c565b5050601180546001600160a01b0319166001600160a01b038516908117909155604080516330fe427560e21b815281516000945063c3f909d4926004808401939192918290030181865afa1580156200023a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000260919062000668565b50601380546001600160a01b0319166001600160a01b038381169190911790915560115460408051631b6b6d2360e01b81529051939450911691631b6b6d23916004808201926020929091908290030181865afa158015620002c6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002ec919062000699565b601280546001600160a01b0319166001600160a01b039290921691909117905550151560c05250620006c0915050565b336001600160a01b03821603620003765760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401620001a1565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b82805482825590600052602060002090810192821562000412579160200282015b8281111562000412578251829062000401908262000543565b5091602001919060010190620003e8565b506200042092915062000424565b5090565b80821115620004205760006200043b828262000445565b5060010162000424565b5080546200045390620004b4565b6000825580601f1062000464575050565b601f01602090049060005260206000209081019062000484919062000487565b50565b5b8082111562000420576000815560010162000488565b634e487b7160e01b600052604160045260246000fd5b600181811c90821680620004c957607f821691505b602082108103620004ea57634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200053e57600081815260208120601f850160051c81016020861015620005195750805b601f850160051c820191505b818110156200053a5782815560010162000525565b5050505b505050565b81516001600160401b038111156200055f576200055f6200049e565b6200057781620005708454620004b4565b84620004f0565b602080601f831160018114620005af5760008415620005965750858301515b600019600386901b1c1916600185901b1785556200053a565b600085815260208120601f198616915b82811015620005e057888601518255948401946001909101908401620005bf565b5085821015620005ff5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6001600160a01b03811681146200048457600080fd5b600080604083850312156200063957600080fd5b825162000646816200060f565b602084015190925080151581146200065d57600080fd5b809150509250929050565b600080604083850312156200067c57600080fd5b825162000689816200060f565b6020939093015192949293505050565b600060208284031215620006ac57600080fd5b8151620006b9816200060f565b9392505050565b60805160a05160c05160e051615abb62000716600039600081816105680152611f7a0152600081816109bc0152613ca701526000818161082701526136f5015260008181610d7901526136ca0152615abb6000f3fe6080604052600436106104d55760003560e01c806379ea994311610279578063a6b594751161015e578063d6051a72116100d6578063e45530831161008a578063fa333dfb1161006f578063fa333dfb14610f88578063fba7ffa31461103b578063fcdc1f631461106857600080fd5b8063e455308314610f52578063f2fde38b14610f6857600080fd5b8063daee1aeb116100bb578063daee1aeb14610ee5578063dbef701e14610f05578063e0114adb14610f2557600080fd5b8063d6051a7214610ea5578063da6cba4714610ec557600080fd5b8063b657bc9c1161012d578063c041982211610112578063c041982214610e50578063c98f10b014610e70578063d4c2490014610e8557600080fd5b8063b657bc9c14610e10578063becde0e114610e3057600080fd5b8063a6b5947514610d9b578063a72aa27e14610dbb578063af953a4a14610ddb578063afb28d1f14610dfb57600080fd5b8063924ca578116101f15780639b429354116101c05780639d385eaa116101a55780639d385eaa14610d275780639d6f1cc714610d47578063a654824814610d6757600080fd5b80639b42935414610cc95780639b51fb0d14610cf657600080fd5b8063924ca57814610c3f578063948108f714610c5f57806396cebc7c14610c7f5780639ac542eb14610c9f57600080fd5b80638340507c11610248578063873c75861161022d578063873c758614610bc75780638da5cb5b14610be75780638fcb3fba14610c1257600080fd5b80638340507c14610b8757806386e330af14610ba757600080fd5b806379ea994314610afa5780637b10399914610b1a5780637e7a46dc14610b475780638243444a14610b6757600080fd5b806345d2ec17116103ba57806360457ff5116103325780637145f11b116102e657806376721303116102cb5780637672130314610a98578063776898c814610ac557806379ba509714610ae557600080fd5b80637145f11b14610a3b57806373644cce14610a6b57600080fd5b8063642f6cef11610317578063642f6cef146109aa57806369cdbadb146109ee5780636e04ff0d14610a1b57600080fd5b806360457ff514610958578063636092e81461098557600080fd5b80635147cd591161038957806357970e931161036e57806357970e93146108f65780635d4ee7f3146109235780635f17e6161461093857600080fd5b80635147cd59146108a457806351c98be3146108d657600080fd5b806345d2ec17146107e8578063469820931461081557806346e7a63e146108495780634b56a42e1461087657600080fd5b806320e3dbd41161044d5780632a9032d31161041c578063328ffd1111610401578063328ffd111461077b5780633ebe8d6c146107a85780634585e33b146107c857600080fd5b80632a9032d3146107095780632b20e3971461072957600080fd5b806320e3dbd41461067c5780632636aecf1461069c57806328c4b57b146106bc57806329e0a841146106dc57600080fd5b806319d97a94116104a45780631e010439116104895780631e010439146105ea578063206c32e814610627578063207b65161461065c57600080fd5b806319d97a941461059d5780631cdde251146105ca57600080fd5b806306c1cc00146104e1578063077ac621146105035780630b7d33e61461053657806312c550271461055657600080fd5b366104dc57005b600080fd5b3480156104ed57600080fd5b506105016104fc366004614429565b611095565b005b34801561050f57600080fd5b5061052361051e3660046144dc565b6112e4565b6040519081526020015b60405180910390f35b34801561054257600080fd5b50610501610551366004614511565b611322565b34801561056257600080fd5b5061058a7f000000000000000000000000000000000000000000000000000000000000000081565b60405161ffff909116815260200161052d565b3480156105a957600080fd5b506105bd6105b8366004614558565b6113b0565b60405161052d91906145df565b3480156105d657600080fd5b506105016105e5366004614614565b61146d565b3480156105f657600080fd5b5061060a610605366004614558565b6115aa565b6040516bffffffffffffffffffffffff909116815260200161052d565b34801561063357600080fd5b50610647610642366004614679565b61163f565b6040805192835260208301919091520161052d565b34801561066857600080fd5b506105bd610677366004614558565b6116c2565b34801561068857600080fd5b506105016106973660046146a5565b61171a565b3480156106a857600080fd5b506105016106b7366004614707565b6118e4565b3480156106c857600080fd5b506105236106d7366004614781565b611bad565b3480156106e857600080fd5b506106fc6106f7366004614558565b611c18565b60405161052d91906147ad565b34801561071557600080fd5b506105016107243660046148ee565b611d1d565b34801561073557600080fd5b506011546107569073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161052d565b34801561078757600080fd5b50610523610796366004614558565b60036020526000908152604090205481565b3480156107b457600080fd5b506105236107c3366004614558565b611dfe565b3480156107d457600080fd5b506105016107e3366004614972565b611e67565b3480156107f457600080fd5b50610808610803366004614679565b612086565b60405161052d91906149a8565b34801561082157600080fd5b506105237f000000000000000000000000000000000000000000000000000000000000000081565b34801561085557600080fd5b50610523610864366004614558565b600a6020526000908152604090205481565b34801561088257600080fd5b50610896610891366004614a10565b6120f5565b60405161052d929190614ada565b3480156108b057600080fd5b506108c46108bf366004614558565b612149565b60405160ff909116815260200161052d565b3480156108e257600080fd5b506105016108f1366004614af5565b6121dd565b34801561090257600080fd5b506012546107569073ffffffffffffffffffffffffffffffffffffffff1681565b34801561092f57600080fd5b50610501612281565b34801561094457600080fd5b50610501610953366004614b4c565b6123bc565b34801561096457600080fd5b50610523610973366004614558565b60076020526000908152604090205481565b34801561099157600080fd5b5060155461060a906bffffffffffffffffffffffff1681565b3480156109b657600080fd5b506109de7f000000000000000000000000000000000000000000000000000000000000000081565b604051901515815260200161052d565b3480156109fa57600080fd5b50610523610a09366004614558565b60086020526000908152604090205481565b348015610a2757600080fd5b50610896610a36366004614972565b612489565b348015610a4757600080fd5b506109de610a56366004614558565b600b6020526000908152604090205460ff1681565b348015610a7757600080fd5b50610523610a86366004614558565b6000908152600c602052604090205490565b348015610aa457600080fd5b50610523610ab3366004614558565b60046020526000908152604090205481565b348015610ad157600080fd5b506109de610ae0366004614558565b6126b2565b348015610af157600080fd5b50610501612704565b348015610b0657600080fd5b50610756610b15366004614558565b612801565b348015610b2657600080fd5b506013546107569073ffffffffffffffffffffffffffffffffffffffff1681565b348015610b5357600080fd5b50610501610b62366004614b6e565b612895565b348015610b7357600080fd5b50610501610b82366004614b6e565b612926565b348015610b9357600080fd5b50610501610ba2366004614bba565b612980565b348015610bb357600080fd5b50610501610bc2366004614c07565b61299e565b348015610bd357600080fd5b50610808610be2366004614b4c565b6129b1565b348015610bf357600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff16610756565b348015610c1e57600080fd5b50610523610c2d366004614558565b60056020526000908152604090205481565b348015610c4b57600080fd5b50610501610c5a366004614b4c565b612a6e565b348015610c6b57600080fd5b50610501610c7a366004614cb8565b612cb3565b348015610c8b57600080fd5b50610501610c9a366004614ce8565b612dcb565b348015610cab57600080fd5b506015546108c4906c01000000000000000000000000900460ff1681565b348015610cd557600080fd5b50610501610ce4366004614b4c565b60009182526009602052604090912055565b348015610d0257600080fd5b5061058a610d11366004614558565b600e6020526000908152604090205461ffff1681565b348015610d3357600080fd5b50610808610d42366004614558565b612fd5565b348015610d5357600080fd5b506105bd610d62366004614558565b613037565b348015610d7357600080fd5b506105237f000000000000000000000000000000000000000000000000000000000000000081565b348015610da757600080fd5b50610501610db6366004614781565b6130e3565b348015610dc757600080fd5b50610501610dd6366004614d05565b61314c565b348015610de757600080fd5b50610501610df6366004614558565b6131f7565b348015610e0757600080fd5b506105bd61327d565b348015610e1c57600080fd5b5061060a610e2b366004614558565b61328a565b348015610e3c57600080fd5b50610501610e4b3660046148ee565b6132e2565b348015610e5c57600080fd5b50610808610e6b366004614b4c565b61337c565b348015610e7c57600080fd5b506105bd613479565b348015610e9157600080fd5b50610501610ea0366004614d2a565b613486565b348015610eb157600080fd5b50610647610ec0366004614b4c565b613505565b348015610ed157600080fd5b50610501610ee0366004614d4f565b61356e565b348015610ef157600080fd5b50610501610f003660046148ee565b6138d5565b348015610f1157600080fd5b50610523610f20366004614b4c565b6139a0565b348015610f3157600080fd5b50610523610f40366004614558565b60096020526000908152604090205481565b348015610f5e57600080fd5b5061052360145481565b348015610f7457600080fd5b50610501610f833660046146a5565b6139d1565b348015610f9457600080fd5b506105bd610fa3366004614db7565b6040805160c0808201835273ffffffffffffffffffffffffffffffffffffffff9890981680825260ff97881660208084019182528385019889526060808501988952608080860198895260a095860197885286519283019490945291519099168985015296519688019690965293519486019490945290519184019190915251828401528051808303909301835260e0909101905290565b34801561104757600080fd5b50610523611056366004614558565b60066020526000908152604090205481565b34801561107457600080fd5b50610523611083366004614558565b60026020526000908152604090205481565b6040805161018081018252600461014082019081527f746573740000000000000000000000000000000000000000000000000000000061016083015281528151602081810184526000808352818401929092523083850181905263ffffffff8b166060850152608084015260ff808a1660a08501528451808301865283815260c085015260e0840189905284519182019094529081526101008201526bffffffffffffffffffffffff8516610120820152601254601154919273ffffffffffffffffffffffffffffffffffffffff9182169263095ea7b392169061117b908c1688614e3f565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815273ffffffffffffffffffffffffffffffffffffffff90921660048301526bffffffffffffffffffffffff1660248201526044016020604051808303816000875af11580156111f9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061121d9190614e83565b5060008860ff1667ffffffffffffffff81111561123c5761123c6142cb565b604051908082528060200260200182016040528015611265578160200160208202803683370190505b50905060005b8960ff168160ff1610156112d8576000611284846139e5565b905080838360ff168151811061129c5761129c614e9e565b602090810291909101810191909152600091825260088152604080832088905560079091529020849055806112d081614ecd565b91505061126b565b50505050505050505050565b600d602052826000526040600020602052816000526040600020818154811061130c57600080fd5b9060005260206000200160009250925050505481565b6013546040517f0b7d33e600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911690630b7d33e69061137a9085908590600401614eec565b600060405180830381600087803b15801561139457600080fd5b505af11580156113a8573d6000803e3d6000fd5b505050505050565b6013546040517f19d97a940000000000000000000000000000000000000000000000000000000081526004810183905260609173ffffffffffffffffffffffffffffffffffffffff16906319d97a94906024015b600060405180830381865afa158015611421573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526114679190810190614f52565b92915050565b6013546040517ffa333dfb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff888116600483015260ff8816602483015260448201879052606482018690526084820185905260a4820184905290911690634ee88d35908990309063fa333dfb9060c401600060405180830381865afa15801561150c573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526115529190810190614f52565b6040518363ffffffff1660e01b815260040161156f929190614eec565b600060405180830381600087803b15801561158957600080fd5b505af115801561159d573d6000803e3d6000fd5b5050505050505050505050565b6013546040517f1e0104390000000000000000000000000000000000000000000000000000000081526004810183905260009173ffffffffffffffffffffffffffffffffffffffff1690631e010439906024015b602060405180830381865afa15801561161b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114679190614f92565b6000828152600d6020908152604080832061ffff8516845282528083208054825181850281018501909352808352849384939291908301828280156116a357602002820191906000526020600020905b81548152602001906001019080831161168f575b505050505090506116b5818251613ab3565b92509250505b9250929050565b6013546040517f207b65160000000000000000000000000000000000000000000000000000000081526004810183905260609173ffffffffffffffffffffffffffffffffffffffff169063207b651690602401611404565b601180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8316908117909155604080517fc3f909d400000000000000000000000000000000000000000000000000000000815281516000939263c3f909d492600480820193918290030181865afa1580156117b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117d49190614fba565b50601380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691909117909155601154604080517f1b6b6d230000000000000000000000000000000000000000000000000000000081529051939450911691631b6b6d23916004808201926020929091908290030181865afa158015611877573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061189b9190614fe8565b601280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff929092169190911790555050565b8560005b81811015611ba257600089898381811061190457611904614e9e565b9050602002013590503073ffffffffffffffffffffffffffffffffffffffff16637e7a46dc828360405160200161193d91815260200190565b6040516020818303038152906040526040518363ffffffff1660e01b8152600401611969929190614eec565b600060405180830381600087803b15801561198357600080fd5b505af1158015611997573d6000803e3d6000fd5b50506013546040517f5147cd59000000000000000000000000000000000000000000000000000000008152600481018590526000935073ffffffffffffffffffffffffffffffffffffffff9091169150635147cd5990602401602060405180830381865afa158015611a0d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a319190615005565b90508060ff16600103611b8d576040517ffa333dfb000000000000000000000000000000000000000000000000000000008152306004820181905260ff8b166024830152604482018a9052606482018890526084820188905260a4820187905260009163fa333dfb9060c401600060405180830381865afa158015611aba573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611b009190810190614f52565b6013546040517f4ee88d3500000000000000000000000000000000000000000000000000000000815291925073ffffffffffffffffffffffffffffffffffffffff1690634ee88d3590611b599086908590600401614eec565b600060405180830381600087803b158015611b7357600080fd5b505af1158015611b87573d6000803e3d6000fd5b50505050505b50508080611b9a90615022565b9150506118e8565b505050505050505050565b6000838152600c602090815260408083208054825181850281018501909352808352611c0e93830182828015611c0257602002820191906000526020600020905b815481526020019060010190808311611bee575b50505050508484613b38565b90505b9392505050565b604080516101408101825260008082526020820181905260609282018390528282018190526080820181905260a0820181905260c0820181905260e082018190526101008201526101208101919091526013546040517fc7c3a19a0000000000000000000000000000000000000000000000000000000081526004810184905273ffffffffffffffffffffffffffffffffffffffff9091169063c7c3a19a90602401600060405180830381865afa158015611cd7573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611467919081019061507d565b8060005b818160ff161015611df85760135473ffffffffffffffffffffffffffffffffffffffff1663c8048022858560ff8516818110611d5f57611d5f614e9e565b905060200201356040518263ffffffff1660e01b8152600401611d8491815260200190565b600060405180830381600087803b158015611d9e57600080fd5b505af1158015611db2573d6000803e3d6000fd5b50505050611de584848360ff16818110611dce57611dce614e9e565b90506020020135600f613c9790919063ffffffff16565b5080611df081614ecd565b915050611d21565b50505050565b6000818152600e602052604081205461ffff1681805b8261ffff168161ffff1611611e5f576000858152600d6020908152604080832061ffff85168452909152902054611e4b908361519c565b915080611e57816151af565b915050611e14565b509392505050565b60005a9050600080611e7b84860186614a10565b91509150600081806020019051810190611e9591906151d0565b60008181526005602090815260408083205460049092528220549293509190611ebc613ca3565b905082600003611edc576000848152600560205260409020819055612037565b600084815260036020526040812054611ef584846151e9565b611eff91906151e9565b6000868152600e6020908152604080832054600d835281842061ffff909116808552908352818420805483518186028101860190945280845295965090949192909190830182828015611f7157602002820191906000526020600020905b815481526020019060010190808311611f5d575b505050505090507f000000000000000000000000000000000000000000000000000000000000000061ffff16815103611fec5781611fae816151af565b6000898152600e6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff83161790559250505b506000868152600d6020908152604080832061ffff909416835292815282822080546001818101835591845282842001859055888352600c8252928220805493840181558252902001555b60008481526006602052604081205461205190600161519c565b600086815260066020908152604080832084905560049091529020839055905061207b8583612a6e565b6112d88589846130e3565b6000828152600d6020908152604080832061ffff851684528252918290208054835181840281018401909452808452606093928301828280156120e857602002820191906000526020600020905b8154815260200190600101908083116120d4575b5050505050905092915050565b600060606000848460405160200161210e9291906151fc565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00181529190526001969095509350505050565b6013546040517f5147cd590000000000000000000000000000000000000000000000000000000081526004810183905260009173ffffffffffffffffffffffffffffffffffffffff1690635147cd5990602401602060405180830381865afa1580156121b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114679190615005565b8160005b8181101561227a5730635f17e61686868481811061220157612201614e9e565b90506020020135856040518363ffffffff1660e01b815260040161223592919091825263ffffffff16602082015260400190565b600060405180830381600087803b15801561224f57600080fd5b505af1158015612263573d6000803e3d6000fd5b50505050808061227290615022565b9150506121e1565b5050505050565b612289613d45565b6012546040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156122f8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061231c91906151d0565b6012546040517fa9059cbb0000000000000000000000000000000000000000000000000000000081523360048201526024810183905291925073ffffffffffffffffffffffffffffffffffffffff169063a9059cbb906044016020604051808303816000875af1158015612394573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123b89190614e83565b5050565b60008281526003602090815260408083208490556005825280832083905560068252808320839055600c90915281206123f4916141ca565b6000828152600e602052604081205461ffff16905b8161ffff168161ffff1611612450576000848152600d6020908152604080832061ffff85168452909152812061243e916141ca565b80612448816151af565b915050612409565b5050506000908152600e6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000169055565b6000606060005a905060006124a085870187614558565b60008181526009602090815260408083205460089092528220549293509190838367ffffffffffffffff8111156124d9576124d96142cb565b6040519080825280601f01601f191660200182016040528015612503576020820181803683370190505b50604051602001612515929190614eec565b60405160208183030381529060405290506000612530613ca3565b9050600061253d866126b2565b90505b835a61254c90896151e9565b6125589061271061519c565b10156125995781406000908152600b6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055612540565b806125b15760008398509850505050505050506116bb565b6040517f6665656449644865780000000000000000000000000000000000000000000000602082015260009060290160405160208183030381529060405280519060200120601760405160200161260891906152e3565b604051602081830303815290604052805190602001200361262a57508161262d565b50425b601760166018838a60405160200161264791815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527ff055e4a20000000000000000000000000000000000000000000000000000000082526126a99594939291600401615412565b60405180910390fd5b60008181526005602052604081205481036126cf57506001919050565b6000828152600360209081526040808320546004909252909120546126f2613ca3565b6126fc91906151e9565b101592915050565b60015473ffffffffffffffffffffffffffffffffffffffff163314612785576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016126a9565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6013546040517f79ea99430000000000000000000000000000000000000000000000000000000081526004810183905260009173ffffffffffffffffffffffffffffffffffffffff16906379ea994390602401602060405180830381865afa158015612871573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114679190614fe8565b6013546040517fcd7f71b500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063cd7f71b5906128ef908690869086906004016154d5565b600060405180830381600087803b15801561290957600080fd5b505af115801561291d573d6000803e3d6000fd5b50505050505050565b6013546040517f4ee88d3500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911690634ee88d35906128ef908690869086906004016154d5565b601761298c838261556f565b506018612999828261556f565b505050565b80516123b89060169060208401906141e8565b6013546040517f06e3b632000000000000000000000000000000000000000000000000000000008152600481018490526024810183905260609173ffffffffffffffffffffffffffffffffffffffff16906306e3b63290604401600060405180830381865afa158015612a28573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611c119190810190615689565b601454600083815260026020526040902054612a8a90836151e9565b11156123b8576013546040517fc7c3a19a0000000000000000000000000000000000000000000000000000000081526004810184905260009173ffffffffffffffffffffffffffffffffffffffff169063c7c3a19a90602401600060405180830381865afa158015612b00573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052612b46919081019061507d565b6013546040517fb657bc9c0000000000000000000000000000000000000000000000000000000081526004810186905291925060009173ffffffffffffffffffffffffffffffffffffffff9091169063b657bc9c90602401602060405180830381865afa158015612bbb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bdf9190614f92565b601554909150612c039082906c01000000000000000000000000900460ff16614e3f565b6bffffffffffffffffffffffff1682606001516bffffffffffffffffffffffff161015611df857601554612c469085906bffffffffffffffffffffffff16612cb3565b60008481526002602090815260409182902085905560155482518781526bffffffffffffffffffffffff909116918101919091529081018490527f49d4100ab0124eb4a9a65dc4ea08d6412a43f6f05c49194983f5b322bcc0a5c09060600160405180910390a150505050565b6012546013546040517f095ea7b300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff91821660048201526bffffffffffffffffffffffff8416602482015291169063095ea7b3906044016020604051808303816000875af1158015612d3b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d5f9190614e83565b506013546040517f948108f7000000000000000000000000000000000000000000000000000000008152600481018490526bffffffffffffffffffffffff8316602482015273ffffffffffffffffffffffffffffffffffffffff9091169063948108f79060440161137a565b6040517fc04198220000000000000000000000000000000000000000000000000000000081526000600482018190526024820181905290309063c041982290604401600060405180830381865afa158015612e2a573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052612e709190810190615689565b80519091506000612e7f613ca3565b905060005b8281101561227a576000848281518110612ea057612ea0614e9e565b60209081029190910101516013546040517f5147cd590000000000000000000000000000000000000000000000000000000081526004810183905291925060009173ffffffffffffffffffffffffffffffffffffffff90911690635147cd5990602401602060405180830381865afa158015612f20573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f449190615005565b90508060ff16600103612fc0578660ff16600003612f90576040513090859084907f97009585a4d2440f981ab6f6eec514343e1e6b2aa9b991a26998e6806f41bf0890600090a4612fc0565b6040513090859084907fc76416badc8398ce17c93eab7b4f60f263241694cf503e4df24f233a8cc1c50d90600090a45b50508080612fcd90615022565b915050612e84565b6000818152600c602090815260409182902080548351818402810184019094528084526060939283018282801561302b57602002820191906000526020600020905b815481526020019060010190808311613017575b50505050509050919050565b6016818154811061304757600080fd5b90600052602060002001600091509050805461306290615290565b80601f016020809104026020016040519081016040528092919081815260200182805461308e90615290565b80156130db5780601f106130b0576101008083540402835291602001916130db565b820191906000526020600020905b8154815290600101906020018083116130be57829003601f168201915b505050505081565b6000838152600760205260409020545b805a6130ff90856151e9565b61310b9061271061519c565b1015611df85781406000908152600b6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690556130f3565b6013546040517fa72aa27e0000000000000000000000000000000000000000000000000000000081526004810184905263ffffffff8316602482015273ffffffffffffffffffffffffffffffffffffffff9091169063a72aa27e90604401600060405180830381600087803b1580156131c457600080fd5b505af11580156131d8573d6000803e3d6000fd5b505050600092835250600a602052604090912063ffffffff9091169055565b6013546040517f744bfe610000000000000000000000000000000000000000000000000000000081526004810183905230602482015273ffffffffffffffffffffffffffffffffffffffff9091169063744bfe6190604401600060405180830381600087803b15801561326957600080fd5b505af115801561227a573d6000803e3d6000fd5b6017805461306290615290565b6013546040517fb657bc9c0000000000000000000000000000000000000000000000000000000081526004810183905260009173ffffffffffffffffffffffffffffffffffffffff169063b657bc9c906024016115fe565b8060005b818163ffffffff161015611df8573063af953a4a858563ffffffff851681811061331257613312614e9e565b905060200201356040518263ffffffff1660e01b815260040161333791815260200190565b600060405180830381600087803b15801561335157600080fd5b505af1158015613365573d6000803e3d6000fd5b5050505080806133749061571a565b9150506132e6565b6060600061338a600f613dc8565b90508084106133c5576040517f1390f2a100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b826000036133da576133d784826151e9565b92505b60008367ffffffffffffffff8111156133f5576133f56142cb565b60405190808252806020026020018201604052801561341e578160200160208202803683370190505b50905060005b8481101561347057613441613439828861519c565b600f90613dd2565b82828151811061345357613453614e9e565b60209081029190910101528061346881615022565b915050613424565b50949350505050565b6018805461306290615290565b6000613490613ca3565b90508160ff166000036134d1576040513090829085907f97009585a4d2440f981ab6f6eec514343e1e6b2aa9b991a26998e6806f41bf0890600090a4505050565b6040513090829085907fc76416badc8398ce17c93eab7b4f60f263241694cf503e4df24f233a8cc1c50d90600090a4505050565b6000828152600c6020908152604080832080548251818502810185019093528083528493849392919083018282801561355d57602002820191906000526020600020905b815481526020019060010190808311613549575b505050505090506116b58185613ab3565b8260005b818110156113a857600086868381811061358e5761358e614e9e565b9050602002013590503073ffffffffffffffffffffffffffffffffffffffff16637e7a46dc82836040516020016135c791815260200190565b6040516020818303038152906040526040518363ffffffff1660e01b81526004016135f3929190614eec565b600060405180830381600087803b15801561360d57600080fd5b505af1158015613621573d6000803e3d6000fd5b50506013546040517f5147cd59000000000000000000000000000000000000000000000000000000008152600481018590526000935073ffffffffffffffffffffffffffffffffffffffff9091169150635147cd5990602401602060405180830381865afa158015613697573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136bb9190615005565b90508060ff166001036138c0577f000000000000000000000000000000000000000000000000000000000000000060ff87161561371557507f00000000000000000000000000000000000000000000000000000000000000005b60003073ffffffffffffffffffffffffffffffffffffffff1663fa333dfb3089858860405160200161374991815260200190565b60405160208183030381529060405261376190615733565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff909416600485015260ff90921660248401526044830152606482015260006084820181905260a482015260c401600060405180830381865afa1580156137ec573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526138329190810190614f52565b6013546040517f4ee88d3500000000000000000000000000000000000000000000000000000000815291925073ffffffffffffffffffffffffffffffffffffffff1690634ee88d359061388b9087908590600401614eec565b600060405180830381600087803b1580156138a557600080fd5b505af11580156138b9573d6000803e3d6000fd5b5050505050505b505080806138cd90615022565b915050613572565b8060005b81811015611df85760008484838181106138f5576138f5614e9e565b9050602002013590503073ffffffffffffffffffffffffffffffffffffffff16637e7a46dc828360405160200161392e91815260200190565b6040516020818303038152906040526040518363ffffffff1660e01b815260040161395a929190614eec565b600060405180830381600087803b15801561397457600080fd5b505af1158015613988573d6000803e3d6000fd5b5050505050808061399890615022565b9150506138d9565b600c60205281600052604060002081815481106139bc57600080fd5b90600052602060002001600091509150505481565b6139d9613d45565b6139e281613dde565b50565b6011546040517f3f678e11000000000000000000000000000000000000000000000000000000008152600091829173ffffffffffffffffffffffffffffffffffffffff90911690633f678e1190613a40908690600401615775565b6020604051808303816000875af1158015613a5f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a8391906151d0565b9050613a90600f82613ed3565b506060909201516000838152600a6020526040902063ffffffff90911690555090565b815160009081908190841580613ac95750808510155b15613ad2578094505b60008092505b85831015613b2e57866001613aed85856151e9565b613af791906151e9565b81518110613b0757613b07614e9e565b602002602001015181613b1a919061519c565b905082613b2681615022565b935050613ad8565b9694955050505050565b82516000908190831580613b4c5750808410155b15613b55578093505b60008467ffffffffffffffff811115613b7057613b706142cb565b604051908082528060200260200182016040528015613b99578160200160208202803683370190505b509050600092505b84831015613c0757866001613bb685856151e9565b613bc091906151e9565b81518110613bd057613bd0614e9e565b6020026020010151818481518110613bea57613bea614e9e565b602090810291909101015282613bff81615022565b935050613ba1565b613c2081600060018451613c1b91906151e9565b613edf565b85606403613c59578060018251613c3791906151e9565b81518110613c4757613c47614e9e565b60200260200101519350505050611c11565b806064825188613c6991906158c7565b613c739190615933565b81518110613c8357613c83614e9e565b602002602001015193505050509392505050565b6000611c118383614057565b60007f000000000000000000000000000000000000000000000000000000000000000015613d4057606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613d17573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613d3b91906151d0565b905090565b504390565b60005473ffffffffffffffffffffffffffffffffffffffff163314613dc6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016126a9565b565b6000611467825490565b6000611c118383614151565b3373ffffffffffffffffffffffffffffffffffffffff821603613e5d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016126a9565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000611c11838361417b565b8181808203613eef575050505050565b6000856002613efe8787615947565b613f089190615967565b613f1290876159cf565b81518110613f2257613f22614e9e565b602002602001015190505b818313614031575b80868481518110613f4857613f48614e9e565b60200260200101511015613f685782613f60816159f7565b935050613f35565b858281518110613f7a57613f7a614e9e565b6020026020010151811015613f9b5781613f9381615a28565b925050613f68565b81831361402c57858281518110613fb457613fb4614e9e565b6020026020010151868481518110613fce57613fce614e9e565b6020026020010151878581518110613fe857613fe8614e9e565b6020026020010188858151811061400157614001614e9e565b6020908102919091010191909152528261401a816159f7565b935050818061402890615a28565b9250505b613f2d565b8185121561404457614044868684613edf565b838312156113a8576113a8868486613edf565b6000818152600183016020526040812054801561414057600061407b6001836151e9565b855490915060009061408f906001906151e9565b90508181146140f45760008660000182815481106140af576140af614e9e565b90600052602060002001549050808760000184815481106140d2576140d2614e9e565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061410557614105615a7f565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050611467565b6000915050611467565b5092915050565b600082600001828154811061416857614168614e9e565b9060005260206000200154905092915050565b60008181526001830160205260408120546141c257508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155611467565b506000611467565b50805460008255906000526020600020908101906139e2919061423e565b82805482825590600052602060002090810192821561422e579160200282015b8281111561422e578251829061421e908261556f565b5091602001919060010190614208565b5061423a929150614253565b5090565b5b8082111561423a576000815560010161423f565b8082111561423a5760006142678282614270565b50600101614253565b50805461427c90615290565b6000825580601f1061428c575050565b601f0160209004906000526020600020908101906139e2919061423e565b60ff811681146139e257600080fd5b63ffffffff811681146139e257600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff8111828210171561431e5761431e6142cb565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561436b5761436b6142cb565b604052919050565b600067ffffffffffffffff82111561438d5761438d6142cb565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f8301126143ca57600080fd5b81356143dd6143d882614373565b614324565b8181528460208386010111156143f257600080fd5b816020850160208301376000918101602001919091529392505050565b6bffffffffffffffffffffffff811681146139e257600080fd5b600080600080600080600060e0888a03121561444457600080fd5b873561444f816142aa565b9650602088013561445f816142b9565b9550604088013561446f816142aa565b9450606088013567ffffffffffffffff81111561448b57600080fd5b6144978a828b016143b9565b94505060808801356144a88161440f565b9699959850939692959460a0840135945060c09093013592915050565b803561ffff811681146144d757600080fd5b919050565b6000806000606084860312156144f157600080fd5b83359250614501602085016144c5565b9150604084013590509250925092565b6000806040838503121561452457600080fd5b82359150602083013567ffffffffffffffff81111561454257600080fd5b61454e858286016143b9565b9150509250929050565b60006020828403121561456a57600080fd5b5035919050565b60005b8381101561458c578181015183820152602001614574565b50506000910152565b600081518084526145ad816020860160208601614571565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611c116020830184614595565b73ffffffffffffffffffffffffffffffffffffffff811681146139e257600080fd5b600080600080600080600060e0888a03121561462f57600080fd5b873596506020880135614641816145f2565b95506040880135614651816142aa565b969995985095966060810135965060808101359560a0820135955060c0909101359350915050565b6000806040838503121561468c57600080fd5b8235915061469c602084016144c5565b90509250929050565b6000602082840312156146b757600080fd5b8135611c11816145f2565b60008083601f8401126146d457600080fd5b50813567ffffffffffffffff8111156146ec57600080fd5b6020830191508360208260051b85010111156116bb57600080fd5b600080600080600080600060c0888a03121561472257600080fd5b873567ffffffffffffffff81111561473957600080fd5b6147458a828b016146c2565b9098509650506020880135614759816142aa565b96999598509596604081013596506060810135956080820135955060a0909101359350915050565b60008060006060848603121561479657600080fd5b505081359360208301359350604090920135919050565b602081526147d460208201835173ffffffffffffffffffffffffffffffffffffffff169052565b600060208301516147ed604084018263ffffffff169052565b50604083015161014080606085015261480a610160850183614595565b9150606085015161482b60808601826bffffffffffffffffffffffff169052565b50608085015173ffffffffffffffffffffffffffffffffffffffff811660a08601525060a085015167ffffffffffffffff811660c08601525060c085015163ffffffff811660e08601525060e0850151610100614897818701836bffffffffffffffffffffffff169052565b86015190506101206148ac8682018315159052565b8601518584037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0018387015290506148e48382614595565b9695505050505050565b6000806020838503121561490157600080fd5b823567ffffffffffffffff81111561491857600080fd5b614924858286016146c2565b90969095509350505050565b60008083601f84011261494257600080fd5b50813567ffffffffffffffff81111561495a57600080fd5b6020830191508360208285010111156116bb57600080fd5b6000806020838503121561498557600080fd5b823567ffffffffffffffff81111561499c57600080fd5b61492485828601614930565b6020808252825182820181905260009190848201906040850190845b818110156149e0578351835292840192918401916001016149c4565b50909695505050505050565b600067ffffffffffffffff821115614a0657614a066142cb565b5060051b60200190565b60008060408385031215614a2357600080fd5b823567ffffffffffffffff80821115614a3b57600080fd5b818501915085601f830112614a4f57600080fd5b81356020614a5f6143d8836149ec565b82815260059290921b84018101918181019089841115614a7e57600080fd5b8286015b84811015614ab657803586811115614a9a5760008081fd5b614aa88c86838b01016143b9565b845250918301918301614a82565b5096505086013592505080821115614acd57600080fd5b5061454e858286016143b9565b8215158152604060208201526000611c0e6040830184614595565b600080600060408486031215614b0a57600080fd5b833567ffffffffffffffff811115614b2157600080fd5b614b2d868287016146c2565b9094509250506020840135614b41816142b9565b809150509250925092565b60008060408385031215614b5f57600080fd5b50508035926020909101359150565b600080600060408486031215614b8357600080fd5b83359250602084013567ffffffffffffffff811115614ba157600080fd5b614bad86828701614930565b9497909650939450505050565b60008060408385031215614bcd57600080fd5b823567ffffffffffffffff80821115614be557600080fd5b614bf1868387016143b9565b93506020850135915080821115614acd57600080fd5b60006020808385031215614c1a57600080fd5b823567ffffffffffffffff80821115614c3257600080fd5b818501915085601f830112614c4657600080fd5b8135614c546143d8826149ec565b81815260059190911b83018401908481019088831115614c7357600080fd5b8585015b83811015614cab57803585811115614c8f5760008081fd5b614c9d8b89838a01016143b9565b845250918601918601614c77565b5098975050505050505050565b60008060408385031215614ccb57600080fd5b823591506020830135614cdd8161440f565b809150509250929050565b600060208284031215614cfa57600080fd5b8135611c11816142aa565b60008060408385031215614d1857600080fd5b823591506020830135614cdd816142b9565b60008060408385031215614d3d57600080fd5b823591506020830135614cdd816142aa565b60008060008060608587031215614d6557600080fd5b843567ffffffffffffffff811115614d7c57600080fd5b614d88878288016146c2565b9095509350506020850135614d9c816142aa565b91506040850135614dac816142aa565b939692955090935050565b60008060008060008060c08789031215614dd057600080fd5b8635614ddb816145f2565b95506020870135614deb816142aa565b95989597505050506040840135936060810135936080820135935060a0909101359150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006bffffffffffffffffffffffff80831681851681830481118215151615614e6a57614e6a614e10565b02949350505050565b805180151581146144d757600080fd5b600060208284031215614e9557600080fd5b611c1182614e73565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff821660ff8103614ee357614ee3614e10565b60010192915050565b828152604060208201526000611c0e6040830184614595565b600082601f830112614f1657600080fd5b8151614f246143d882614373565b818152846020838601011115614f3957600080fd5b614f4a826020830160208701614571565b949350505050565b600060208284031215614f6457600080fd5b815167ffffffffffffffff811115614f7b57600080fd5b614f4a84828501614f05565b80516144d78161440f565b600060208284031215614fa457600080fd5b8151611c118161440f565b80516144d7816145f2565b60008060408385031215614fcd57600080fd5b8251614fd8816145f2565b6020939093015192949293505050565b600060208284031215614ffa57600080fd5b8151611c11816145f2565b60006020828403121561501757600080fd5b8151611c11816142aa565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361505357615053614e10565b5060010190565b80516144d7816142b9565b805167ffffffffffffffff811681146144d757600080fd5b60006020828403121561508f57600080fd5b815167ffffffffffffffff808211156150a757600080fd5b9083019061014082860312156150bc57600080fd5b6150c46142fa565b6150cd83614faf565b81526150db6020840161505a565b60208201526040830151828111156150f257600080fd5b6150fe87828601614f05565b60408301525061511060608401614f87565b606082015261512160808401614faf565b608082015261513260a08401615065565b60a082015261514360c0840161505a565b60c082015261515460e08401614f87565b60e0820152610100615167818501614e73565b90820152610120838101518381111561517f57600080fd5b61518b88828701614f05565b918301919091525095945050505050565b8082018082111561146757611467614e10565b600061ffff8083168181036151c6576151c6614e10565b6001019392505050565b6000602082840312156151e257600080fd5b5051919050565b8181038181111561146757611467614e10565b6000604082016040835280855180835260608501915060608160051b8601019250602080880160005b83811015615271577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa088870301855261525f868351614595565b95509382019390820190600101615225565b5050858403818701525050506152878185614595565b95945050505050565b600181811c908216806152a457607f821691505b6020821081036152dd577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b60008083546152f181615290565b60018281168015615309576001811461533c5761536b565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008416875282151583028701945061536b565b8760005260208060002060005b858110156153625781548a820152908401908201615349565b50505082870194505b50929695505050505050565b6000815461538481615290565b8085526020600183811680156153a157600181146153d957615407565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008516838901528284151560051b8901019550615407565b866000528260002060005b858110156153ff5781548a82018601529083019084016153e4565b890184019650505b505050505092915050565b60a08152600061542560a0830188615377565b6020838203818501528188548084528284019150828160051b8501018a6000528360002060005b83811015615497577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08784030185526154858383615377565b9486019492506001918201910161544c565b505086810360408801526154ab818b615377565b94505050505084606084015282810360808401526154c98185614595565b98975050505050505050565b83815260406020820152816040820152818360608301376000818301606090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016010192915050565b601f82111561299957600081815260208120601f850160051c810160208610156155505750805b601f850160051c820191505b818110156113a85782815560010161555c565b815167ffffffffffffffff811115615589576155896142cb565b61559d816155978454615290565b84615529565b602080601f8311600181146155f057600084156155ba5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556113a8565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561563d5788860151825594840194600190910190840161561e565b508582101561567957878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b6000602080838503121561569c57600080fd5b825167ffffffffffffffff8111156156b357600080fd5b8301601f810185136156c457600080fd5b80516156d26143d8826149ec565b81815260059190911b820183019083810190878311156156f157600080fd5b928401925b8284101561570f578351825292840192908401906156f6565b979650505050505050565b600063ffffffff8083168181036151c6576151c6614e10565b805160208083015191908110156152dd577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60209190910360031b1b16919050565b6020815260008251610140806020850152615794610160850183614595565b915060208501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0808685030160408701526157d08483614595565b9350604087015191506157fb606087018373ffffffffffffffffffffffffffffffffffffffff169052565b606087015163ffffffff811660808801529150608087015173ffffffffffffffffffffffffffffffffffffffff811660a0880152915060a087015160ff811660c0880152915060c08701519150808685030160e087015261585c8483614595565b935060e0870151915061010081878603018188015261587b8584614595565b94508088015192505061012081878603018188015261589a8584614595565b945080880151925050506158bd828601826bffffffffffffffffffffffff169052565b5090949350505050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156158ff576158ff614e10565b500290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261594257615942615904565b500490565b818103600083128015838313168383128216171561414a5761414a614e10565b60008261597657615976615904565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f8000000000000000000000000000000000000000000000000000000000000000831416156159ca576159ca614e10565b500590565b80820182811260008312801582168215821617156159ef576159ef614e10565b505092915050565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361505357615053614e10565b60007f80000000000000000000000000000000000000000000000000000000000000008203615a5957615a59614e10565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000810000a307834353534343832643535353334343264343135323432343935343532353534643264353434353533353434653435353430303030303030303030303030303030307834323534343332643535353334343264343135323432343935343532353534643264353434353533353434653435353430303030303030303030303030303030",
+}
+
+var VerifiableLoadStreamsLookupUpkeepABI = VerifiableLoadStreamsLookupUpkeepMetaData.ABI
+
+var VerifiableLoadStreamsLookupUpkeepBin = VerifiableLoadStreamsLookupUpkeepMetaData.Bin
+
+func DeployVerifiableLoadStreamsLookupUpkeep(auth *bind.TransactOpts, backend bind.ContractBackend, _registrar common.Address, _useArb bool) (common.Address, *types.Transaction, *VerifiableLoadStreamsLookupUpkeep, error) {
+ parsed, err := VerifiableLoadStreamsLookupUpkeepMetaData.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(VerifiableLoadStreamsLookupUpkeepBin), backend, _registrar, _useArb)
+ if err != nil {
+ return common.Address{}, nil, nil, err
+ }
+ return address, tx, &VerifiableLoadStreamsLookupUpkeep{VerifiableLoadStreamsLookupUpkeepCaller: VerifiableLoadStreamsLookupUpkeepCaller{contract: contract}, VerifiableLoadStreamsLookupUpkeepTransactor: VerifiableLoadStreamsLookupUpkeepTransactor{contract: contract}, VerifiableLoadStreamsLookupUpkeepFilterer: VerifiableLoadStreamsLookupUpkeepFilterer{contract: contract}}, nil
+}
+
+type VerifiableLoadStreamsLookupUpkeep struct {
+ address common.Address
+ abi abi.ABI
+ VerifiableLoadStreamsLookupUpkeepCaller
+ VerifiableLoadStreamsLookupUpkeepTransactor
+ VerifiableLoadStreamsLookupUpkeepFilterer
+}
+
+type VerifiableLoadStreamsLookupUpkeepCaller struct {
+ contract *bind.BoundContract
+}
+
+type VerifiableLoadStreamsLookupUpkeepTransactor struct {
+ contract *bind.BoundContract
+}
+
+type VerifiableLoadStreamsLookupUpkeepFilterer struct {
+ contract *bind.BoundContract
+}
+
+type VerifiableLoadStreamsLookupUpkeepSession struct {
+ Contract *VerifiableLoadStreamsLookupUpkeep
+ CallOpts bind.CallOpts
+ TransactOpts bind.TransactOpts
+}
+
+type VerifiableLoadStreamsLookupUpkeepCallerSession struct {
+ Contract *VerifiableLoadStreamsLookupUpkeepCaller
+ CallOpts bind.CallOpts
+}
+
+type VerifiableLoadStreamsLookupUpkeepTransactorSession struct {
+ Contract *VerifiableLoadStreamsLookupUpkeepTransactor
+ TransactOpts bind.TransactOpts
+}
+
+type VerifiableLoadStreamsLookupUpkeepRaw struct {
+ Contract *VerifiableLoadStreamsLookupUpkeep
+}
+
+type VerifiableLoadStreamsLookupUpkeepCallerRaw struct {
+ Contract *VerifiableLoadStreamsLookupUpkeepCaller
+}
+
+type VerifiableLoadStreamsLookupUpkeepTransactorRaw struct {
+ Contract *VerifiableLoadStreamsLookupUpkeepTransactor
+}
+
+func NewVerifiableLoadStreamsLookupUpkeep(address common.Address, backend bind.ContractBackend) (*VerifiableLoadStreamsLookupUpkeep, error) {
+ abi, err := abi.JSON(strings.NewReader(VerifiableLoadStreamsLookupUpkeepABI))
+ if err != nil {
+ return nil, err
+ }
+ contract, err := bindVerifiableLoadStreamsLookupUpkeep(address, backend, backend, backend)
+ if err != nil {
+ return nil, err
+ }
+ return &VerifiableLoadStreamsLookupUpkeep{address: address, abi: abi, VerifiableLoadStreamsLookupUpkeepCaller: VerifiableLoadStreamsLookupUpkeepCaller{contract: contract}, VerifiableLoadStreamsLookupUpkeepTransactor: VerifiableLoadStreamsLookupUpkeepTransactor{contract: contract}, VerifiableLoadStreamsLookupUpkeepFilterer: VerifiableLoadStreamsLookupUpkeepFilterer{contract: contract}}, nil
+}
+
+func NewVerifiableLoadStreamsLookupUpkeepCaller(address common.Address, caller bind.ContractCaller) (*VerifiableLoadStreamsLookupUpkeepCaller, error) {
+ contract, err := bindVerifiableLoadStreamsLookupUpkeep(address, caller, nil, nil)
+ if err != nil {
+ return nil, err
+ }
+ return &VerifiableLoadStreamsLookupUpkeepCaller{contract: contract}, nil
+}
+
+func NewVerifiableLoadStreamsLookupUpkeepTransactor(address common.Address, transactor bind.ContractTransactor) (*VerifiableLoadStreamsLookupUpkeepTransactor, error) {
+ contract, err := bindVerifiableLoadStreamsLookupUpkeep(address, nil, transactor, nil)
+ if err != nil {
+ return nil, err
+ }
+ return &VerifiableLoadStreamsLookupUpkeepTransactor{contract: contract}, nil
+}
+
+func NewVerifiableLoadStreamsLookupUpkeepFilterer(address common.Address, filterer bind.ContractFilterer) (*VerifiableLoadStreamsLookupUpkeepFilterer, error) {
+ contract, err := bindVerifiableLoadStreamsLookupUpkeep(address, nil, nil, filterer)
+ if err != nil {
+ return nil, err
+ }
+ return &VerifiableLoadStreamsLookupUpkeepFilterer{contract: contract}, nil
+}
+
+func bindVerifiableLoadStreamsLookupUpkeep(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) {
+ parsed, err := VerifiableLoadStreamsLookupUpkeepMetaData.GetAbi()
+ if err != nil {
+ return nil, err
+ }
+ return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.VerifiableLoadStreamsLookupUpkeepCaller.contract.Call(opts, result, method, params...)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.VerifiableLoadStreamsLookupUpkeepTransactor.contract.Transfer(opts)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.VerifiableLoadStreamsLookupUpkeepTransactor.contract.Transact(opts, method, params...)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.contract.Call(opts, result, method, params...)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.contract.Transfer(opts)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.contract.Transact(opts, method, params...)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCaller) BUCKETSIZE(opts *bind.CallOpts) (uint16, error) {
+ var out []interface{}
+ err := _VerifiableLoadStreamsLookupUpkeep.contract.Call(opts, &out, "BUCKET_SIZE")
+
+ if err != nil {
+ return *new(uint16), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(uint16)).(*uint16)
+
+ return out0, err
+
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) BUCKETSIZE() (uint16, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.BUCKETSIZE(&_VerifiableLoadStreamsLookupUpkeep.CallOpts)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCallerSession) BUCKETSIZE() (uint16, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.BUCKETSIZE(&_VerifiableLoadStreamsLookupUpkeep.CallOpts)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCaller) AddLinkAmount(opts *bind.CallOpts) (*big.Int, error) {
+ var out []interface{}
+ err := _VerifiableLoadStreamsLookupUpkeep.contract.Call(opts, &out, "addLinkAmount")
+
+ if err != nil {
+ return *new(*big.Int), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
+
+ return out0, err
+
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) AddLinkAmount() (*big.Int, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.AddLinkAmount(&_VerifiableLoadStreamsLookupUpkeep.CallOpts)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCallerSession) AddLinkAmount() (*big.Int, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.AddLinkAmount(&_VerifiableLoadStreamsLookupUpkeep.CallOpts)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCaller) BucketedDelays(opts *bind.CallOpts, arg0 *big.Int, arg1 uint16, arg2 *big.Int) (*big.Int, error) {
+ var out []interface{}
+ err := _VerifiableLoadStreamsLookupUpkeep.contract.Call(opts, &out, "bucketedDelays", arg0, arg1, arg2)
+
+ if err != nil {
+ return *new(*big.Int), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
+
+ return out0, err
+
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) BucketedDelays(arg0 *big.Int, arg1 uint16, arg2 *big.Int) (*big.Int, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.BucketedDelays(&_VerifiableLoadStreamsLookupUpkeep.CallOpts, arg0, arg1, arg2)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCallerSession) BucketedDelays(arg0 *big.Int, arg1 uint16, arg2 *big.Int) (*big.Int, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.BucketedDelays(&_VerifiableLoadStreamsLookupUpkeep.CallOpts, arg0, arg1, arg2)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCaller) Buckets(opts *bind.CallOpts, arg0 *big.Int) (uint16, error) {
+ var out []interface{}
+ err := _VerifiableLoadStreamsLookupUpkeep.contract.Call(opts, &out, "buckets", arg0)
+
+ if err != nil {
+ return *new(uint16), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(uint16)).(*uint16)
+
+ return out0, err
+
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) Buckets(arg0 *big.Int) (uint16, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.Buckets(&_VerifiableLoadStreamsLookupUpkeep.CallOpts, arg0)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCallerSession) Buckets(arg0 *big.Int) (uint16, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.Buckets(&_VerifiableLoadStreamsLookupUpkeep.CallOpts, arg0)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCaller) CheckCallback(opts *bind.CallOpts, values [][]byte, extraData []byte) (bool, []byte, error) {
+ var out []interface{}
+ err := _VerifiableLoadStreamsLookupUpkeep.contract.Call(opts, &out, "checkCallback", values, extraData)
+
+ if err != nil {
+ return *new(bool), *new([]byte), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(bool)).(*bool)
+ out1 := *abi.ConvertType(out[1], new([]byte)).(*[]byte)
+
+ return out0, out1, err
+
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) CheckCallback(values [][]byte, extraData []byte) (bool, []byte, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.CheckCallback(&_VerifiableLoadStreamsLookupUpkeep.CallOpts, values, extraData)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCallerSession) CheckCallback(values [][]byte, extraData []byte) (bool, []byte, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.CheckCallback(&_VerifiableLoadStreamsLookupUpkeep.CallOpts, values, extraData)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCaller) CheckGasToBurns(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) {
+ var out []interface{}
+ err := _VerifiableLoadStreamsLookupUpkeep.contract.Call(opts, &out, "checkGasToBurns", arg0)
+
+ if err != nil {
+ return *new(*big.Int), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
+
+ return out0, err
+
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) CheckGasToBurns(arg0 *big.Int) (*big.Int, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.CheckGasToBurns(&_VerifiableLoadStreamsLookupUpkeep.CallOpts, arg0)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCallerSession) CheckGasToBurns(arg0 *big.Int) (*big.Int, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.CheckGasToBurns(&_VerifiableLoadStreamsLookupUpkeep.CallOpts, arg0)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCaller) Counters(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) {
+ var out []interface{}
+ err := _VerifiableLoadStreamsLookupUpkeep.contract.Call(opts, &out, "counters", arg0)
+
+ if err != nil {
+ return *new(*big.Int), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
+
+ return out0, err
+
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) Counters(arg0 *big.Int) (*big.Int, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.Counters(&_VerifiableLoadStreamsLookupUpkeep.CallOpts, arg0)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCallerSession) Counters(arg0 *big.Int) (*big.Int, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.Counters(&_VerifiableLoadStreamsLookupUpkeep.CallOpts, arg0)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCaller) Delays(opts *bind.CallOpts, arg0 *big.Int, arg1 *big.Int) (*big.Int, error) {
+ var out []interface{}
+ err := _VerifiableLoadStreamsLookupUpkeep.contract.Call(opts, &out, "delays", arg0, arg1)
+
+ if err != nil {
+ return *new(*big.Int), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
+
+ return out0, err
+
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) Delays(arg0 *big.Int, arg1 *big.Int) (*big.Int, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.Delays(&_VerifiableLoadStreamsLookupUpkeep.CallOpts, arg0, arg1)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCallerSession) Delays(arg0 *big.Int, arg1 *big.Int) (*big.Int, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.Delays(&_VerifiableLoadStreamsLookupUpkeep.CallOpts, arg0, arg1)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCaller) DummyMap(opts *bind.CallOpts, arg0 [32]byte) (bool, error) {
+ var out []interface{}
+ err := _VerifiableLoadStreamsLookupUpkeep.contract.Call(opts, &out, "dummyMap", arg0)
+
+ if err != nil {
+ return *new(bool), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(bool)).(*bool)
+
+ return out0, err
+
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) DummyMap(arg0 [32]byte) (bool, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.DummyMap(&_VerifiableLoadStreamsLookupUpkeep.CallOpts, arg0)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCallerSession) DummyMap(arg0 [32]byte) (bool, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.DummyMap(&_VerifiableLoadStreamsLookupUpkeep.CallOpts, arg0)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCaller) Eligible(opts *bind.CallOpts, upkeepId *big.Int) (bool, error) {
+ var out []interface{}
+ err := _VerifiableLoadStreamsLookupUpkeep.contract.Call(opts, &out, "eligible", upkeepId)
+
+ if err != nil {
+ return *new(bool), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(bool)).(*bool)
+
+ return out0, err
+
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) Eligible(upkeepId *big.Int) (bool, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.Eligible(&_VerifiableLoadStreamsLookupUpkeep.CallOpts, upkeepId)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCallerSession) Eligible(upkeepId *big.Int) (bool, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.Eligible(&_VerifiableLoadStreamsLookupUpkeep.CallOpts, upkeepId)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCaller) EmittedAgainSig(opts *bind.CallOpts) ([32]byte, error) {
+ var out []interface{}
+ err := _VerifiableLoadStreamsLookupUpkeep.contract.Call(opts, &out, "emittedAgainSig")
+
+ if err != nil {
+ return *new([32]byte), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte)
+
+ return out0, err
+
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) EmittedAgainSig() ([32]byte, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.EmittedAgainSig(&_VerifiableLoadStreamsLookupUpkeep.CallOpts)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCallerSession) EmittedAgainSig() ([32]byte, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.EmittedAgainSig(&_VerifiableLoadStreamsLookupUpkeep.CallOpts)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCaller) EmittedSig(opts *bind.CallOpts) ([32]byte, error) {
+ var out []interface{}
+ err := _VerifiableLoadStreamsLookupUpkeep.contract.Call(opts, &out, "emittedSig")
+
+ if err != nil {
+ return *new([32]byte), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte)
+
+ return out0, err
+
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) EmittedSig() ([32]byte, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.EmittedSig(&_VerifiableLoadStreamsLookupUpkeep.CallOpts)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCallerSession) EmittedSig() ([32]byte, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.EmittedSig(&_VerifiableLoadStreamsLookupUpkeep.CallOpts)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCaller) FeedParamKey(opts *bind.CallOpts) (string, error) {
+ var out []interface{}
+ err := _VerifiableLoadStreamsLookupUpkeep.contract.Call(opts, &out, "feedParamKey")
+
+ if err != nil {
+ return *new(string), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(string)).(*string)
+
+ return out0, err
+
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) FeedParamKey() (string, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.FeedParamKey(&_VerifiableLoadStreamsLookupUpkeep.CallOpts)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCallerSession) FeedParamKey() (string, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.FeedParamKey(&_VerifiableLoadStreamsLookupUpkeep.CallOpts)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCaller) FeedsHex(opts *bind.CallOpts, arg0 *big.Int) (string, error) {
+ var out []interface{}
+ err := _VerifiableLoadStreamsLookupUpkeep.contract.Call(opts, &out, "feedsHex", arg0)
+
+ if err != nil {
+ return *new(string), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(string)).(*string)
+
+ return out0, err
+
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) FeedsHex(arg0 *big.Int) (string, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.FeedsHex(&_VerifiableLoadStreamsLookupUpkeep.CallOpts, arg0)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCallerSession) FeedsHex(arg0 *big.Int) (string, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.FeedsHex(&_VerifiableLoadStreamsLookupUpkeep.CallOpts, arg0)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCaller) FirstPerformBlocks(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) {
+ var out []interface{}
+ err := _VerifiableLoadStreamsLookupUpkeep.contract.Call(opts, &out, "firstPerformBlocks", arg0)
+
+ if err != nil {
+ return *new(*big.Int), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
+
+ return out0, err
+
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) FirstPerformBlocks(arg0 *big.Int) (*big.Int, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.FirstPerformBlocks(&_VerifiableLoadStreamsLookupUpkeep.CallOpts, arg0)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCallerSession) FirstPerformBlocks(arg0 *big.Int) (*big.Int, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.FirstPerformBlocks(&_VerifiableLoadStreamsLookupUpkeep.CallOpts, arg0)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCaller) GasLimits(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) {
+ var out []interface{}
+ err := _VerifiableLoadStreamsLookupUpkeep.contract.Call(opts, &out, "gasLimits", arg0)
+
+ if err != nil {
+ return *new(*big.Int), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
+
+ return out0, err
+
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) GasLimits(arg0 *big.Int) (*big.Int, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.GasLimits(&_VerifiableLoadStreamsLookupUpkeep.CallOpts, arg0)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCallerSession) GasLimits(arg0 *big.Int) (*big.Int, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.GasLimits(&_VerifiableLoadStreamsLookupUpkeep.CallOpts, arg0)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCaller) GetActiveUpkeepIDsDeployedByThisContract(opts *bind.CallOpts, startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error) {
+ var out []interface{}
+ err := _VerifiableLoadStreamsLookupUpkeep.contract.Call(opts, &out, "getActiveUpkeepIDsDeployedByThisContract", startIndex, maxCount)
+
+ if err != nil {
+ return *new([]*big.Int), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new([]*big.Int)).(*[]*big.Int)
+
+ return out0, err
+
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) GetActiveUpkeepIDsDeployedByThisContract(startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.GetActiveUpkeepIDsDeployedByThisContract(&_VerifiableLoadStreamsLookupUpkeep.CallOpts, startIndex, maxCount)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCallerSession) GetActiveUpkeepIDsDeployedByThisContract(startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.GetActiveUpkeepIDsDeployedByThisContract(&_VerifiableLoadStreamsLookupUpkeep.CallOpts, startIndex, maxCount)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCaller) GetAllActiveUpkeepIDsOnRegistry(opts *bind.CallOpts, startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error) {
+ var out []interface{}
+ err := _VerifiableLoadStreamsLookupUpkeep.contract.Call(opts, &out, "getAllActiveUpkeepIDsOnRegistry", startIndex, maxCount)
+
+ if err != nil {
+ return *new([]*big.Int), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new([]*big.Int)).(*[]*big.Int)
+
+ return out0, err
+
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) GetAllActiveUpkeepIDsOnRegistry(startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.GetAllActiveUpkeepIDsOnRegistry(&_VerifiableLoadStreamsLookupUpkeep.CallOpts, startIndex, maxCount)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCallerSession) GetAllActiveUpkeepIDsOnRegistry(startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.GetAllActiveUpkeepIDsOnRegistry(&_VerifiableLoadStreamsLookupUpkeep.CallOpts, startIndex, maxCount)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCaller) GetBalance(opts *bind.CallOpts, id *big.Int) (*big.Int, error) {
+ var out []interface{}
+ err := _VerifiableLoadStreamsLookupUpkeep.contract.Call(opts, &out, "getBalance", id)
+
+ if err != nil {
+ return *new(*big.Int), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
+
+ return out0, err
+
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) GetBalance(id *big.Int) (*big.Int, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.GetBalance(&_VerifiableLoadStreamsLookupUpkeep.CallOpts, id)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCallerSession) GetBalance(id *big.Int) (*big.Int, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.GetBalance(&_VerifiableLoadStreamsLookupUpkeep.CallOpts, id)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCaller) GetBucketedDelays(opts *bind.CallOpts, upkeepId *big.Int, bucket uint16) ([]*big.Int, error) {
+ var out []interface{}
+ err := _VerifiableLoadStreamsLookupUpkeep.contract.Call(opts, &out, "getBucketedDelays", upkeepId, bucket)
+
+ if err != nil {
+ return *new([]*big.Int), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new([]*big.Int)).(*[]*big.Int)
+
+ return out0, err
+
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) GetBucketedDelays(upkeepId *big.Int, bucket uint16) ([]*big.Int, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.GetBucketedDelays(&_VerifiableLoadStreamsLookupUpkeep.CallOpts, upkeepId, bucket)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCallerSession) GetBucketedDelays(upkeepId *big.Int, bucket uint16) ([]*big.Int, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.GetBucketedDelays(&_VerifiableLoadStreamsLookupUpkeep.CallOpts, upkeepId, bucket)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCaller) GetBucketedDelaysLength(opts *bind.CallOpts, upkeepId *big.Int) (*big.Int, error) {
+ var out []interface{}
+ err := _VerifiableLoadStreamsLookupUpkeep.contract.Call(opts, &out, "getBucketedDelaysLength", upkeepId)
+
+ if err != nil {
+ return *new(*big.Int), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
+
+ return out0, err
+
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) GetBucketedDelaysLength(upkeepId *big.Int) (*big.Int, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.GetBucketedDelaysLength(&_VerifiableLoadStreamsLookupUpkeep.CallOpts, upkeepId)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCallerSession) GetBucketedDelaysLength(upkeepId *big.Int) (*big.Int, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.GetBucketedDelaysLength(&_VerifiableLoadStreamsLookupUpkeep.CallOpts, upkeepId)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCaller) GetDelays(opts *bind.CallOpts, upkeepId *big.Int) ([]*big.Int, error) {
+ var out []interface{}
+ err := _VerifiableLoadStreamsLookupUpkeep.contract.Call(opts, &out, "getDelays", upkeepId)
+
+ if err != nil {
+ return *new([]*big.Int), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new([]*big.Int)).(*[]*big.Int)
+
+ return out0, err
+
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) GetDelays(upkeepId *big.Int) ([]*big.Int, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.GetDelays(&_VerifiableLoadStreamsLookupUpkeep.CallOpts, upkeepId)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCallerSession) GetDelays(upkeepId *big.Int) ([]*big.Int, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.GetDelays(&_VerifiableLoadStreamsLookupUpkeep.CallOpts, upkeepId)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCaller) GetDelaysLength(opts *bind.CallOpts, upkeepId *big.Int) (*big.Int, error) {
+ var out []interface{}
+ err := _VerifiableLoadStreamsLookupUpkeep.contract.Call(opts, &out, "getDelaysLength", upkeepId)
+
+ if err != nil {
+ return *new(*big.Int), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
+
+ return out0, err
+
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) GetDelaysLength(upkeepId *big.Int) (*big.Int, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.GetDelaysLength(&_VerifiableLoadStreamsLookupUpkeep.CallOpts, upkeepId)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCallerSession) GetDelaysLength(upkeepId *big.Int) (*big.Int, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.GetDelaysLength(&_VerifiableLoadStreamsLookupUpkeep.CallOpts, upkeepId)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCaller) GetForwarder(opts *bind.CallOpts, upkeepID *big.Int) (common.Address, error) {
+ var out []interface{}
+ err := _VerifiableLoadStreamsLookupUpkeep.contract.Call(opts, &out, "getForwarder", upkeepID)
+
+ if err != nil {
+ return *new(common.Address), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address)
+
+ return out0, err
+
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) GetForwarder(upkeepID *big.Int) (common.Address, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.GetForwarder(&_VerifiableLoadStreamsLookupUpkeep.CallOpts, upkeepID)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCallerSession) GetForwarder(upkeepID *big.Int) (common.Address, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.GetForwarder(&_VerifiableLoadStreamsLookupUpkeep.CallOpts, upkeepID)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCaller) GetLogTriggerConfig(opts *bind.CallOpts, addr common.Address, selector uint8, topic0 [32]byte, topic1 [32]byte, topic2 [32]byte, topic3 [32]byte) ([]byte, error) {
+ var out []interface{}
+ err := _VerifiableLoadStreamsLookupUpkeep.contract.Call(opts, &out, "getLogTriggerConfig", addr, selector, topic0, topic1, topic2, topic3)
+
+ if err != nil {
+ return *new([]byte), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte)
+
+ return out0, err
+
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) GetLogTriggerConfig(addr common.Address, selector uint8, topic0 [32]byte, topic1 [32]byte, topic2 [32]byte, topic3 [32]byte) ([]byte, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.GetLogTriggerConfig(&_VerifiableLoadStreamsLookupUpkeep.CallOpts, addr, selector, topic0, topic1, topic2, topic3)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCallerSession) GetLogTriggerConfig(addr common.Address, selector uint8, topic0 [32]byte, topic1 [32]byte, topic2 [32]byte, topic3 [32]byte) ([]byte, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.GetLogTriggerConfig(&_VerifiableLoadStreamsLookupUpkeep.CallOpts, addr, selector, topic0, topic1, topic2, topic3)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCaller) GetMinBalanceForUpkeep(opts *bind.CallOpts, upkeepId *big.Int) (*big.Int, error) {
+ var out []interface{}
+ err := _VerifiableLoadStreamsLookupUpkeep.contract.Call(opts, &out, "getMinBalanceForUpkeep", upkeepId)
+
+ if err != nil {
+ return *new(*big.Int), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
+
+ return out0, err
+
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) GetMinBalanceForUpkeep(upkeepId *big.Int) (*big.Int, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.GetMinBalanceForUpkeep(&_VerifiableLoadStreamsLookupUpkeep.CallOpts, upkeepId)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCallerSession) GetMinBalanceForUpkeep(upkeepId *big.Int) (*big.Int, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.GetMinBalanceForUpkeep(&_VerifiableLoadStreamsLookupUpkeep.CallOpts, upkeepId)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCaller) GetPxDelayLastNPerforms(opts *bind.CallOpts, upkeepId *big.Int, p *big.Int, n *big.Int) (*big.Int, error) {
+ var out []interface{}
+ err := _VerifiableLoadStreamsLookupUpkeep.contract.Call(opts, &out, "getPxDelayLastNPerforms", upkeepId, p, n)
+
+ if err != nil {
+ return *new(*big.Int), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
+
+ return out0, err
+
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) GetPxDelayLastNPerforms(upkeepId *big.Int, p *big.Int, n *big.Int) (*big.Int, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.GetPxDelayLastNPerforms(&_VerifiableLoadStreamsLookupUpkeep.CallOpts, upkeepId, p, n)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCallerSession) GetPxDelayLastNPerforms(upkeepId *big.Int, p *big.Int, n *big.Int) (*big.Int, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.GetPxDelayLastNPerforms(&_VerifiableLoadStreamsLookupUpkeep.CallOpts, upkeepId, p, n)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCaller) GetSumDelayInBucket(opts *bind.CallOpts, upkeepId *big.Int, bucket uint16) (*big.Int, *big.Int, error) {
+ var out []interface{}
+ err := _VerifiableLoadStreamsLookupUpkeep.contract.Call(opts, &out, "getSumDelayInBucket", upkeepId, bucket)
+
+ if err != nil {
+ return *new(*big.Int), *new(*big.Int), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
+ out1 := *abi.ConvertType(out[1], new(*big.Int)).(**big.Int)
+
+ return out0, out1, err
+
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) GetSumDelayInBucket(upkeepId *big.Int, bucket uint16) (*big.Int, *big.Int, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.GetSumDelayInBucket(&_VerifiableLoadStreamsLookupUpkeep.CallOpts, upkeepId, bucket)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCallerSession) GetSumDelayInBucket(upkeepId *big.Int, bucket uint16) (*big.Int, *big.Int, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.GetSumDelayInBucket(&_VerifiableLoadStreamsLookupUpkeep.CallOpts, upkeepId, bucket)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCaller) GetSumDelayLastNPerforms(opts *bind.CallOpts, upkeepId *big.Int, n *big.Int) (*big.Int, *big.Int, error) {
+ var out []interface{}
+ err := _VerifiableLoadStreamsLookupUpkeep.contract.Call(opts, &out, "getSumDelayLastNPerforms", upkeepId, n)
+
+ if err != nil {
+ return *new(*big.Int), *new(*big.Int), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
+ out1 := *abi.ConvertType(out[1], new(*big.Int)).(**big.Int)
+
+ return out0, out1, err
+
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) GetSumDelayLastNPerforms(upkeepId *big.Int, n *big.Int) (*big.Int, *big.Int, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.GetSumDelayLastNPerforms(&_VerifiableLoadStreamsLookupUpkeep.CallOpts, upkeepId, n)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCallerSession) GetSumDelayLastNPerforms(upkeepId *big.Int, n *big.Int) (*big.Int, *big.Int, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.GetSumDelayLastNPerforms(&_VerifiableLoadStreamsLookupUpkeep.CallOpts, upkeepId, n)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCaller) GetTriggerType(opts *bind.CallOpts, upkeepId *big.Int) (uint8, error) {
+ var out []interface{}
+ err := _VerifiableLoadStreamsLookupUpkeep.contract.Call(opts, &out, "getTriggerType", upkeepId)
+
+ if err != nil {
+ return *new(uint8), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8)
+
+ return out0, err
+
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) GetTriggerType(upkeepId *big.Int) (uint8, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.GetTriggerType(&_VerifiableLoadStreamsLookupUpkeep.CallOpts, upkeepId)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCallerSession) GetTriggerType(upkeepId *big.Int) (uint8, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.GetTriggerType(&_VerifiableLoadStreamsLookupUpkeep.CallOpts, upkeepId)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCaller) GetUpkeepInfo(opts *bind.CallOpts, upkeepId *big.Int) (KeeperRegistryBase21UpkeepInfo, error) {
+ var out []interface{}
+ err := _VerifiableLoadStreamsLookupUpkeep.contract.Call(opts, &out, "getUpkeepInfo", upkeepId)
+
+ if err != nil {
+ return *new(KeeperRegistryBase21UpkeepInfo), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(KeeperRegistryBase21UpkeepInfo)).(*KeeperRegistryBase21UpkeepInfo)
+
+ return out0, err
+
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) GetUpkeepInfo(upkeepId *big.Int) (KeeperRegistryBase21UpkeepInfo, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.GetUpkeepInfo(&_VerifiableLoadStreamsLookupUpkeep.CallOpts, upkeepId)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCallerSession) GetUpkeepInfo(upkeepId *big.Int) (KeeperRegistryBase21UpkeepInfo, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.GetUpkeepInfo(&_VerifiableLoadStreamsLookupUpkeep.CallOpts, upkeepId)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCaller) GetUpkeepPrivilegeConfig(opts *bind.CallOpts, upkeepId *big.Int) ([]byte, error) {
+ var out []interface{}
+ err := _VerifiableLoadStreamsLookupUpkeep.contract.Call(opts, &out, "getUpkeepPrivilegeConfig", upkeepId)
+
+ if err != nil {
+ return *new([]byte), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte)
+
+ return out0, err
+
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) GetUpkeepPrivilegeConfig(upkeepId *big.Int) ([]byte, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.GetUpkeepPrivilegeConfig(&_VerifiableLoadStreamsLookupUpkeep.CallOpts, upkeepId)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCallerSession) GetUpkeepPrivilegeConfig(upkeepId *big.Int) ([]byte, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.GetUpkeepPrivilegeConfig(&_VerifiableLoadStreamsLookupUpkeep.CallOpts, upkeepId)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCaller) GetUpkeepTriggerConfig(opts *bind.CallOpts, upkeepId *big.Int) ([]byte, error) {
+ var out []interface{}
+ err := _VerifiableLoadStreamsLookupUpkeep.contract.Call(opts, &out, "getUpkeepTriggerConfig", upkeepId)
+
+ if err != nil {
+ return *new([]byte), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte)
+
+ return out0, err
+
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) GetUpkeepTriggerConfig(upkeepId *big.Int) ([]byte, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.GetUpkeepTriggerConfig(&_VerifiableLoadStreamsLookupUpkeep.CallOpts, upkeepId)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCallerSession) GetUpkeepTriggerConfig(upkeepId *big.Int) ([]byte, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.GetUpkeepTriggerConfig(&_VerifiableLoadStreamsLookupUpkeep.CallOpts, upkeepId)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCaller) Intervals(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) {
+ var out []interface{}
+ err := _VerifiableLoadStreamsLookupUpkeep.contract.Call(opts, &out, "intervals", arg0)
+
+ if err != nil {
+ return *new(*big.Int), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
+
+ return out0, err
+
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) Intervals(arg0 *big.Int) (*big.Int, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.Intervals(&_VerifiableLoadStreamsLookupUpkeep.CallOpts, arg0)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCallerSession) Intervals(arg0 *big.Int) (*big.Int, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.Intervals(&_VerifiableLoadStreamsLookupUpkeep.CallOpts, arg0)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCaller) LastTopUpBlocks(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) {
+ var out []interface{}
+ err := _VerifiableLoadStreamsLookupUpkeep.contract.Call(opts, &out, "lastTopUpBlocks", arg0)
+
+ if err != nil {
+ return *new(*big.Int), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
+
+ return out0, err
+
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) LastTopUpBlocks(arg0 *big.Int) (*big.Int, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.LastTopUpBlocks(&_VerifiableLoadStreamsLookupUpkeep.CallOpts, arg0)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCallerSession) LastTopUpBlocks(arg0 *big.Int) (*big.Int, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.LastTopUpBlocks(&_VerifiableLoadStreamsLookupUpkeep.CallOpts, arg0)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCaller) LinkToken(opts *bind.CallOpts) (common.Address, error) {
+ var out []interface{}
+ err := _VerifiableLoadStreamsLookupUpkeep.contract.Call(opts, &out, "linkToken")
+
+ if err != nil {
+ return *new(common.Address), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address)
+
+ return out0, err
+
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) LinkToken() (common.Address, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.LinkToken(&_VerifiableLoadStreamsLookupUpkeep.CallOpts)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCallerSession) LinkToken() (common.Address, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.LinkToken(&_VerifiableLoadStreamsLookupUpkeep.CallOpts)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCaller) MinBalanceThresholdMultiplier(opts *bind.CallOpts) (uint8, error) {
+ var out []interface{}
+ err := _VerifiableLoadStreamsLookupUpkeep.contract.Call(opts, &out, "minBalanceThresholdMultiplier")
+
+ if err != nil {
+ return *new(uint8), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8)
+
+ return out0, err
+
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) MinBalanceThresholdMultiplier() (uint8, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.MinBalanceThresholdMultiplier(&_VerifiableLoadStreamsLookupUpkeep.CallOpts)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCallerSession) MinBalanceThresholdMultiplier() (uint8, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.MinBalanceThresholdMultiplier(&_VerifiableLoadStreamsLookupUpkeep.CallOpts)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCaller) Owner(opts *bind.CallOpts) (common.Address, error) {
+ var out []interface{}
+ err := _VerifiableLoadStreamsLookupUpkeep.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 (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) Owner() (common.Address, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.Owner(&_VerifiableLoadStreamsLookupUpkeep.CallOpts)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCallerSession) Owner() (common.Address, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.Owner(&_VerifiableLoadStreamsLookupUpkeep.CallOpts)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCaller) PerformDataSizes(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) {
+ var out []interface{}
+ err := _VerifiableLoadStreamsLookupUpkeep.contract.Call(opts, &out, "performDataSizes", arg0)
+
+ if err != nil {
+ return *new(*big.Int), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
+
+ return out0, err
+
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) PerformDataSizes(arg0 *big.Int) (*big.Int, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.PerformDataSizes(&_VerifiableLoadStreamsLookupUpkeep.CallOpts, arg0)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCallerSession) PerformDataSizes(arg0 *big.Int) (*big.Int, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.PerformDataSizes(&_VerifiableLoadStreamsLookupUpkeep.CallOpts, arg0)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCaller) PerformGasToBurns(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) {
+ var out []interface{}
+ err := _VerifiableLoadStreamsLookupUpkeep.contract.Call(opts, &out, "performGasToBurns", arg0)
+
+ if err != nil {
+ return *new(*big.Int), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
+
+ return out0, err
+
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) PerformGasToBurns(arg0 *big.Int) (*big.Int, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.PerformGasToBurns(&_VerifiableLoadStreamsLookupUpkeep.CallOpts, arg0)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCallerSession) PerformGasToBurns(arg0 *big.Int) (*big.Int, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.PerformGasToBurns(&_VerifiableLoadStreamsLookupUpkeep.CallOpts, arg0)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCaller) PreviousPerformBlocks(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) {
+ var out []interface{}
+ err := _VerifiableLoadStreamsLookupUpkeep.contract.Call(opts, &out, "previousPerformBlocks", arg0)
+
+ if err != nil {
+ return *new(*big.Int), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
+
+ return out0, err
+
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) PreviousPerformBlocks(arg0 *big.Int) (*big.Int, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.PreviousPerformBlocks(&_VerifiableLoadStreamsLookupUpkeep.CallOpts, arg0)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCallerSession) PreviousPerformBlocks(arg0 *big.Int) (*big.Int, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.PreviousPerformBlocks(&_VerifiableLoadStreamsLookupUpkeep.CallOpts, arg0)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCaller) Registrar(opts *bind.CallOpts) (common.Address, error) {
+ var out []interface{}
+ err := _VerifiableLoadStreamsLookupUpkeep.contract.Call(opts, &out, "registrar")
+
+ if err != nil {
+ return *new(common.Address), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address)
+
+ return out0, err
+
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) Registrar() (common.Address, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.Registrar(&_VerifiableLoadStreamsLookupUpkeep.CallOpts)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCallerSession) Registrar() (common.Address, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.Registrar(&_VerifiableLoadStreamsLookupUpkeep.CallOpts)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCaller) Registry(opts *bind.CallOpts) (common.Address, error) {
+ var out []interface{}
+ err := _VerifiableLoadStreamsLookupUpkeep.contract.Call(opts, &out, "registry")
+
+ if err != nil {
+ return *new(common.Address), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address)
+
+ return out0, err
+
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) Registry() (common.Address, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.Registry(&_VerifiableLoadStreamsLookupUpkeep.CallOpts)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCallerSession) Registry() (common.Address, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.Registry(&_VerifiableLoadStreamsLookupUpkeep.CallOpts)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCaller) TimeParamKey(opts *bind.CallOpts) (string, error) {
+ var out []interface{}
+ err := _VerifiableLoadStreamsLookupUpkeep.contract.Call(opts, &out, "timeParamKey")
+
+ if err != nil {
+ return *new(string), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(string)).(*string)
+
+ return out0, err
+
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) TimeParamKey() (string, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.TimeParamKey(&_VerifiableLoadStreamsLookupUpkeep.CallOpts)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCallerSession) TimeParamKey() (string, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.TimeParamKey(&_VerifiableLoadStreamsLookupUpkeep.CallOpts)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCaller) UpkeepTopUpCheckInterval(opts *bind.CallOpts) (*big.Int, error) {
+ var out []interface{}
+ err := _VerifiableLoadStreamsLookupUpkeep.contract.Call(opts, &out, "upkeepTopUpCheckInterval")
+
+ if err != nil {
+ return *new(*big.Int), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
+
+ return out0, err
+
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) UpkeepTopUpCheckInterval() (*big.Int, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.UpkeepTopUpCheckInterval(&_VerifiableLoadStreamsLookupUpkeep.CallOpts)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCallerSession) UpkeepTopUpCheckInterval() (*big.Int, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.UpkeepTopUpCheckInterval(&_VerifiableLoadStreamsLookupUpkeep.CallOpts)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCaller) UseArbitrumBlockNum(opts *bind.CallOpts) (bool, error) {
+ var out []interface{}
+ err := _VerifiableLoadStreamsLookupUpkeep.contract.Call(opts, &out, "useArbitrumBlockNum")
+
+ if err != nil {
+ return *new(bool), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(bool)).(*bool)
+
+ return out0, err
+
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) UseArbitrumBlockNum() (bool, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.UseArbitrumBlockNum(&_VerifiableLoadStreamsLookupUpkeep.CallOpts)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepCallerSession) UseArbitrumBlockNum() (bool, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.UseArbitrumBlockNum(&_VerifiableLoadStreamsLookupUpkeep.CallOpts)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.contract.Transact(opts, "acceptOwnership")
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) AcceptOwnership() (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.AcceptOwnership(&_VerifiableLoadStreamsLookupUpkeep.TransactOpts)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepTransactorSession) AcceptOwnership() (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.AcceptOwnership(&_VerifiableLoadStreamsLookupUpkeep.TransactOpts)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepTransactor) AddFunds(opts *bind.TransactOpts, upkeepId *big.Int, amount *big.Int) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.contract.Transact(opts, "addFunds", upkeepId, amount)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) AddFunds(upkeepId *big.Int, amount *big.Int) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.AddFunds(&_VerifiableLoadStreamsLookupUpkeep.TransactOpts, upkeepId, amount)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepTransactorSession) AddFunds(upkeepId *big.Int, amount *big.Int) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.AddFunds(&_VerifiableLoadStreamsLookupUpkeep.TransactOpts, upkeepId, amount)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepTransactor) BatchCancelUpkeeps(opts *bind.TransactOpts, upkeepIds []*big.Int) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.contract.Transact(opts, "batchCancelUpkeeps", upkeepIds)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) BatchCancelUpkeeps(upkeepIds []*big.Int) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.BatchCancelUpkeeps(&_VerifiableLoadStreamsLookupUpkeep.TransactOpts, upkeepIds)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepTransactorSession) BatchCancelUpkeeps(upkeepIds []*big.Int) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.BatchCancelUpkeeps(&_VerifiableLoadStreamsLookupUpkeep.TransactOpts, upkeepIds)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepTransactor) BatchPreparingUpkeeps(opts *bind.TransactOpts, upkeepIds []*big.Int, selector uint8, topic0 [32]byte, topic1 [32]byte, topic2 [32]byte, topic3 [32]byte) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.contract.Transact(opts, "batchPreparingUpkeeps", upkeepIds, selector, topic0, topic1, topic2, topic3)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) BatchPreparingUpkeeps(upkeepIds []*big.Int, selector uint8, topic0 [32]byte, topic1 [32]byte, topic2 [32]byte, topic3 [32]byte) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.BatchPreparingUpkeeps(&_VerifiableLoadStreamsLookupUpkeep.TransactOpts, upkeepIds, selector, topic0, topic1, topic2, topic3)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepTransactorSession) BatchPreparingUpkeeps(upkeepIds []*big.Int, selector uint8, topic0 [32]byte, topic1 [32]byte, topic2 [32]byte, topic3 [32]byte) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.BatchPreparingUpkeeps(&_VerifiableLoadStreamsLookupUpkeep.TransactOpts, upkeepIds, selector, topic0, topic1, topic2, topic3)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepTransactor) BatchPreparingUpkeepsSimple(opts *bind.TransactOpts, upkeepIds []*big.Int, log uint8, selector uint8) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.contract.Transact(opts, "batchPreparingUpkeepsSimple", upkeepIds, log, selector)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) BatchPreparingUpkeepsSimple(upkeepIds []*big.Int, log uint8, selector uint8) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.BatchPreparingUpkeepsSimple(&_VerifiableLoadStreamsLookupUpkeep.TransactOpts, upkeepIds, log, selector)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepTransactorSession) BatchPreparingUpkeepsSimple(upkeepIds []*big.Int, log uint8, selector uint8) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.BatchPreparingUpkeepsSimple(&_VerifiableLoadStreamsLookupUpkeep.TransactOpts, upkeepIds, log, selector)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepTransactor) BatchRegisterUpkeeps(opts *bind.TransactOpts, number uint8, gasLimit uint32, triggerType uint8, triggerConfig []byte, amount *big.Int, checkGasToBurn *big.Int, performGasToBurn *big.Int) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.contract.Transact(opts, "batchRegisterUpkeeps", number, gasLimit, triggerType, triggerConfig, amount, checkGasToBurn, performGasToBurn)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) BatchRegisterUpkeeps(number uint8, gasLimit uint32, triggerType uint8, triggerConfig []byte, amount *big.Int, checkGasToBurn *big.Int, performGasToBurn *big.Int) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.BatchRegisterUpkeeps(&_VerifiableLoadStreamsLookupUpkeep.TransactOpts, number, gasLimit, triggerType, triggerConfig, amount, checkGasToBurn, performGasToBurn)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepTransactorSession) BatchRegisterUpkeeps(number uint8, gasLimit uint32, triggerType uint8, triggerConfig []byte, amount *big.Int, checkGasToBurn *big.Int, performGasToBurn *big.Int) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.BatchRegisterUpkeeps(&_VerifiableLoadStreamsLookupUpkeep.TransactOpts, number, gasLimit, triggerType, triggerConfig, amount, checkGasToBurn, performGasToBurn)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepTransactor) BatchSendLogs(opts *bind.TransactOpts, log uint8) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.contract.Transact(opts, "batchSendLogs", log)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) BatchSendLogs(log uint8) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.BatchSendLogs(&_VerifiableLoadStreamsLookupUpkeep.TransactOpts, log)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepTransactorSession) BatchSendLogs(log uint8) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.BatchSendLogs(&_VerifiableLoadStreamsLookupUpkeep.TransactOpts, log)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepTransactor) BatchSetIntervals(opts *bind.TransactOpts, upkeepIds []*big.Int, interval uint32) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.contract.Transact(opts, "batchSetIntervals", upkeepIds, interval)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) BatchSetIntervals(upkeepIds []*big.Int, interval uint32) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.BatchSetIntervals(&_VerifiableLoadStreamsLookupUpkeep.TransactOpts, upkeepIds, interval)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepTransactorSession) BatchSetIntervals(upkeepIds []*big.Int, interval uint32) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.BatchSetIntervals(&_VerifiableLoadStreamsLookupUpkeep.TransactOpts, upkeepIds, interval)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepTransactor) BatchUpdatePipelineData(opts *bind.TransactOpts, upkeepIds []*big.Int) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.contract.Transact(opts, "batchUpdatePipelineData", upkeepIds)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) BatchUpdatePipelineData(upkeepIds []*big.Int) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.BatchUpdatePipelineData(&_VerifiableLoadStreamsLookupUpkeep.TransactOpts, upkeepIds)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepTransactorSession) BatchUpdatePipelineData(upkeepIds []*big.Int) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.BatchUpdatePipelineData(&_VerifiableLoadStreamsLookupUpkeep.TransactOpts, upkeepIds)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepTransactor) BatchWithdrawLinks(opts *bind.TransactOpts, upkeepIds []*big.Int) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.contract.Transact(opts, "batchWithdrawLinks", upkeepIds)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) BatchWithdrawLinks(upkeepIds []*big.Int) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.BatchWithdrawLinks(&_VerifiableLoadStreamsLookupUpkeep.TransactOpts, upkeepIds)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepTransactorSession) BatchWithdrawLinks(upkeepIds []*big.Int) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.BatchWithdrawLinks(&_VerifiableLoadStreamsLookupUpkeep.TransactOpts, upkeepIds)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepTransactor) BurnPerformGas(opts *bind.TransactOpts, upkeepId *big.Int, startGas *big.Int, blockNum *big.Int) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.contract.Transact(opts, "burnPerformGas", upkeepId, startGas, blockNum)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) BurnPerformGas(upkeepId *big.Int, startGas *big.Int, blockNum *big.Int) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.BurnPerformGas(&_VerifiableLoadStreamsLookupUpkeep.TransactOpts, upkeepId, startGas, blockNum)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepTransactorSession) BurnPerformGas(upkeepId *big.Int, startGas *big.Int, blockNum *big.Int) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.BurnPerformGas(&_VerifiableLoadStreamsLookupUpkeep.TransactOpts, upkeepId, startGas, blockNum)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepTransactor) CheckUpkeep(opts *bind.TransactOpts, checkData []byte) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.contract.Transact(opts, "checkUpkeep", checkData)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) CheckUpkeep(checkData []byte) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.CheckUpkeep(&_VerifiableLoadStreamsLookupUpkeep.TransactOpts, checkData)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepTransactorSession) CheckUpkeep(checkData []byte) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.CheckUpkeep(&_VerifiableLoadStreamsLookupUpkeep.TransactOpts, checkData)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepTransactor) PerformUpkeep(opts *bind.TransactOpts, performData []byte) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.contract.Transact(opts, "performUpkeep", performData)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) PerformUpkeep(performData []byte) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.PerformUpkeep(&_VerifiableLoadStreamsLookupUpkeep.TransactOpts, performData)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepTransactorSession) PerformUpkeep(performData []byte) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.PerformUpkeep(&_VerifiableLoadStreamsLookupUpkeep.TransactOpts, performData)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepTransactor) SendLog(opts *bind.TransactOpts, upkeepId *big.Int, log uint8) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.contract.Transact(opts, "sendLog", upkeepId, log)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) SendLog(upkeepId *big.Int, log uint8) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.SendLog(&_VerifiableLoadStreamsLookupUpkeep.TransactOpts, upkeepId, log)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepTransactorSession) SendLog(upkeepId *big.Int, log uint8) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.SendLog(&_VerifiableLoadStreamsLookupUpkeep.TransactOpts, upkeepId, log)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepTransactor) SetConfig(opts *bind.TransactOpts, newRegistrar common.Address) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.contract.Transact(opts, "setConfig", newRegistrar)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) SetConfig(newRegistrar common.Address) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.SetConfig(&_VerifiableLoadStreamsLookupUpkeep.TransactOpts, newRegistrar)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepTransactorSession) SetConfig(newRegistrar common.Address) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.SetConfig(&_VerifiableLoadStreamsLookupUpkeep.TransactOpts, newRegistrar)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepTransactor) SetFeeds(opts *bind.TransactOpts, _feeds []string) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.contract.Transact(opts, "setFeeds", _feeds)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) SetFeeds(_feeds []string) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.SetFeeds(&_VerifiableLoadStreamsLookupUpkeep.TransactOpts, _feeds)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepTransactorSession) SetFeeds(_feeds []string) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.SetFeeds(&_VerifiableLoadStreamsLookupUpkeep.TransactOpts, _feeds)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepTransactor) SetInterval(opts *bind.TransactOpts, upkeepId *big.Int, _interval *big.Int) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.contract.Transact(opts, "setInterval", upkeepId, _interval)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) SetInterval(upkeepId *big.Int, _interval *big.Int) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.SetInterval(&_VerifiableLoadStreamsLookupUpkeep.TransactOpts, upkeepId, _interval)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepTransactorSession) SetInterval(upkeepId *big.Int, _interval *big.Int) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.SetInterval(&_VerifiableLoadStreamsLookupUpkeep.TransactOpts, upkeepId, _interval)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepTransactor) SetParamKeys(opts *bind.TransactOpts, _feedParamKey string, _timeParamKey string) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.contract.Transact(opts, "setParamKeys", _feedParamKey, _timeParamKey)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) SetParamKeys(_feedParamKey string, _timeParamKey string) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.SetParamKeys(&_VerifiableLoadStreamsLookupUpkeep.TransactOpts, _feedParamKey, _timeParamKey)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepTransactorSession) SetParamKeys(_feedParamKey string, _timeParamKey string) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.SetParamKeys(&_VerifiableLoadStreamsLookupUpkeep.TransactOpts, _feedParamKey, _timeParamKey)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepTransactor) SetPerformDataSize(opts *bind.TransactOpts, upkeepId *big.Int, value *big.Int) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.contract.Transact(opts, "setPerformDataSize", upkeepId, value)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) SetPerformDataSize(upkeepId *big.Int, value *big.Int) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.SetPerformDataSize(&_VerifiableLoadStreamsLookupUpkeep.TransactOpts, upkeepId, value)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepTransactorSession) SetPerformDataSize(upkeepId *big.Int, value *big.Int) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.SetPerformDataSize(&_VerifiableLoadStreamsLookupUpkeep.TransactOpts, upkeepId, value)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepTransactor) SetUpkeepGasLimit(opts *bind.TransactOpts, upkeepId *big.Int, gasLimit uint32) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.contract.Transact(opts, "setUpkeepGasLimit", upkeepId, gasLimit)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) SetUpkeepGasLimit(upkeepId *big.Int, gasLimit uint32) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.SetUpkeepGasLimit(&_VerifiableLoadStreamsLookupUpkeep.TransactOpts, upkeepId, gasLimit)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepTransactorSession) SetUpkeepGasLimit(upkeepId *big.Int, gasLimit uint32) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.SetUpkeepGasLimit(&_VerifiableLoadStreamsLookupUpkeep.TransactOpts, upkeepId, gasLimit)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepTransactor) SetUpkeepPrivilegeConfig(opts *bind.TransactOpts, upkeepId *big.Int, cfg []byte) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.contract.Transact(opts, "setUpkeepPrivilegeConfig", upkeepId, cfg)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) SetUpkeepPrivilegeConfig(upkeepId *big.Int, cfg []byte) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.SetUpkeepPrivilegeConfig(&_VerifiableLoadStreamsLookupUpkeep.TransactOpts, upkeepId, cfg)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepTransactorSession) SetUpkeepPrivilegeConfig(upkeepId *big.Int, cfg []byte) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.SetUpkeepPrivilegeConfig(&_VerifiableLoadStreamsLookupUpkeep.TransactOpts, upkeepId, cfg)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepTransactor) TopUpFund(opts *bind.TransactOpts, upkeepId *big.Int, blockNum *big.Int) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.contract.Transact(opts, "topUpFund", upkeepId, blockNum)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) TopUpFund(upkeepId *big.Int, blockNum *big.Int) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.TopUpFund(&_VerifiableLoadStreamsLookupUpkeep.TransactOpts, upkeepId, blockNum)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepTransactorSession) TopUpFund(upkeepId *big.Int, blockNum *big.Int) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.TopUpFund(&_VerifiableLoadStreamsLookupUpkeep.TransactOpts, upkeepId, blockNum)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.contract.Transact(opts, "transferOwnership", to)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) TransferOwnership(to common.Address) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.TransferOwnership(&_VerifiableLoadStreamsLookupUpkeep.TransactOpts, to)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.TransferOwnership(&_VerifiableLoadStreamsLookupUpkeep.TransactOpts, to)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepTransactor) UpdateLogTriggerConfig1(opts *bind.TransactOpts, upkeepId *big.Int, addr common.Address, selector uint8, topic0 [32]byte, topic1 [32]byte, topic2 [32]byte, topic3 [32]byte) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.contract.Transact(opts, "updateLogTriggerConfig1", upkeepId, addr, selector, topic0, topic1, topic2, topic3)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) UpdateLogTriggerConfig1(upkeepId *big.Int, addr common.Address, selector uint8, topic0 [32]byte, topic1 [32]byte, topic2 [32]byte, topic3 [32]byte) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.UpdateLogTriggerConfig1(&_VerifiableLoadStreamsLookupUpkeep.TransactOpts, upkeepId, addr, selector, topic0, topic1, topic2, topic3)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepTransactorSession) UpdateLogTriggerConfig1(upkeepId *big.Int, addr common.Address, selector uint8, topic0 [32]byte, topic1 [32]byte, topic2 [32]byte, topic3 [32]byte) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.UpdateLogTriggerConfig1(&_VerifiableLoadStreamsLookupUpkeep.TransactOpts, upkeepId, addr, selector, topic0, topic1, topic2, topic3)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepTransactor) UpdateLogTriggerConfig2(opts *bind.TransactOpts, upkeepId *big.Int, cfg []byte) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.contract.Transact(opts, "updateLogTriggerConfig2", upkeepId, cfg)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) UpdateLogTriggerConfig2(upkeepId *big.Int, cfg []byte) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.UpdateLogTriggerConfig2(&_VerifiableLoadStreamsLookupUpkeep.TransactOpts, upkeepId, cfg)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepTransactorSession) UpdateLogTriggerConfig2(upkeepId *big.Int, cfg []byte) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.UpdateLogTriggerConfig2(&_VerifiableLoadStreamsLookupUpkeep.TransactOpts, upkeepId, cfg)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepTransactor) UpdateUpkeepPipelineData(opts *bind.TransactOpts, upkeepId *big.Int, pipelineData []byte) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.contract.Transact(opts, "updateUpkeepPipelineData", upkeepId, pipelineData)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) UpdateUpkeepPipelineData(upkeepId *big.Int, pipelineData []byte) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.UpdateUpkeepPipelineData(&_VerifiableLoadStreamsLookupUpkeep.TransactOpts, upkeepId, pipelineData)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepTransactorSession) UpdateUpkeepPipelineData(upkeepId *big.Int, pipelineData []byte) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.UpdateUpkeepPipelineData(&_VerifiableLoadStreamsLookupUpkeep.TransactOpts, upkeepId, pipelineData)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepTransactor) WithdrawLinks(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.contract.Transact(opts, "withdrawLinks")
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) WithdrawLinks() (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.WithdrawLinks(&_VerifiableLoadStreamsLookupUpkeep.TransactOpts)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepTransactorSession) WithdrawLinks() (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.WithdrawLinks(&_VerifiableLoadStreamsLookupUpkeep.TransactOpts)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepTransactor) WithdrawLinks0(opts *bind.TransactOpts, upkeepId *big.Int) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.contract.Transact(opts, "withdrawLinks0", upkeepId)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) WithdrawLinks0(upkeepId *big.Int) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.WithdrawLinks0(&_VerifiableLoadStreamsLookupUpkeep.TransactOpts, upkeepId)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepTransactorSession) WithdrawLinks0(upkeepId *big.Int) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.WithdrawLinks0(&_VerifiableLoadStreamsLookupUpkeep.TransactOpts, upkeepId)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepTransactor) Receive(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.contract.RawTransact(opts, nil)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepSession) Receive() (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.Receive(&_VerifiableLoadStreamsLookupUpkeep.TransactOpts)
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepTransactorSession) Receive() (*types.Transaction, error) {
+ return _VerifiableLoadStreamsLookupUpkeep.Contract.Receive(&_VerifiableLoadStreamsLookupUpkeep.TransactOpts)
+}
+
+type VerifiableLoadStreamsLookupUpkeepLogEmittedIterator struct {
+ Event *VerifiableLoadStreamsLookupUpkeepLogEmitted
+
+ contract *bind.BoundContract
+ event string
+
+ logs chan types.Log
+ sub ethereum.Subscription
+ done bool
+ fail error
+}
+
+func (it *VerifiableLoadStreamsLookupUpkeepLogEmittedIterator) Next() bool {
+
+ if it.fail != nil {
+ return false
+ }
+
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(VerifiableLoadStreamsLookupUpkeepLogEmitted)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+
+ select {
+ case log := <-it.logs:
+ it.Event = new(VerifiableLoadStreamsLookupUpkeepLogEmitted)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+func (it *VerifiableLoadStreamsLookupUpkeepLogEmittedIterator) Error() error {
+ return it.fail
+}
+
+func (it *VerifiableLoadStreamsLookupUpkeepLogEmittedIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+type VerifiableLoadStreamsLookupUpkeepLogEmitted struct {
+ UpkeepId *big.Int
+ BlockNum *big.Int
+ Addr common.Address
+ Raw types.Log
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepFilterer) FilterLogEmitted(opts *bind.FilterOpts, upkeepId []*big.Int, blockNum []*big.Int, addr []common.Address) (*VerifiableLoadStreamsLookupUpkeepLogEmittedIterator, error) {
+
+ var upkeepIdRule []interface{}
+ for _, upkeepIdItem := range upkeepId {
+ upkeepIdRule = append(upkeepIdRule, upkeepIdItem)
+ }
+ var blockNumRule []interface{}
+ for _, blockNumItem := range blockNum {
+ blockNumRule = append(blockNumRule, blockNumItem)
+ }
+ var addrRule []interface{}
+ for _, addrItem := range addr {
+ addrRule = append(addrRule, addrItem)
+ }
+
+ logs, sub, err := _VerifiableLoadStreamsLookupUpkeep.contract.FilterLogs(opts, "LogEmitted", upkeepIdRule, blockNumRule, addrRule)
+ if err != nil {
+ return nil, err
+ }
+ return &VerifiableLoadStreamsLookupUpkeepLogEmittedIterator{contract: _VerifiableLoadStreamsLookupUpkeep.contract, event: "LogEmitted", logs: logs, sub: sub}, nil
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepFilterer) WatchLogEmitted(opts *bind.WatchOpts, sink chan<- *VerifiableLoadStreamsLookupUpkeepLogEmitted, upkeepId []*big.Int, blockNum []*big.Int, addr []common.Address) (event.Subscription, error) {
+
+ var upkeepIdRule []interface{}
+ for _, upkeepIdItem := range upkeepId {
+ upkeepIdRule = append(upkeepIdRule, upkeepIdItem)
+ }
+ var blockNumRule []interface{}
+ for _, blockNumItem := range blockNum {
+ blockNumRule = append(blockNumRule, blockNumItem)
+ }
+ var addrRule []interface{}
+ for _, addrItem := range addr {
+ addrRule = append(addrRule, addrItem)
+ }
+
+ logs, sub, err := _VerifiableLoadStreamsLookupUpkeep.contract.WatchLogs(opts, "LogEmitted", upkeepIdRule, blockNumRule, addrRule)
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+
+ event := new(VerifiableLoadStreamsLookupUpkeepLogEmitted)
+ if err := _VerifiableLoadStreamsLookupUpkeep.contract.UnpackLog(event, "LogEmitted", log); err != nil {
+ return err
+ }
+ event.Raw = log
+
+ select {
+ case sink <- event:
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ }
+ }), nil
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepFilterer) ParseLogEmitted(log types.Log) (*VerifiableLoadStreamsLookupUpkeepLogEmitted, error) {
+ event := new(VerifiableLoadStreamsLookupUpkeepLogEmitted)
+ if err := _VerifiableLoadStreamsLookupUpkeep.contract.UnpackLog(event, "LogEmitted", log); err != nil {
+ return nil, err
+ }
+ event.Raw = log
+ return event, nil
+}
+
+type VerifiableLoadStreamsLookupUpkeepLogEmittedAgainIterator struct {
+ Event *VerifiableLoadStreamsLookupUpkeepLogEmittedAgain
+
+ contract *bind.BoundContract
+ event string
+
+ logs chan types.Log
+ sub ethereum.Subscription
+ done bool
+ fail error
+}
+
+func (it *VerifiableLoadStreamsLookupUpkeepLogEmittedAgainIterator) Next() bool {
+
+ if it.fail != nil {
+ return false
+ }
+
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(VerifiableLoadStreamsLookupUpkeepLogEmittedAgain)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+
+ select {
+ case log := <-it.logs:
+ it.Event = new(VerifiableLoadStreamsLookupUpkeepLogEmittedAgain)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+func (it *VerifiableLoadStreamsLookupUpkeepLogEmittedAgainIterator) Error() error {
+ return it.fail
+}
+
+func (it *VerifiableLoadStreamsLookupUpkeepLogEmittedAgainIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+type VerifiableLoadStreamsLookupUpkeepLogEmittedAgain struct {
+ UpkeepId *big.Int
+ BlockNum *big.Int
+ Addr common.Address
+ Raw types.Log
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepFilterer) FilterLogEmittedAgain(opts *bind.FilterOpts, upkeepId []*big.Int, blockNum []*big.Int, addr []common.Address) (*VerifiableLoadStreamsLookupUpkeepLogEmittedAgainIterator, error) {
+
+ var upkeepIdRule []interface{}
+ for _, upkeepIdItem := range upkeepId {
+ upkeepIdRule = append(upkeepIdRule, upkeepIdItem)
+ }
+ var blockNumRule []interface{}
+ for _, blockNumItem := range blockNum {
+ blockNumRule = append(blockNumRule, blockNumItem)
+ }
+ var addrRule []interface{}
+ for _, addrItem := range addr {
+ addrRule = append(addrRule, addrItem)
+ }
+
+ logs, sub, err := _VerifiableLoadStreamsLookupUpkeep.contract.FilterLogs(opts, "LogEmittedAgain", upkeepIdRule, blockNumRule, addrRule)
+ if err != nil {
+ return nil, err
+ }
+ return &VerifiableLoadStreamsLookupUpkeepLogEmittedAgainIterator{contract: _VerifiableLoadStreamsLookupUpkeep.contract, event: "LogEmittedAgain", logs: logs, sub: sub}, nil
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepFilterer) WatchLogEmittedAgain(opts *bind.WatchOpts, sink chan<- *VerifiableLoadStreamsLookupUpkeepLogEmittedAgain, upkeepId []*big.Int, blockNum []*big.Int, addr []common.Address) (event.Subscription, error) {
+
+ var upkeepIdRule []interface{}
+ for _, upkeepIdItem := range upkeepId {
+ upkeepIdRule = append(upkeepIdRule, upkeepIdItem)
+ }
+ var blockNumRule []interface{}
+ for _, blockNumItem := range blockNum {
+ blockNumRule = append(blockNumRule, blockNumItem)
+ }
+ var addrRule []interface{}
+ for _, addrItem := range addr {
+ addrRule = append(addrRule, addrItem)
+ }
+
+ logs, sub, err := _VerifiableLoadStreamsLookupUpkeep.contract.WatchLogs(opts, "LogEmittedAgain", upkeepIdRule, blockNumRule, addrRule)
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+
+ event := new(VerifiableLoadStreamsLookupUpkeepLogEmittedAgain)
+ if err := _VerifiableLoadStreamsLookupUpkeep.contract.UnpackLog(event, "LogEmittedAgain", log); err != nil {
+ return err
+ }
+ event.Raw = log
+
+ select {
+ case sink <- event:
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ }
+ }), nil
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepFilterer) ParseLogEmittedAgain(log types.Log) (*VerifiableLoadStreamsLookupUpkeepLogEmittedAgain, error) {
+ event := new(VerifiableLoadStreamsLookupUpkeepLogEmittedAgain)
+ if err := _VerifiableLoadStreamsLookupUpkeep.contract.UnpackLog(event, "LogEmittedAgain", log); err != nil {
+ return nil, err
+ }
+ event.Raw = log
+ return event, nil
+}
+
+type VerifiableLoadStreamsLookupUpkeepOwnershipTransferRequestedIterator struct {
+ Event *VerifiableLoadStreamsLookupUpkeepOwnershipTransferRequested
+
+ contract *bind.BoundContract
+ event string
+
+ logs chan types.Log
+ sub ethereum.Subscription
+ done bool
+ fail error
+}
+
+func (it *VerifiableLoadStreamsLookupUpkeepOwnershipTransferRequestedIterator) Next() bool {
+
+ if it.fail != nil {
+ return false
+ }
+
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(VerifiableLoadStreamsLookupUpkeepOwnershipTransferRequested)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+
+ select {
+ case log := <-it.logs:
+ it.Event = new(VerifiableLoadStreamsLookupUpkeepOwnershipTransferRequested)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+func (it *VerifiableLoadStreamsLookupUpkeepOwnershipTransferRequestedIterator) Error() error {
+ return it.fail
+}
+
+func (it *VerifiableLoadStreamsLookupUpkeepOwnershipTransferRequestedIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+type VerifiableLoadStreamsLookupUpkeepOwnershipTransferRequested struct {
+ From common.Address
+ To common.Address
+ Raw types.Log
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VerifiableLoadStreamsLookupUpkeepOwnershipTransferRequestedIterator, 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 := _VerifiableLoadStreamsLookupUpkeep.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule)
+ if err != nil {
+ return nil, err
+ }
+ return &VerifiableLoadStreamsLookupUpkeepOwnershipTransferRequestedIterator{contract: _VerifiableLoadStreamsLookupUpkeep.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *VerifiableLoadStreamsLookupUpkeepOwnershipTransferRequested, 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 := _VerifiableLoadStreamsLookupUpkeep.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(VerifiableLoadStreamsLookupUpkeepOwnershipTransferRequested)
+ if err := _VerifiableLoadStreamsLookupUpkeep.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 (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepFilterer) ParseOwnershipTransferRequested(log types.Log) (*VerifiableLoadStreamsLookupUpkeepOwnershipTransferRequested, error) {
+ event := new(VerifiableLoadStreamsLookupUpkeepOwnershipTransferRequested)
+ if err := _VerifiableLoadStreamsLookupUpkeep.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil {
+ return nil, err
+ }
+ event.Raw = log
+ return event, nil
+}
+
+type VerifiableLoadStreamsLookupUpkeepOwnershipTransferredIterator struct {
+ Event *VerifiableLoadStreamsLookupUpkeepOwnershipTransferred
+
+ contract *bind.BoundContract
+ event string
+
+ logs chan types.Log
+ sub ethereum.Subscription
+ done bool
+ fail error
+}
+
+func (it *VerifiableLoadStreamsLookupUpkeepOwnershipTransferredIterator) Next() bool {
+
+ if it.fail != nil {
+ return false
+ }
+
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(VerifiableLoadStreamsLookupUpkeepOwnershipTransferred)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+
+ select {
+ case log := <-it.logs:
+ it.Event = new(VerifiableLoadStreamsLookupUpkeepOwnershipTransferred)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+func (it *VerifiableLoadStreamsLookupUpkeepOwnershipTransferredIterator) Error() error {
+ return it.fail
+}
+
+func (it *VerifiableLoadStreamsLookupUpkeepOwnershipTransferredIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+type VerifiableLoadStreamsLookupUpkeepOwnershipTransferred struct {
+ From common.Address
+ To common.Address
+ Raw types.Log
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VerifiableLoadStreamsLookupUpkeepOwnershipTransferredIterator, 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 := _VerifiableLoadStreamsLookupUpkeep.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule)
+ if err != nil {
+ return nil, err
+ }
+ return &VerifiableLoadStreamsLookupUpkeepOwnershipTransferredIterator{contract: _VerifiableLoadStreamsLookupUpkeep.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *VerifiableLoadStreamsLookupUpkeepOwnershipTransferred, 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 := _VerifiableLoadStreamsLookupUpkeep.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(VerifiableLoadStreamsLookupUpkeepOwnershipTransferred)
+ if err := _VerifiableLoadStreamsLookupUpkeep.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 (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepFilterer) ParseOwnershipTransferred(log types.Log) (*VerifiableLoadStreamsLookupUpkeepOwnershipTransferred, error) {
+ event := new(VerifiableLoadStreamsLookupUpkeepOwnershipTransferred)
+ if err := _VerifiableLoadStreamsLookupUpkeep.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil {
+ return nil, err
+ }
+ event.Raw = log
+ return event, nil
+}
+
+type VerifiableLoadStreamsLookupUpkeepUpkeepTopUpIterator struct {
+ Event *VerifiableLoadStreamsLookupUpkeepUpkeepTopUp
+
+ contract *bind.BoundContract
+ event string
+
+ logs chan types.Log
+ sub ethereum.Subscription
+ done bool
+ fail error
+}
+
+func (it *VerifiableLoadStreamsLookupUpkeepUpkeepTopUpIterator) Next() bool {
+
+ if it.fail != nil {
+ return false
+ }
+
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(VerifiableLoadStreamsLookupUpkeepUpkeepTopUp)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+
+ select {
+ case log := <-it.logs:
+ it.Event = new(VerifiableLoadStreamsLookupUpkeepUpkeepTopUp)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+func (it *VerifiableLoadStreamsLookupUpkeepUpkeepTopUpIterator) Error() error {
+ return it.fail
+}
+
+func (it *VerifiableLoadStreamsLookupUpkeepUpkeepTopUpIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+type VerifiableLoadStreamsLookupUpkeepUpkeepTopUp struct {
+ UpkeepId *big.Int
+ Amount *big.Int
+ BlockNum *big.Int
+ Raw types.Log
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepFilterer) FilterUpkeepTopUp(opts *bind.FilterOpts) (*VerifiableLoadStreamsLookupUpkeepUpkeepTopUpIterator, error) {
+
+ logs, sub, err := _VerifiableLoadStreamsLookupUpkeep.contract.FilterLogs(opts, "UpkeepTopUp")
+ if err != nil {
+ return nil, err
+ }
+ return &VerifiableLoadStreamsLookupUpkeepUpkeepTopUpIterator{contract: _VerifiableLoadStreamsLookupUpkeep.contract, event: "UpkeepTopUp", logs: logs, sub: sub}, nil
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepFilterer) WatchUpkeepTopUp(opts *bind.WatchOpts, sink chan<- *VerifiableLoadStreamsLookupUpkeepUpkeepTopUp) (event.Subscription, error) {
+
+ logs, sub, err := _VerifiableLoadStreamsLookupUpkeep.contract.WatchLogs(opts, "UpkeepTopUp")
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+
+ event := new(VerifiableLoadStreamsLookupUpkeepUpkeepTopUp)
+ if err := _VerifiableLoadStreamsLookupUpkeep.contract.UnpackLog(event, "UpkeepTopUp", log); err != nil {
+ return err
+ }
+ event.Raw = log
+
+ select {
+ case sink <- event:
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ }
+ }), nil
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeepFilterer) ParseUpkeepTopUp(log types.Log) (*VerifiableLoadStreamsLookupUpkeepUpkeepTopUp, error) {
+ event := new(VerifiableLoadStreamsLookupUpkeepUpkeepTopUp)
+ if err := _VerifiableLoadStreamsLookupUpkeep.contract.UnpackLog(event, "UpkeepTopUp", log); err != nil {
+ return nil, err
+ }
+ event.Raw = log
+ return event, nil
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeep) ParseLog(log types.Log) (generated.AbigenLog, error) {
+ switch log.Topics[0] {
+ case _VerifiableLoadStreamsLookupUpkeep.abi.Events["LogEmitted"].ID:
+ return _VerifiableLoadStreamsLookupUpkeep.ParseLogEmitted(log)
+ case _VerifiableLoadStreamsLookupUpkeep.abi.Events["LogEmittedAgain"].ID:
+ return _VerifiableLoadStreamsLookupUpkeep.ParseLogEmittedAgain(log)
+ case _VerifiableLoadStreamsLookupUpkeep.abi.Events["OwnershipTransferRequested"].ID:
+ return _VerifiableLoadStreamsLookupUpkeep.ParseOwnershipTransferRequested(log)
+ case _VerifiableLoadStreamsLookupUpkeep.abi.Events["OwnershipTransferred"].ID:
+ return _VerifiableLoadStreamsLookupUpkeep.ParseOwnershipTransferred(log)
+ case _VerifiableLoadStreamsLookupUpkeep.abi.Events["UpkeepTopUp"].ID:
+ return _VerifiableLoadStreamsLookupUpkeep.ParseUpkeepTopUp(log)
+
+ default:
+ return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0])
+ }
+}
+
+func (VerifiableLoadStreamsLookupUpkeepLogEmitted) Topic() common.Hash {
+ return common.HexToHash("0x97009585a4d2440f981ab6f6eec514343e1e6b2aa9b991a26998e6806f41bf08")
+}
+
+func (VerifiableLoadStreamsLookupUpkeepLogEmittedAgain) Topic() common.Hash {
+ return common.HexToHash("0xc76416badc8398ce17c93eab7b4f60f263241694cf503e4df24f233a8cc1c50d")
+}
+
+func (VerifiableLoadStreamsLookupUpkeepOwnershipTransferRequested) Topic() common.Hash {
+ return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278")
+}
+
+func (VerifiableLoadStreamsLookupUpkeepOwnershipTransferred) Topic() common.Hash {
+ return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0")
+}
+
+func (VerifiableLoadStreamsLookupUpkeepUpkeepTopUp) Topic() common.Hash {
+ return common.HexToHash("0x49d4100ab0124eb4a9a65dc4ea08d6412a43f6f05c49194983f5b322bcc0a5c0")
+}
+
+func (_VerifiableLoadStreamsLookupUpkeep *VerifiableLoadStreamsLookupUpkeep) Address() common.Address {
+ return _VerifiableLoadStreamsLookupUpkeep.address
+}
+
+type VerifiableLoadStreamsLookupUpkeepInterface interface {
+ BUCKETSIZE(opts *bind.CallOpts) (uint16, error)
+
+ AddLinkAmount(opts *bind.CallOpts) (*big.Int, error)
+
+ BucketedDelays(opts *bind.CallOpts, arg0 *big.Int, arg1 uint16, arg2 *big.Int) (*big.Int, error)
+
+ Buckets(opts *bind.CallOpts, arg0 *big.Int) (uint16, error)
+
+ CheckCallback(opts *bind.CallOpts, values [][]byte, extraData []byte) (bool, []byte, error)
+
+ CheckGasToBurns(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error)
+
+ Counters(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error)
+
+ Delays(opts *bind.CallOpts, arg0 *big.Int, arg1 *big.Int) (*big.Int, error)
+
+ DummyMap(opts *bind.CallOpts, arg0 [32]byte) (bool, error)
+
+ Eligible(opts *bind.CallOpts, upkeepId *big.Int) (bool, error)
+
+ EmittedAgainSig(opts *bind.CallOpts) ([32]byte, error)
+
+ EmittedSig(opts *bind.CallOpts) ([32]byte, error)
+
+ FeedParamKey(opts *bind.CallOpts) (string, error)
+
+ FeedsHex(opts *bind.CallOpts, arg0 *big.Int) (string, error)
+
+ FirstPerformBlocks(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error)
+
+ GasLimits(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error)
+
+ GetActiveUpkeepIDsDeployedByThisContract(opts *bind.CallOpts, startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error)
+
+ GetAllActiveUpkeepIDsOnRegistry(opts *bind.CallOpts, startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error)
+
+ GetBalance(opts *bind.CallOpts, id *big.Int) (*big.Int, error)
+
+ GetBucketedDelays(opts *bind.CallOpts, upkeepId *big.Int, bucket uint16) ([]*big.Int, error)
+
+ GetBucketedDelaysLength(opts *bind.CallOpts, upkeepId *big.Int) (*big.Int, error)
+
+ GetDelays(opts *bind.CallOpts, upkeepId *big.Int) ([]*big.Int, error)
+
+ GetDelaysLength(opts *bind.CallOpts, upkeepId *big.Int) (*big.Int, error)
+
+ GetForwarder(opts *bind.CallOpts, upkeepID *big.Int) (common.Address, error)
+
+ GetLogTriggerConfig(opts *bind.CallOpts, addr common.Address, selector uint8, topic0 [32]byte, topic1 [32]byte, topic2 [32]byte, topic3 [32]byte) ([]byte, error)
+
+ GetMinBalanceForUpkeep(opts *bind.CallOpts, upkeepId *big.Int) (*big.Int, error)
+
+ GetPxDelayLastNPerforms(opts *bind.CallOpts, upkeepId *big.Int, p *big.Int, n *big.Int) (*big.Int, error)
+
+ GetSumDelayInBucket(opts *bind.CallOpts, upkeepId *big.Int, bucket uint16) (*big.Int, *big.Int, error)
+
+ GetSumDelayLastNPerforms(opts *bind.CallOpts, upkeepId *big.Int, n *big.Int) (*big.Int, *big.Int, error)
+
+ GetTriggerType(opts *bind.CallOpts, upkeepId *big.Int) (uint8, error)
+
+ GetUpkeepInfo(opts *bind.CallOpts, upkeepId *big.Int) (KeeperRegistryBase21UpkeepInfo, error)
+
+ GetUpkeepPrivilegeConfig(opts *bind.CallOpts, upkeepId *big.Int) ([]byte, error)
+
+ GetUpkeepTriggerConfig(opts *bind.CallOpts, upkeepId *big.Int) ([]byte, error)
+
+ Intervals(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error)
+
+ LastTopUpBlocks(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error)
+
+ LinkToken(opts *bind.CallOpts) (common.Address, error)
+
+ MinBalanceThresholdMultiplier(opts *bind.CallOpts) (uint8, error)
+
+ Owner(opts *bind.CallOpts) (common.Address, error)
+
+ PerformDataSizes(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error)
+
+ PerformGasToBurns(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error)
+
+ PreviousPerformBlocks(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error)
+
+ Registrar(opts *bind.CallOpts) (common.Address, error)
+
+ Registry(opts *bind.CallOpts) (common.Address, error)
+
+ TimeParamKey(opts *bind.CallOpts) (string, error)
+
+ UpkeepTopUpCheckInterval(opts *bind.CallOpts) (*big.Int, error)
+
+ UseArbitrumBlockNum(opts *bind.CallOpts) (bool, error)
+
+ AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error)
+
+ AddFunds(opts *bind.TransactOpts, upkeepId *big.Int, amount *big.Int) (*types.Transaction, error)
+
+ BatchCancelUpkeeps(opts *bind.TransactOpts, upkeepIds []*big.Int) (*types.Transaction, error)
+
+ BatchPreparingUpkeeps(opts *bind.TransactOpts, upkeepIds []*big.Int, selector uint8, topic0 [32]byte, topic1 [32]byte, topic2 [32]byte, topic3 [32]byte) (*types.Transaction, error)
+
+ BatchPreparingUpkeepsSimple(opts *bind.TransactOpts, upkeepIds []*big.Int, log uint8, selector uint8) (*types.Transaction, error)
+
+ BatchRegisterUpkeeps(opts *bind.TransactOpts, number uint8, gasLimit uint32, triggerType uint8, triggerConfig []byte, amount *big.Int, checkGasToBurn *big.Int, performGasToBurn *big.Int) (*types.Transaction, error)
+
+ BatchSendLogs(opts *bind.TransactOpts, log uint8) (*types.Transaction, error)
+
+ BatchSetIntervals(opts *bind.TransactOpts, upkeepIds []*big.Int, interval uint32) (*types.Transaction, error)
+
+ BatchUpdatePipelineData(opts *bind.TransactOpts, upkeepIds []*big.Int) (*types.Transaction, error)
+
+ BatchWithdrawLinks(opts *bind.TransactOpts, upkeepIds []*big.Int) (*types.Transaction, error)
+
+ BurnPerformGas(opts *bind.TransactOpts, upkeepId *big.Int, startGas *big.Int, blockNum *big.Int) (*types.Transaction, error)
+
+ CheckUpkeep(opts *bind.TransactOpts, checkData []byte) (*types.Transaction, error)
+
+ PerformUpkeep(opts *bind.TransactOpts, performData []byte) (*types.Transaction, error)
+
+ SendLog(opts *bind.TransactOpts, upkeepId *big.Int, log uint8) (*types.Transaction, error)
+
+ SetConfig(opts *bind.TransactOpts, newRegistrar common.Address) (*types.Transaction, error)
+
+ SetFeeds(opts *bind.TransactOpts, _feeds []string) (*types.Transaction, error)
+
+ SetInterval(opts *bind.TransactOpts, upkeepId *big.Int, _interval *big.Int) (*types.Transaction, error)
+
+ SetParamKeys(opts *bind.TransactOpts, _feedParamKey string, _timeParamKey string) (*types.Transaction, error)
+
+ SetPerformDataSize(opts *bind.TransactOpts, upkeepId *big.Int, value *big.Int) (*types.Transaction, error)
+
+ SetUpkeepGasLimit(opts *bind.TransactOpts, upkeepId *big.Int, gasLimit uint32) (*types.Transaction, error)
+
+ SetUpkeepPrivilegeConfig(opts *bind.TransactOpts, upkeepId *big.Int, cfg []byte) (*types.Transaction, error)
+
+ TopUpFund(opts *bind.TransactOpts, upkeepId *big.Int, blockNum *big.Int) (*types.Transaction, error)
+
+ TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error)
+
+ UpdateLogTriggerConfig1(opts *bind.TransactOpts, upkeepId *big.Int, addr common.Address, selector uint8, topic0 [32]byte, topic1 [32]byte, topic2 [32]byte, topic3 [32]byte) (*types.Transaction, error)
+
+ UpdateLogTriggerConfig2(opts *bind.TransactOpts, upkeepId *big.Int, cfg []byte) (*types.Transaction, error)
+
+ UpdateUpkeepPipelineData(opts *bind.TransactOpts, upkeepId *big.Int, pipelineData []byte) (*types.Transaction, error)
+
+ WithdrawLinks(opts *bind.TransactOpts) (*types.Transaction, error)
+
+ WithdrawLinks0(opts *bind.TransactOpts, upkeepId *big.Int) (*types.Transaction, error)
+
+ Receive(opts *bind.TransactOpts) (*types.Transaction, error)
+
+ FilterLogEmitted(opts *bind.FilterOpts, upkeepId []*big.Int, blockNum []*big.Int, addr []common.Address) (*VerifiableLoadStreamsLookupUpkeepLogEmittedIterator, error)
+
+ WatchLogEmitted(opts *bind.WatchOpts, sink chan<- *VerifiableLoadStreamsLookupUpkeepLogEmitted, upkeepId []*big.Int, blockNum []*big.Int, addr []common.Address) (event.Subscription, error)
+
+ ParseLogEmitted(log types.Log) (*VerifiableLoadStreamsLookupUpkeepLogEmitted, error)
+
+ FilterLogEmittedAgain(opts *bind.FilterOpts, upkeepId []*big.Int, blockNum []*big.Int, addr []common.Address) (*VerifiableLoadStreamsLookupUpkeepLogEmittedAgainIterator, error)
+
+ WatchLogEmittedAgain(opts *bind.WatchOpts, sink chan<- *VerifiableLoadStreamsLookupUpkeepLogEmittedAgain, upkeepId []*big.Int, blockNum []*big.Int, addr []common.Address) (event.Subscription, error)
+
+ ParseLogEmittedAgain(log types.Log) (*VerifiableLoadStreamsLookupUpkeepLogEmittedAgain, error)
+
+ FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VerifiableLoadStreamsLookupUpkeepOwnershipTransferRequestedIterator, error)
+
+ WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *VerifiableLoadStreamsLookupUpkeepOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error)
+
+ ParseOwnershipTransferRequested(log types.Log) (*VerifiableLoadStreamsLookupUpkeepOwnershipTransferRequested, error)
+
+ FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VerifiableLoadStreamsLookupUpkeepOwnershipTransferredIterator, error)
+
+ WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *VerifiableLoadStreamsLookupUpkeepOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error)
+
+ ParseOwnershipTransferred(log types.Log) (*VerifiableLoadStreamsLookupUpkeepOwnershipTransferred, error)
+
+ FilterUpkeepTopUp(opts *bind.FilterOpts) (*VerifiableLoadStreamsLookupUpkeepUpkeepTopUpIterator, error)
+
+ WatchUpkeepTopUp(opts *bind.WatchOpts, sink chan<- *VerifiableLoadStreamsLookupUpkeepUpkeepTopUp) (event.Subscription, error)
+
+ ParseUpkeepTopUp(log types.Log) (*VerifiableLoadStreamsLookupUpkeepUpkeepTopUp, error)
+
+ ParseLog(log types.Log) (generated.AbigenLog, error)
+
+ Address() common.Address
+}
diff --git a/core/gethwrappers/generated/verifiable_load_upkeep_wrapper/verifiable_load_upkeep_wrapper.go b/core/gethwrappers/generated/verifiable_load_upkeep_wrapper/verifiable_load_upkeep_wrapper.go
index 41d3ee1ff61..6dc8e73f1fd 100644
--- a/core/gethwrappers/generated/verifiable_load_upkeep_wrapper/verifiable_load_upkeep_wrapper.go
+++ b/core/gethwrappers/generated/verifiable_load_upkeep_wrapper/verifiable_load_upkeep_wrapper.go
@@ -30,9 +30,22 @@ var (
_ = abi.ConvertType
)
+type KeeperRegistryBase21UpkeepInfo struct {
+ Target common.Address
+ PerformGas uint32
+ CheckData []byte
+ Balance *big.Int
+ Admin common.Address
+ MaxValidBlocknumber uint64
+ LastPerformedBlockNumber uint32
+ AmountSpent *big.Int
+ Paused bool
+ OffchainConfig []byte
+}
+
var VerifiableLoadUpkeepMetaData = &bind.MetaData{
- ABI: "[{\"inputs\":[{\"internalType\":\"contractAutomationRegistrar2_1\",\"name\":\"_registrar\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_useArb\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"IndexOutOfRange\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"blockNum\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"LogEmitted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Received\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"blockNum\",\"type\":\"uint256\"}],\"name\":\"UpkeepTopUp\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"}],\"name\":\"UpkeepsRegistered\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BUCKET_SIZE\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"addFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"addLinkAmount\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"}],\"name\":\"batchCancelUpkeeps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"number\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"},{\"internalType\":\"uint256\",\"name\":\"checkGasToBurn\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"performGasToBurn\",\"type\":\"uint256\"}],\"name\":\"batchRegisterUpkeeps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"batchSendLogs\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"},{\"internalType\":\"uint32\",\"name\":\"interval\",\"type\":\"uint32\"}],\"name\":\"batchSetIntervals\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"}],\"name\":\"batchUpdatePipelineData\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"}],\"name\":\"batchWithdrawLinks\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"bucketedDelays\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"buckets\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"startGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"blockNum\",\"type\":\"uint256\"}],\"name\":\"burnPerformGas\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"cancelUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"checkGasToBurns\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"}],\"name\":\"checkUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"counters\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"delays\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"dummyMap\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"eligible\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"emittedSig\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"firstPerformBlocks\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"gasLimits\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"startIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxCount\",\"type\":\"uint256\"}],\"name\":\"getActiveUpkeepIDs\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"bucket\",\"type\":\"uint16\"}],\"name\":\"getBucketedDelays\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getBucketedDelaysLength\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getDelays\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getDelaysLength\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getLogTriggerConfig\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"logTrigger\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"p\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"n\",\"type\":\"uint256\"}],\"name\":\"getPxDelayLastNPerforms\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"bucket\",\"type\":\"uint16\"}],\"name\":\"getSumDelayInBucket\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"n\",\"type\":\"uint256\"}],\"name\":\"getSumDelayLastNPerforms\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"intervals\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"lastTopUpBlocks\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"linkToken\",\"outputs\":[{\"internalType\":\"contractLinkTokenInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"minBalanceThresholdMultiplier\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"performDataSizes\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"performGasToBurns\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"}],\"name\":\"performUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"previousPerformBlocks\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"registrar\",\"outputs\":[{\"internalType\":\"contractAutomationRegistrar2_1\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"registry\",\"outputs\":[{\"internalType\":\"contractIKeeperRegistryMaster\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"sendLog\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"setAddLinkAmount\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"setCheckGasToBurn\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractAutomationRegistrar2_1\",\"name\":\"newRegistrar\",\"type\":\"address\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_interval\",\"type\":\"uint256\"}],\"name\":\"setInterval\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"newMinBalanceThresholdMultiplier\",\"type\":\"uint8\"}],\"name\":\"setMinBalanceThresholdMultiplier\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"setPerformDataSize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"setPerformGasToBurn\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"}],\"name\":\"setUpkeepGasLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"newInterval\",\"type\":\"uint256\"}],\"name\":\"setUpkeepTopUpCheckInterval\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"blockNum\",\"type\":\"uint256\"}],\"name\":\"topUpFund\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"pipelineData\",\"type\":\"bytes\"}],\"name\":\"updateUpkeepPipelineData\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"upkeepTopUpCheckInterval\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"useArbitrumBlockNum\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawLinks\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"withdrawLinks\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]",
- Bin: "0x60e06040527f97009585a4d2440f981ab6f6eec514343e1e6b2aa9b991a26998e6806f41bf086080526005601455601580546001600160681b0319166c140000000002c68af0bb140000179055606460c0523480156200005e57600080fd5b506040516200456738038062004567833981016040819052620000819162000310565b81813380600081620000da5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b03848116919091179091558116156200010d576200010d816200024c565b5050601180546001600160a01b0319166001600160a01b038516908117909155604080516330fe427560e21b815281516000945063c3f909d4926004808401939192918290030181865afa1580156200016a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000190919062000353565b50601380546001600160a01b0319166001600160a01b038381169190911790915560115460408051631b6b6d2360e01b81529051939450911691631b6b6d23916004808201926020929091908290030181865afa158015620001f6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200021c919062000384565b601280546001600160a01b0319166001600160a01b039290921691909117905550151560a05250620003ab915050565b336001600160a01b03821603620002a65760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401620000d1565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6001600160a01b03811681146200030d57600080fd5b50565b600080604083850312156200032457600080fd5b82516200033181620002f7565b602084015190925080151581146200034857600080fd5b809150509250929050565b600080604083850312156200036757600080fd5b82516200037481620002f7565b6020939093015192949293505050565b6000602082840312156200039757600080fd5b8151620003a481620002f7565b9392505050565b60805160a05160c051614177620003f0600039600081816104c401526118d30152600081816107b20152612b1e015260008181610adc01526112f101526141776000f3fe60806040526004361061039b5760003560e01c8063776898c8116101dc578063a72aa27e11610102578063d6051a72116100a0578063e45530831161006f578063e455308314610d31578063f2fde38b14610d47578063fba7ffa314610d67578063fcdc1f6314610d9457600080fd5b8063d6051a7214610ca4578063daee1aeb14610cc4578063dbef701e14610ce4578063e0114adb14610d0457600080fd5b8063becde0e1116100dc578063becde0e114610bab578063c357f1f314610bcb578063c804802214610c25578063d355852814610c4557600080fd5b8063a72aa27e14610b3e578063a79c404314610b5e578063af953a4a14610b8b57600080fd5b8063948108f71161017a5780639d385eaa116101495780639d385eaa14610aaa578063a654824814610aca578063a6b5947514610afe578063a6c60d8914610b1e57600080fd5b8063948108f7146109f05780639ac542eb14610a105780639b42935414610a4c5780639b51fb0d14610a7957600080fd5b80637e7a46dc116101b65780637e7a46dc146109585780638da5cb5b146109785780638fcb3fba146109a3578063924ca578146109d057600080fd5b8063776898c8146108f657806379ba5097146109165780637b1039991461092b57600080fd5b806346e7a63e116102c1578063636092e81161025f5780636e04ff0d1161022e5780636e04ff0d1461083e5780637145f11b1461086c57806373644cce1461089c57806376721303146108c957600080fd5b8063636092e81461075e578063642f6cef146107a057806369cdbadb146107e457806369e9b7731461081157600080fd5b8063597109921161029b57806359710992146106e75780635d4ee7f3146106fc5780635f17e6161461071157806360457ff51461073157600080fd5b806346e7a63e1461066d57806351c98be31461069a57806357970e93146106ba57600080fd5b806320e3dbd411610339578063328ffd1111610308578063328ffd11146105e05780633ebe8d6c1461060d5780634585e33b1461062d57806345d2ec171461064d57600080fd5b806320e3dbd41461052e57806328c4b57b1461054e5780632a9032d31461056e5780632b20e3971461058e57600080fd5b80630d4a4fb1116103755780630d4a4fb1146104655780630e577d421461049257806312c55027146104b2578063206c32e8146104f957600080fd5b806306c1cc00146103df57806306e3b63214610401578063077ac6211461043757600080fd5b366103da57604080513381523460208201527f88a5966d370b9919b20f3e2c13ff65706f196a4e32cc2c12bf57088f88525874910160405180910390a1005b600080fd5b3480156103eb57600080fd5b506103ff6103fa3660046133cc565b610dc1565b005b34801561040d57600080fd5b5061042161041c366004613468565b61117d565b60405161042e919061348a565b60405180910390f35b34801561044357600080fd5b506104576104523660046134e5565b61127c565b60405190815260200161042e565b34801561047157600080fd5b5061048561048036600461351a565b6112ba565b60405161042e91906135a1565b34801561049e57600080fd5b506103ff6104ad36600461351a565b6113d7565b3480156104be57600080fd5b506104e67f000000000000000000000000000000000000000000000000000000000000000081565b60405161ffff909116815260200161042e565b34801561050557600080fd5b506105196105143660046135b4565b61141f565b6040805192835260208301919091520161042e565b34801561053a57600080fd5b506103ff610549366004613602565b6114a2565b34801561055a57600080fd5b5061045761056936600461361f565b61166c565b34801561057a57600080fd5b506103ff610589366004613690565b6116d7565b34801561059a57600080fd5b506011546105bb9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161042e565b3480156105ec57600080fd5b506104576105fb36600461351a565b60036020526000908152604090205481565b34801561061957600080fd5b5061045761062836600461351a565b611771565b34801561063957600080fd5b506103ff610648366004613714565b6117da565b34801561065957600080fd5b506104216106683660046135b4565b6119e9565b34801561067957600080fd5b5061045761068836600461351a565b600a6020526000908152604090205481565b3480156106a657600080fd5b506103ff6106b536600461374a565b611a58565b3480156106c657600080fd5b506012546105bb9073ffffffffffffffffffffffffffffffffffffffff1681565b3480156106f357600080fd5b506103ff611afc565b34801561070857600080fd5b506103ff611ce7565b34801561071d57600080fd5b506103ff61072c366004613468565b611e22565b34801561073d57600080fd5b5061045761074c36600461351a565b60076020526000908152604090205481565b34801561076a57600080fd5b50601554610783906bffffffffffffffffffffffff1681565b6040516bffffffffffffffffffffffff909116815260200161042e565b3480156107ac57600080fd5b506107d47f000000000000000000000000000000000000000000000000000000000000000081565b604051901515815260200161042e565b3480156107f057600080fd5b506104576107ff36600461351a565b60086020526000908152604090205481565b34801561081d57600080fd5b506103ff61082c366004613468565b60009182526008602052604090912055565b34801561084a57600080fd5b5061085e610859366004613714565b611eef565b60405161042e9291906137a1565b34801561087857600080fd5b506107d461088736600461351a565b600b6020526000908152604090205460ff1681565b3480156108a857600080fd5b506104576108b736600461351a565b6000908152600c602052604090205490565b3480156108d557600080fd5b506104576108e436600461351a565b60046020526000908152604090205481565b34801561090257600080fd5b506107d461091136600461351a565b61201c565b34801561092257600080fd5b506103ff61206e565b34801561093757600080fd5b506013546105bb9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561096457600080fd5b506103ff6109733660046137bc565b612170565b34801561098457600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff166105bb565b3480156109af57600080fd5b506104576109be36600461351a565b60056020526000908152604090205481565b3480156109dc57600080fd5b506103ff6109eb366004613468565b612201565b3480156109fc57600080fd5b506103ff610a0b366004613808565b612446565b348015610a1c57600080fd5b50601554610a3a906c01000000000000000000000000900460ff1681565b60405160ff909116815260200161042e565b348015610a5857600080fd5b506103ff610a67366004613468565b60009182526009602052604090912055565b348015610a8557600080fd5b506104e6610a9436600461351a565b600e6020526000908152604090205461ffff1681565b348015610ab657600080fd5b50610421610ac536600461351a565b61258f565b348015610ad657600080fd5b506104577f000000000000000000000000000000000000000000000000000000000000000081565b348015610b0a57600080fd5b506103ff610b1936600461361f565b6125f1565b348015610b2a57600080fd5b506103ff610b3936600461351a565b601455565b348015610b4a57600080fd5b506103ff610b59366004613838565b61265a565b348015610b6a57600080fd5b506103ff610b79366004613468565b60009182526007602052604090912055565b348015610b9757600080fd5b506103ff610ba636600461351a565b612705565b348015610bb757600080fd5b506103ff610bc6366004613690565b61278b565b348015610bd757600080fd5b506103ff610be636600461385d565b601580547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff92909216919091179055565b348015610c3157600080fd5b506103ff610c4036600461351a565b612825565b348015610c5157600080fd5b506103ff610c6036600461387a565b6015805460ff9092166c01000000000000000000000000027fffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffff909216919091179055565b348015610cb057600080fd5b50610519610cbf366004613468565b6128bd565b348015610cd057600080fd5b506103ff610cdf366004613690565b612926565b348015610cf057600080fd5b50610457610cff366004613468565b6129f1565b348015610d1057600080fd5b50610457610d1f36600461351a565b60096020526000908152604090205481565b348015610d3d57600080fd5b5061045760145481565b348015610d5357600080fd5b506103ff610d62366004613602565b612a22565b348015610d7357600080fd5b50610457610d8236600461351a565b60066020526000908152604090205481565b348015610da057600080fd5b50610457610daf36600461351a565b60026020526000908152604090205481565b6040805161018081018252600461014082019081527f746573740000000000000000000000000000000000000000000000000000000061016083015281528151602081810184526000808352818401929092523083850181905263ffffffff8b166060850152608084015260ff808a1660a08501528451808301865283815260c085015260e0840189905284519182019094529081526101008201526bffffffffffffffffffffffff8516610120820152601254601154919273ffffffffffffffffffffffffffffffffffffffff9182169263095ea7b3921690610ea7908c16886138c6565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815273ffffffffffffffffffffffffffffffffffffffff90921660048301526bffffffffffffffffffffffff1660248201526044016020604051808303816000875af1158015610f25573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f49919061390a565b5060008860ff1667ffffffffffffffff811115610f6857610f6861326e565b604051908082528060200260200182016040528015610f91578160200160208202803683370190505b50905060005b8960ff168160ff16101561113a576000610fb084612a36565b90508860ff166001036110e8576040517f0d4a4fb1000000000000000000000000000000000000000000000000000000008152600481018290526000903090630d4a4fb190602401600060405180830381865afa158015611015573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261105b9190810190613972565b6013546040517f4ee88d3500000000000000000000000000000000000000000000000000000000815291925073ffffffffffffffffffffffffffffffffffffffff1690634ee88d35906110b490859085906004016139a7565b600060405180830381600087803b1580156110ce57600080fd5b505af11580156110e2573d6000803e3d6000fd5b50505050505b80838360ff16815181106110fe576110fe6139c0565b60209081029190910181019190915260009182526008815260408083208890556007909152902084905580611132816139ef565b915050610f97565b507f2ee10f7eb180441fb9fbba75b10c0162b5390b557712c93426243ca8f383c7118160405161116a919061348a565b60405180910390a1505050505050505050565b6060600061118b600f612b04565b90508084106111c6576040517f1390f2a100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b826000036111db576111d88482613a0e565b92505b60008367ffffffffffffffff8111156111f6576111f661326e565b60405190808252806020026020018201604052801561121f578160200160208202803683370190505b50905060005b848110156112715761124261123a8288613a21565b600f90612b0e565b828281518110611254576112546139c0565b60209081029190910101528061126981613a34565b915050611225565b509150505b92915050565b600d60205282600052604060002060205281600052604060002081815481106112a457600080fd5b9060005260206000200160009250925050505481565b606060006040518060c001604052803073ffffffffffffffffffffffffffffffffffffffff168152602001600160ff1681526020017f000000000000000000000000000000000000000000000000000000000000000081526020018460405160200161132891815260200190565b60405160208183030381529060405261134090613a6c565b81526020016000801b81526020016000801b8152509050806040516020016113c09190600060c08201905073ffffffffffffffffffffffffffffffffffffffff835116825260ff602084015116602083015260408301516040830152606083015160608301526080830151608083015260a083015160a083015292915050565b604051602081830303815290604052915050919050565b60006113e1612b1a565b604051308152909150819083907f97009585a4d2440f981ab6f6eec514343e1e6b2aa9b991a26998e6806f41bf089060200160405180910390a35050565b6000828152600d6020908152604080832061ffff85168452825280832080548251818502810185019093528083528493849392919083018282801561148357602002820191906000526020600020905b81548152602001906001019080831161146f575b50505050509050611495818251612bbc565b92509250505b9250929050565b601180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8316908117909155604080517fc3f909d400000000000000000000000000000000000000000000000000000000815281516000939263c3f909d492600480820193918290030181865afa158015611538573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061155c9190613abc565b50601380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691909117909155601154604080517f1b6b6d230000000000000000000000000000000000000000000000000000000081529051939450911691631b6b6d23916004808201926020929091908290030181865afa1580156115ff573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116239190613aea565b601280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff929092169190911790555050565b6000838152600c6020908152604080832080548251818502810185019093528083526116cd938301828280156116c157602002820191906000526020600020905b8154815260200190600101908083116116ad575b50505050508484612c41565b90505b9392505050565b8060005b818160ff16101561176b573063c8048022858560ff8516818110611701576117016139c0565b905060200201356040518263ffffffff1660e01b815260040161172691815260200190565b600060405180830381600087803b15801561174057600080fd5b505af1158015611754573d6000803e3d6000fd5b505050508080611763906139ef565b9150506116db565b50505050565b6000818152600e602052604081205461ffff1681805b8261ffff168161ffff16116117d2576000858152600d6020908152604080832061ffff851684529091529020546117be9083613a21565b9150806117ca81613b07565b915050611787565b509392505050565b60005a905060006117ed83850185613b28565b5060008181526005602090815260408083205460049092528220549293509190611815612b1a565b905082600003611835576000848152600560205260409020819055611990565b60008481526003602052604081205461184e8484613a0e565b6118589190613a0e565b6000868152600e6020908152604080832054600d835281842061ffff9091168085529083528184208054835181860281018601909452808452959650909491929091908301828280156118ca57602002820191906000526020600020905b8154815260200190600101908083116118b6575b505050505090507f000000000000000000000000000000000000000000000000000000000000000061ffff16815103611945578161190781613b07565b6000898152600e6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff83161790559250505b506000868152600d6020908152604080832061ffff909416835292815282822080546001818101835591845282842001859055888352600c8252928220805493840181558252902001555b6000848152600660205260408120546119aa906001613a21565b60008681526006602090815260408083208490556004909152902083905590506119d48583612201565b6119df8587846125f1565b5050505050505050565b6000828152600d6020908152604080832061ffff85168452825291829020805483518184028101840190945280845260609392830182828015611a4b57602002820191906000526020600020905b815481526020019060010190808311611a37575b5050505050905092915050565b8160005b81811015611af55730635f17e616868684818110611a7c57611a7c6139c0565b90506020020135856040518363ffffffff1660e01b8152600401611ab092919091825263ffffffff16602082015260400190565b600060405180830381600087803b158015611aca57600080fd5b505af1158015611ade573d6000803e3d6000fd5b505050508080611aed90613a34565b915050611a5c565b5050505050565b6013546040517f06e3b632000000000000000000000000000000000000000000000000000000008152600060048201819052602482018190529173ffffffffffffffffffffffffffffffffffffffff16906306e3b63290604401600060405180830381865afa158015611b73573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611bb99190810190613b6f565b80519091506000611bc8612b1a565b905060005b8281101561176b576000848281518110611be957611be96139c0565b60209081029190910101516013546040517f5147cd590000000000000000000000000000000000000000000000000000000081526004810183905291925060009173ffffffffffffffffffffffffffffffffffffffff90911690635147cd5990602401602060405180830381865afa158015611c69573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c8d9190613c15565b90508060ff16600103611cd257604051308152849083907f97009585a4d2440f981ab6f6eec514343e1e6b2aa9b991a26998e6806f41bf089060200160405180910390a35b50508080611cdf90613a34565b915050611bcd565b611cef612da0565b6012546040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015611d5e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d829190613c32565b6012546040517fa9059cbb0000000000000000000000000000000000000000000000000000000081523360048201526024810183905291925073ffffffffffffffffffffffffffffffffffffffff169063a9059cbb906044016020604051808303816000875af1158015611dfa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e1e919061390a565b5050565b60008281526003602090815260408083208490556005825280832083905560068252808320839055600c9091528120611e5a9161321b565b6000828152600e602052604081205461ffff16905b8161ffff168161ffff1611611eb6576000848152600d6020908152604080832061ffff851684529091528120611ea49161321b565b80611eae81613b07565b915050611e6f565b5050506000908152600e6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000169055565b6000606060005a90506000611f068587018761351a565b60008181526009602090815260408083205460089092528220549293509190838367ffffffffffffffff811115611f3f57611f3f61326e565b6040519080825280601f01601f191660200182016040528015611f69576020820181803683370190505b50604051602001611f7b9291906139a7565b60405160208183030381529060405290506000611f96612b1a565b90506000611fa38661201c565b90505b835a611fb29089613a0e565b611fbe90612710613a21565b101561200c5781406000908152600b6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690558161200481613c4b565b925050611fa6565b9a91995090975050505050505050565b600081815260056020526040812054810361203957506001919050565b60008281526003602090815260408083205460049092529091205461205c612b1a565b6120669190613a0e565b101592915050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146120f4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6013546040517fcd7f71b500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063cd7f71b5906121ca90869086908690600401613c80565b600060405180830381600087803b1580156121e457600080fd5b505af11580156121f8573d6000803e3d6000fd5b50505050505050565b60145460008381526002602052604090205461221d9083613a0e565b1115611e1e576013546040517fc7c3a19a0000000000000000000000000000000000000000000000000000000081526004810184905260009173ffffffffffffffffffffffffffffffffffffffff169063c7c3a19a90602401600060405180830381865afa158015612293573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526122d99190810190613d02565b6013546040517fb657bc9c0000000000000000000000000000000000000000000000000000000081526004810186905291925060009173ffffffffffffffffffffffffffffffffffffffff9091169063b657bc9c90602401602060405180830381865afa15801561234e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123729190613e21565b6015549091506123969082906c01000000000000000000000000900460ff166138c6565b6bffffffffffffffffffffffff1682606001516bffffffffffffffffffffffff16101561176b576015546123d99085906bffffffffffffffffffffffff16612446565b60008481526002602090815260409182902085905560155482518781526bffffffffffffffffffffffff909116918101919091529081018490527f49d4100ab0124eb4a9a65dc4ea08d6412a43f6f05c49194983f5b322bcc0a5c09060600160405180910390a150505050565b6012546013546040517f095ea7b300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff91821660048201526bffffffffffffffffffffffff8416602482015291169063095ea7b3906044016020604051808303816000875af11580156124ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124f2919061390a565b506013546040517f948108f7000000000000000000000000000000000000000000000000000000008152600481018490526bffffffffffffffffffffffff8316602482015273ffffffffffffffffffffffffffffffffffffffff9091169063948108f790604401600060405180830381600087803b15801561257357600080fd5b505af1158015612587573d6000803e3d6000fd5b505050505050565b6000818152600c60209081526040918290208054835181840281018401909452808452606093928301828280156125e557602002820191906000526020600020905b8154815260200190600101908083116125d1575b50505050509050919050565b6000838152600760205260409020545b805a61260d9085613a0e565b61261990612710613a21565b101561176b5781406000908152600b6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055612601565b6013546040517fa72aa27e0000000000000000000000000000000000000000000000000000000081526004810184905263ffffffff8316602482015273ffffffffffffffffffffffffffffffffffffffff9091169063a72aa27e90604401600060405180830381600087803b1580156126d257600080fd5b505af11580156126e6573d6000803e3d6000fd5b505050600092835250600a602052604090912063ffffffff9091169055565b6013546040517f744bfe610000000000000000000000000000000000000000000000000000000081526004810183905230602482015273ffffffffffffffffffffffffffffffffffffffff9091169063744bfe6190604401600060405180830381600087803b15801561277757600080fd5b505af1158015611af5573d6000803e3d6000fd5b8060005b818163ffffffff16101561176b573063af953a4a858563ffffffff85168181106127bb576127bb6139c0565b905060200201356040518263ffffffff1660e01b81526004016127e091815260200190565b600060405180830381600087803b1580156127fa57600080fd5b505af115801561280e573d6000803e3d6000fd5b50505050808061281d90613e3e565b91505061278f565b6013546040517fc80480220000000000000000000000000000000000000000000000000000000081526004810183905273ffffffffffffffffffffffffffffffffffffffff9091169063c804802290602401600060405180830381600087803b15801561289157600080fd5b505af11580156128a5573d6000803e3d6000fd5b50505050611e1e81600f612e2390919063ffffffff16565b6000828152600c6020908152604080832080548251818502810185019093528083528493849392919083018282801561291557602002820191906000526020600020905b815481526020019060010190808311612901575b505050505090506114958185612bbc565b8060005b8181101561176b576000848483818110612946576129466139c0565b9050602002013590503073ffffffffffffffffffffffffffffffffffffffff16637e7a46dc828360405160200161297f91815260200190565b6040516020818303038152906040526040518363ffffffff1660e01b81526004016129ab9291906139a7565b600060405180830381600087803b1580156129c557600080fd5b505af11580156129d9573d6000803e3d6000fd5b505050505080806129e990613a34565b91505061292a565b600c6020528160005260406000208181548110612a0d57600080fd5b90600052602060002001600091509150505481565b612a2a612da0565b612a3381612e2f565b50565b6011546040517f3f678e11000000000000000000000000000000000000000000000000000000008152600091829173ffffffffffffffffffffffffffffffffffffffff90911690633f678e1190612a91908690600401613e57565b6020604051808303816000875af1158015612ab0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ad49190613c32565b9050612ae1600f82612f24565b506060909201516000838152600a6020526040902063ffffffff90911690555090565b6000611276825490565b60006116d08383612f30565b60007f000000000000000000000000000000000000000000000000000000000000000015612bb757606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612b8e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bb29190613c32565b905090565b504390565b815160009081908190841580612bd25750808510155b15612bdb578094505b60008092505b85831015612c3757866001612bf68585613a0e565b612c009190613a0e565b81518110612c1057612c106139c0565b602002602001015181612c239190613a21565b905082612c2f81613a34565b935050612be1565b9694955050505050565b82516000908190831580612c555750808410155b15612c5e578093505b60008467ffffffffffffffff811115612c7957612c7961326e565b604051908082528060200260200182016040528015612ca2578160200160208202803683370190505b509050600092505b84831015612d1057866001612cbf8585613a0e565b612cc99190613a0e565b81518110612cd957612cd96139c0565b6020026020010151818481518110612cf357612cf36139c0565b602090810291909101015282612d0881613a34565b935050612caa565b612d2981600060018451612d249190613a0e565b612f5a565b85606403612d62578060018251612d409190613a0e565b81518110612d5057612d506139c0565b602002602001015193505050506116d0565b806064825188612d729190613fa9565b612d7c9190614015565b81518110612d8c57612d8c6139c0565b602002602001015193505050509392505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314612e21576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016120eb565b565b60006116d083836130d2565b3373ffffffffffffffffffffffffffffffffffffffff821603612eae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016120eb565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60006116d083836131cc565b6000826000018281548110612f4757612f476139c0565b9060005260206000200154905092915050565b8181808203612f6a575050505050565b6000856002612f798787614029565b612f839190614049565b612f8d90876140b1565b81518110612f9d57612f9d6139c0565b602002602001015190505b8183136130ac575b80868481518110612fc357612fc36139c0565b60200260200101511015612fe35782612fdb816140d9565b935050612fb0565b858281518110612ff557612ff56139c0565b6020026020010151811015613016578161300e8161410a565b925050612fe3565b8183136130a75785828151811061302f5761302f6139c0565b6020026020010151868481518110613049576130496139c0565b6020026020010151878581518110613063576130636139c0565b6020026020010188858151811061307c5761307c6139c0565b60209081029190910101919091525282613095816140d9565b93505081806130a39061410a565b9250505b612fa8565b818512156130bf576130bf868684612f5a565b8383121561258757612587868486612f5a565b600081815260018301602052604081205480156131bb5760006130f6600183613a0e565b855490915060009061310a90600190613a0e565b905081811461316f57600086600001828154811061312a5761312a6139c0565b906000526020600020015490508087600001848154811061314d5761314d6139c0565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806131805761318061413b565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050611276565b6000915050611276565b5092915050565b600081815260018301602052604081205461321357508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155611276565b506000611276565b5080546000825590600052602060002090810190612a3391905b808211156132495760008155600101613235565b5090565b60ff81168114612a3357600080fd5b63ffffffff81168114612a3357600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff811182821017156132c1576132c161326e565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561330e5761330e61326e565b604052919050565b600067ffffffffffffffff8211156133305761333061326e565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261336d57600080fd5b813561338061337b82613316565b6132c7565b81815284602083860101111561339557600080fd5b816020850160208301376000918101602001919091529392505050565b6bffffffffffffffffffffffff81168114612a3357600080fd5b600080600080600080600060e0888a0312156133e757600080fd5b87356133f28161324d565b965060208801356134028161325c565b955060408801356134128161324d565b9450606088013567ffffffffffffffff81111561342e57600080fd5b61343a8a828b0161335c565b945050608088013561344b816133b2565b9699959850939692959460a0840135945060c09093013592915050565b6000806040838503121561347b57600080fd5b50508035926020909101359150565b6020808252825182820181905260009190848201906040850190845b818110156134c2578351835292840192918401916001016134a6565b50909695505050505050565b803561ffff811681146134e057600080fd5b919050565b6000806000606084860312156134fa57600080fd5b8335925061350a602085016134ce565b9150604084013590509250925092565b60006020828403121561352c57600080fd5b5035919050565b60005b8381101561354e578181015183820152602001613536565b50506000910152565b6000815180845261356f816020860160208601613533565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006116d06020830184613557565b600080604083850312156135c757600080fd5b823591506135d7602084016134ce565b90509250929050565b73ffffffffffffffffffffffffffffffffffffffff81168114612a3357600080fd5b60006020828403121561361457600080fd5b81356116d0816135e0565b60008060006060848603121561363457600080fd5b505081359360208301359350604090920135919050565b60008083601f84011261365d57600080fd5b50813567ffffffffffffffff81111561367557600080fd5b6020830191508360208260051b850101111561149b57600080fd5b600080602083850312156136a357600080fd5b823567ffffffffffffffff8111156136ba57600080fd5b6136c68582860161364b565b90969095509350505050565b60008083601f8401126136e457600080fd5b50813567ffffffffffffffff8111156136fc57600080fd5b60208301915083602082850101111561149b57600080fd5b6000806020838503121561372757600080fd5b823567ffffffffffffffff81111561373e57600080fd5b6136c6858286016136d2565b60008060006040848603121561375f57600080fd5b833567ffffffffffffffff81111561377657600080fd5b6137828682870161364b565b90945092505060208401356137968161325c565b809150509250925092565b82151581526040602082015260006116cd6040830184613557565b6000806000604084860312156137d157600080fd5b83359250602084013567ffffffffffffffff8111156137ef57600080fd5b6137fb868287016136d2565b9497909650939450505050565b6000806040838503121561381b57600080fd5b82359150602083013561382d816133b2565b809150509250929050565b6000806040838503121561384b57600080fd5b82359150602083013561382d8161325c565b60006020828403121561386f57600080fd5b81356116d0816133b2565b60006020828403121561388c57600080fd5b81356116d08161324d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006bffffffffffffffffffffffff808316818516818304811182151516156138f1576138f1613897565b02949350505050565b805180151581146134e057600080fd5b60006020828403121561391c57600080fd5b6116d0826138fa565b600082601f83011261393657600080fd5b815161394461337b82613316565b81815284602083860101111561395957600080fd5b61396a826020830160208701613533565b949350505050565b60006020828403121561398457600080fd5b815167ffffffffffffffff81111561399b57600080fd5b61396a84828501613925565b8281526040602082015260006116cd6040830184613557565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff821660ff8103613a0557613a05613897565b60010192915050565b8181038181111561127657611276613897565b8082018082111561127657611276613897565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613a6557613a65613897565b5060010190565b80516020808301519190811015613aab577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8160200360031b1b821691505b50919050565b80516134e0816135e0565b60008060408385031215613acf57600080fd5b8251613ada816135e0565b6020939093015192949293505050565b600060208284031215613afc57600080fd5b81516116d0816135e0565b600061ffff808316818103613b1e57613b1e613897565b6001019392505050565b60008060408385031215613b3b57600080fd5b82359150602083013567ffffffffffffffff811115613b5957600080fd5b613b658582860161335c565b9150509250929050565b60006020808385031215613b8257600080fd5b825167ffffffffffffffff80821115613b9a57600080fd5b818501915085601f830112613bae57600080fd5b815181811115613bc057613bc061326e565b8060051b9150613bd18483016132c7565b8181529183018401918481019088841115613beb57600080fd5b938501935b83851015613c0957845182529385019390850190613bf0565b98975050505050505050565b600060208284031215613c2757600080fd5b81516116d08161324d565b600060208284031215613c4457600080fd5b5051919050565b600081613c5a57613c5a613897565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b83815260406020820152816040820152818360608301376000818301606090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016010192915050565b80516134e08161325c565b80516134e0816133b2565b805167ffffffffffffffff811681146134e057600080fd5b600060208284031215613d1457600080fd5b815167ffffffffffffffff80821115613d2c57600080fd5b908301906101408286031215613d4157600080fd5b613d4961329d565b613d5283613ab1565b8152613d6060208401613cd4565b6020820152604083015182811115613d7757600080fd5b613d8387828601613925565b604083015250613d9560608401613cdf565b6060820152613da660808401613ab1565b6080820152613db760a08401613cea565b60a0820152613dc860c08401613cd4565b60c0820152613dd960e08401613cdf565b60e0820152610100613dec8185016138fa565b908201526101208381015183811115613e0457600080fd5b613e1088828701613925565b918301919091525095945050505050565b600060208284031215613e3357600080fd5b81516116d0816133b2565b600063ffffffff808316818103613b1e57613b1e613897565b6020815260008251610140806020850152613e76610160850183613557565b915060208501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe080868503016040870152613eb28483613557565b935060408701519150613edd606087018373ffffffffffffffffffffffffffffffffffffffff169052565b606087015163ffffffff811660808801529150608087015173ffffffffffffffffffffffffffffffffffffffff811660a0880152915060a087015160ff811660c0880152915060c08701519150808685030160e0870152613f3e8483613557565b935060e08701519150610100818786030181880152613f5d8584613557565b945080880151925050610120818786030181880152613f7c8584613557565b94508088015192505050613f9f828601826bffffffffffffffffffffffff169052565b5090949350505050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615613fe157613fe1613897565b500290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261402457614024613fe6565b500490565b81810360008312801583831316838312821617156131c5576131c5613897565b60008261405857614058613fe6565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f8000000000000000000000000000000000000000000000000000000000000000831416156140ac576140ac613897565b500590565b80820182811260008312801582168215821617156140d1576140d1613897565b505092915050565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613a6557613a65613897565b60007f80000000000000000000000000000000000000000000000000000000000000008203613c5a57613c5a613897565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000810000a",
+ ABI: "[{\"inputs\":[{\"internalType\":\"contractAutomationRegistrar2_1\",\"name\":\"_registrar\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_useArb\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"IndexOutOfRange\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"blockNum\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"LogEmitted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"blockNum\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"LogEmittedAgain\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"blockNum\",\"type\":\"uint256\"}],\"name\":\"UpkeepTopUp\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BUCKET_SIZE\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"addFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"addLinkAmount\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"}],\"name\":\"batchCancelUpkeeps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"},{\"internalType\":\"uint8\",\"name\":\"selector\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"topic0\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"topic1\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"topic2\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"topic3\",\"type\":\"bytes32\"}],\"name\":\"batchPreparingUpkeeps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"},{\"internalType\":\"uint8\",\"name\":\"log\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"selector\",\"type\":\"uint8\"}],\"name\":\"batchPreparingUpkeepsSimple\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"number\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"triggerType\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"triggerConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"},{\"internalType\":\"uint256\",\"name\":\"checkGasToBurn\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"performGasToBurn\",\"type\":\"uint256\"}],\"name\":\"batchRegisterUpkeeps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"log\",\"type\":\"uint8\"}],\"name\":\"batchSendLogs\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"},{\"internalType\":\"uint32\",\"name\":\"interval\",\"type\":\"uint32\"}],\"name\":\"batchSetIntervals\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"}],\"name\":\"batchUpdatePipelineData\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"upkeepIds\",\"type\":\"uint256[]\"}],\"name\":\"batchWithdrawLinks\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"bucketedDelays\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"buckets\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"startGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"blockNum\",\"type\":\"uint256\"}],\"name\":\"burnPerformGas\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"checkGasToBurns\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"}],\"name\":\"checkUpkeep\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"counters\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"delays\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"dummyMap\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"eligible\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"emittedAgainSig\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"emittedSig\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"feedParamKey\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"feedsHex\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"firstPerformBlocks\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"gasLimits\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"startIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxCount\",\"type\":\"uint256\"}],\"name\":\"getActiveUpkeepIDsDeployedByThisContract\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"startIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxCount\",\"type\":\"uint256\"}],\"name\":\"getAllActiveUpkeepIDsOnRegistry\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"getBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"bucket\",\"type\":\"uint16\"}],\"name\":\"getBucketedDelays\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getBucketedDelaysLength\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getDelays\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getDelaysLength\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepID\",\"type\":\"uint256\"}],\"name\":\"getForwarder\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"selector\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"topic0\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"topic1\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"topic2\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"topic3\",\"type\":\"bytes32\"}],\"name\":\"getLogTriggerConfig\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"logTrigger\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getMinBalanceForUpkeep\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"p\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"n\",\"type\":\"uint256\"}],\"name\":\"getPxDelayLastNPerforms\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"bucket\",\"type\":\"uint16\"}],\"name\":\"getSumDelayInBucket\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"n\",\"type\":\"uint256\"}],\"name\":\"getSumDelayLastNPerforms\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getTriggerType\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getUpkeepInfo\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"performGas\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"checkData\",\"type\":\"bytes\"},{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"maxValidBlocknumber\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"lastPerformedBlockNumber\",\"type\":\"uint32\"},{\"internalType\":\"uint96\",\"name\":\"amountSpent\",\"type\":\"uint96\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"internalType\":\"structKeeperRegistryBase2_1.UpkeepInfo\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getUpkeepPrivilegeConfig\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"getUpkeepTriggerConfig\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"intervals\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"lastTopUpBlocks\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"linkToken\",\"outputs\":[{\"internalType\":\"contractLinkTokenInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"minBalanceThresholdMultiplier\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"performDataSizes\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"performGasToBurns\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"performData\",\"type\":\"bytes\"}],\"name\":\"performUpkeep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"previousPerformBlocks\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"registrar\",\"outputs\":[{\"internalType\":\"contractAutomationRegistrar2_1\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"registry\",\"outputs\":[{\"internalType\":\"contractIKeeperRegistryMaster\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"log\",\"type\":\"uint8\"}],\"name\":\"sendLog\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractAutomationRegistrar2_1\",\"name\":\"newRegistrar\",\"type\":\"address\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string[]\",\"name\":\"_feeds\",\"type\":\"string[]\"}],\"name\":\"setFeeds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_interval\",\"type\":\"uint256\"}],\"name\":\"setInterval\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_feedParamKey\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_timeParamKey\",\"type\":\"string\"}],\"name\":\"setParamKeys\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"setPerformDataSize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"}],\"name\":\"setUpkeepGasLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"cfg\",\"type\":\"bytes\"}],\"name\":\"setUpkeepPrivilegeConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"timeParamKey\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"blockNum\",\"type\":\"uint256\"}],\"name\":\"topUpFund\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"selector\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"topic0\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"topic1\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"topic2\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"topic3\",\"type\":\"bytes32\"}],\"name\":\"updateLogTriggerConfig1\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"cfg\",\"type\":\"bytes\"}],\"name\":\"updateLogTriggerConfig2\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"pipelineData\",\"type\":\"bytes\"}],\"name\":\"updateUpkeepPipelineData\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"upkeepTopUpCheckInterval\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"useArbitrumBlockNum\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"withdrawLinks\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"upkeepId\",\"type\":\"uint256\"}],\"name\":\"withdrawLinks\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]",
+ Bin: "0x7f97009585a4d2440f981ab6f6eec514343e1e6b2aa9b991a26998e6806f41bf086080527fc76416badc8398ce17c93eab7b4f60f263241694cf503e4df24f233a8cc1c50d60a0526005601455601580546001600160681b0319166c140000000002c68af0bb140000179055606460e0526101c060405260426101408181526101009182919062005d0761016039815260200160405180608001604052806042815260200162005d49604291399052620000be906016906002620003c7565b506040805180820190915260098152680cccacac892c890caf60bb1b6020820152601790620000ee908262000543565b5060408051808201909152600b81526a313637b1b5a73ab6b132b960a91b602082015260189062000120908262000543565b503480156200012e57600080fd5b5060405162005d8b38038062005d8b833981016040819052620001519162000625565b81813380600081620001aa5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620001dd57620001dd816200031c565b5050601180546001600160a01b0319166001600160a01b038516908117909155604080516330fe427560e21b815281516000945063c3f909d4926004808401939192918290030181865afa1580156200023a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000260919062000668565b50601380546001600160a01b0319166001600160a01b038381169190911790915560115460408051631b6b6d2360e01b81529051939450911691631b6b6d23916004808201926020929091908290030181865afa158015620002c6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002ec919062000699565b601280546001600160a01b0319166001600160a01b039290921691909117905550151560c05250620006c0915050565b336001600160a01b03821603620003765760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401620001a1565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b82805482825590600052602060002090810192821562000412579160200282015b8281111562000412578251829062000401908262000543565b5091602001919060010190620003e8565b506200042092915062000424565b5090565b80821115620004205760006200043b828262000445565b5060010162000424565b5080546200045390620004b4565b6000825580601f1062000464575050565b601f01602090049060005260206000209081019062000484919062000487565b50565b5b8082111562000420576000815560010162000488565b634e487b7160e01b600052604160045260246000fd5b600181811c90821680620004c957607f821691505b602082108103620004ea57634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200053e57600081815260208120601f850160051c81016020861015620005195750805b601f850160051c820191505b818110156200053a5782815560010162000525565b5050505b505050565b81516001600160401b038111156200055f576200055f6200049e565b6200057781620005708454620004b4565b84620004f0565b602080601f831160018114620005af5760008415620005965750858301515b600019600386901b1c1916600185901b1785556200053a565b600085815260208120601f198616915b82811015620005e057888601518255948401946001909101908401620005bf565b5085821015620005ff5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6001600160a01b03811681146200048457600080fd5b600080604083850312156200063957600080fd5b825162000646816200060f565b602084015190925080151581146200065d57600080fd5b809150509250929050565b600080604083850312156200067c57600080fd5b825162000689816200060f565b6020939093015192949293505050565b600060208284031215620006ac57600080fd5b8151620006b9816200060f565b9392505050565b60805160a05160c05160e0516155f1620007166000396000818161054d0152611f250152600081816109730152613b1101526000818161080c015261355f015260008181610d3e015261353401526155f16000f3fe6080604052600436106104ba5760003560e01c806379ea994311610279578063a6b594751161015e578063d6051a72116100d6578063e45530831161008a578063fa333dfb1161006f578063fa333dfb14610f4d578063fba7ffa314611000578063fcdc1f631461102d57600080fd5b8063e455308314610f17578063f2fde38b14610f2d57600080fd5b8063daee1aeb116100bb578063daee1aeb14610eaa578063dbef701e14610eca578063e0114adb14610eea57600080fd5b8063d6051a7214610e6a578063da6cba4714610e8a57600080fd5b8063b657bc9c1161012d578063c041982211610112578063c041982214610e15578063c98f10b014610e35578063d4c2490014610e4a57600080fd5b8063b657bc9c14610dd5578063becde0e114610df557600080fd5b8063a6b5947514610d60578063a72aa27e14610d80578063af953a4a14610da0578063afb28d1f14610dc057600080fd5b8063924ca578116101f15780639b429354116101c05780639d385eaa116101a55780639d385eaa14610cec5780639d6f1cc714610d0c578063a654824814610d2c57600080fd5b80639b42935414610c8e5780639b51fb0d14610cbb57600080fd5b8063924ca57814610c04578063948108f714610c2457806396cebc7c14610c445780639ac542eb14610c6457600080fd5b80638340507c11610248578063873c75861161022d578063873c758614610b8c5780638da5cb5b14610bac5780638fcb3fba14610bd757600080fd5b80638340507c14610b4c57806386e330af14610b6c57600080fd5b806379ea994314610abf5780637b10399914610adf5780637e7a46dc14610b0c5780638243444a14610b2c57600080fd5b806345d2ec171161039f578063636092e8116103175780637145f11b116102e657806376721303116102cb5780637672130314610a5d578063776898c814610a8a57806379ba509714610aaa57600080fd5b80637145f11b14610a0057806373644cce14610a3057600080fd5b8063636092e81461093c578063642f6cef1461096157806369cdbadb146109a55780636e04ff0d146109d257600080fd5b806351c98be31161036e5780635d4ee7f3116103535780635d4ee7f3146108da5780635f17e616146108ef57806360457ff51461090f57600080fd5b806351c98be31461088d57806357970e93146108ad57600080fd5b806345d2ec17146107cd57806346982093146107fa57806346e7a63e1461082e5780635147cd591461085b57600080fd5b806320e3dbd4116104325780632a9032d311610401578063328ffd11116103e6578063328ffd11146107605780633ebe8d6c1461078d5780634585e33b146107ad57600080fd5b80632a9032d3146106ee5780632b20e3971461070e57600080fd5b806320e3dbd4146106615780632636aecf1461068157806328c4b57b146106a157806329e0a841146106c157600080fd5b806319d97a94116104895780631e0104391161046e5780631e010439146105cf578063206c32e81461060c578063207b65161461064157600080fd5b806319d97a94146105825780631cdde251146105af57600080fd5b806306c1cc00146104c6578063077ac621146104e85780630b7d33e61461051b57806312c550271461053b57600080fd5b366104c157005b600080fd5b3480156104d257600080fd5b506104e66104e1366004614293565b61105a565b005b3480156104f457600080fd5b50610508610503366004614346565b6112a9565b6040519081526020015b60405180910390f35b34801561052757600080fd5b506104e661053636600461437b565b6112e7565b34801561054757600080fd5b5061056f7f000000000000000000000000000000000000000000000000000000000000000081565b60405161ffff9091168152602001610512565b34801561058e57600080fd5b506105a261059d3660046143c2565b611375565b6040516105129190614449565b3480156105bb57600080fd5b506104e66105ca36600461447e565b611432565b3480156105db57600080fd5b506105ef6105ea3660046143c2565b61156f565b6040516bffffffffffffffffffffffff9091168152602001610512565b34801561061857600080fd5b5061062c6106273660046144e3565b611604565b60408051928352602083019190915201610512565b34801561064d57600080fd5b506105a261065c3660046143c2565b611687565b34801561066d57600080fd5b506104e661067c36600461450f565b6116df565b34801561068d57600080fd5b506104e661069c366004614571565b6118a9565b3480156106ad57600080fd5b506105086106bc3660046145eb565b611b72565b3480156106cd57600080fd5b506106e16106dc3660046143c2565b611bdd565b6040516105129190614617565b3480156106fa57600080fd5b506104e6610709366004614758565b611ce2565b34801561071a57600080fd5b5060115461073b9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610512565b34801561076c57600080fd5b5061050861077b3660046143c2565b60036020526000908152604090205481565b34801561079957600080fd5b506105086107a83660046143c2565b611dc3565b3480156107b957600080fd5b506104e66107c83660046147dc565b611e2c565b3480156107d957600080fd5b506107ed6107e83660046144e3565b61203b565b6040516105129190614812565b34801561080657600080fd5b506105087f000000000000000000000000000000000000000000000000000000000000000081565b34801561083a57600080fd5b506105086108493660046143c2565b600a6020526000908152604090205481565b34801561086757600080fd5b5061087b6108763660046143c2565b6120aa565b60405160ff9091168152602001610512565b34801561089957600080fd5b506104e66108a8366004614856565b61213e565b3480156108b957600080fd5b5060125461073b9073ffffffffffffffffffffffffffffffffffffffff1681565b3480156108e657600080fd5b506104e66121e2565b3480156108fb57600080fd5b506104e661090a3660046148ad565b61231d565b34801561091b57600080fd5b5061050861092a3660046143c2565b60076020526000908152604090205481565b34801561094857600080fd5b506015546105ef906bffffffffffffffffffffffff1681565b34801561096d57600080fd5b506109957f000000000000000000000000000000000000000000000000000000000000000081565b6040519015158152602001610512565b3480156109b157600080fd5b506105086109c03660046143c2565b60086020526000908152604090205481565b3480156109de57600080fd5b506109f26109ed3660046147dc565b6123ea565b6040516105129291906148cf565b348015610a0c57600080fd5b50610995610a1b3660046143c2565b600b6020526000908152604090205460ff1681565b348015610a3c57600080fd5b50610508610a4b3660046143c2565b6000908152600c602052604090205490565b348015610a6957600080fd5b50610508610a783660046143c2565b60046020526000908152604090205481565b348015610a9657600080fd5b50610995610aa53660046143c2565b612517565b348015610ab657600080fd5b506104e6612569565b348015610acb57600080fd5b5061073b610ada3660046143c2565b61266b565b348015610aeb57600080fd5b5060135461073b9073ffffffffffffffffffffffffffffffffffffffff1681565b348015610b1857600080fd5b506104e6610b273660046148ea565b6126ff565b348015610b3857600080fd5b506104e6610b473660046148ea565b612790565b348015610b5857600080fd5b506104e6610b67366004614936565b6127ea565b348015610b7857600080fd5b506104e6610b873660046149b4565b612808565b348015610b9857600080fd5b506107ed610ba73660046148ad565b61281b565b348015610bb857600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff1661073b565b348015610be357600080fd5b50610508610bf23660046143c2565b60056020526000908152604090205481565b348015610c1057600080fd5b506104e6610c1f3660046148ad565b6128d8565b348015610c3057600080fd5b506104e6610c3f366004614a65565b612b1d565b348015610c5057600080fd5b506104e6610c5f366004614a95565b612c35565b348015610c7057600080fd5b5060155461087b906c01000000000000000000000000900460ff1681565b348015610c9a57600080fd5b506104e6610ca93660046148ad565b60009182526009602052604090912055565b348015610cc757600080fd5b5061056f610cd63660046143c2565b600e6020526000908152604090205461ffff1681565b348015610cf857600080fd5b506107ed610d073660046143c2565b612e3f565b348015610d1857600080fd5b506105a2610d273660046143c2565b612ea1565b348015610d3857600080fd5b506105087f000000000000000000000000000000000000000000000000000000000000000081565b348015610d6c57600080fd5b506104e6610d7b3660046145eb565b612f4d565b348015610d8c57600080fd5b506104e6610d9b366004614ab2565b612fb6565b348015610dac57600080fd5b506104e6610dbb3660046143c2565b613061565b348015610dcc57600080fd5b506105a26130e7565b348015610de157600080fd5b506105ef610df03660046143c2565b6130f4565b348015610e0157600080fd5b506104e6610e10366004614758565b61314c565b348015610e2157600080fd5b506107ed610e303660046148ad565b6131e6565b348015610e4157600080fd5b506105a26132e3565b348015610e5657600080fd5b506104e6610e65366004614ad7565b6132f0565b348015610e7657600080fd5b5061062c610e853660046148ad565b61336f565b348015610e9657600080fd5b506104e6610ea5366004614afc565b6133d8565b348015610eb657600080fd5b506104e6610ec5366004614758565b61373f565b348015610ed657600080fd5b50610508610ee53660046148ad565b61380a565b348015610ef657600080fd5b50610508610f053660046143c2565b60096020526000908152604090205481565b348015610f2357600080fd5b5061050860145481565b348015610f3957600080fd5b506104e6610f4836600461450f565b61383b565b348015610f5957600080fd5b506105a2610f68366004614b64565b6040805160c0808201835273ffffffffffffffffffffffffffffffffffffffff9890981680825260ff97881660208084019182528385019889526060808501988952608080860198895260a095860197885286519283019490945291519099168985015296519688019690965293519486019490945290519184019190915251828401528051808303909301835260e0909101905290565b34801561100c57600080fd5b5061050861101b3660046143c2565b60066020526000908152604090205481565b34801561103957600080fd5b506105086110483660046143c2565b60026020526000908152604090205481565b6040805161018081018252600461014082019081527f746573740000000000000000000000000000000000000000000000000000000061016083015281528151602081810184526000808352818401929092523083850181905263ffffffff8b166060850152608084015260ff808a1660a08501528451808301865283815260c085015260e0840189905284519182019094529081526101008201526bffffffffffffffffffffffff8516610120820152601254601154919273ffffffffffffffffffffffffffffffffffffffff9182169263095ea7b3921690611140908c1688614bec565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815273ffffffffffffffffffffffffffffffffffffffff90921660048301526bffffffffffffffffffffffff1660248201526044016020604051808303816000875af11580156111be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111e29190614c30565b5060008860ff1667ffffffffffffffff81111561120157611201614135565b60405190808252806020026020018201604052801561122a578160200160208202803683370190505b50905060005b8960ff168160ff16101561129d5760006112498461384f565b905080838360ff168151811061126157611261614c4b565b6020908102919091018101919091526000918252600881526040808320889055600790915290208490558061129581614c7a565b915050611230565b50505050505050505050565b600d60205282600052604060002060205281600052604060002081815481106112d157600080fd5b9060005260206000200160009250925050505481565b6013546040517f0b7d33e600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911690630b7d33e69061133f9085908590600401614c99565b600060405180830381600087803b15801561135957600080fd5b505af115801561136d573d6000803e3d6000fd5b505050505050565b6013546040517f19d97a940000000000000000000000000000000000000000000000000000000081526004810183905260609173ffffffffffffffffffffffffffffffffffffffff16906319d97a94906024015b600060405180830381865afa1580156113e6573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261142c9190810190614cff565b92915050565b6013546040517ffa333dfb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff888116600483015260ff8816602483015260448201879052606482018690526084820185905260a4820184905290911690634ee88d35908990309063fa333dfb9060c401600060405180830381865afa1580156114d1573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526115179190810190614cff565b6040518363ffffffff1660e01b8152600401611534929190614c99565b600060405180830381600087803b15801561154e57600080fd5b505af1158015611562573d6000803e3d6000fd5b5050505050505050505050565b6013546040517f1e0104390000000000000000000000000000000000000000000000000000000081526004810183905260009173ffffffffffffffffffffffffffffffffffffffff1690631e010439906024015b602060405180830381865afa1580156115e0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061142c9190614d3f565b6000828152600d6020908152604080832061ffff85168452825280832080548251818502810185019093528083528493849392919083018282801561166857602002820191906000526020600020905b815481526020019060010190808311611654575b5050505050905061167a81825161391d565b92509250505b9250929050565b6013546040517f207b65160000000000000000000000000000000000000000000000000000000081526004810183905260609173ffffffffffffffffffffffffffffffffffffffff169063207b6516906024016113c9565b601180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8316908117909155604080517fc3f909d400000000000000000000000000000000000000000000000000000000815281516000939263c3f909d492600480820193918290030181865afa158015611775573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117999190614d67565b50601380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691909117909155601154604080517f1b6b6d230000000000000000000000000000000000000000000000000000000081529051939450911691631b6b6d23916004808201926020929091908290030181865afa15801561183c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118609190614d95565b601280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff929092169190911790555050565b8560005b81811015611b675760008989838181106118c9576118c9614c4b565b9050602002013590503073ffffffffffffffffffffffffffffffffffffffff16637e7a46dc828360405160200161190291815260200190565b6040516020818303038152906040526040518363ffffffff1660e01b815260040161192e929190614c99565b600060405180830381600087803b15801561194857600080fd5b505af115801561195c573d6000803e3d6000fd5b50506013546040517f5147cd59000000000000000000000000000000000000000000000000000000008152600481018590526000935073ffffffffffffffffffffffffffffffffffffffff9091169150635147cd5990602401602060405180830381865afa1580156119d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119f69190614db2565b90508060ff16600103611b52576040517ffa333dfb000000000000000000000000000000000000000000000000000000008152306004820181905260ff8b166024830152604482018a9052606482018890526084820188905260a4820187905260009163fa333dfb9060c401600060405180830381865afa158015611a7f573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611ac59190810190614cff565b6013546040517f4ee88d3500000000000000000000000000000000000000000000000000000000815291925073ffffffffffffffffffffffffffffffffffffffff1690634ee88d3590611b1e9086908590600401614c99565b600060405180830381600087803b158015611b3857600080fd5b505af1158015611b4c573d6000803e3d6000fd5b50505050505b50508080611b5f90614dcf565b9150506118ad565b505050505050505050565b6000838152600c602090815260408083208054825181850281018501909352808352611bd393830182828015611bc757602002820191906000526020600020905b815481526020019060010190808311611bb3575b505050505084846139a2565b90505b9392505050565b604080516101408101825260008082526020820181905260609282018390528282018190526080820181905260a0820181905260c0820181905260e082018190526101008201526101208101919091526013546040517fc7c3a19a0000000000000000000000000000000000000000000000000000000081526004810184905273ffffffffffffffffffffffffffffffffffffffff9091169063c7c3a19a90602401600060405180830381865afa158015611c9c573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261142c9190810190614e2a565b8060005b818160ff161015611dbd5760135473ffffffffffffffffffffffffffffffffffffffff1663c8048022858560ff8516818110611d2457611d24614c4b565b905060200201356040518263ffffffff1660e01b8152600401611d4991815260200190565b600060405180830381600087803b158015611d6357600080fd5b505af1158015611d77573d6000803e3d6000fd5b50505050611daa84848360ff16818110611d9357611d93614c4b565b90506020020135600f613b0190919063ffffffff16565b5080611db581614c7a565b915050611ce6565b50505050565b6000818152600e602052604081205461ffff1681805b8261ffff168161ffff1611611e24576000858152600d6020908152604080832061ffff85168452909152902054611e109083614f49565b915080611e1c81614f5c565b915050611dd9565b509392505050565b60005a90506000611e3f8385018561437b565b5060008181526005602090815260408083205460049092528220549293509190611e67613b0d565b905082600003611e87576000848152600560205260409020819055611fe2565b600084815260036020526040812054611ea08484614f7d565b611eaa9190614f7d565b6000868152600e6020908152604080832054600d835281842061ffff909116808552908352818420805483518186028101860190945280845295965090949192909190830182828015611f1c57602002820191906000526020600020905b815481526020019060010190808311611f08575b505050505090507f000000000000000000000000000000000000000000000000000000000000000061ffff16815103611f975781611f5981614f5c565b6000898152600e6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff83161790559250505b506000868152600d6020908152604080832061ffff909416835292815282822080546001818101835591845282842001859055888352600c8252928220805493840181558252902001555b600084815260066020526040812054611ffc906001614f49565b600086815260066020908152604080832084905560049091529020839055905061202685836128d8565b612031858784612f4d565b5050505050505050565b6000828152600d6020908152604080832061ffff8516845282529182902080548351818402810184019094528084526060939283018282801561209d57602002820191906000526020600020905b815481526020019060010190808311612089575b5050505050905092915050565b6013546040517f5147cd590000000000000000000000000000000000000000000000000000000081526004810183905260009173ffffffffffffffffffffffffffffffffffffffff1690635147cd5990602401602060405180830381865afa15801561211a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061142c9190614db2565b8160005b818110156121db5730635f17e61686868481811061216257612162614c4b565b90506020020135856040518363ffffffff1660e01b815260040161219692919091825263ffffffff16602082015260400190565b600060405180830381600087803b1580156121b057600080fd5b505af11580156121c4573d6000803e3d6000fd5b5050505080806121d390614dcf565b915050612142565b5050505050565b6121ea613baf565b6012546040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612259573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061227d9190614f90565b6012546040517fa9059cbb0000000000000000000000000000000000000000000000000000000081523360048201526024810183905291925073ffffffffffffffffffffffffffffffffffffffff169063a9059cbb906044016020604051808303816000875af11580156122f5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123199190614c30565b5050565b60008281526003602090815260408083208490556005825280832083905560068252808320839055600c909152812061235591614034565b6000828152600e602052604081205461ffff16905b8161ffff168161ffff16116123b1576000848152600d6020908152604080832061ffff85168452909152812061239f91614034565b806123a981614f5c565b91505061236a565b5050506000908152600e6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000169055565b6000606060005a90506000612401858701876143c2565b60008181526009602090815260408083205460089092528220549293509190838367ffffffffffffffff81111561243a5761243a614135565b6040519080825280601f01601f191660200182016040528015612464576020820181803683370190505b50604051602001612476929190614c99565b60405160208183030381529060405290506000612491613b0d565b9050600061249e86612517565b90505b835a6124ad9089614f7d565b6124b990612710614f49565b10156125075781406000908152600b6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055816124ff81614fa9565b9250506124a1565b9a91995090975050505050505050565b600081815260056020526040812054810361253457506001919050565b600082815260036020908152604080832054600490925290912054612557613b0d565b6125619190614f7d565b101592915050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146125ef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6013546040517f79ea99430000000000000000000000000000000000000000000000000000000081526004810183905260009173ffffffffffffffffffffffffffffffffffffffff16906379ea994390602401602060405180830381865afa1580156126db573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061142c9190614d95565b6013546040517fcd7f71b500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063cd7f71b59061275990869086908690600401614fde565b600060405180830381600087803b15801561277357600080fd5b505af1158015612787573d6000803e3d6000fd5b50505050505050565b6013546040517f4ee88d3500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911690634ee88d359061275990869086908690600401614fde565b60176127f683826150cb565b50601861280382826150cb565b505050565b8051612319906016906020840190614052565b6013546040517f06e3b632000000000000000000000000000000000000000000000000000000008152600481018490526024810183905260609173ffffffffffffffffffffffffffffffffffffffff16906306e3b63290604401600060405180830381865afa158015612892573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611bd691908101906151e5565b6014546000838152600260205260409020546128f49083614f7d565b1115612319576013546040517fc7c3a19a0000000000000000000000000000000000000000000000000000000081526004810184905260009173ffffffffffffffffffffffffffffffffffffffff169063c7c3a19a90602401600060405180830381865afa15801561296a573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526129b09190810190614e2a565b6013546040517fb657bc9c0000000000000000000000000000000000000000000000000000000081526004810186905291925060009173ffffffffffffffffffffffffffffffffffffffff9091169063b657bc9c90602401602060405180830381865afa158015612a25573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a499190614d3f565b601554909150612a6d9082906c01000000000000000000000000900460ff16614bec565b6bffffffffffffffffffffffff1682606001516bffffffffffffffffffffffff161015611dbd57601554612ab09085906bffffffffffffffffffffffff16612b1d565b60008481526002602090815260409182902085905560155482518781526bffffffffffffffffffffffff909116918101919091529081018490527f49d4100ab0124eb4a9a65dc4ea08d6412a43f6f05c49194983f5b322bcc0a5c09060600160405180910390a150505050565b6012546013546040517f095ea7b300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff91821660048201526bffffffffffffffffffffffff8416602482015291169063095ea7b3906044016020604051808303816000875af1158015612ba5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bc99190614c30565b506013546040517f948108f7000000000000000000000000000000000000000000000000000000008152600481018490526bffffffffffffffffffffffff8316602482015273ffffffffffffffffffffffffffffffffffffffff9091169063948108f79060440161133f565b6040517fc04198220000000000000000000000000000000000000000000000000000000081526000600482018190526024820181905290309063c041982290604401600060405180830381865afa158015612c94573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052612cda91908101906151e5565b80519091506000612ce9613b0d565b905060005b828110156121db576000848281518110612d0a57612d0a614c4b565b60209081029190910101516013546040517f5147cd590000000000000000000000000000000000000000000000000000000081526004810183905291925060009173ffffffffffffffffffffffffffffffffffffffff90911690635147cd5990602401602060405180830381865afa158015612d8a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612dae9190614db2565b90508060ff16600103612e2a578660ff16600003612dfa576040513090859084907f97009585a4d2440f981ab6f6eec514343e1e6b2aa9b991a26998e6806f41bf0890600090a4612e2a565b6040513090859084907fc76416badc8398ce17c93eab7b4f60f263241694cf503e4df24f233a8cc1c50d90600090a45b50508080612e3790614dcf565b915050612cee565b6000818152600c6020908152604091829020805483518184028101840190945280845260609392830182828015612e9557602002820191906000526020600020905b815481526020019060010190808311612e81575b50505050509050919050565b60168181548110612eb157600080fd5b906000526020600020016000915090508054612ecc90615032565b80601f0160208091040260200160405190810160405280929190818152602001828054612ef890615032565b8015612f455780601f10612f1a57610100808354040283529160200191612f45565b820191906000526020600020905b815481529060010190602001808311612f2857829003601f168201915b505050505081565b6000838152600760205260409020545b805a612f699085614f7d565b612f7590612710614f49565b1015611dbd5781406000908152600b6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055612f5d565b6013546040517fa72aa27e0000000000000000000000000000000000000000000000000000000081526004810184905263ffffffff8316602482015273ffffffffffffffffffffffffffffffffffffffff9091169063a72aa27e90604401600060405180830381600087803b15801561302e57600080fd5b505af1158015613042573d6000803e3d6000fd5b505050600092835250600a602052604090912063ffffffff9091169055565b6013546040517f744bfe610000000000000000000000000000000000000000000000000000000081526004810183905230602482015273ffffffffffffffffffffffffffffffffffffffff9091169063744bfe6190604401600060405180830381600087803b1580156130d357600080fd5b505af11580156121db573d6000803e3d6000fd5b60178054612ecc90615032565b6013546040517fb657bc9c0000000000000000000000000000000000000000000000000000000081526004810183905260009173ffffffffffffffffffffffffffffffffffffffff169063b657bc9c906024016115c3565b8060005b818163ffffffff161015611dbd573063af953a4a858563ffffffff851681811061317c5761317c614c4b565b905060200201356040518263ffffffff1660e01b81526004016131a191815260200190565b600060405180830381600087803b1580156131bb57600080fd5b505af11580156131cf573d6000803e3d6000fd5b5050505080806131de90615276565b915050613150565b606060006131f4600f613c32565b905080841061322f576040517f1390f2a100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82600003613244576132418482614f7d565b92505b60008367ffffffffffffffff81111561325f5761325f614135565b604051908082528060200260200182016040528015613288578160200160208202803683370190505b50905060005b848110156132da576132ab6132a38288614f49565b600f90613c3c565b8282815181106132bd576132bd614c4b565b6020908102919091010152806132d281614dcf565b91505061328e565b50949350505050565b60188054612ecc90615032565b60006132fa613b0d565b90508160ff1660000361333b576040513090829085907f97009585a4d2440f981ab6f6eec514343e1e6b2aa9b991a26998e6806f41bf0890600090a4505050565b6040513090829085907fc76416badc8398ce17c93eab7b4f60f263241694cf503e4df24f233a8cc1c50d90600090a4505050565b6000828152600c602090815260408083208054825181850281018501909352808352849384939291908301828280156133c757602002820191906000526020600020905b8154815260200190600101908083116133b3575b5050505050905061167a818561391d565b8260005b8181101561136d5760008686838181106133f8576133f8614c4b565b9050602002013590503073ffffffffffffffffffffffffffffffffffffffff16637e7a46dc828360405160200161343191815260200190565b6040516020818303038152906040526040518363ffffffff1660e01b815260040161345d929190614c99565b600060405180830381600087803b15801561347757600080fd5b505af115801561348b573d6000803e3d6000fd5b50506013546040517f5147cd59000000000000000000000000000000000000000000000000000000008152600481018590526000935073ffffffffffffffffffffffffffffffffffffffff9091169150635147cd5990602401602060405180830381865afa158015613501573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135259190614db2565b90508060ff1660010361372a577f000000000000000000000000000000000000000000000000000000000000000060ff87161561357f57507f00000000000000000000000000000000000000000000000000000000000000005b60003073ffffffffffffffffffffffffffffffffffffffff1663fa333dfb308985886040516020016135b391815260200190565b6040516020818303038152906040526135cb9061528f565b60405160e086901b7fffffffff0000000000000000000000000000000000000000000000000000000016815273ffffffffffffffffffffffffffffffffffffffff909416600485015260ff90921660248401526044830152606482015260006084820181905260a482015260c401600060405180830381865afa158015613656573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261369c9190810190614cff565b6013546040517f4ee88d3500000000000000000000000000000000000000000000000000000000815291925073ffffffffffffffffffffffffffffffffffffffff1690634ee88d35906136f59087908590600401614c99565b600060405180830381600087803b15801561370f57600080fd5b505af1158015613723573d6000803e3d6000fd5b5050505050505b5050808061373790614dcf565b9150506133dc565b8060005b81811015611dbd57600084848381811061375f5761375f614c4b565b9050602002013590503073ffffffffffffffffffffffffffffffffffffffff16637e7a46dc828360405160200161379891815260200190565b6040516020818303038152906040526040518363ffffffff1660e01b81526004016137c4929190614c99565b600060405180830381600087803b1580156137de57600080fd5b505af11580156137f2573d6000803e3d6000fd5b5050505050808061380290614dcf565b915050613743565b600c602052816000526040600020818154811061382657600080fd5b90600052602060002001600091509150505481565b613843613baf565b61384c81613c48565b50565b6011546040517f3f678e11000000000000000000000000000000000000000000000000000000008152600091829173ffffffffffffffffffffffffffffffffffffffff90911690633f678e11906138aa9086906004016152d1565b6020604051808303816000875af11580156138c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138ed9190614f90565b90506138fa600f82613d3d565b506060909201516000838152600a6020526040902063ffffffff90911690555090565b8151600090819081908415806139335750808510155b1561393c578094505b60008092505b85831015613998578660016139578585614f7d565b6139619190614f7d565b8151811061397157613971614c4b565b6020026020010151816139849190614f49565b90508261399081614dcf565b935050613942565b9694955050505050565b825160009081908315806139b65750808410155b156139bf578093505b60008467ffffffffffffffff8111156139da576139da614135565b604051908082528060200260200182016040528015613a03578160200160208202803683370190505b509050600092505b84831015613a7157866001613a208585614f7d565b613a2a9190614f7d565b81518110613a3a57613a3a614c4b565b6020026020010151818481518110613a5457613a54614c4b565b602090810291909101015282613a6981614dcf565b935050613a0b565b613a8a81600060018451613a859190614f7d565b613d49565b85606403613ac3578060018251613aa19190614f7d565b81518110613ab157613ab1614c4b565b60200260200101519350505050611bd6565b806064825188613ad39190615423565b613add919061548f565b81518110613aed57613aed614c4b565b602002602001015193505050509392505050565b6000611bd68383613ec1565b60007f000000000000000000000000000000000000000000000000000000000000000015613baa57606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613b81573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ba59190614f90565b905090565b504390565b60005473ffffffffffffffffffffffffffffffffffffffff163314613c30576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016125e6565b565b600061142c825490565b6000611bd68383613fbb565b3373ffffffffffffffffffffffffffffffffffffffff821603613cc7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016125e6565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000611bd68383613fe5565b8181808203613d59575050505050565b6000856002613d6887876154a3565b613d7291906154c3565b613d7c908761552b565b81518110613d8c57613d8c614c4b565b602002602001015190505b818313613e9b575b80868481518110613db257613db2614c4b565b60200260200101511015613dd25782613dca81615553565b935050613d9f565b858281518110613de457613de4614c4b565b6020026020010151811015613e055781613dfd81615584565b925050613dd2565b818313613e9657858281518110613e1e57613e1e614c4b565b6020026020010151868481518110613e3857613e38614c4b565b6020026020010151878581518110613e5257613e52614c4b565b60200260200101888581518110613e6b57613e6b614c4b565b60209081029190910101919091525282613e8481615553565b9350508180613e9290615584565b9250505b613d97565b81851215613eae57613eae868684613d49565b8383121561136d5761136d868486613d49565b60008181526001830160205260408120548015613faa576000613ee5600183614f7d565b8554909150600090613ef990600190614f7d565b9050818114613f5e576000866000018281548110613f1957613f19614c4b565b9060005260206000200154905080876000018481548110613f3c57613f3c614c4b565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080613f6f57613f6f6155b5565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061142c565b600091505061142c565b5092915050565b6000826000018281548110613fd257613fd2614c4b565b9060005260206000200154905092915050565b600081815260018301602052604081205461402c5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561142c565b50600061142c565b508054600082559060005260206000209081019061384c91906140a8565b828054828255906000526020600020908101928215614098579160200282015b82811115614098578251829061408890826150cb565b5091602001919060010190614072565b506140a49291506140bd565b5090565b5b808211156140a457600081556001016140a9565b808211156140a45760006140d182826140da565b506001016140bd565b5080546140e690615032565b6000825580601f106140f6575050565b601f01602090049060005260206000209081019061384c91906140a8565b60ff8116811461384c57600080fd5b63ffffffff8116811461384c57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff8111828210171561418857614188614135565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156141d5576141d5614135565b604052919050565b600067ffffffffffffffff8211156141f7576141f7614135565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261423457600080fd5b8135614247614242826141dd565b61418e565b81815284602083860101111561425c57600080fd5b816020850160208301376000918101602001919091529392505050565b6bffffffffffffffffffffffff8116811461384c57600080fd5b600080600080600080600060e0888a0312156142ae57600080fd5b87356142b981614114565b965060208801356142c981614123565b955060408801356142d981614114565b9450606088013567ffffffffffffffff8111156142f557600080fd5b6143018a828b01614223565b945050608088013561431281614279565b9699959850939692959460a0840135945060c09093013592915050565b803561ffff8116811461434157600080fd5b919050565b60008060006060848603121561435b57600080fd5b8335925061436b6020850161432f565b9150604084013590509250925092565b6000806040838503121561438e57600080fd5b82359150602083013567ffffffffffffffff8111156143ac57600080fd5b6143b885828601614223565b9150509250929050565b6000602082840312156143d457600080fd5b5035919050565b60005b838110156143f65781810151838201526020016143de565b50506000910152565b600081518084526144178160208601602086016143db565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611bd660208301846143ff565b73ffffffffffffffffffffffffffffffffffffffff8116811461384c57600080fd5b600080600080600080600060e0888a03121561449957600080fd5b8735965060208801356144ab8161445c565b955060408801356144bb81614114565b969995985095966060810135965060808101359560a0820135955060c0909101359350915050565b600080604083850312156144f657600080fd5b823591506145066020840161432f565b90509250929050565b60006020828403121561452157600080fd5b8135611bd68161445c565b60008083601f84011261453e57600080fd5b50813567ffffffffffffffff81111561455657600080fd5b6020830191508360208260051b850101111561168057600080fd5b600080600080600080600060c0888a03121561458c57600080fd5b873567ffffffffffffffff8111156145a357600080fd5b6145af8a828b0161452c565b90985096505060208801356145c381614114565b96999598509596604081013596506060810135956080820135955060a0909101359350915050565b60008060006060848603121561460057600080fd5b505081359360208301359350604090920135919050565b6020815261463e60208201835173ffffffffffffffffffffffffffffffffffffffff169052565b60006020830151614657604084018263ffffffff169052565b5060408301516101408060608501526146746101608501836143ff565b9150606085015161469560808601826bffffffffffffffffffffffff169052565b50608085015173ffffffffffffffffffffffffffffffffffffffff811660a08601525060a085015167ffffffffffffffff811660c08601525060c085015163ffffffff811660e08601525060e0850151610100614701818701836bffffffffffffffffffffffff169052565b86015190506101206147168682018315159052565b8601518584037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00183870152905061474e83826143ff565b9695505050505050565b6000806020838503121561476b57600080fd5b823567ffffffffffffffff81111561478257600080fd5b61478e8582860161452c565b90969095509350505050565b60008083601f8401126147ac57600080fd5b50813567ffffffffffffffff8111156147c457600080fd5b60208301915083602082850101111561168057600080fd5b600080602083850312156147ef57600080fd5b823567ffffffffffffffff81111561480657600080fd5b61478e8582860161479a565b6020808252825182820181905260009190848201906040850190845b8181101561484a5783518352928401929184019160010161482e565b50909695505050505050565b60008060006040848603121561486b57600080fd5b833567ffffffffffffffff81111561488257600080fd5b61488e8682870161452c565b90945092505060208401356148a281614123565b809150509250925092565b600080604083850312156148c057600080fd5b50508035926020909101359150565b8215158152604060208201526000611bd360408301846143ff565b6000806000604084860312156148ff57600080fd5b83359250602084013567ffffffffffffffff81111561491d57600080fd5b6149298682870161479a565b9497909650939450505050565b6000806040838503121561494957600080fd5b823567ffffffffffffffff8082111561496157600080fd5b61496d86838701614223565b9350602085013591508082111561498357600080fd5b506143b885828601614223565b600067ffffffffffffffff8211156149aa576149aa614135565b5060051b60200190565b600060208083850312156149c757600080fd5b823567ffffffffffffffff808211156149df57600080fd5b818501915085601f8301126149f357600080fd5b8135614a0161424282614990565b81815260059190911b83018401908481019088831115614a2057600080fd5b8585015b83811015614a5857803585811115614a3c5760008081fd5b614a4a8b89838a0101614223565b845250918601918601614a24565b5098975050505050505050565b60008060408385031215614a7857600080fd5b823591506020830135614a8a81614279565b809150509250929050565b600060208284031215614aa757600080fd5b8135611bd681614114565b60008060408385031215614ac557600080fd5b823591506020830135614a8a81614123565b60008060408385031215614aea57600080fd5b823591506020830135614a8a81614114565b60008060008060608587031215614b1257600080fd5b843567ffffffffffffffff811115614b2957600080fd5b614b358782880161452c565b9095509350506020850135614b4981614114565b91506040850135614b5981614114565b939692955090935050565b60008060008060008060c08789031215614b7d57600080fd5b8635614b888161445c565b95506020870135614b9881614114565b95989597505050506040840135936060810135936080820135935060a0909101359150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006bffffffffffffffffffffffff80831681851681830481118215151615614c1757614c17614bbd565b02949350505050565b8051801515811461434157600080fd5b600060208284031215614c4257600080fd5b611bd682614c20565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff821660ff8103614c9057614c90614bbd565b60010192915050565b828152604060208201526000611bd360408301846143ff565b600082601f830112614cc357600080fd5b8151614cd1614242826141dd565b818152846020838601011115614ce657600080fd5b614cf78260208301602087016143db565b949350505050565b600060208284031215614d1157600080fd5b815167ffffffffffffffff811115614d2857600080fd5b614cf784828501614cb2565b805161434181614279565b600060208284031215614d5157600080fd5b8151611bd681614279565b80516143418161445c565b60008060408385031215614d7a57600080fd5b8251614d858161445c565b6020939093015192949293505050565b600060208284031215614da757600080fd5b8151611bd68161445c565b600060208284031215614dc457600080fd5b8151611bd681614114565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203614e0057614e00614bbd565b5060010190565b805161434181614123565b805167ffffffffffffffff8116811461434157600080fd5b600060208284031215614e3c57600080fd5b815167ffffffffffffffff80821115614e5457600080fd5b908301906101408286031215614e6957600080fd5b614e71614164565b614e7a83614d5c565b8152614e8860208401614e07565b6020820152604083015182811115614e9f57600080fd5b614eab87828601614cb2565b604083015250614ebd60608401614d34565b6060820152614ece60808401614d5c565b6080820152614edf60a08401614e12565b60a0820152614ef060c08401614e07565b60c0820152614f0160e08401614d34565b60e0820152610100614f14818501614c20565b908201526101208381015183811115614f2c57600080fd5b614f3888828701614cb2565b918301919091525095945050505050565b8082018082111561142c5761142c614bbd565b600061ffff808316818103614f7357614f73614bbd565b6001019392505050565b8181038181111561142c5761142c614bbd565b600060208284031215614fa257600080fd5b5051919050565b600081614fb857614fb8614bbd565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b83815260406020820152816040820152818360608301376000818301606090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016010192915050565b600181811c9082168061504657607f821691505b60208210810361507f577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b601f82111561280357600081815260208120601f850160051c810160208610156150ac5750805b601f850160051c820191505b8181101561136d578281556001016150b8565b815167ffffffffffffffff8111156150e5576150e5614135565b6150f9816150f38454615032565b84615085565b602080601f83116001811461514c57600084156151165750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b17855561136d565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156151995788860151825594840194600190910190840161517a565b50858210156151d557878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600060208083850312156151f857600080fd5b825167ffffffffffffffff81111561520f57600080fd5b8301601f8101851361522057600080fd5b805161522e61424282614990565b81815260059190911b8201830190838101908783111561524d57600080fd5b928401925b8284101561526b57835182529284019290840190615252565b979650505050505050565b600063ffffffff808316818103614f7357614f73614bbd565b8051602080830151919081101561507f577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60209190910360031b1b16919050565b60208152600082516101408060208501526152f06101608501836143ff565b915060208501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08086850301604087015261532c84836143ff565b935060408701519150615357606087018373ffffffffffffffffffffffffffffffffffffffff169052565b606087015163ffffffff811660808801529150608087015173ffffffffffffffffffffffffffffffffffffffff811660a0880152915060a087015160ff811660c0880152915060c08701519150808685030160e08701526153b884836143ff565b935060e087015191506101008187860301818801526153d785846143ff565b9450808801519250506101208187860301818801526153f685846143ff565b94508088015192505050615419828601826bffffffffffffffffffffffff169052565b5090949350505050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561545b5761545b614bbd565b500290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261549e5761549e615460565b500490565b8181036000831280158383131683831282161715613fb457613fb4614bbd565b6000826154d2576154d2615460565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f80000000000000000000000000000000000000000000000000000000000000008314161561552657615526614bbd565b500590565b808201828112600083128015821682158216171561554b5761554b614bbd565b505092915050565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203614e0057614e00614bbd565b60007f80000000000000000000000000000000000000000000000000000000000000008203614fb857614fb8614bbd565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000810000a307834353534343832643535353334343264343135323432343935343532353534643264353434353533353434653435353430303030303030303030303030303030307834323534343332643535353334343264343135323432343935343532353534643264353434353533353434653435353430303030303030303030303030303030",
}
var VerifiableLoadUpkeepABI = VerifiableLoadUpkeepMetaData.ABI
@@ -369,6 +382,28 @@ func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCallerSession) Eligible(upkeepI
return _VerifiableLoadUpkeep.Contract.Eligible(&_VerifiableLoadUpkeep.CallOpts, upkeepId)
}
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCaller) EmittedAgainSig(opts *bind.CallOpts) ([32]byte, error) {
+ var out []interface{}
+ err := _VerifiableLoadUpkeep.contract.Call(opts, &out, "emittedAgainSig")
+
+ if err != nil {
+ return *new([32]byte), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte)
+
+ return out0, err
+
+}
+
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepSession) EmittedAgainSig() ([32]byte, error) {
+ return _VerifiableLoadUpkeep.Contract.EmittedAgainSig(&_VerifiableLoadUpkeep.CallOpts)
+}
+
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCallerSession) EmittedAgainSig() ([32]byte, error) {
+ return _VerifiableLoadUpkeep.Contract.EmittedAgainSig(&_VerifiableLoadUpkeep.CallOpts)
+}
+
func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCaller) EmittedSig(opts *bind.CallOpts) ([32]byte, error) {
var out []interface{}
err := _VerifiableLoadUpkeep.contract.Call(opts, &out, "emittedSig")
@@ -391,6 +426,50 @@ func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCallerSession) EmittedSig() ([3
return _VerifiableLoadUpkeep.Contract.EmittedSig(&_VerifiableLoadUpkeep.CallOpts)
}
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCaller) FeedParamKey(opts *bind.CallOpts) (string, error) {
+ var out []interface{}
+ err := _VerifiableLoadUpkeep.contract.Call(opts, &out, "feedParamKey")
+
+ if err != nil {
+ return *new(string), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(string)).(*string)
+
+ return out0, err
+
+}
+
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepSession) FeedParamKey() (string, error) {
+ return _VerifiableLoadUpkeep.Contract.FeedParamKey(&_VerifiableLoadUpkeep.CallOpts)
+}
+
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCallerSession) FeedParamKey() (string, error) {
+ return _VerifiableLoadUpkeep.Contract.FeedParamKey(&_VerifiableLoadUpkeep.CallOpts)
+}
+
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCaller) FeedsHex(opts *bind.CallOpts, arg0 *big.Int) (string, error) {
+ var out []interface{}
+ err := _VerifiableLoadUpkeep.contract.Call(opts, &out, "feedsHex", arg0)
+
+ if err != nil {
+ return *new(string), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(string)).(*string)
+
+ return out0, err
+
+}
+
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepSession) FeedsHex(arg0 *big.Int) (string, error) {
+ return _VerifiableLoadUpkeep.Contract.FeedsHex(&_VerifiableLoadUpkeep.CallOpts, arg0)
+}
+
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCallerSession) FeedsHex(arg0 *big.Int) (string, error) {
+ return _VerifiableLoadUpkeep.Contract.FeedsHex(&_VerifiableLoadUpkeep.CallOpts, arg0)
+}
+
func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCaller) FirstPerformBlocks(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) {
var out []interface{}
err := _VerifiableLoadUpkeep.contract.Call(opts, &out, "firstPerformBlocks", arg0)
@@ -435,9 +514,9 @@ func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCallerSession) GasLimits(arg0 *
return _VerifiableLoadUpkeep.Contract.GasLimits(&_VerifiableLoadUpkeep.CallOpts, arg0)
}
-func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCaller) GetActiveUpkeepIDs(opts *bind.CallOpts, startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error) {
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCaller) GetActiveUpkeepIDsDeployedByThisContract(opts *bind.CallOpts, startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error) {
var out []interface{}
- err := _VerifiableLoadUpkeep.contract.Call(opts, &out, "getActiveUpkeepIDs", startIndex, maxCount)
+ err := _VerifiableLoadUpkeep.contract.Call(opts, &out, "getActiveUpkeepIDsDeployedByThisContract", startIndex, maxCount)
if err != nil {
return *new([]*big.Int), err
@@ -449,12 +528,56 @@ func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCaller) GetActiveUpkeepIDs(opts
}
-func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepSession) GetActiveUpkeepIDs(startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error) {
- return _VerifiableLoadUpkeep.Contract.GetActiveUpkeepIDs(&_VerifiableLoadUpkeep.CallOpts, startIndex, maxCount)
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepSession) GetActiveUpkeepIDsDeployedByThisContract(startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error) {
+ return _VerifiableLoadUpkeep.Contract.GetActiveUpkeepIDsDeployedByThisContract(&_VerifiableLoadUpkeep.CallOpts, startIndex, maxCount)
+}
+
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCallerSession) GetActiveUpkeepIDsDeployedByThisContract(startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error) {
+ return _VerifiableLoadUpkeep.Contract.GetActiveUpkeepIDsDeployedByThisContract(&_VerifiableLoadUpkeep.CallOpts, startIndex, maxCount)
+}
+
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCaller) GetAllActiveUpkeepIDsOnRegistry(opts *bind.CallOpts, startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error) {
+ var out []interface{}
+ err := _VerifiableLoadUpkeep.contract.Call(opts, &out, "getAllActiveUpkeepIDsOnRegistry", startIndex, maxCount)
+
+ if err != nil {
+ return *new([]*big.Int), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new([]*big.Int)).(*[]*big.Int)
+
+ return out0, err
+
+}
+
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepSession) GetAllActiveUpkeepIDsOnRegistry(startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error) {
+ return _VerifiableLoadUpkeep.Contract.GetAllActiveUpkeepIDsOnRegistry(&_VerifiableLoadUpkeep.CallOpts, startIndex, maxCount)
+}
+
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCallerSession) GetAllActiveUpkeepIDsOnRegistry(startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error) {
+ return _VerifiableLoadUpkeep.Contract.GetAllActiveUpkeepIDsOnRegistry(&_VerifiableLoadUpkeep.CallOpts, startIndex, maxCount)
+}
+
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCaller) GetBalance(opts *bind.CallOpts, id *big.Int) (*big.Int, error) {
+ var out []interface{}
+ err := _VerifiableLoadUpkeep.contract.Call(opts, &out, "getBalance", id)
+
+ if err != nil {
+ return *new(*big.Int), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
+
+ return out0, err
+
+}
+
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepSession) GetBalance(id *big.Int) (*big.Int, error) {
+ return _VerifiableLoadUpkeep.Contract.GetBalance(&_VerifiableLoadUpkeep.CallOpts, id)
}
-func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCallerSession) GetActiveUpkeepIDs(startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error) {
- return _VerifiableLoadUpkeep.Contract.GetActiveUpkeepIDs(&_VerifiableLoadUpkeep.CallOpts, startIndex, maxCount)
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCallerSession) GetBalance(id *big.Int) (*big.Int, error) {
+ return _VerifiableLoadUpkeep.Contract.GetBalance(&_VerifiableLoadUpkeep.CallOpts, id)
}
func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCaller) GetBucketedDelays(opts *bind.CallOpts, upkeepId *big.Int, bucket uint16) ([]*big.Int, error) {
@@ -545,9 +668,31 @@ func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCallerSession) GetDelaysLength(
return _VerifiableLoadUpkeep.Contract.GetDelaysLength(&_VerifiableLoadUpkeep.CallOpts, upkeepId)
}
-func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCaller) GetLogTriggerConfig(opts *bind.CallOpts, upkeepId *big.Int) ([]byte, error) {
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCaller) GetForwarder(opts *bind.CallOpts, upkeepID *big.Int) (common.Address, error) {
+ var out []interface{}
+ err := _VerifiableLoadUpkeep.contract.Call(opts, &out, "getForwarder", upkeepID)
+
+ if err != nil {
+ return *new(common.Address), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address)
+
+ return out0, err
+
+}
+
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepSession) GetForwarder(upkeepID *big.Int) (common.Address, error) {
+ return _VerifiableLoadUpkeep.Contract.GetForwarder(&_VerifiableLoadUpkeep.CallOpts, upkeepID)
+}
+
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCallerSession) GetForwarder(upkeepID *big.Int) (common.Address, error) {
+ return _VerifiableLoadUpkeep.Contract.GetForwarder(&_VerifiableLoadUpkeep.CallOpts, upkeepID)
+}
+
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCaller) GetLogTriggerConfig(opts *bind.CallOpts, addr common.Address, selector uint8, topic0 [32]byte, topic1 [32]byte, topic2 [32]byte, topic3 [32]byte) ([]byte, error) {
var out []interface{}
- err := _VerifiableLoadUpkeep.contract.Call(opts, &out, "getLogTriggerConfig", upkeepId)
+ err := _VerifiableLoadUpkeep.contract.Call(opts, &out, "getLogTriggerConfig", addr, selector, topic0, topic1, topic2, topic3)
if err != nil {
return *new([]byte), err
@@ -559,12 +704,34 @@ func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCaller) GetLogTriggerConfig(opt
}
-func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepSession) GetLogTriggerConfig(upkeepId *big.Int) ([]byte, error) {
- return _VerifiableLoadUpkeep.Contract.GetLogTriggerConfig(&_VerifiableLoadUpkeep.CallOpts, upkeepId)
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepSession) GetLogTriggerConfig(addr common.Address, selector uint8, topic0 [32]byte, topic1 [32]byte, topic2 [32]byte, topic3 [32]byte) ([]byte, error) {
+ return _VerifiableLoadUpkeep.Contract.GetLogTriggerConfig(&_VerifiableLoadUpkeep.CallOpts, addr, selector, topic0, topic1, topic2, topic3)
}
-func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCallerSession) GetLogTriggerConfig(upkeepId *big.Int) ([]byte, error) {
- return _VerifiableLoadUpkeep.Contract.GetLogTriggerConfig(&_VerifiableLoadUpkeep.CallOpts, upkeepId)
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCallerSession) GetLogTriggerConfig(addr common.Address, selector uint8, topic0 [32]byte, topic1 [32]byte, topic2 [32]byte, topic3 [32]byte) ([]byte, error) {
+ return _VerifiableLoadUpkeep.Contract.GetLogTriggerConfig(&_VerifiableLoadUpkeep.CallOpts, addr, selector, topic0, topic1, topic2, topic3)
+}
+
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCaller) GetMinBalanceForUpkeep(opts *bind.CallOpts, upkeepId *big.Int) (*big.Int, error) {
+ var out []interface{}
+ err := _VerifiableLoadUpkeep.contract.Call(opts, &out, "getMinBalanceForUpkeep", upkeepId)
+
+ if err != nil {
+ return *new(*big.Int), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
+
+ return out0, err
+
+}
+
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepSession) GetMinBalanceForUpkeep(upkeepId *big.Int) (*big.Int, error) {
+ return _VerifiableLoadUpkeep.Contract.GetMinBalanceForUpkeep(&_VerifiableLoadUpkeep.CallOpts, upkeepId)
+}
+
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCallerSession) GetMinBalanceForUpkeep(upkeepId *big.Int) (*big.Int, error) {
+ return _VerifiableLoadUpkeep.Contract.GetMinBalanceForUpkeep(&_VerifiableLoadUpkeep.CallOpts, upkeepId)
}
func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCaller) GetPxDelayLastNPerforms(opts *bind.CallOpts, upkeepId *big.Int, p *big.Int, n *big.Int) (*big.Int, error) {
@@ -635,6 +802,94 @@ func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCallerSession) GetSumDelayLastN
return _VerifiableLoadUpkeep.Contract.GetSumDelayLastNPerforms(&_VerifiableLoadUpkeep.CallOpts, upkeepId, n)
}
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCaller) GetTriggerType(opts *bind.CallOpts, upkeepId *big.Int) (uint8, error) {
+ var out []interface{}
+ err := _VerifiableLoadUpkeep.contract.Call(opts, &out, "getTriggerType", upkeepId)
+
+ if err != nil {
+ return *new(uint8), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8)
+
+ return out0, err
+
+}
+
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepSession) GetTriggerType(upkeepId *big.Int) (uint8, error) {
+ return _VerifiableLoadUpkeep.Contract.GetTriggerType(&_VerifiableLoadUpkeep.CallOpts, upkeepId)
+}
+
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCallerSession) GetTriggerType(upkeepId *big.Int) (uint8, error) {
+ return _VerifiableLoadUpkeep.Contract.GetTriggerType(&_VerifiableLoadUpkeep.CallOpts, upkeepId)
+}
+
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCaller) GetUpkeepInfo(opts *bind.CallOpts, upkeepId *big.Int) (KeeperRegistryBase21UpkeepInfo, error) {
+ var out []interface{}
+ err := _VerifiableLoadUpkeep.contract.Call(opts, &out, "getUpkeepInfo", upkeepId)
+
+ if err != nil {
+ return *new(KeeperRegistryBase21UpkeepInfo), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(KeeperRegistryBase21UpkeepInfo)).(*KeeperRegistryBase21UpkeepInfo)
+
+ return out0, err
+
+}
+
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepSession) GetUpkeepInfo(upkeepId *big.Int) (KeeperRegistryBase21UpkeepInfo, error) {
+ return _VerifiableLoadUpkeep.Contract.GetUpkeepInfo(&_VerifiableLoadUpkeep.CallOpts, upkeepId)
+}
+
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCallerSession) GetUpkeepInfo(upkeepId *big.Int) (KeeperRegistryBase21UpkeepInfo, error) {
+ return _VerifiableLoadUpkeep.Contract.GetUpkeepInfo(&_VerifiableLoadUpkeep.CallOpts, upkeepId)
+}
+
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCaller) GetUpkeepPrivilegeConfig(opts *bind.CallOpts, upkeepId *big.Int) ([]byte, error) {
+ var out []interface{}
+ err := _VerifiableLoadUpkeep.contract.Call(opts, &out, "getUpkeepPrivilegeConfig", upkeepId)
+
+ if err != nil {
+ return *new([]byte), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte)
+
+ return out0, err
+
+}
+
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepSession) GetUpkeepPrivilegeConfig(upkeepId *big.Int) ([]byte, error) {
+ return _VerifiableLoadUpkeep.Contract.GetUpkeepPrivilegeConfig(&_VerifiableLoadUpkeep.CallOpts, upkeepId)
+}
+
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCallerSession) GetUpkeepPrivilegeConfig(upkeepId *big.Int) ([]byte, error) {
+ return _VerifiableLoadUpkeep.Contract.GetUpkeepPrivilegeConfig(&_VerifiableLoadUpkeep.CallOpts, upkeepId)
+}
+
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCaller) GetUpkeepTriggerConfig(opts *bind.CallOpts, upkeepId *big.Int) ([]byte, error) {
+ var out []interface{}
+ err := _VerifiableLoadUpkeep.contract.Call(opts, &out, "getUpkeepTriggerConfig", upkeepId)
+
+ if err != nil {
+ return *new([]byte), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte)
+
+ return out0, err
+
+}
+
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepSession) GetUpkeepTriggerConfig(upkeepId *big.Int) ([]byte, error) {
+ return _VerifiableLoadUpkeep.Contract.GetUpkeepTriggerConfig(&_VerifiableLoadUpkeep.CallOpts, upkeepId)
+}
+
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCallerSession) GetUpkeepTriggerConfig(upkeepId *big.Int) ([]byte, error) {
+ return _VerifiableLoadUpkeep.Contract.GetUpkeepTriggerConfig(&_VerifiableLoadUpkeep.CallOpts, upkeepId)
+}
+
func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCaller) Intervals(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) {
var out []interface{}
err := _VerifiableLoadUpkeep.contract.Call(opts, &out, "intervals", arg0)
@@ -855,6 +1110,28 @@ func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCallerSession) Registry() (comm
return _VerifiableLoadUpkeep.Contract.Registry(&_VerifiableLoadUpkeep.CallOpts)
}
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCaller) TimeParamKey(opts *bind.CallOpts) (string, error) {
+ var out []interface{}
+ err := _VerifiableLoadUpkeep.contract.Call(opts, &out, "timeParamKey")
+
+ if err != nil {
+ return *new(string), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(string)).(*string)
+
+ return out0, err
+
+}
+
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepSession) TimeParamKey() (string, error) {
+ return _VerifiableLoadUpkeep.Contract.TimeParamKey(&_VerifiableLoadUpkeep.CallOpts)
+}
+
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCallerSession) TimeParamKey() (string, error) {
+ return _VerifiableLoadUpkeep.Contract.TimeParamKey(&_VerifiableLoadUpkeep.CallOpts)
+}
+
func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepCaller) UpkeepTopUpCheckInterval(opts *bind.CallOpts) (*big.Int, error) {
var out []interface{}
err := _VerifiableLoadUpkeep.contract.Call(opts, &out, "upkeepTopUpCheckInterval")
@@ -935,6 +1212,30 @@ func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactorSession) BatchCancelU
return _VerifiableLoadUpkeep.Contract.BatchCancelUpkeeps(&_VerifiableLoadUpkeep.TransactOpts, upkeepIds)
}
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactor) BatchPreparingUpkeeps(opts *bind.TransactOpts, upkeepIds []*big.Int, selector uint8, topic0 [32]byte, topic1 [32]byte, topic2 [32]byte, topic3 [32]byte) (*types.Transaction, error) {
+ return _VerifiableLoadUpkeep.contract.Transact(opts, "batchPreparingUpkeeps", upkeepIds, selector, topic0, topic1, topic2, topic3)
+}
+
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepSession) BatchPreparingUpkeeps(upkeepIds []*big.Int, selector uint8, topic0 [32]byte, topic1 [32]byte, topic2 [32]byte, topic3 [32]byte) (*types.Transaction, error) {
+ return _VerifiableLoadUpkeep.Contract.BatchPreparingUpkeeps(&_VerifiableLoadUpkeep.TransactOpts, upkeepIds, selector, topic0, topic1, topic2, topic3)
+}
+
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactorSession) BatchPreparingUpkeeps(upkeepIds []*big.Int, selector uint8, topic0 [32]byte, topic1 [32]byte, topic2 [32]byte, topic3 [32]byte) (*types.Transaction, error) {
+ return _VerifiableLoadUpkeep.Contract.BatchPreparingUpkeeps(&_VerifiableLoadUpkeep.TransactOpts, upkeepIds, selector, topic0, topic1, topic2, topic3)
+}
+
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactor) BatchPreparingUpkeepsSimple(opts *bind.TransactOpts, upkeepIds []*big.Int, log uint8, selector uint8) (*types.Transaction, error) {
+ return _VerifiableLoadUpkeep.contract.Transact(opts, "batchPreparingUpkeepsSimple", upkeepIds, log, selector)
+}
+
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepSession) BatchPreparingUpkeepsSimple(upkeepIds []*big.Int, log uint8, selector uint8) (*types.Transaction, error) {
+ return _VerifiableLoadUpkeep.Contract.BatchPreparingUpkeepsSimple(&_VerifiableLoadUpkeep.TransactOpts, upkeepIds, log, selector)
+}
+
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactorSession) BatchPreparingUpkeepsSimple(upkeepIds []*big.Int, log uint8, selector uint8) (*types.Transaction, error) {
+ return _VerifiableLoadUpkeep.Contract.BatchPreparingUpkeepsSimple(&_VerifiableLoadUpkeep.TransactOpts, upkeepIds, log, selector)
+}
+
func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactor) BatchRegisterUpkeeps(opts *bind.TransactOpts, number uint8, gasLimit uint32, triggerType uint8, triggerConfig []byte, amount *big.Int, checkGasToBurn *big.Int, performGasToBurn *big.Int) (*types.Transaction, error) {
return _VerifiableLoadUpkeep.contract.Transact(opts, "batchRegisterUpkeeps", number, gasLimit, triggerType, triggerConfig, amount, checkGasToBurn, performGasToBurn)
}
@@ -947,16 +1248,16 @@ func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactorSession) BatchRegiste
return _VerifiableLoadUpkeep.Contract.BatchRegisterUpkeeps(&_VerifiableLoadUpkeep.TransactOpts, number, gasLimit, triggerType, triggerConfig, amount, checkGasToBurn, performGasToBurn)
}
-func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactor) BatchSendLogs(opts *bind.TransactOpts) (*types.Transaction, error) {
- return _VerifiableLoadUpkeep.contract.Transact(opts, "batchSendLogs")
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactor) BatchSendLogs(opts *bind.TransactOpts, log uint8) (*types.Transaction, error) {
+ return _VerifiableLoadUpkeep.contract.Transact(opts, "batchSendLogs", log)
}
-func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepSession) BatchSendLogs() (*types.Transaction, error) {
- return _VerifiableLoadUpkeep.Contract.BatchSendLogs(&_VerifiableLoadUpkeep.TransactOpts)
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepSession) BatchSendLogs(log uint8) (*types.Transaction, error) {
+ return _VerifiableLoadUpkeep.Contract.BatchSendLogs(&_VerifiableLoadUpkeep.TransactOpts, log)
}
-func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactorSession) BatchSendLogs() (*types.Transaction, error) {
- return _VerifiableLoadUpkeep.Contract.BatchSendLogs(&_VerifiableLoadUpkeep.TransactOpts)
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactorSession) BatchSendLogs(log uint8) (*types.Transaction, error) {
+ return _VerifiableLoadUpkeep.Contract.BatchSendLogs(&_VerifiableLoadUpkeep.TransactOpts, log)
}
func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactor) BatchSetIntervals(opts *bind.TransactOpts, upkeepIds []*big.Int, interval uint32) (*types.Transaction, error) {
@@ -1007,18 +1308,6 @@ func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactorSession) BurnPerformG
return _VerifiableLoadUpkeep.Contract.BurnPerformGas(&_VerifiableLoadUpkeep.TransactOpts, upkeepId, startGas, blockNum)
}
-func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactor) CancelUpkeep(opts *bind.TransactOpts, upkeepId *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadUpkeep.contract.Transact(opts, "cancelUpkeep", upkeepId)
-}
-
-func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepSession) CancelUpkeep(upkeepId *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadUpkeep.Contract.CancelUpkeep(&_VerifiableLoadUpkeep.TransactOpts, upkeepId)
-}
-
-func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactorSession) CancelUpkeep(upkeepId *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadUpkeep.Contract.CancelUpkeep(&_VerifiableLoadUpkeep.TransactOpts, upkeepId)
-}
-
func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactor) CheckUpkeep(opts *bind.TransactOpts, checkData []byte) (*types.Transaction, error) {
return _VerifiableLoadUpkeep.contract.Transact(opts, "checkUpkeep", checkData)
}
@@ -1043,40 +1332,16 @@ func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactorSession) PerformUpkee
return _VerifiableLoadUpkeep.Contract.PerformUpkeep(&_VerifiableLoadUpkeep.TransactOpts, performData)
}
-func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactor) SendLog(opts *bind.TransactOpts, upkeepId *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadUpkeep.contract.Transact(opts, "sendLog", upkeepId)
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactor) SendLog(opts *bind.TransactOpts, upkeepId *big.Int, log uint8) (*types.Transaction, error) {
+ return _VerifiableLoadUpkeep.contract.Transact(opts, "sendLog", upkeepId, log)
}
-func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepSession) SendLog(upkeepId *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadUpkeep.Contract.SendLog(&_VerifiableLoadUpkeep.TransactOpts, upkeepId)
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepSession) SendLog(upkeepId *big.Int, log uint8) (*types.Transaction, error) {
+ return _VerifiableLoadUpkeep.Contract.SendLog(&_VerifiableLoadUpkeep.TransactOpts, upkeepId, log)
}
-func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactorSession) SendLog(upkeepId *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadUpkeep.Contract.SendLog(&_VerifiableLoadUpkeep.TransactOpts, upkeepId)
-}
-
-func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactor) SetAddLinkAmount(opts *bind.TransactOpts, amount *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadUpkeep.contract.Transact(opts, "setAddLinkAmount", amount)
-}
-
-func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepSession) SetAddLinkAmount(amount *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadUpkeep.Contract.SetAddLinkAmount(&_VerifiableLoadUpkeep.TransactOpts, amount)
-}
-
-func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactorSession) SetAddLinkAmount(amount *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadUpkeep.Contract.SetAddLinkAmount(&_VerifiableLoadUpkeep.TransactOpts, amount)
-}
-
-func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactor) SetCheckGasToBurn(opts *bind.TransactOpts, upkeepId *big.Int, value *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadUpkeep.contract.Transact(opts, "setCheckGasToBurn", upkeepId, value)
-}
-
-func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepSession) SetCheckGasToBurn(upkeepId *big.Int, value *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadUpkeep.Contract.SetCheckGasToBurn(&_VerifiableLoadUpkeep.TransactOpts, upkeepId, value)
-}
-
-func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactorSession) SetCheckGasToBurn(upkeepId *big.Int, value *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadUpkeep.Contract.SetCheckGasToBurn(&_VerifiableLoadUpkeep.TransactOpts, upkeepId, value)
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactorSession) SendLog(upkeepId *big.Int, log uint8) (*types.Transaction, error) {
+ return _VerifiableLoadUpkeep.Contract.SendLog(&_VerifiableLoadUpkeep.TransactOpts, upkeepId, log)
}
func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactor) SetConfig(opts *bind.TransactOpts, newRegistrar common.Address) (*types.Transaction, error) {
@@ -1091,6 +1356,18 @@ func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactorSession) SetConfig(ne
return _VerifiableLoadUpkeep.Contract.SetConfig(&_VerifiableLoadUpkeep.TransactOpts, newRegistrar)
}
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactor) SetFeeds(opts *bind.TransactOpts, _feeds []string) (*types.Transaction, error) {
+ return _VerifiableLoadUpkeep.contract.Transact(opts, "setFeeds", _feeds)
+}
+
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepSession) SetFeeds(_feeds []string) (*types.Transaction, error) {
+ return _VerifiableLoadUpkeep.Contract.SetFeeds(&_VerifiableLoadUpkeep.TransactOpts, _feeds)
+}
+
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactorSession) SetFeeds(_feeds []string) (*types.Transaction, error) {
+ return _VerifiableLoadUpkeep.Contract.SetFeeds(&_VerifiableLoadUpkeep.TransactOpts, _feeds)
+}
+
func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactor) SetInterval(opts *bind.TransactOpts, upkeepId *big.Int, _interval *big.Int) (*types.Transaction, error) {
return _VerifiableLoadUpkeep.contract.Transact(opts, "setInterval", upkeepId, _interval)
}
@@ -1103,16 +1380,16 @@ func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactorSession) SetInterval(
return _VerifiableLoadUpkeep.Contract.SetInterval(&_VerifiableLoadUpkeep.TransactOpts, upkeepId, _interval)
}
-func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactor) SetMinBalanceThresholdMultiplier(opts *bind.TransactOpts, newMinBalanceThresholdMultiplier uint8) (*types.Transaction, error) {
- return _VerifiableLoadUpkeep.contract.Transact(opts, "setMinBalanceThresholdMultiplier", newMinBalanceThresholdMultiplier)
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactor) SetParamKeys(opts *bind.TransactOpts, _feedParamKey string, _timeParamKey string) (*types.Transaction, error) {
+ return _VerifiableLoadUpkeep.contract.Transact(opts, "setParamKeys", _feedParamKey, _timeParamKey)
}
-func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepSession) SetMinBalanceThresholdMultiplier(newMinBalanceThresholdMultiplier uint8) (*types.Transaction, error) {
- return _VerifiableLoadUpkeep.Contract.SetMinBalanceThresholdMultiplier(&_VerifiableLoadUpkeep.TransactOpts, newMinBalanceThresholdMultiplier)
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepSession) SetParamKeys(_feedParamKey string, _timeParamKey string) (*types.Transaction, error) {
+ return _VerifiableLoadUpkeep.Contract.SetParamKeys(&_VerifiableLoadUpkeep.TransactOpts, _feedParamKey, _timeParamKey)
}
-func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactorSession) SetMinBalanceThresholdMultiplier(newMinBalanceThresholdMultiplier uint8) (*types.Transaction, error) {
- return _VerifiableLoadUpkeep.Contract.SetMinBalanceThresholdMultiplier(&_VerifiableLoadUpkeep.TransactOpts, newMinBalanceThresholdMultiplier)
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactorSession) SetParamKeys(_feedParamKey string, _timeParamKey string) (*types.Transaction, error) {
+ return _VerifiableLoadUpkeep.Contract.SetParamKeys(&_VerifiableLoadUpkeep.TransactOpts, _feedParamKey, _timeParamKey)
}
func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactor) SetPerformDataSize(opts *bind.TransactOpts, upkeepId *big.Int, value *big.Int) (*types.Transaction, error) {
@@ -1127,18 +1404,6 @@ func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactorSession) SetPerformDa
return _VerifiableLoadUpkeep.Contract.SetPerformDataSize(&_VerifiableLoadUpkeep.TransactOpts, upkeepId, value)
}
-func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactor) SetPerformGasToBurn(opts *bind.TransactOpts, upkeepId *big.Int, value *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadUpkeep.contract.Transact(opts, "setPerformGasToBurn", upkeepId, value)
-}
-
-func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepSession) SetPerformGasToBurn(upkeepId *big.Int, value *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadUpkeep.Contract.SetPerformGasToBurn(&_VerifiableLoadUpkeep.TransactOpts, upkeepId, value)
-}
-
-func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactorSession) SetPerformGasToBurn(upkeepId *big.Int, value *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadUpkeep.Contract.SetPerformGasToBurn(&_VerifiableLoadUpkeep.TransactOpts, upkeepId, value)
-}
-
func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactor) SetUpkeepGasLimit(opts *bind.TransactOpts, upkeepId *big.Int, gasLimit uint32) (*types.Transaction, error) {
return _VerifiableLoadUpkeep.contract.Transact(opts, "setUpkeepGasLimit", upkeepId, gasLimit)
}
@@ -1151,16 +1416,16 @@ func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactorSession) SetUpkeepGas
return _VerifiableLoadUpkeep.Contract.SetUpkeepGasLimit(&_VerifiableLoadUpkeep.TransactOpts, upkeepId, gasLimit)
}
-func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactor) SetUpkeepTopUpCheckInterval(opts *bind.TransactOpts, newInterval *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadUpkeep.contract.Transact(opts, "setUpkeepTopUpCheckInterval", newInterval)
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactor) SetUpkeepPrivilegeConfig(opts *bind.TransactOpts, upkeepId *big.Int, cfg []byte) (*types.Transaction, error) {
+ return _VerifiableLoadUpkeep.contract.Transact(opts, "setUpkeepPrivilegeConfig", upkeepId, cfg)
}
-func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepSession) SetUpkeepTopUpCheckInterval(newInterval *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadUpkeep.Contract.SetUpkeepTopUpCheckInterval(&_VerifiableLoadUpkeep.TransactOpts, newInterval)
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepSession) SetUpkeepPrivilegeConfig(upkeepId *big.Int, cfg []byte) (*types.Transaction, error) {
+ return _VerifiableLoadUpkeep.Contract.SetUpkeepPrivilegeConfig(&_VerifiableLoadUpkeep.TransactOpts, upkeepId, cfg)
}
-func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactorSession) SetUpkeepTopUpCheckInterval(newInterval *big.Int) (*types.Transaction, error) {
- return _VerifiableLoadUpkeep.Contract.SetUpkeepTopUpCheckInterval(&_VerifiableLoadUpkeep.TransactOpts, newInterval)
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactorSession) SetUpkeepPrivilegeConfig(upkeepId *big.Int, cfg []byte) (*types.Transaction, error) {
+ return _VerifiableLoadUpkeep.Contract.SetUpkeepPrivilegeConfig(&_VerifiableLoadUpkeep.TransactOpts, upkeepId, cfg)
}
func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactor) TopUpFund(opts *bind.TransactOpts, upkeepId *big.Int, blockNum *big.Int) (*types.Transaction, error) {
@@ -1187,6 +1452,30 @@ func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactorSession) TransferOwne
return _VerifiableLoadUpkeep.Contract.TransferOwnership(&_VerifiableLoadUpkeep.TransactOpts, to)
}
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactor) UpdateLogTriggerConfig1(opts *bind.TransactOpts, upkeepId *big.Int, addr common.Address, selector uint8, topic0 [32]byte, topic1 [32]byte, topic2 [32]byte, topic3 [32]byte) (*types.Transaction, error) {
+ return _VerifiableLoadUpkeep.contract.Transact(opts, "updateLogTriggerConfig1", upkeepId, addr, selector, topic0, topic1, topic2, topic3)
+}
+
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepSession) UpdateLogTriggerConfig1(upkeepId *big.Int, addr common.Address, selector uint8, topic0 [32]byte, topic1 [32]byte, topic2 [32]byte, topic3 [32]byte) (*types.Transaction, error) {
+ return _VerifiableLoadUpkeep.Contract.UpdateLogTriggerConfig1(&_VerifiableLoadUpkeep.TransactOpts, upkeepId, addr, selector, topic0, topic1, topic2, topic3)
+}
+
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactorSession) UpdateLogTriggerConfig1(upkeepId *big.Int, addr common.Address, selector uint8, topic0 [32]byte, topic1 [32]byte, topic2 [32]byte, topic3 [32]byte) (*types.Transaction, error) {
+ return _VerifiableLoadUpkeep.Contract.UpdateLogTriggerConfig1(&_VerifiableLoadUpkeep.TransactOpts, upkeepId, addr, selector, topic0, topic1, topic2, topic3)
+}
+
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactor) UpdateLogTriggerConfig2(opts *bind.TransactOpts, upkeepId *big.Int, cfg []byte) (*types.Transaction, error) {
+ return _VerifiableLoadUpkeep.contract.Transact(opts, "updateLogTriggerConfig2", upkeepId, cfg)
+}
+
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepSession) UpdateLogTriggerConfig2(upkeepId *big.Int, cfg []byte) (*types.Transaction, error) {
+ return _VerifiableLoadUpkeep.Contract.UpdateLogTriggerConfig2(&_VerifiableLoadUpkeep.TransactOpts, upkeepId, cfg)
+}
+
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactorSession) UpdateLogTriggerConfig2(upkeepId *big.Int, cfg []byte) (*types.Transaction, error) {
+ return _VerifiableLoadUpkeep.Contract.UpdateLogTriggerConfig2(&_VerifiableLoadUpkeep.TransactOpts, upkeepId, cfg)
+}
+
func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepTransactor) UpdateUpkeepPipelineData(opts *bind.TransactOpts, upkeepId *big.Int, pipelineData []byte) (*types.Transaction, error) {
return _VerifiableLoadUpkeep.contract.Transact(opts, "updateUpkeepPipelineData", upkeepId, pipelineData)
}
@@ -1302,7 +1591,7 @@ type VerifiableLoadUpkeepLogEmitted struct {
Raw types.Log
}
-func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) FilterLogEmitted(opts *bind.FilterOpts, upkeepId []*big.Int, blockNum []*big.Int) (*VerifiableLoadUpkeepLogEmittedIterator, error) {
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) FilterLogEmitted(opts *bind.FilterOpts, upkeepId []*big.Int, blockNum []*big.Int, addr []common.Address) (*VerifiableLoadUpkeepLogEmittedIterator, error) {
var upkeepIdRule []interface{}
for _, upkeepIdItem := range upkeepId {
@@ -1312,15 +1601,19 @@ func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) FilterLogEmitted(opts
for _, blockNumItem := range blockNum {
blockNumRule = append(blockNumRule, blockNumItem)
}
+ var addrRule []interface{}
+ for _, addrItem := range addr {
+ addrRule = append(addrRule, addrItem)
+ }
- logs, sub, err := _VerifiableLoadUpkeep.contract.FilterLogs(opts, "LogEmitted", upkeepIdRule, blockNumRule)
+ logs, sub, err := _VerifiableLoadUpkeep.contract.FilterLogs(opts, "LogEmitted", upkeepIdRule, blockNumRule, addrRule)
if err != nil {
return nil, err
}
return &VerifiableLoadUpkeepLogEmittedIterator{contract: _VerifiableLoadUpkeep.contract, event: "LogEmitted", logs: logs, sub: sub}, nil
}
-func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) WatchLogEmitted(opts *bind.WatchOpts, sink chan<- *VerifiableLoadUpkeepLogEmitted, upkeepId []*big.Int, blockNum []*big.Int) (event.Subscription, error) {
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) WatchLogEmitted(opts *bind.WatchOpts, sink chan<- *VerifiableLoadUpkeepLogEmitted, upkeepId []*big.Int, blockNum []*big.Int, addr []common.Address) (event.Subscription, error) {
var upkeepIdRule []interface{}
for _, upkeepIdItem := range upkeepId {
@@ -1330,8 +1623,12 @@ func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) WatchLogEmitted(opts
for _, blockNumItem := range blockNum {
blockNumRule = append(blockNumRule, blockNumItem)
}
+ var addrRule []interface{}
+ for _, addrItem := range addr {
+ addrRule = append(addrRule, addrItem)
+ }
- logs, sub, err := _VerifiableLoadUpkeep.contract.WatchLogs(opts, "LogEmitted", upkeepIdRule, blockNumRule)
+ logs, sub, err := _VerifiableLoadUpkeep.contract.WatchLogs(opts, "LogEmitted", upkeepIdRule, blockNumRule, addrRule)
if err != nil {
return nil, err
}
@@ -1372,8 +1669,8 @@ func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) ParseLogEmitted(log t
return event, nil
}
-type VerifiableLoadUpkeepOwnershipTransferRequestedIterator struct {
- Event *VerifiableLoadUpkeepOwnershipTransferRequested
+type VerifiableLoadUpkeepLogEmittedAgainIterator struct {
+ Event *VerifiableLoadUpkeepLogEmittedAgain
contract *bind.BoundContract
event string
@@ -1384,7 +1681,7 @@ type VerifiableLoadUpkeepOwnershipTransferRequestedIterator struct {
fail error
}
-func (it *VerifiableLoadUpkeepOwnershipTransferRequestedIterator) Next() bool {
+func (it *VerifiableLoadUpkeepLogEmittedAgainIterator) Next() bool {
if it.fail != nil {
return false
@@ -1393,7 +1690,7 @@ func (it *VerifiableLoadUpkeepOwnershipTransferRequestedIterator) Next() bool {
if it.done {
select {
case log := <-it.logs:
- it.Event = new(VerifiableLoadUpkeepOwnershipTransferRequested)
+ it.Event = new(VerifiableLoadUpkeepLogEmittedAgain)
if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
it.fail = err
return false
@@ -1408,7 +1705,7 @@ func (it *VerifiableLoadUpkeepOwnershipTransferRequestedIterator) Next() bool {
select {
case log := <-it.logs:
- it.Event = new(VerifiableLoadUpkeepOwnershipTransferRequested)
+ it.Event = new(VerifiableLoadUpkeepLogEmittedAgain)
if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
it.fail = err
return false
@@ -1423,51 +1720,60 @@ func (it *VerifiableLoadUpkeepOwnershipTransferRequestedIterator) Next() bool {
}
}
-func (it *VerifiableLoadUpkeepOwnershipTransferRequestedIterator) Error() error {
+func (it *VerifiableLoadUpkeepLogEmittedAgainIterator) Error() error {
return it.fail
}
-func (it *VerifiableLoadUpkeepOwnershipTransferRequestedIterator) Close() error {
+func (it *VerifiableLoadUpkeepLogEmittedAgainIterator) Close() error {
it.sub.Unsubscribe()
return nil
}
-type VerifiableLoadUpkeepOwnershipTransferRequested struct {
- From common.Address
- To common.Address
- Raw types.Log
+type VerifiableLoadUpkeepLogEmittedAgain struct {
+ UpkeepId *big.Int
+ BlockNum *big.Int
+ Addr common.Address
+ Raw types.Log
}
-func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VerifiableLoadUpkeepOwnershipTransferRequestedIterator, error) {
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) FilterLogEmittedAgain(opts *bind.FilterOpts, upkeepId []*big.Int, blockNum []*big.Int, addr []common.Address) (*VerifiableLoadUpkeepLogEmittedAgainIterator, error) {
- var fromRule []interface{}
- for _, fromItem := range from {
- fromRule = append(fromRule, fromItem)
+ var upkeepIdRule []interface{}
+ for _, upkeepIdItem := range upkeepId {
+ upkeepIdRule = append(upkeepIdRule, upkeepIdItem)
}
- var toRule []interface{}
- for _, toItem := range to {
- toRule = append(toRule, toItem)
+ var blockNumRule []interface{}
+ for _, blockNumItem := range blockNum {
+ blockNumRule = append(blockNumRule, blockNumItem)
+ }
+ var addrRule []interface{}
+ for _, addrItem := range addr {
+ addrRule = append(addrRule, addrItem)
}
- logs, sub, err := _VerifiableLoadUpkeep.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule)
+ logs, sub, err := _VerifiableLoadUpkeep.contract.FilterLogs(opts, "LogEmittedAgain", upkeepIdRule, blockNumRule, addrRule)
if err != nil {
return nil, err
}
- return &VerifiableLoadUpkeepOwnershipTransferRequestedIterator{contract: _VerifiableLoadUpkeep.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil
+ return &VerifiableLoadUpkeepLogEmittedAgainIterator{contract: _VerifiableLoadUpkeep.contract, event: "LogEmittedAgain", logs: logs, sub: sub}, nil
}
-func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *VerifiableLoadUpkeepOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) {
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) WatchLogEmittedAgain(opts *bind.WatchOpts, sink chan<- *VerifiableLoadUpkeepLogEmittedAgain, upkeepId []*big.Int, blockNum []*big.Int, addr []common.Address) (event.Subscription, error) {
- var fromRule []interface{}
- for _, fromItem := range from {
- fromRule = append(fromRule, fromItem)
+ var upkeepIdRule []interface{}
+ for _, upkeepIdItem := range upkeepId {
+ upkeepIdRule = append(upkeepIdRule, upkeepIdItem)
}
- var toRule []interface{}
- for _, toItem := range to {
- toRule = append(toRule, toItem)
+ var blockNumRule []interface{}
+ for _, blockNumItem := range blockNum {
+ blockNumRule = append(blockNumRule, blockNumItem)
+ }
+ var addrRule []interface{}
+ for _, addrItem := range addr {
+ addrRule = append(addrRule, addrItem)
}
- logs, sub, err := _VerifiableLoadUpkeep.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule)
+ logs, sub, err := _VerifiableLoadUpkeep.contract.WatchLogs(opts, "LogEmittedAgain", upkeepIdRule, blockNumRule, addrRule)
if err != nil {
return nil, err
}
@@ -1477,8 +1783,8 @@ func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) WatchOwnershipTransfe
select {
case log := <-logs:
- event := new(VerifiableLoadUpkeepOwnershipTransferRequested)
- if err := _VerifiableLoadUpkeep.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil {
+ event := new(VerifiableLoadUpkeepLogEmittedAgain)
+ if err := _VerifiableLoadUpkeep.contract.UnpackLog(event, "LogEmittedAgain", log); err != nil {
return err
}
event.Raw = log
@@ -1499,17 +1805,17 @@ func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) WatchOwnershipTransfe
}), nil
}
-func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) ParseOwnershipTransferRequested(log types.Log) (*VerifiableLoadUpkeepOwnershipTransferRequested, error) {
- event := new(VerifiableLoadUpkeepOwnershipTransferRequested)
- if err := _VerifiableLoadUpkeep.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil {
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) ParseLogEmittedAgain(log types.Log) (*VerifiableLoadUpkeepLogEmittedAgain, error) {
+ event := new(VerifiableLoadUpkeepLogEmittedAgain)
+ if err := _VerifiableLoadUpkeep.contract.UnpackLog(event, "LogEmittedAgain", log); err != nil {
return nil, err
}
event.Raw = log
return event, nil
}
-type VerifiableLoadUpkeepOwnershipTransferredIterator struct {
- Event *VerifiableLoadUpkeepOwnershipTransferred
+type VerifiableLoadUpkeepOwnershipTransferRequestedIterator struct {
+ Event *VerifiableLoadUpkeepOwnershipTransferRequested
contract *bind.BoundContract
event string
@@ -1520,7 +1826,7 @@ type VerifiableLoadUpkeepOwnershipTransferredIterator struct {
fail error
}
-func (it *VerifiableLoadUpkeepOwnershipTransferredIterator) Next() bool {
+func (it *VerifiableLoadUpkeepOwnershipTransferRequestedIterator) Next() bool {
if it.fail != nil {
return false
@@ -1529,7 +1835,7 @@ func (it *VerifiableLoadUpkeepOwnershipTransferredIterator) Next() bool {
if it.done {
select {
case log := <-it.logs:
- it.Event = new(VerifiableLoadUpkeepOwnershipTransferred)
+ it.Event = new(VerifiableLoadUpkeepOwnershipTransferRequested)
if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
it.fail = err
return false
@@ -1544,7 +1850,7 @@ func (it *VerifiableLoadUpkeepOwnershipTransferredIterator) Next() bool {
select {
case log := <-it.logs:
- it.Event = new(VerifiableLoadUpkeepOwnershipTransferred)
+ it.Event = new(VerifiableLoadUpkeepOwnershipTransferRequested)
if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
it.fail = err
return false
@@ -1559,22 +1865,22 @@ func (it *VerifiableLoadUpkeepOwnershipTransferredIterator) Next() bool {
}
}
-func (it *VerifiableLoadUpkeepOwnershipTransferredIterator) Error() error {
+func (it *VerifiableLoadUpkeepOwnershipTransferRequestedIterator) Error() error {
return it.fail
}
-func (it *VerifiableLoadUpkeepOwnershipTransferredIterator) Close() error {
+func (it *VerifiableLoadUpkeepOwnershipTransferRequestedIterator) Close() error {
it.sub.Unsubscribe()
return nil
}
-type VerifiableLoadUpkeepOwnershipTransferred struct {
+type VerifiableLoadUpkeepOwnershipTransferRequested struct {
From common.Address
To common.Address
Raw types.Log
}
-func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VerifiableLoadUpkeepOwnershipTransferredIterator, error) {
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VerifiableLoadUpkeepOwnershipTransferRequestedIterator, error) {
var fromRule []interface{}
for _, fromItem := range from {
@@ -1585,14 +1891,14 @@ func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) FilterOwnershipTransf
toRule = append(toRule, toItem)
}
- logs, sub, err := _VerifiableLoadUpkeep.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule)
+ logs, sub, err := _VerifiableLoadUpkeep.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule)
if err != nil {
return nil, err
}
- return &VerifiableLoadUpkeepOwnershipTransferredIterator{contract: _VerifiableLoadUpkeep.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil
+ return &VerifiableLoadUpkeepOwnershipTransferRequestedIterator{contract: _VerifiableLoadUpkeep.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil
}
-func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *VerifiableLoadUpkeepOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) {
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *VerifiableLoadUpkeepOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) {
var fromRule []interface{}
for _, fromItem := range from {
@@ -1603,7 +1909,7 @@ func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) WatchOwnershipTransfe
toRule = append(toRule, toItem)
}
- logs, sub, err := _VerifiableLoadUpkeep.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule)
+ logs, sub, err := _VerifiableLoadUpkeep.contract.WatchLogs(opts, "OwnershipTransferRequested", fromRule, toRule)
if err != nil {
return nil, err
}
@@ -1613,8 +1919,8 @@ func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) WatchOwnershipTransfe
select {
case log := <-logs:
- event := new(VerifiableLoadUpkeepOwnershipTransferred)
- if err := _VerifiableLoadUpkeep.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil {
+ event := new(VerifiableLoadUpkeepOwnershipTransferRequested)
+ if err := _VerifiableLoadUpkeep.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil {
return err
}
event.Raw = log
@@ -1635,17 +1941,17 @@ func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) WatchOwnershipTransfe
}), nil
}
-func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) ParseOwnershipTransferred(log types.Log) (*VerifiableLoadUpkeepOwnershipTransferred, error) {
- event := new(VerifiableLoadUpkeepOwnershipTransferred)
- if err := _VerifiableLoadUpkeep.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil {
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) ParseOwnershipTransferRequested(log types.Log) (*VerifiableLoadUpkeepOwnershipTransferRequested, error) {
+ event := new(VerifiableLoadUpkeepOwnershipTransferRequested)
+ if err := _VerifiableLoadUpkeep.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil {
return nil, err
}
event.Raw = log
return event, nil
}
-type VerifiableLoadUpkeepReceivedIterator struct {
- Event *VerifiableLoadUpkeepReceived
+type VerifiableLoadUpkeepOwnershipTransferredIterator struct {
+ Event *VerifiableLoadUpkeepOwnershipTransferred
contract *bind.BoundContract
event string
@@ -1656,7 +1962,7 @@ type VerifiableLoadUpkeepReceivedIterator struct {
fail error
}
-func (it *VerifiableLoadUpkeepReceivedIterator) Next() bool {
+func (it *VerifiableLoadUpkeepOwnershipTransferredIterator) Next() bool {
if it.fail != nil {
return false
@@ -1665,7 +1971,7 @@ func (it *VerifiableLoadUpkeepReceivedIterator) Next() bool {
if it.done {
select {
case log := <-it.logs:
- it.Event = new(VerifiableLoadUpkeepReceived)
+ it.Event = new(VerifiableLoadUpkeepOwnershipTransferred)
if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
it.fail = err
return false
@@ -1680,7 +1986,7 @@ func (it *VerifiableLoadUpkeepReceivedIterator) Next() bool {
select {
case log := <-it.logs:
- it.Event = new(VerifiableLoadUpkeepReceived)
+ it.Event = new(VerifiableLoadUpkeepOwnershipTransferred)
if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
it.fail = err
return false
@@ -1695,33 +2001,51 @@ func (it *VerifiableLoadUpkeepReceivedIterator) Next() bool {
}
}
-func (it *VerifiableLoadUpkeepReceivedIterator) Error() error {
+func (it *VerifiableLoadUpkeepOwnershipTransferredIterator) Error() error {
return it.fail
}
-func (it *VerifiableLoadUpkeepReceivedIterator) Close() error {
+func (it *VerifiableLoadUpkeepOwnershipTransferredIterator) Close() error {
it.sub.Unsubscribe()
return nil
}
-type VerifiableLoadUpkeepReceived struct {
- Sender common.Address
- Value *big.Int
- Raw types.Log
+type VerifiableLoadUpkeepOwnershipTransferred struct {
+ From common.Address
+ To common.Address
+ Raw types.Log
}
-func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) FilterReceived(opts *bind.FilterOpts) (*VerifiableLoadUpkeepReceivedIterator, error) {
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VerifiableLoadUpkeepOwnershipTransferredIterator, error) {
+
+ var fromRule []interface{}
+ for _, fromItem := range from {
+ fromRule = append(fromRule, fromItem)
+ }
+ var toRule []interface{}
+ for _, toItem := range to {
+ toRule = append(toRule, toItem)
+ }
- logs, sub, err := _VerifiableLoadUpkeep.contract.FilterLogs(opts, "Received")
+ logs, sub, err := _VerifiableLoadUpkeep.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule)
if err != nil {
return nil, err
}
- return &VerifiableLoadUpkeepReceivedIterator{contract: _VerifiableLoadUpkeep.contract, event: "Received", logs: logs, sub: sub}, nil
+ return &VerifiableLoadUpkeepOwnershipTransferredIterator{contract: _VerifiableLoadUpkeep.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil
}
-func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) WatchReceived(opts *bind.WatchOpts, sink chan<- *VerifiableLoadUpkeepReceived) (event.Subscription, error) {
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *VerifiableLoadUpkeepOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) {
- logs, sub, err := _VerifiableLoadUpkeep.contract.WatchLogs(opts, "Received")
+ var fromRule []interface{}
+ for _, fromItem := range from {
+ fromRule = append(fromRule, fromItem)
+ }
+ var toRule []interface{}
+ for _, toItem := range to {
+ toRule = append(toRule, toItem)
+ }
+
+ logs, sub, err := _VerifiableLoadUpkeep.contract.WatchLogs(opts, "OwnershipTransferred", fromRule, toRule)
if err != nil {
return nil, err
}
@@ -1731,8 +2055,8 @@ func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) WatchReceived(opts *b
select {
case log := <-logs:
- event := new(VerifiableLoadUpkeepReceived)
- if err := _VerifiableLoadUpkeep.contract.UnpackLog(event, "Received", log); err != nil {
+ event := new(VerifiableLoadUpkeepOwnershipTransferred)
+ if err := _VerifiableLoadUpkeep.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil {
return err
}
event.Raw = log
@@ -1753,9 +2077,9 @@ func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) WatchReceived(opts *b
}), nil
}
-func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) ParseReceived(log types.Log) (*VerifiableLoadUpkeepReceived, error) {
- event := new(VerifiableLoadUpkeepReceived)
- if err := _VerifiableLoadUpkeep.contract.UnpackLog(event, "Received", log); err != nil {
+func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) ParseOwnershipTransferred(log types.Log) (*VerifiableLoadUpkeepOwnershipTransferred, error) {
+ event := new(VerifiableLoadUpkeepOwnershipTransferred)
+ if err := _VerifiableLoadUpkeep.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil {
return nil, err
}
event.Raw = log
@@ -1881,137 +2205,18 @@ func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) ParseUpkeepTopUp(log
return event, nil
}
-type VerifiableLoadUpkeepUpkeepsRegisteredIterator struct {
- Event *VerifiableLoadUpkeepUpkeepsRegistered
-
- contract *bind.BoundContract
- event string
-
- logs chan types.Log
- sub ethereum.Subscription
- done bool
- fail error
-}
-
-func (it *VerifiableLoadUpkeepUpkeepsRegisteredIterator) Next() bool {
-
- if it.fail != nil {
- return false
- }
-
- if it.done {
- select {
- case log := <-it.logs:
- it.Event = new(VerifiableLoadUpkeepUpkeepsRegistered)
- if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
- it.fail = err
- return false
- }
- it.Event.Raw = log
- return true
-
- default:
- return false
- }
- }
-
- select {
- case log := <-it.logs:
- it.Event = new(VerifiableLoadUpkeepUpkeepsRegistered)
- if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
- it.fail = err
- return false
- }
- it.Event.Raw = log
- return true
-
- case err := <-it.sub.Err():
- it.done = true
- it.fail = err
- return it.Next()
- }
-}
-
-func (it *VerifiableLoadUpkeepUpkeepsRegisteredIterator) Error() error {
- return it.fail
-}
-
-func (it *VerifiableLoadUpkeepUpkeepsRegisteredIterator) Close() error {
- it.sub.Unsubscribe()
- return nil
-}
-
-type VerifiableLoadUpkeepUpkeepsRegistered struct {
- UpkeepIds []*big.Int
- Raw types.Log
-}
-
-func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) FilterUpkeepsRegistered(opts *bind.FilterOpts) (*VerifiableLoadUpkeepUpkeepsRegisteredIterator, error) {
-
- logs, sub, err := _VerifiableLoadUpkeep.contract.FilterLogs(opts, "UpkeepsRegistered")
- if err != nil {
- return nil, err
- }
- return &VerifiableLoadUpkeepUpkeepsRegisteredIterator{contract: _VerifiableLoadUpkeep.contract, event: "UpkeepsRegistered", logs: logs, sub: sub}, nil
-}
-
-func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) WatchUpkeepsRegistered(opts *bind.WatchOpts, sink chan<- *VerifiableLoadUpkeepUpkeepsRegistered) (event.Subscription, error) {
-
- logs, sub, err := _VerifiableLoadUpkeep.contract.WatchLogs(opts, "UpkeepsRegistered")
- if err != nil {
- return nil, err
- }
- return event.NewSubscription(func(quit <-chan struct{}) error {
- defer sub.Unsubscribe()
- for {
- select {
- case log := <-logs:
-
- event := new(VerifiableLoadUpkeepUpkeepsRegistered)
- if err := _VerifiableLoadUpkeep.contract.UnpackLog(event, "UpkeepsRegistered", log); err != nil {
- return err
- }
- event.Raw = log
-
- select {
- case sink <- event:
- case err := <-sub.Err():
- return err
- case <-quit:
- return nil
- }
- case err := <-sub.Err():
- return err
- case <-quit:
- return nil
- }
- }
- }), nil
-}
-
-func (_VerifiableLoadUpkeep *VerifiableLoadUpkeepFilterer) ParseUpkeepsRegistered(log types.Log) (*VerifiableLoadUpkeepUpkeepsRegistered, error) {
- event := new(VerifiableLoadUpkeepUpkeepsRegistered)
- if err := _VerifiableLoadUpkeep.contract.UnpackLog(event, "UpkeepsRegistered", log); err != nil {
- return nil, err
- }
- event.Raw = log
- return event, nil
-}
-
func (_VerifiableLoadUpkeep *VerifiableLoadUpkeep) ParseLog(log types.Log) (generated.AbigenLog, error) {
switch log.Topics[0] {
case _VerifiableLoadUpkeep.abi.Events["LogEmitted"].ID:
return _VerifiableLoadUpkeep.ParseLogEmitted(log)
+ case _VerifiableLoadUpkeep.abi.Events["LogEmittedAgain"].ID:
+ return _VerifiableLoadUpkeep.ParseLogEmittedAgain(log)
case _VerifiableLoadUpkeep.abi.Events["OwnershipTransferRequested"].ID:
return _VerifiableLoadUpkeep.ParseOwnershipTransferRequested(log)
case _VerifiableLoadUpkeep.abi.Events["OwnershipTransferred"].ID:
return _VerifiableLoadUpkeep.ParseOwnershipTransferred(log)
- case _VerifiableLoadUpkeep.abi.Events["Received"].ID:
- return _VerifiableLoadUpkeep.ParseReceived(log)
case _VerifiableLoadUpkeep.abi.Events["UpkeepTopUp"].ID:
return _VerifiableLoadUpkeep.ParseUpkeepTopUp(log)
- case _VerifiableLoadUpkeep.abi.Events["UpkeepsRegistered"].ID:
- return _VerifiableLoadUpkeep.ParseUpkeepsRegistered(log)
default:
return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0])
@@ -2022,6 +2227,10 @@ func (VerifiableLoadUpkeepLogEmitted) Topic() common.Hash {
return common.HexToHash("0x97009585a4d2440f981ab6f6eec514343e1e6b2aa9b991a26998e6806f41bf08")
}
+func (VerifiableLoadUpkeepLogEmittedAgain) Topic() common.Hash {
+ return common.HexToHash("0xc76416badc8398ce17c93eab7b4f60f263241694cf503e4df24f233a8cc1c50d")
+}
+
func (VerifiableLoadUpkeepOwnershipTransferRequested) Topic() common.Hash {
return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278")
}
@@ -2030,18 +2239,10 @@ func (VerifiableLoadUpkeepOwnershipTransferred) Topic() common.Hash {
return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0")
}
-func (VerifiableLoadUpkeepReceived) Topic() common.Hash {
- return common.HexToHash("0x88a5966d370b9919b20f3e2c13ff65706f196a4e32cc2c12bf57088f88525874")
-}
-
func (VerifiableLoadUpkeepUpkeepTopUp) Topic() common.Hash {
return common.HexToHash("0x49d4100ab0124eb4a9a65dc4ea08d6412a43f6f05c49194983f5b322bcc0a5c0")
}
-func (VerifiableLoadUpkeepUpkeepsRegistered) Topic() common.Hash {
- return common.HexToHash("0x2ee10f7eb180441fb9fbba75b10c0162b5390b557712c93426243ca8f383c711")
-}
-
func (_VerifiableLoadUpkeep *VerifiableLoadUpkeep) Address() common.Address {
return _VerifiableLoadUpkeep.address
}
@@ -2065,13 +2266,23 @@ type VerifiableLoadUpkeepInterface interface {
Eligible(opts *bind.CallOpts, upkeepId *big.Int) (bool, error)
+ EmittedAgainSig(opts *bind.CallOpts) ([32]byte, error)
+
EmittedSig(opts *bind.CallOpts) ([32]byte, error)
+ FeedParamKey(opts *bind.CallOpts) (string, error)
+
+ FeedsHex(opts *bind.CallOpts, arg0 *big.Int) (string, error)
+
FirstPerformBlocks(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error)
GasLimits(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error)
- GetActiveUpkeepIDs(opts *bind.CallOpts, startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error)
+ GetActiveUpkeepIDsDeployedByThisContract(opts *bind.CallOpts, startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error)
+
+ GetAllActiveUpkeepIDsOnRegistry(opts *bind.CallOpts, startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error)
+
+ GetBalance(opts *bind.CallOpts, id *big.Int) (*big.Int, error)
GetBucketedDelays(opts *bind.CallOpts, upkeepId *big.Int, bucket uint16) ([]*big.Int, error)
@@ -2081,7 +2292,11 @@ type VerifiableLoadUpkeepInterface interface {
GetDelaysLength(opts *bind.CallOpts, upkeepId *big.Int) (*big.Int, error)
- GetLogTriggerConfig(opts *bind.CallOpts, upkeepId *big.Int) ([]byte, error)
+ GetForwarder(opts *bind.CallOpts, upkeepID *big.Int) (common.Address, error)
+
+ GetLogTriggerConfig(opts *bind.CallOpts, addr common.Address, selector uint8, topic0 [32]byte, topic1 [32]byte, topic2 [32]byte, topic3 [32]byte) ([]byte, error)
+
+ GetMinBalanceForUpkeep(opts *bind.CallOpts, upkeepId *big.Int) (*big.Int, error)
GetPxDelayLastNPerforms(opts *bind.CallOpts, upkeepId *big.Int, p *big.Int, n *big.Int) (*big.Int, error)
@@ -2089,6 +2304,14 @@ type VerifiableLoadUpkeepInterface interface {
GetSumDelayLastNPerforms(opts *bind.CallOpts, upkeepId *big.Int, n *big.Int) (*big.Int, *big.Int, error)
+ GetTriggerType(opts *bind.CallOpts, upkeepId *big.Int) (uint8, error)
+
+ GetUpkeepInfo(opts *bind.CallOpts, upkeepId *big.Int) (KeeperRegistryBase21UpkeepInfo, error)
+
+ GetUpkeepPrivilegeConfig(opts *bind.CallOpts, upkeepId *big.Int) ([]byte, error)
+
+ GetUpkeepTriggerConfig(opts *bind.CallOpts, upkeepId *big.Int) ([]byte, error)
+
Intervals(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error)
LastTopUpBlocks(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error)
@@ -2109,6 +2332,8 @@ type VerifiableLoadUpkeepInterface interface {
Registry(opts *bind.CallOpts) (common.Address, error)
+ TimeParamKey(opts *bind.CallOpts) (string, error)
+
UpkeepTopUpCheckInterval(opts *bind.CallOpts) (*big.Int, error)
UseArbitrumBlockNum(opts *bind.CallOpts) (bool, error)
@@ -2119,9 +2344,13 @@ type VerifiableLoadUpkeepInterface interface {
BatchCancelUpkeeps(opts *bind.TransactOpts, upkeepIds []*big.Int) (*types.Transaction, error)
+ BatchPreparingUpkeeps(opts *bind.TransactOpts, upkeepIds []*big.Int, selector uint8, topic0 [32]byte, topic1 [32]byte, topic2 [32]byte, topic3 [32]byte) (*types.Transaction, error)
+
+ BatchPreparingUpkeepsSimple(opts *bind.TransactOpts, upkeepIds []*big.Int, log uint8, selector uint8) (*types.Transaction, error)
+
BatchRegisterUpkeeps(opts *bind.TransactOpts, number uint8, gasLimit uint32, triggerType uint8, triggerConfig []byte, amount *big.Int, checkGasToBurn *big.Int, performGasToBurn *big.Int) (*types.Transaction, error)
- BatchSendLogs(opts *bind.TransactOpts) (*types.Transaction, error)
+ BatchSendLogs(opts *bind.TransactOpts, log uint8) (*types.Transaction, error)
BatchSetIntervals(opts *bind.TransactOpts, upkeepIds []*big.Int, interval uint32) (*types.Transaction, error)
@@ -2131,36 +2360,34 @@ type VerifiableLoadUpkeepInterface interface {
BurnPerformGas(opts *bind.TransactOpts, upkeepId *big.Int, startGas *big.Int, blockNum *big.Int) (*types.Transaction, error)
- CancelUpkeep(opts *bind.TransactOpts, upkeepId *big.Int) (*types.Transaction, error)
-
CheckUpkeep(opts *bind.TransactOpts, checkData []byte) (*types.Transaction, error)
PerformUpkeep(opts *bind.TransactOpts, performData []byte) (*types.Transaction, error)
- SendLog(opts *bind.TransactOpts, upkeepId *big.Int) (*types.Transaction, error)
-
- SetAddLinkAmount(opts *bind.TransactOpts, amount *big.Int) (*types.Transaction, error)
-
- SetCheckGasToBurn(opts *bind.TransactOpts, upkeepId *big.Int, value *big.Int) (*types.Transaction, error)
+ SendLog(opts *bind.TransactOpts, upkeepId *big.Int, log uint8) (*types.Transaction, error)
SetConfig(opts *bind.TransactOpts, newRegistrar common.Address) (*types.Transaction, error)
+ SetFeeds(opts *bind.TransactOpts, _feeds []string) (*types.Transaction, error)
+
SetInterval(opts *bind.TransactOpts, upkeepId *big.Int, _interval *big.Int) (*types.Transaction, error)
- SetMinBalanceThresholdMultiplier(opts *bind.TransactOpts, newMinBalanceThresholdMultiplier uint8) (*types.Transaction, error)
+ SetParamKeys(opts *bind.TransactOpts, _feedParamKey string, _timeParamKey string) (*types.Transaction, error)
SetPerformDataSize(opts *bind.TransactOpts, upkeepId *big.Int, value *big.Int) (*types.Transaction, error)
- SetPerformGasToBurn(opts *bind.TransactOpts, upkeepId *big.Int, value *big.Int) (*types.Transaction, error)
-
SetUpkeepGasLimit(opts *bind.TransactOpts, upkeepId *big.Int, gasLimit uint32) (*types.Transaction, error)
- SetUpkeepTopUpCheckInterval(opts *bind.TransactOpts, newInterval *big.Int) (*types.Transaction, error)
+ SetUpkeepPrivilegeConfig(opts *bind.TransactOpts, upkeepId *big.Int, cfg []byte) (*types.Transaction, error)
TopUpFund(opts *bind.TransactOpts, upkeepId *big.Int, blockNum *big.Int) (*types.Transaction, error)
TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error)
+ UpdateLogTriggerConfig1(opts *bind.TransactOpts, upkeepId *big.Int, addr common.Address, selector uint8, topic0 [32]byte, topic1 [32]byte, topic2 [32]byte, topic3 [32]byte) (*types.Transaction, error)
+
+ UpdateLogTriggerConfig2(opts *bind.TransactOpts, upkeepId *big.Int, cfg []byte) (*types.Transaction, error)
+
UpdateUpkeepPipelineData(opts *bind.TransactOpts, upkeepId *big.Int, pipelineData []byte) (*types.Transaction, error)
WithdrawLinks(opts *bind.TransactOpts) (*types.Transaction, error)
@@ -2169,12 +2396,18 @@ type VerifiableLoadUpkeepInterface interface {
Receive(opts *bind.TransactOpts) (*types.Transaction, error)
- FilterLogEmitted(opts *bind.FilterOpts, upkeepId []*big.Int, blockNum []*big.Int) (*VerifiableLoadUpkeepLogEmittedIterator, error)
+ FilterLogEmitted(opts *bind.FilterOpts, upkeepId []*big.Int, blockNum []*big.Int, addr []common.Address) (*VerifiableLoadUpkeepLogEmittedIterator, error)
- WatchLogEmitted(opts *bind.WatchOpts, sink chan<- *VerifiableLoadUpkeepLogEmitted, upkeepId []*big.Int, blockNum []*big.Int) (event.Subscription, error)
+ WatchLogEmitted(opts *bind.WatchOpts, sink chan<- *VerifiableLoadUpkeepLogEmitted, upkeepId []*big.Int, blockNum []*big.Int, addr []common.Address) (event.Subscription, error)
ParseLogEmitted(log types.Log) (*VerifiableLoadUpkeepLogEmitted, error)
+ FilterLogEmittedAgain(opts *bind.FilterOpts, upkeepId []*big.Int, blockNum []*big.Int, addr []common.Address) (*VerifiableLoadUpkeepLogEmittedAgainIterator, error)
+
+ WatchLogEmittedAgain(opts *bind.WatchOpts, sink chan<- *VerifiableLoadUpkeepLogEmittedAgain, upkeepId []*big.Int, blockNum []*big.Int, addr []common.Address) (event.Subscription, error)
+
+ ParseLogEmittedAgain(log types.Log) (*VerifiableLoadUpkeepLogEmittedAgain, error)
+
FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VerifiableLoadUpkeepOwnershipTransferRequestedIterator, error)
WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *VerifiableLoadUpkeepOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error)
@@ -2187,24 +2420,12 @@ type VerifiableLoadUpkeepInterface interface {
ParseOwnershipTransferred(log types.Log) (*VerifiableLoadUpkeepOwnershipTransferred, error)
- FilterReceived(opts *bind.FilterOpts) (*VerifiableLoadUpkeepReceivedIterator, error)
-
- WatchReceived(opts *bind.WatchOpts, sink chan<- *VerifiableLoadUpkeepReceived) (event.Subscription, error)
-
- ParseReceived(log types.Log) (*VerifiableLoadUpkeepReceived, error)
-
FilterUpkeepTopUp(opts *bind.FilterOpts) (*VerifiableLoadUpkeepUpkeepTopUpIterator, error)
WatchUpkeepTopUp(opts *bind.WatchOpts, sink chan<- *VerifiableLoadUpkeepUpkeepTopUp) (event.Subscription, error)
ParseUpkeepTopUp(log types.Log) (*VerifiableLoadUpkeepUpkeepTopUp, error)
- FilterUpkeepsRegistered(opts *bind.FilterOpts) (*VerifiableLoadUpkeepUpkeepsRegisteredIterator, error)
-
- WatchUpkeepsRegistered(opts *bind.WatchOpts, sink chan<- *VerifiableLoadUpkeepUpkeepsRegistered) (event.Subscription, error)
-
- ParseUpkeepsRegistered(log types.Log) (*VerifiableLoadUpkeepUpkeepsRegistered, error)
-
ParseLog(log types.Log) (generated.AbigenLog, error)
Address() common.Address
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 3c6eff6b6ba..51021b789e7 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: "0x60e06040523480156200001157600080fd5b50604051620059b4380380620059b48339810160408190526200003491620001b1565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000e8565b5050506001600160601b0319606093841b811660805290831b811660a052911b1660c052620001fb565b6001600160a01b038116331415620001435760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b0381168114620001ac57600080fd5b919050565b600080600060608486031215620001c757600080fd5b620001d28462000194565b9250620001e26020850162000194565b9150620001f26040850162000194565b90509250925092565b60805160601c60a05160601c60c05160601c61574f620002656000396000818161051901526138f00152600081816106030152613dfb01526000818161036d015281816114da0152818161237701528181612dae01528181612eea015261350f015261574f6000f3fe608060405234801561001057600080fd5b506004361061025b5760003560e01c80636f64f03f11610145578063ad178361116100bd578063d2f9f9a71161008c578063e72f6e3011610071578063e72f6e30146106e0578063e82ad7d4146106f3578063f2fde38b1461071657600080fd5b8063d2f9f9a7146106ba578063d7ae1d30146106cd57600080fd5b8063ad178361146105fe578063af198b9714610625578063c3f909d414610655578063caf70c4a146106a757600080fd5b80638da5cb5b11610114578063a21a23e4116100f9578063a21a23e4146105c0578063a47c7696146105c8578063a4c0ed36146105eb57600080fd5b80638da5cb5b1461059c5780639f87fad7146105ad57600080fd5b80636f64f03f1461055b5780637341c10c1461056e57806379ba509714610581578063823597401461058957600080fd5b8063356dac71116101d85780635fbbc0d2116101a757806366316d8d1161018c57806366316d8d14610501578063689c45171461051457806369bcdb7d1461053b57600080fd5b80635fbbc0d2146103f357806364d51a2a146104f957600080fd5b8063356dac71146103a757806340d6bb82146103af5780634cb48a54146103cd5780635d3b1d30146103e057600080fd5b806308821d581161022f57806315c48b841161021457806315c48b841461030e578063181f5a77146103295780631b6b6d231461036857600080fd5b806308821d58146102cf57806312b58349146102e257600080fd5b80620122911461026057806302bcc5b61461028057806304c357cb1461029557806306bfa637146102a8575b600080fd5b610268610729565b60405161027793929190615299565b60405180910390f35b61029361028e3660046150e5565b6107a5565b005b6102936102a3366004615100565b610837565b60055467ffffffffffffffff165b60405167ffffffffffffffff9091168152602001610277565b6102936102dd366004614df6565b6109eb565b6005546801000000000000000090046bffffffffffffffffffffffff165b604051908152602001610277565b61031660c881565b60405161ffff9091168152602001610277565b604080518082018252601681527f565246436f6f7264696e61746f72563220312e302e3000000000000000000000602082015290516102779190615244565b61038f7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610277565b600a54610300565b6103b86101f481565b60405163ffffffff9091168152602001610277565b6102936103db366004614f8f565b610bb0565b6103006103ee366004614e69565b610fa7565b600c546040805163ffffffff80841682526401000000008404811660208301526801000000000000000084048116928201929092526c010000000000000000000000008304821660608201527001000000000000000000000000000000008304909116608082015262ffffff740100000000000000000000000000000000000000008304811660a0830152770100000000000000000000000000000000000000000000008304811660c08301527a0100000000000000000000000000000000000000000000000000008304811660e08301527d01000000000000000000000000000000000000000000000000000000000090920490911661010082015261012001610277565b610316606481565b61029361050f366004614dae565b611385565b61038f7f000000000000000000000000000000000000000000000000000000000000000081565b6103006105493660046150cc565b60009081526009602052604090205490565b610293610569366004614cf3565b6115d4565b61029361057c366004615100565b611704565b610293611951565b6102936105973660046150e5565b611a1a565b6000546001600160a01b031661038f565b6102936105bb366004615100565b611be0565b6102b661201f565b6105db6105d63660046150e5565b612202565b6040516102779493929190615437565b6102936105f9366004614d27565b612325565b61038f7f000000000000000000000000000000000000000000000000000000000000000081565b610638610633366004614ec7565b61257c565b6040516bffffffffffffffffffffffff9091168152602001610277565b600b546040805161ffff8316815263ffffffff6201000084048116602083015267010000000000000084048116928201929092526b010000000000000000000000909204166060820152608001610277565b6103006106b5366004614e12565b612a16565b6103b86106c83660046150e5565b612a46565b6102936106db366004615100565b612c3b565b6102936106ee366004614cd8565b612d75565b6107066107013660046150e5565b612fb2565b6040519015158152602001610277565b610293610724366004614cd8565b6131d5565b600b546007805460408051602080840282018101909252828152600094859460609461ffff8316946201000090930463ffffffff1693919283919083018282801561079357602002820191906000526020600020905b81548152602001906001019080831161077f575b50505050509050925092509250909192565b6107ad6131e6565b67ffffffffffffffff81166000908152600360205260409020546001600160a01b0316610806576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff81166000908152600360205260409020546108349082906001600160a01b0316613242565b50565b67ffffffffffffffff821660009081526003602052604090205482906001600160a01b031680610893576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336001600160a01b038216146108e5576040517fd8a3fb520000000000000000000000000000000000000000000000000000000081526001600160a01b03821660048201526024015b60405180910390fd5b600b546601000000000000900460ff161561092c576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff84166000908152600360205260409020600101546001600160a01b038481169116146109e55767ffffffffffffffff841660008181526003602090815260409182902060010180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0388169081179091558251338152918201527f69436ea6df009049404f564eff6622cd00522b0bd6a89efd9e52a355c4a879be91015b60405180910390a25b50505050565b6109f36131e6565b604080518082018252600091610a22919084906002908390839080828437600092019190915250612a16915050565b6000818152600660205260409020549091506001600160a01b031680610a77576040517f77f5b84c000000000000000000000000000000000000000000000000000000008152600481018390526024016108dc565b600082815260066020526040812080547fffffffffffffffffffffffff00000000000000000000000000000000000000001690555b600754811015610b67578260078281548110610aca57610aca6156e4565b90600052602060002001541415610b55576007805460009190610aef9060019061559e565b81548110610aff57610aff6156e4565b906000526020600020015490508060078381548110610b2057610b206156e4565b6000918252602090912001556007805480610b3d57610b3d6156b5565b60019003818190600052602060002001600090559055505b80610b5f816155e2565b915050610aac565b50806001600160a01b03167f72be339577868f868798bac2c93e52d6f034fef4689a9848996c14ebb7416c0d83604051610ba391815260200190565b60405180910390a2505050565b610bb86131e6565b60c861ffff87161115610c0b576040517fa738697600000000000000000000000000000000000000000000000000000000815261ffff871660048201819052602482015260c860448201526064016108dc565b60008213610c48576040517f43d4cf66000000000000000000000000000000000000000000000000000000008152600481018390526024016108dc565b6040805160a0808201835261ffff891680835263ffffffff89811660208086018290526000868801528a831660608088018290528b85166080988901819052600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000001690971762010000909502949094177fffffffffffffffffffffffffffffffffff000000000000000000ffffffffffff166701000000000000009092027fffffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffff16919091176b010000000000000000000000909302929092179093558651600c80549489015189890151938a0151978a0151968a015160c08b015160e08c01516101008d01519588167fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000009099169890981764010000000093881693909302929092177fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff1668010000000000000000958716959095027fffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffff16949094176c0100000000000000000000000098861698909802979097177fffffffffffffffffff00000000000000ffffffffffffffffffffffffffffffff1670010000000000000000000000000000000096909416959095027fffffffffffffffffff000000ffffffffffffffffffffffffffffffffffffffff16929092177401000000000000000000000000000000000000000062ffffff92831602177fffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffff1677010000000000000000000000000000000000000000000000958216959095027fffffff000000ffffffffffffffffffffffffffffffffffffffffffffffffffff16949094177a01000000000000000000000000000000000000000000000000000092851692909202919091177cffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167d0100000000000000000000000000000000000000000000000000000000009390911692909202919091178155600a84905590517fc21e3bd2e0b339d2848f0dd956947a88966c242c0c0c582a33137a5c1ceb5cb291610f979189918991899189918991906152f8565b60405180910390a1505050505050565b600b546000906601000000000000900460ff1615610ff1576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff85166000908152600360205260409020546001600160a01b031661104a576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b33600090815260026020908152604080832067ffffffffffffffff808a16855292529091205416806110ba576040517ff0019fe600000000000000000000000000000000000000000000000000000000815267ffffffffffffffff871660048201523360248201526044016108dc565b600b5461ffff90811690861610806110d6575060c861ffff8616115b1561112657600b546040517fa738697600000000000000000000000000000000000000000000000000000000815261ffff8088166004830152909116602482015260c860448201526064016108dc565b600b5463ffffffff620100009091048116908516111561118d57600b546040517ff5d7e01e00000000000000000000000000000000000000000000000000000000815263ffffffff80871660048301526201000090920490911660248201526044016108dc565b6101f463ffffffff841611156111df576040517f47386bec00000000000000000000000000000000000000000000000000000000815263ffffffff841660048201526101f460248201526044016108dc565b60006111ec8260016154fa565b6040805160208082018c9052338284015267ffffffffffffffff808c16606084015284166080808401919091528351808403909101815260a08301845280519082012060c083018d905260e080840182905284518085039091018152610100909301909352815191012091925081611262613667565b60408051602081019390935282015267ffffffffffffffff8a16606082015263ffffffff8089166080830152871660a08201523360c082015260e00160408051808303601f19018152828252805160209182012060008681526009835283902055848352820183905261ffff8a169082015263ffffffff808916606083015287166080820152339067ffffffffffffffff8b16908c907f63373d1c4696214b898952999c9aaec57dac1ee2723cec59bea6888f489a97729060a00160405180910390a45033600090815260026020908152604080832067ffffffffffffffff808d16855292529091208054919093167fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000009091161790915591505095945050505050565b600b546601000000000000900460ff16156113cc576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152600860205260409020546bffffffffffffffffffffffff80831691161015611426576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b33600090815260086020526040812080548392906114539084906bffffffffffffffffffffffff166155b5565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555080600560088282829054906101000a90046bffffffffffffffffffffffff166114aa91906155b5565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9059cbb83836040518363ffffffff1660e01b81526004016115489291906001600160a01b039290921682526bffffffffffffffffffffffff16602082015260400190565b602060405180830381600087803b15801561156257600080fd5b505af1158015611576573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061159a9190614e2e565b6115d0576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050565b6115dc6131e6565b60408051808201825260009161160b919084906002908390839080828437600092019190915250612a16915050565b6000818152600660205260409020549091506001600160a01b031615611660576040517f4a0b8fa7000000000000000000000000000000000000000000000000000000008152600481018290526024016108dc565b600081815260066020908152604080832080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0388169081179091556007805460018101825594527fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c688909301849055518381527fe729ae16526293f74ade739043022254f1489f616295a25bf72dfb4511ed73b89101610ba3565b67ffffffffffffffff821660009081526003602052604090205482906001600160a01b031680611760576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336001600160a01b038216146117ad576040517fd8a3fb520000000000000000000000000000000000000000000000000000000081526001600160a01b03821660048201526024016108dc565b600b546601000000000000900460ff16156117f4576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff84166000908152600360205260409020600201546064141561184b576040517f05a48e0f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b038316600090815260026020908152604080832067ffffffffffffffff80891685529252909120541615611885576109e5565b6001600160a01b038316600081815260026020818152604080842067ffffffffffffffff8a1680865290835281852080547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000166001908117909155600384528286209094018054948501815585529382902090920180547fffffffffffffffffffffffff00000000000000000000000000000000000000001685179055905192835290917f43dc749a04ac8fb825cbd514f7c0e13f13bc6f2ee66043b76629d51776cff8e091016109dc565b6001546001600160a01b031633146119ab5760405162461bcd60e51b815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016108dc565b60008054337fffffffffffffffffffffffff0000000000000000000000000000000000000000808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b600b546601000000000000900460ff1615611a61576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff81166000908152600360205260409020546001600160a01b0316611aba576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff81166000908152600360205260409020600101546001600160a01b03163314611b425767ffffffffffffffff8116600090815260036020526040908190206001015490517fd084e9750000000000000000000000000000000000000000000000000000000081526001600160a01b0390911660048201526024016108dc565b67ffffffffffffffff81166000818152600360209081526040918290208054337fffffffffffffffffffffffff0000000000000000000000000000000000000000808316821784556001909301805490931690925583516001600160a01b03909116808252928101919091529092917f6f1dc65165ffffedfd8e507b4a0f1fcfdada045ed11f6c26ba27cedfe87802f0910160405180910390a25050565b67ffffffffffffffff821660009081526003602052604090205482906001600160a01b031680611c3c576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336001600160a01b03821614611c89576040517fd8a3fb520000000000000000000000000000000000000000000000000000000081526001600160a01b03821660048201526024016108dc565b600b546601000000000000900460ff1615611cd0576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611cd984612fb2565b15611d10576040517fb42f66e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b038316600090815260026020908152604080832067ffffffffffffffff808916855292529091205416611d91576040517ff0019fe600000000000000000000000000000000000000000000000000000000815267ffffffffffffffff851660048201526001600160a01b03841660248201526044016108dc565b67ffffffffffffffff8416600090815260036020908152604080832060020180548251818502810185019093528083529192909190830182828015611dff57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611de1575b50505050509050600060018251611e16919061559e565b905060005b8251811015611f8e57856001600160a01b0316838281518110611e4057611e406156e4565b60200260200101516001600160a01b03161415611f7c576000838381518110611e6b57611e6b6156e4565b6020026020010151905080600360008a67ffffffffffffffff1667ffffffffffffffff1681526020019081526020016000206002018381548110611eb157611eb16156e4565b600091825260208083209190910180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03949094169390931790925567ffffffffffffffff8a168152600390915260409020600201805480611f1e57611f1e6156b5565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905501905550611f8e565b80611f86816155e2565b915050611e1b565b506001600160a01b038516600081815260026020908152604080832067ffffffffffffffff8b168085529083529281902080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001690555192835290917f182bff9831466789164ca77075fffd84916d35a8180ba73c27e45634549b445b91015b60405180910390a2505050505050565b600b546000906601000000000000900460ff1615612069576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6005805467ffffffffffffffff169060006120838361561b565b82546101009290920a67ffffffffffffffff8181021990931691831602179091556005541690506000806040519080825280602002602001820160405280156120d6578160200160208202803683370190505b506040805180820182526000808252602080830182815267ffffffffffffffff888116808552600484528685209551865493516bffffffffffffffffffffffff9091167fffffffffffffffffffffffff0000000000000000000000000000000000000000948516176c01000000000000000000000000919093160291909117909455845160608101865233815280830184815281870188815295855260038452959093208351815483166001600160a01b03918216178255955160018201805490931696169590951790559151805194955090936121ba9260028501920190614a32565b505060405133815267ffffffffffffffff841691507f464722b4166576d3dcbba877b999bc35cf911f4eaf434b7eba68fa113951d0bf9060200160405180910390a250905090565b67ffffffffffffffff8116600090815260036020526040812054819081906060906001600160a01b0316612262576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff80861660009081526004602090815260408083205460038352928190208054600290910180548351818602810186019094528084526bffffffffffffffffffffffff8616966c01000000000000000000000000909604909516946001600160a01b0390921693909291839183018282801561230f57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116122f1575b5050505050905093509350935093509193509193565b600b546601000000000000900460ff161561236c576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146123ce576040517f44b0e3c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208114612408576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612416828401846150e5565b67ffffffffffffffff81166000908152600360205260409020549091506001600160a01b0316612472576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff8116600090815260046020526040812080546bffffffffffffffffffffffff16918691906124a98385615526565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555084600560088282829054906101000a90046bffffffffffffffffffffffff166125009190615526565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508167ffffffffffffffff167fd39ec07f4e209f627a4c427971473820dc129761ba28de8906bd56f57101d4f882878461256791906154e2565b6040805192835260208301919091520161200f565b600b546000906601000000000000900460ff16156125c6576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005a905060008060006125da8787613700565b9250925092506000866060015163ffffffff1667ffffffffffffffff81111561260557612605615713565b60405190808252806020026020018201604052801561262e578160200160208202803683370190505b50905060005b876060015163ffffffff168110156126a25760408051602081018590529081018290526060016040516020818303038152906040528051906020012060001c828281518110612685576126856156e4565b60209081029190910101528061269a816155e2565b915050612634565b506000838152600960205260408082208290555181907f1fe543e300000000000000000000000000000000000000000000000000000000906126ea90879086906024016153e9565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090941693909317909252600b80547fffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffff166601000000000000179055908a015160808b015191925060009161279a9163ffffffff169084613a0e565b600b80547fffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffff1690556020808c01805167ffffffffffffffff9081166000908152600490935260408084205492518216845290922080549394506c01000000000000000000000000918290048316936001939192600c9261281e9286929004166154fa565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060006128758a600b600001600b9054906101000a900463ffffffff1663ffffffff1661286f85612a46565b3a613a5c565b6020808e015167ffffffffffffffff166000908152600490915260409020549091506bffffffffffffffffffffffff808316911610156128e1576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020808d015167ffffffffffffffff166000908152600490915260408120805483929061291d9084906bffffffffffffffffffffffff166155b5565b82546101009290920a6bffffffffffffffffffffffff81810219909316918316021790915560008b8152600660209081526040808320546001600160a01b03168352600890915281208054859450909261297991859116615526565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550877f7dffc5ae5ee4e2e4df1651cf6ad329a73cebdb728f37ea0187b9b17e036756e48883866040516129fc939291909283526bffffffffffffffffffffffff9190911660208301521515604082015260600190565b60405180910390a299505050505050505050505b92915050565b600081604051602001612a299190615236565b604051602081830303815290604052805190602001209050919050565b6040805161012081018252600c5463ffffffff80821683526401000000008204811660208401526801000000000000000082048116938301939093526c010000000000000000000000008104831660608301527001000000000000000000000000000000008104909216608082015262ffffff740100000000000000000000000000000000000000008304811660a08301819052770100000000000000000000000000000000000000000000008404821660c08401527a0100000000000000000000000000000000000000000000000000008404821660e08401527d0100000000000000000000000000000000000000000000000000000000009093041661010082015260009167ffffffffffffffff841611612b64575192915050565b8267ffffffffffffffff168160a0015162ffffff16108015612b9957508060c0015162ffffff168367ffffffffffffffff1611155b15612ba8576020015192915050565b8267ffffffffffffffff168160c0015162ffffff16108015612bdd57508060e0015162ffffff168367ffffffffffffffff1611155b15612bec576040015192915050565b8267ffffffffffffffff168160e0015162ffffff16108015612c22575080610100015162ffffff168367ffffffffffffffff1611155b15612c31576060015192915050565b6080015192915050565b67ffffffffffffffff821660009081526003602052604090205482906001600160a01b031680612c97576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336001600160a01b03821614612ce4576040517fd8a3fb520000000000000000000000000000000000000000000000000000000081526001600160a01b03821660048201526024016108dc565b600b546601000000000000900460ff1615612d2b576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612d3484612fb2565b15612d6b576040517fb42f66e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6109e58484613242565b612d7d6131e6565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a082319060240160206040518083038186803b158015612df857600080fd5b505afa158015612e0c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e309190614e50565b6005549091506801000000000000000090046bffffffffffffffffffffffff1681811115612e94576040517fa99da30200000000000000000000000000000000000000000000000000000000815260048101829052602481018390526044016108dc565b81811015612fad576000612ea8828461559e565b6040517fa9059cbb0000000000000000000000000000000000000000000000000000000081526001600160a01b038681166004830152602482018390529192507f00000000000000000000000000000000000000000000000000000000000000009091169063a9059cbb90604401602060405180830381600087803b158015612f3057600080fd5b505af1158015612f44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f689190614e2e565b50604080516001600160a01b0386168152602081018390527f59bfc682b673f8cbf945f1e454df9334834abf7dfe7f92237ca29ecb9b436600910160405180910390a1505b505050565b67ffffffffffffffff81166000908152600360209081526040808320815160608101835281546001600160a01b039081168252600183015416818501526002820180548451818702810187018652818152879693958601939092919083018282801561304757602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311613029575b505050505081525050905060005b8160400151518110156131cb5760005b6007548110156131b857600061318160078381548110613087576130876156e4565b9060005260206000200154856040015185815181106130a8576130a86156e4565b60200260200101518860026000896040015189815181106130cb576130cb6156e4565b6020908102919091018101516001600160a01b03168252818101929092526040908101600090812067ffffffffffffffff808f16835293522054166040805160208082018790526001600160a01b03959095168183015267ffffffffffffffff9384166060820152919092166080808301919091528251808303909101815260a08201835280519084012060c082019490945260e080820185905282518083039091018152610100909101909152805191012091565b50600081815260096020526040902054909150156131a55750600195945050505050565b50806131b0816155e2565b915050613065565b50806131c3816155e2565b915050613055565b5060009392505050565b6131dd6131e6565b61083481613b7c565b6000546001600160a01b031633146132405760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016108dc565b565b600b546601000000000000900460ff1615613289576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff82166000908152600360209081526040808320815160608101835281546001600160a01b0390811682526001830154168185015260028201805484518187028101870186528181529295939486019383018282801561331a57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116132fc575b5050509190925250505067ffffffffffffffff80851660009081526004602090815260408083208151808301909252546bffffffffffffffffffffffff81168083526c01000000000000000000000000909104909416918101919091529293505b8360400151518110156134145760026000856040015183815181106133a2576133a26156e4565b6020908102919091018101516001600160a01b03168252818101929092526040908101600090812067ffffffffffffffff8a168252909252902080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001690558061340c816155e2565b91505061337b565b5067ffffffffffffffff8516600090815260036020526040812080547fffffffffffffffffffffffff0000000000000000000000000000000000000000908116825560018201805490911690559061346f6002830182614aaf565b505067ffffffffffffffff8516600090815260046020526040902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055600580548291906008906134df9084906801000000000000000090046bffffffffffffffffffffffff166155b5565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9059cbb85836bffffffffffffffffffffffff166040518363ffffffff1660e01b815260040161357d9291906001600160a01b03929092168252602082015260400190565b602060405180830381600087803b15801561359757600080fd5b505af11580156135ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135cf9190614e2e565b613605576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516001600160a01b03861681526bffffffffffffffffffffffff8316602082015267ffffffffffffffff8716917fe8ed5b475a5b5987aa9165e8731bb78043f39eee32ec5a1169a89e27fcd49815910160405180910390a25050505050565b60004661a4b181148061367c575062066eed81145b156136f95760646001600160a01b031663a3b1b31d6040518163ffffffff1660e01b815260040160206040518083038186803b1580156136bb57600080fd5b505afa1580156136cf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136f39190614e50565b91505090565b4391505090565b60008060006137128560000151612a16565b6000818152600660205260409020549093506001600160a01b031680613767576040517f77f5b84c000000000000000000000000000000000000000000000000000000008152600481018590526024016108dc565b6080860151604051613786918691602001918252602082015260400190565b60408051601f19818403018152918152815160209283012060008181526009909352912054909350806137e5576040517f3688124a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b85516020808801516040808a015160608b015160808c01519251613851968b96909594910195865267ffffffffffffffff948516602087015292909316604085015263ffffffff90811660608501529190911660808301526001600160a01b031660a082015260c00190565b60405160208183030381529060405280519060200120811461389f576040517fd529142c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006138ae8760000151613c3e565b9050806139ba5786516040517fe9413d3800000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063e9413d389060240160206040518083038186803b15801561393a57600080fd5b505afa15801561394e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139729190614e50565b9050806139ba5786516040517f175dadad00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016108dc565b60008860800151826040516020016139dc929190918252602082015260400190565b6040516020818303038152906040528051906020012060001c9050613a018982613d45565b9450505050509250925092565b60005a611388811015613a2057600080fd5b611388810390508460408204820311613a3857600080fd5b50823b613a4457600080fd5b60008083516020850160008789f190505b9392505050565b600080613a67613db0565b905060008113613aa6576040517f43d4cf66000000000000000000000000000000000000000000000000000000008152600481018290526024016108dc565b6000613ab0613eb7565b9050600082825a613ac18b8b6154e2565b613acb919061559e565b613ad59088615561565b613adf91906154e2565b613af190670de0b6b3a7640000615561565b613afb919061554d565b90506000613b1463ffffffff881664e8d4a51000615561565b9050613b2c816b033b2e3c9fd0803ce800000061559e565b821115613b65576040517fe80fa38100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b613b6f81836154e2565b9998505050505050505050565b6001600160a01b038116331415613bd55760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016108dc565b600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60004661a4b1811480613c53575062066eed81145b15613d35576101008367ffffffffffffffff16613c6e613667565b613c78919061559e565b1180613c955750613c87613667565b8367ffffffffffffffff1610155b15613ca35750600092915050565b6040517f2b407a8200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152606490632b407a829060240160206040518083038186803b158015613cfd57600080fd5b505afa158015613d11573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a559190614e50565b505067ffffffffffffffff164090565b6000613d798360000151846020015185604001518660600151868860a001518960c001518a60e001518b6101000151613f13565b60038360200151604051602001613d919291906153d5565b60408051601f1981840301815291905280516020909101209392505050565b600b54604080517ffeaf968c0000000000000000000000000000000000000000000000000000000081529051600092670100000000000000900463ffffffff169182151591849182917f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169163feaf968c9160048083019260a0929190829003018186803b158015613e4957600080fd5b505afa158015613e5d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613e81919061512a565b509450909250849150508015613ea55750613e9c824261559e565b8463ffffffff16105b15613eaf5750600a545b949350505050565b60004661a4b1811480613ecc575062066eed81145b15613f0b57606c6001600160a01b031663c6f7de0e6040518163ffffffff1660e01b815260040160206040518083038186803b1580156136bb57600080fd5b600091505090565b613f1c8961414e565b613f685760405162461bcd60e51b815260206004820152601a60248201527f7075626c6963206b6579206973206e6f74206f6e20637572766500000000000060448201526064016108dc565b613f718861414e565b613fbd5760405162461bcd60e51b815260206004820152601560248201527f67616d6d61206973206e6f74206f6e206375727665000000000000000000000060448201526064016108dc565b613fc68361414e565b6140125760405162461bcd60e51b815260206004820152601d60248201527f6347616d6d615769746e657373206973206e6f74206f6e20637572766500000060448201526064016108dc565b61401b8261414e565b6140675760405162461bcd60e51b815260206004820152601c60248201527f73486173685769746e657373206973206e6f74206f6e2063757276650000000060448201526064016108dc565b614073878a8887614227565b6140bf5760405162461bcd60e51b815260206004820152601960248201527f6164647228632a706b2b732a6729213d5f755769746e6573730000000000000060448201526064016108dc565b60006140cb8a87614378565b905060006140de898b878b8689896143dc565b905060006140ef838d8d8a86614508565b9050808a146141405760405162461bcd60e51b815260206004820152600d60248201527f696e76616c69642070726f6f660000000000000000000000000000000000000060448201526064016108dc565b505050505050505050505050565b80516000906401000003d019116141a75760405162461bcd60e51b815260206004820152601260248201527f696e76616c696420782d6f7264696e617465000000000000000000000000000060448201526064016108dc565b60208201516401000003d019116142005760405162461bcd60e51b815260206004820152601260248201527f696e76616c696420792d6f7264696e617465000000000000000000000000000060448201526064016108dc565b60208201516401000003d0199080096142208360005b6020020151614548565b1492915050565b60006001600160a01b03821661427f5760405162461bcd60e51b815260206004820152600b60248201527f626164207769746e65737300000000000000000000000000000000000000000060448201526064016108dc565b60208401516000906001161561429657601c614299565b601b5b905060007ffffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd03641418587600060200201510986517ffffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141918203925060009190890987516040805160008082526020820180845287905260ff88169282019290925260608101929092526080820183905291925060019060a0016020604051602081039080840390855afa158015614350573d6000803e3d6000fd5b5050604051601f1901516001600160a01b039081169088161495505050505050949350505050565b614380614acd565b6143ad6001848460405160200161439993929190615215565b60405160208183030381529060405261456c565b90505b6143b98161414e565b612a105780516040805160208101929092526143d59101614399565b90506143b0565b6143e4614acd565b825186516401000003d01990819006910614156144435760405162461bcd60e51b815260206004820152601e60248201527f706f696e747320696e2073756d206d7573742062652064697374696e6374000060448201526064016108dc565b61444e8789886145bb565b61449a5760405162461bcd60e51b815260206004820152601660248201527f4669727374206d756c20636865636b206661696c65640000000000000000000060448201526064016108dc565b6144a58486856145bb565b6144f15760405162461bcd60e51b815260206004820152601760248201527f5365636f6e64206d756c20636865636b206661696c656400000000000000000060448201526064016108dc565b6144fc868484614703565b98975050505050505050565b600060028686868587604051602001614526969594939291906151a3565b60408051601f1981840301815291905280516020909101209695505050505050565b6000806401000003d01980848509840990506401000003d019600782089392505050565b614574614acd565b61457d826147ca565b815261459261458d826000614216565b614805565b6020820181905260029006600114156145b6576020810180516401000003d0190390525b919050565b60008261460a5760405162461bcd60e51b815260206004820152600b60248201527f7a65726f207363616c617200000000000000000000000000000000000000000060448201526064016108dc565b8351602085015160009061462090600290615643565b1561462c57601c61462f565b601b5b905060007ffffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd03641418387096040805160008082526020820180845281905260ff86169282019290925260608101869052608081018390529192509060019060a0016020604051602081039080840390855afa1580156146af573d6000803e3d6000fd5b5050506020604051035190506000866040516020016146ce9190615191565b60408051601f1981840301815291905280516020909101206001600160a01b0392831692169190911498975050505050505050565b61470b614acd565b83516020808601518551918601516000938493849361472c93909190614825565b919450925090506401000003d01985820960011461478c5760405162461bcd60e51b815260206004820152601960248201527f696e765a206d75737420626520696e7665727365206f66207a0000000000000060448201526064016108dc565b60405180604001604052806401000003d019806147ab576147ab615686565b87860981526020016401000003d0198785099052979650505050505050565b805160208201205b6401000003d01981106145b6576040805160208082019390935281518082038401815290820190915280519101206147d2565b6000612a1082600261481e6401000003d01960016154e2565b901c614905565b60008080600180826401000003d019896401000003d019038808905060006401000003d0198b6401000003d019038a0890506000614865838385856149c5565b909850905061487688828e886149e9565b909850905061488788828c876149e9565b9098509050600061489a8d878b856149e9565b90985090506148ab888286866149c5565b90985090506148bc88828e896149e9565b90985090508181146148f1576401000003d019818a0998506401000003d01982890997506401000003d01981830996506148f5565b8196505b5050505050509450945094915050565b600080614910614aeb565b6020808252818101819052604082015260608101859052608081018490526401000003d01960a0820152614942614b09565b60208160c08460057ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa9250826149bb5760405162461bcd60e51b815260206004820152601260248201527f6269674d6f64457870206661696c75726521000000000000000000000000000060448201526064016108dc565b5195945050505050565b6000806401000003d0198487096401000003d0198487099097909650945050505050565b600080806401000003d019878509905060006401000003d01987876401000003d019030990506401000003d0198183086401000003d01986890990999098509650505050505050565b828054828255906000526020600020908101928215614a9f579160200282015b82811115614a9f57825182547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03909116178255602090920191600190910190614a52565b50614aab929150614b27565b5090565b50805460008255906000526020600020908101906108349190614b27565b60405180604001604052806002906020820280368337509192915050565b6040518060c001604052806006906020820280368337509192915050565b60405180602001604052806001906020820280368337509192915050565b5b80821115614aab5760008155600101614b28565b80356001600160a01b03811681146145b657600080fd5b8060408101831015612a1057600080fd5b600082601f830112614b7557600080fd5b6040516040810181811067ffffffffffffffff82111715614b9857614b98615713565b8060405250808385604086011115614baf57600080fd5b60005b6002811015614bd1578135835260209283019290910190600101614bb2565b509195945050505050565b600060a08284031215614bee57600080fd5b60405160a0810181811067ffffffffffffffff82111715614c1157614c11615713565b604052905080614c2083614ca6565b8152614c2e60208401614ca6565b6020820152614c3f60408401614c92565b6040820152614c5060608401614c92565b6060820152614c6160808401614b3c565b60808201525092915050565b803561ffff811681146145b657600080fd5b803562ffffff811681146145b657600080fd5b803563ffffffff811681146145b657600080fd5b803567ffffffffffffffff811681146145b657600080fd5b805169ffffffffffffffffffff811681146145b657600080fd5b600060208284031215614cea57600080fd5b613a5582614b3c565b60008060608385031215614d0657600080fd5b614d0f83614b3c565b9150614d1e8460208501614b53565b90509250929050565b60008060008060608587031215614d3d57600080fd5b614d4685614b3c565b935060208501359250604085013567ffffffffffffffff80821115614d6a57600080fd5b818701915087601f830112614d7e57600080fd5b813581811115614d8d57600080fd5b886020828501011115614d9f57600080fd5b95989497505060200194505050565b60008060408385031215614dc157600080fd5b614dca83614b3c565b915060208301356bffffffffffffffffffffffff81168114614deb57600080fd5b809150509250929050565b600060408284031215614e0857600080fd5b613a558383614b53565b600060408284031215614e2457600080fd5b613a558383614b64565b600060208284031215614e4057600080fd5b81518015158114613a5557600080fd5b600060208284031215614e6257600080fd5b5051919050565b600080600080600060a08688031215614e8157600080fd5b85359450614e9160208701614ca6565b9350614e9f60408701614c6d565b9250614ead60608701614c92565b9150614ebb60808701614c92565b90509295509295909350565b600080828403610240811215614edc57600080fd5b6101a080821215614eec57600080fd5b614ef46154b8565b9150614f008686614b64565b8252614f0f8660408701614b64565b60208301526080850135604083015260a0850135606083015260c08501356080830152614f3e60e08601614b3c565b60a0830152610100614f5287828801614b64565b60c0840152614f65876101408801614b64565b60e08401526101808601358184015250819350614f8486828701614bdc565b925050509250929050565b6000806000806000808688036101c0811215614faa57600080fd5b614fb388614c6d565b9650614fc160208901614c92565b9550614fcf60408901614c92565b9450614fdd60608901614c92565b935060808801359250610120807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff608301121561501857600080fd5b6150206154b8565b915061502e60a08a01614c92565b825261503c60c08a01614c92565b602083015261504d60e08a01614c92565b6040830152610100615060818b01614c92565b6060840152615070828b01614c92565b60808401526150826101408b01614c7f565b60a08401526150946101608b01614c7f565b60c08401526150a66101808b01614c7f565b60e08401526150b86101a08b01614c7f565b818401525050809150509295509295509295565b6000602082840312156150de57600080fd5b5035919050565b6000602082840312156150f757600080fd5b613a5582614ca6565b6000806040838503121561511357600080fd5b61511c83614ca6565b9150614d1e60208401614b3c565b600080600080600060a0868803121561514257600080fd5b61514b86614cbe565b9450602086015193506040860151925060608601519150614ebb60808701614cbe565b8060005b60028110156109e5578151845260209384019390910190600101615172565b61519b818361516e565b604001919050565b8681526151b3602082018761516e565b6151c0606082018661516e565b6151cd60a082018561516e565b6151da60e082018461516e565b60609190911b7fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166101208201526101340195945050505050565b838152615225602082018461516e565b606081019190915260800192915050565b60408101612a10828461516e565b600060208083528351808285015260005b8181101561527157858101830151858201604001528201615255565b81811115615283576000604083870101525b50601f01601f1916929092016040019392505050565b60006060820161ffff86168352602063ffffffff86168185015260606040850152818551808452608086019150828701935060005b818110156152ea578451835293830193918301916001016152ce565b509098975050505050505050565b60006101c08201905061ffff8816825263ffffffff808816602084015280871660408401528086166060840152846080840152835481811660a085015261534c60c08501838360201c1663ffffffff169052565b61536360e08501838360401c1663ffffffff169052565b61537b6101008501838360601c1663ffffffff169052565b6153936101208501838360801c1663ffffffff169052565b62ffffff60a082901c811661014086015260b882901c811661016086015260d082901c1661018085015260e81c6101a090930192909252979650505050505050565b82815260608101613a55602083018461516e565b6000604082018483526020604081850152818551808452606086019150828701935060005b8181101561542a5784518352938301939183019160010161540e565b5090979650505050505050565b6000608082016bffffffffffffffffffffffff87168352602067ffffffffffffffff8716818501526001600160a01b0380871660408601526080606086015282865180855260a087019150838801945060005b818110156154a857855184168352948401949184019160010161548a565b50909a9950505050505050505050565b604051610120810167ffffffffffffffff811182821017156154dc576154dc615713565b60405290565b600082198211156154f5576154f5615657565b500190565b600067ffffffffffffffff80831681851680830382111561551d5761551d615657565b01949350505050565b60006bffffffffffffffffffffffff80831681851680830382111561551d5761551d615657565b60008261555c5761555c615686565b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561559957615599615657565b500290565b6000828210156155b0576155b0615657565b500390565b60006bffffffffffffffffffffffff838116908316818110156155da576155da615657565b039392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561561457615614615657565b5060010190565b600067ffffffffffffffff8083168181141561563957615639615657565b6001019392505050565b60008261565257615652615686565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fdfea164736f6c6343000806000a",
+ Bin: "0x60e06040523480156200001157600080fd5b50604051620059c1380380620059c18339810160408190526200003491620001b1565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000e8565b5050506001600160601b0319606093841b811660805290831b811660a052911b1660c052620001fb565b6001600160a01b038116331415620001435760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b0381168114620001ac57600080fd5b919050565b600080600060608486031215620001c757600080fd5b620001d28462000194565b9250620001e26020850162000194565b9150620001f26040850162000194565b90509250925092565b60805160601c60a05160601c60c05160601c61575c620002656000396000818161051901526138f00152600081816106030152613e0801526000818161036d015281816114da0152818161237701528181612dae01528181612eea015261350f015261575c6000f3fe608060405234801561001057600080fd5b506004361061025b5760003560e01c80636f64f03f11610145578063ad178361116100bd578063d2f9f9a71161008c578063e72f6e3011610071578063e72f6e30146106e0578063e82ad7d4146106f3578063f2fde38b1461071657600080fd5b8063d2f9f9a7146106ba578063d7ae1d30146106cd57600080fd5b8063ad178361146105fe578063af198b9714610625578063c3f909d414610655578063caf70c4a146106a757600080fd5b80638da5cb5b11610114578063a21a23e4116100f9578063a21a23e4146105c0578063a47c7696146105c8578063a4c0ed36146105eb57600080fd5b80638da5cb5b1461059c5780639f87fad7146105ad57600080fd5b80636f64f03f1461055b5780637341c10c1461056e57806379ba509714610581578063823597401461058957600080fd5b8063356dac71116101d85780635fbbc0d2116101a757806366316d8d1161018c57806366316d8d14610501578063689c45171461051457806369bcdb7d1461053b57600080fd5b80635fbbc0d2146103f357806364d51a2a146104f957600080fd5b8063356dac71146103a757806340d6bb82146103af5780634cb48a54146103cd5780635d3b1d30146103e057600080fd5b806308821d581161022f57806315c48b841161021457806315c48b841461030e578063181f5a77146103295780631b6b6d231461036857600080fd5b806308821d58146102cf57806312b58349146102e257600080fd5b80620122911461026057806302bcc5b61461028057806304c357cb1461029557806306bfa637146102a8575b600080fd5b610268610729565b604051610277939291906152a6565b60405180910390f35b61029361028e3660046150f2565b6107a5565b005b6102936102a336600461510d565b610837565b60055467ffffffffffffffff165b60405167ffffffffffffffff9091168152602001610277565b6102936102dd366004614e03565b6109eb565b6005546801000000000000000090046bffffffffffffffffffffffff165b604051908152602001610277565b61031660c881565b60405161ffff9091168152602001610277565b604080518082018252601681527f565246436f6f7264696e61746f72563220312e302e3000000000000000000000602082015290516102779190615251565b61038f7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610277565b600a54610300565b6103b86101f481565b60405163ffffffff9091168152602001610277565b6102936103db366004614f9c565b610bb0565b6103006103ee366004614e76565b610fa7565b600c546040805163ffffffff80841682526401000000008404811660208301526801000000000000000084048116928201929092526c010000000000000000000000008304821660608201527001000000000000000000000000000000008304909116608082015262ffffff740100000000000000000000000000000000000000008304811660a0830152770100000000000000000000000000000000000000000000008304811660c08301527a0100000000000000000000000000000000000000000000000000008304811660e08301527d01000000000000000000000000000000000000000000000000000000000090920490911661010082015261012001610277565b610316606481565b61029361050f366004614dbb565b611385565b61038f7f000000000000000000000000000000000000000000000000000000000000000081565b6103006105493660046150d9565b60009081526009602052604090205490565b610293610569366004614d00565b6115d4565b61029361057c36600461510d565b611704565b610293611951565b6102936105973660046150f2565b611a1a565b6000546001600160a01b031661038f565b6102936105bb36600461510d565b611be0565b6102b661201f565b6105db6105d63660046150f2565b612202565b6040516102779493929190615444565b6102936105f9366004614d34565b612325565b61038f7f000000000000000000000000000000000000000000000000000000000000000081565b610638610633366004614ed4565b61257c565b6040516bffffffffffffffffffffffff9091168152602001610277565b600b546040805161ffff8316815263ffffffff6201000084048116602083015267010000000000000084048116928201929092526b010000000000000000000000909204166060820152608001610277565b6103006106b5366004614e1f565b612a16565b6103b86106c83660046150f2565b612a46565b6102936106db36600461510d565b612c3b565b6102936106ee366004614ce5565b612d75565b6107066107013660046150f2565b612fb2565b6040519015158152602001610277565b610293610724366004614ce5565b6131d5565b600b546007805460408051602080840282018101909252828152600094859460609461ffff8316946201000090930463ffffffff1693919283919083018282801561079357602002820191906000526020600020905b81548152602001906001019080831161077f575b50505050509050925092509250909192565b6107ad6131e6565b67ffffffffffffffff81166000908152600360205260409020546001600160a01b0316610806576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff81166000908152600360205260409020546108349082906001600160a01b0316613242565b50565b67ffffffffffffffff821660009081526003602052604090205482906001600160a01b031680610893576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336001600160a01b038216146108e5576040517fd8a3fb520000000000000000000000000000000000000000000000000000000081526001600160a01b03821660048201526024015b60405180910390fd5b600b546601000000000000900460ff161561092c576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff84166000908152600360205260409020600101546001600160a01b038481169116146109e55767ffffffffffffffff841660008181526003602090815260409182902060010180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0388169081179091558251338152918201527f69436ea6df009049404f564eff6622cd00522b0bd6a89efd9e52a355c4a879be91015b60405180910390a25b50505050565b6109f36131e6565b604080518082018252600091610a22919084906002908390839080828437600092019190915250612a16915050565b6000818152600660205260409020549091506001600160a01b031680610a77576040517f77f5b84c000000000000000000000000000000000000000000000000000000008152600481018390526024016108dc565b600082815260066020526040812080547fffffffffffffffffffffffff00000000000000000000000000000000000000001690555b600754811015610b67578260078281548110610aca57610aca6156f1565b90600052602060002001541415610b55576007805460009190610aef906001906155ab565b81548110610aff57610aff6156f1565b906000526020600020015490508060078381548110610b2057610b206156f1565b6000918252602090912001556007805480610b3d57610b3d6156c2565b60019003818190600052602060002001600090559055505b80610b5f816155ef565b915050610aac565b50806001600160a01b03167f72be339577868f868798bac2c93e52d6f034fef4689a9848996c14ebb7416c0d83604051610ba391815260200190565b60405180910390a2505050565b610bb86131e6565b60c861ffff87161115610c0b576040517fa738697600000000000000000000000000000000000000000000000000000000815261ffff871660048201819052602482015260c860448201526064016108dc565b60008213610c48576040517f43d4cf66000000000000000000000000000000000000000000000000000000008152600481018390526024016108dc565b6040805160a0808201835261ffff891680835263ffffffff89811660208086018290526000868801528a831660608088018290528b85166080988901819052600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000001690971762010000909502949094177fffffffffffffffffffffffffffffffffff000000000000000000ffffffffffff166701000000000000009092027fffffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffff16919091176b010000000000000000000000909302929092179093558651600c80549489015189890151938a0151978a0151968a015160c08b015160e08c01516101008d01519588167fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000009099169890981764010000000093881693909302929092177fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff1668010000000000000000958716959095027fffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffff16949094176c0100000000000000000000000098861698909802979097177fffffffffffffffffff00000000000000ffffffffffffffffffffffffffffffff1670010000000000000000000000000000000096909416959095027fffffffffffffffffff000000ffffffffffffffffffffffffffffffffffffffff16929092177401000000000000000000000000000000000000000062ffffff92831602177fffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffff1677010000000000000000000000000000000000000000000000958216959095027fffffff000000ffffffffffffffffffffffffffffffffffffffffffffffffffff16949094177a01000000000000000000000000000000000000000000000000000092851692909202919091177cffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167d0100000000000000000000000000000000000000000000000000000000009390911692909202919091178155600a84905590517fc21e3bd2e0b339d2848f0dd956947a88966c242c0c0c582a33137a5c1ceb5cb291610f97918991899189918991899190615305565b60405180910390a1505050505050565b600b546000906601000000000000900460ff1615610ff1576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff85166000908152600360205260409020546001600160a01b031661104a576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b33600090815260026020908152604080832067ffffffffffffffff808a16855292529091205416806110ba576040517ff0019fe600000000000000000000000000000000000000000000000000000000815267ffffffffffffffff871660048201523360248201526044016108dc565b600b5461ffff90811690861610806110d6575060c861ffff8616115b1561112657600b546040517fa738697600000000000000000000000000000000000000000000000000000000815261ffff8088166004830152909116602482015260c860448201526064016108dc565b600b5463ffffffff620100009091048116908516111561118d57600b546040517ff5d7e01e00000000000000000000000000000000000000000000000000000000815263ffffffff80871660048301526201000090920490911660248201526044016108dc565b6101f463ffffffff841611156111df576040517f47386bec00000000000000000000000000000000000000000000000000000000815263ffffffff841660048201526101f460248201526044016108dc565b60006111ec826001615507565b6040805160208082018c9052338284015267ffffffffffffffff808c16606084015284166080808401919091528351808403909101815260a08301845280519082012060c083018d905260e080840182905284518085039091018152610100909301909352815191012091925081611262613667565b60408051602081019390935282015267ffffffffffffffff8a16606082015263ffffffff8089166080830152871660a08201523360c082015260e00160408051808303601f19018152828252805160209182012060008681526009835283902055848352820183905261ffff8a169082015263ffffffff808916606083015287166080820152339067ffffffffffffffff8b16908c907f63373d1c4696214b898952999c9aaec57dac1ee2723cec59bea6888f489a97729060a00160405180910390a45033600090815260026020908152604080832067ffffffffffffffff808d16855292529091208054919093167fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000009091161790915591505095945050505050565b600b546601000000000000900460ff16156113cc576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152600860205260409020546bffffffffffffffffffffffff80831691161015611426576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b33600090815260086020526040812080548392906114539084906bffffffffffffffffffffffff166155c2565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555080600560088282829054906101000a90046bffffffffffffffffffffffff166114aa91906155c2565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9059cbb83836040518363ffffffff1660e01b81526004016115489291906001600160a01b039290921682526bffffffffffffffffffffffff16602082015260400190565b602060405180830381600087803b15801561156257600080fd5b505af1158015611576573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061159a9190614e3b565b6115d0576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050565b6115dc6131e6565b60408051808201825260009161160b919084906002908390839080828437600092019190915250612a16915050565b6000818152600660205260409020549091506001600160a01b031615611660576040517f4a0b8fa7000000000000000000000000000000000000000000000000000000008152600481018290526024016108dc565b600081815260066020908152604080832080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0388169081179091556007805460018101825594527fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c688909301849055518381527fe729ae16526293f74ade739043022254f1489f616295a25bf72dfb4511ed73b89101610ba3565b67ffffffffffffffff821660009081526003602052604090205482906001600160a01b031680611760576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336001600160a01b038216146117ad576040517fd8a3fb520000000000000000000000000000000000000000000000000000000081526001600160a01b03821660048201526024016108dc565b600b546601000000000000900460ff16156117f4576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff84166000908152600360205260409020600201546064141561184b576040517f05a48e0f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b038316600090815260026020908152604080832067ffffffffffffffff80891685529252909120541615611885576109e5565b6001600160a01b038316600081815260026020818152604080842067ffffffffffffffff8a1680865290835281852080547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000166001908117909155600384528286209094018054948501815585529382902090920180547fffffffffffffffffffffffff00000000000000000000000000000000000000001685179055905192835290917f43dc749a04ac8fb825cbd514f7c0e13f13bc6f2ee66043b76629d51776cff8e091016109dc565b6001546001600160a01b031633146119ab5760405162461bcd60e51b815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016108dc565b60008054337fffffffffffffffffffffffff0000000000000000000000000000000000000000808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b600b546601000000000000900460ff1615611a61576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff81166000908152600360205260409020546001600160a01b0316611aba576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff81166000908152600360205260409020600101546001600160a01b03163314611b425767ffffffffffffffff8116600090815260036020526040908190206001015490517fd084e9750000000000000000000000000000000000000000000000000000000081526001600160a01b0390911660048201526024016108dc565b67ffffffffffffffff81166000818152600360209081526040918290208054337fffffffffffffffffffffffff0000000000000000000000000000000000000000808316821784556001909301805490931690925583516001600160a01b03909116808252928101919091529092917f6f1dc65165ffffedfd8e507b4a0f1fcfdada045ed11f6c26ba27cedfe87802f0910160405180910390a25050565b67ffffffffffffffff821660009081526003602052604090205482906001600160a01b031680611c3c576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336001600160a01b03821614611c89576040517fd8a3fb520000000000000000000000000000000000000000000000000000000081526001600160a01b03821660048201526024016108dc565b600b546601000000000000900460ff1615611cd0576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611cd984612fb2565b15611d10576040517fb42f66e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b038316600090815260026020908152604080832067ffffffffffffffff808916855292529091205416611d91576040517ff0019fe600000000000000000000000000000000000000000000000000000000815267ffffffffffffffff851660048201526001600160a01b03841660248201526044016108dc565b67ffffffffffffffff8416600090815260036020908152604080832060020180548251818502810185019093528083529192909190830182828015611dff57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611de1575b50505050509050600060018251611e1691906155ab565b905060005b8251811015611f8e57856001600160a01b0316838281518110611e4057611e406156f1565b60200260200101516001600160a01b03161415611f7c576000838381518110611e6b57611e6b6156f1565b6020026020010151905080600360008a67ffffffffffffffff1667ffffffffffffffff1681526020019081526020016000206002018381548110611eb157611eb16156f1565b600091825260208083209190910180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03949094169390931790925567ffffffffffffffff8a168152600390915260409020600201805480611f1e57611f1e6156c2565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905501905550611f8e565b80611f86816155ef565b915050611e1b565b506001600160a01b038516600081815260026020908152604080832067ffffffffffffffff8b168085529083529281902080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001690555192835290917f182bff9831466789164ca77075fffd84916d35a8180ba73c27e45634549b445b91015b60405180910390a2505050505050565b600b546000906601000000000000900460ff1615612069576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6005805467ffffffffffffffff1690600061208383615628565b82546101009290920a67ffffffffffffffff8181021990931691831602179091556005541690506000806040519080825280602002602001820160405280156120d6578160200160208202803683370190505b506040805180820182526000808252602080830182815267ffffffffffffffff888116808552600484528685209551865493516bffffffffffffffffffffffff9091167fffffffffffffffffffffffff0000000000000000000000000000000000000000948516176c01000000000000000000000000919093160291909117909455845160608101865233815280830184815281870188815295855260038452959093208351815483166001600160a01b03918216178255955160018201805490931696169590951790559151805194955090936121ba9260028501920190614a3f565b505060405133815267ffffffffffffffff841691507f464722b4166576d3dcbba877b999bc35cf911f4eaf434b7eba68fa113951d0bf9060200160405180910390a250905090565b67ffffffffffffffff8116600090815260036020526040812054819081906060906001600160a01b0316612262576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff80861660009081526004602090815260408083205460038352928190208054600290910180548351818602810186019094528084526bffffffffffffffffffffffff8616966c01000000000000000000000000909604909516946001600160a01b0390921693909291839183018282801561230f57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116122f1575b5050505050905093509350935093509193509193565b600b546601000000000000900460ff161561236c576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146123ce576040517f44b0e3c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208114612408576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612416828401846150f2565b67ffffffffffffffff81166000908152600360205260409020549091506001600160a01b0316612472576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff8116600090815260046020526040812080546bffffffffffffffffffffffff16918691906124a98385615533565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555084600560088282829054906101000a90046bffffffffffffffffffffffff166125009190615533565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508167ffffffffffffffff167fd39ec07f4e209f627a4c427971473820dc129761ba28de8906bd56f57101d4f882878461256791906154ef565b6040805192835260208301919091520161200f565b600b546000906601000000000000900460ff16156125c6576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005a905060008060006125da8787613700565b9250925092506000866060015163ffffffff1667ffffffffffffffff81111561260557612605615720565b60405190808252806020026020018201604052801561262e578160200160208202803683370190505b50905060005b876060015163ffffffff168110156126a25760408051602081018590529081018290526060016040516020818303038152906040528051906020012060001c828281518110612685576126856156f1565b60209081029190910101528061269a816155ef565b915050612634565b506000838152600960205260408082208290555181907f1fe543e300000000000000000000000000000000000000000000000000000000906126ea90879086906024016153f6565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090941693909317909252600b80547fffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffff166601000000000000179055908a015160808b015191925060009161279a9163ffffffff169084613a0e565b600b80547fffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffff1690556020808c01805167ffffffffffffffff9081166000908152600490935260408084205492518216845290922080549394506c01000000000000000000000000918290048316936001939192600c9261281e928692900416615507565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060006128758a600b600001600b9054906101000a900463ffffffff1663ffffffff1661286f85612a46565b3a613a5c565b6020808e015167ffffffffffffffff166000908152600490915260409020549091506bffffffffffffffffffffffff808316911610156128e1576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020808d015167ffffffffffffffff166000908152600490915260408120805483929061291d9084906bffffffffffffffffffffffff166155c2565b82546101009290920a6bffffffffffffffffffffffff81810219909316918316021790915560008b8152600660209081526040808320546001600160a01b03168352600890915281208054859450909261297991859116615533565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550877f7dffc5ae5ee4e2e4df1651cf6ad329a73cebdb728f37ea0187b9b17e036756e48883866040516129fc939291909283526bffffffffffffffffffffffff9190911660208301521515604082015260600190565b60405180910390a299505050505050505050505b92915050565b600081604051602001612a299190615243565b604051602081830303815290604052805190602001209050919050565b6040805161012081018252600c5463ffffffff80821683526401000000008204811660208401526801000000000000000082048116938301939093526c010000000000000000000000008104831660608301527001000000000000000000000000000000008104909216608082015262ffffff740100000000000000000000000000000000000000008304811660a08301819052770100000000000000000000000000000000000000000000008404821660c08401527a0100000000000000000000000000000000000000000000000000008404821660e08401527d0100000000000000000000000000000000000000000000000000000000009093041661010082015260009167ffffffffffffffff841611612b64575192915050565b8267ffffffffffffffff168160a0015162ffffff16108015612b9957508060c0015162ffffff168367ffffffffffffffff1611155b15612ba8576020015192915050565b8267ffffffffffffffff168160c0015162ffffff16108015612bdd57508060e0015162ffffff168367ffffffffffffffff1611155b15612bec576040015192915050565b8267ffffffffffffffff168160e0015162ffffff16108015612c22575080610100015162ffffff168367ffffffffffffffff1611155b15612c31576060015192915050565b6080015192915050565b67ffffffffffffffff821660009081526003602052604090205482906001600160a01b031680612c97576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336001600160a01b03821614612ce4576040517fd8a3fb520000000000000000000000000000000000000000000000000000000081526001600160a01b03821660048201526024016108dc565b600b546601000000000000900460ff1615612d2b576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612d3484612fb2565b15612d6b576040517fb42f66e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6109e58484613242565b612d7d6131e6565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a082319060240160206040518083038186803b158015612df857600080fd5b505afa158015612e0c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e309190614e5d565b6005549091506801000000000000000090046bffffffffffffffffffffffff1681811115612e94576040517fa99da30200000000000000000000000000000000000000000000000000000000815260048101829052602481018390526044016108dc565b81811015612fad576000612ea882846155ab565b6040517fa9059cbb0000000000000000000000000000000000000000000000000000000081526001600160a01b038681166004830152602482018390529192507f00000000000000000000000000000000000000000000000000000000000000009091169063a9059cbb90604401602060405180830381600087803b158015612f3057600080fd5b505af1158015612f44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f689190614e3b565b50604080516001600160a01b0386168152602081018390527f59bfc682b673f8cbf945f1e454df9334834abf7dfe7f92237ca29ecb9b436600910160405180910390a1505b505050565b67ffffffffffffffff81166000908152600360209081526040808320815160608101835281546001600160a01b039081168252600183015416818501526002820180548451818702810187018652818152879693958601939092919083018282801561304757602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311613029575b505050505081525050905060005b8160400151518110156131cb5760005b6007548110156131b857600061318160078381548110613087576130876156f1565b9060005260206000200154856040015185815181106130a8576130a86156f1565b60200260200101518860026000896040015189815181106130cb576130cb6156f1565b6020908102919091018101516001600160a01b03168252818101929092526040908101600090812067ffffffffffffffff808f16835293522054166040805160208082018790526001600160a01b03959095168183015267ffffffffffffffff9384166060820152919092166080808301919091528251808303909101815260a08201835280519084012060c082019490945260e080820185905282518083039091018152610100909101909152805191012091565b50600081815260096020526040902054909150156131a55750600195945050505050565b50806131b0816155ef565b915050613065565b50806131c3816155ef565b915050613055565b5060009392505050565b6131dd6131e6565b61083481613b7c565b6000546001600160a01b031633146132405760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016108dc565b565b600b546601000000000000900460ff1615613289576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff82166000908152600360209081526040808320815160608101835281546001600160a01b0390811682526001830154168185015260028201805484518187028101870186528181529295939486019383018282801561331a57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116132fc575b5050509190925250505067ffffffffffffffff80851660009081526004602090815260408083208151808301909252546bffffffffffffffffffffffff81168083526c01000000000000000000000000909104909416918101919091529293505b8360400151518110156134145760026000856040015183815181106133a2576133a26156f1565b6020908102919091018101516001600160a01b03168252818101929092526040908101600090812067ffffffffffffffff8a168252909252902080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001690558061340c816155ef565b91505061337b565b5067ffffffffffffffff8516600090815260036020526040812080547fffffffffffffffffffffffff0000000000000000000000000000000000000000908116825560018201805490911690559061346f6002830182614abc565b505067ffffffffffffffff8516600090815260046020526040902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055600580548291906008906134df9084906801000000000000000090046bffffffffffffffffffffffff166155c2565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9059cbb85836bffffffffffffffffffffffff166040518363ffffffff1660e01b815260040161357d9291906001600160a01b03929092168252602082015260400190565b602060405180830381600087803b15801561359757600080fd5b505af11580156135ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135cf9190614e3b565b613605576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516001600160a01b03861681526bffffffffffffffffffffffff8316602082015267ffffffffffffffff8716917fe8ed5b475a5b5987aa9165e8731bb78043f39eee32ec5a1169a89e27fcd49815910160405180910390a25050505050565b60004661a4b181148061367c575062066eed81145b156136f95760646001600160a01b031663a3b1b31d6040518163ffffffff1660e01b815260040160206040518083038186803b1580156136bb57600080fd5b505afa1580156136cf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136f39190614e5d565b91505090565b4391505090565b60008060006137128560000151612a16565b6000818152600660205260409020549093506001600160a01b031680613767576040517f77f5b84c000000000000000000000000000000000000000000000000000000008152600481018590526024016108dc565b6080860151604051613786918691602001918252602082015260400190565b60408051601f19818403018152918152815160209283012060008181526009909352912054909350806137e5576040517f3688124a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b85516020808801516040808a015160608b015160808c01519251613851968b96909594910195865267ffffffffffffffff948516602087015292909316604085015263ffffffff90811660608501529190911660808301526001600160a01b031660a082015260c00190565b60405160208183030381529060405280519060200120811461389f576040517fd529142c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006138ae8760000151613c3e565b9050806139ba5786516040517fe9413d3800000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063e9413d389060240160206040518083038186803b15801561393a57600080fd5b505afa15801561394e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139729190614e5d565b9050806139ba5786516040517f175dadad00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016108dc565b60008860800151826040516020016139dc929190918252602082015260400190565b6040516020818303038152906040528051906020012060001c9050613a018982613d52565b9450505050509250925092565b60005a611388811015613a2057600080fd5b611388810390508460408204820311613a3857600080fd5b50823b613a4457600080fd5b60008083516020850160008789f190505b9392505050565b600080613a67613dbd565b905060008113613aa6576040517f43d4cf66000000000000000000000000000000000000000000000000000000008152600481018290526024016108dc565b6000613ab0613ec4565b9050600082825a613ac18b8b6154ef565b613acb91906155ab565b613ad5908861556e565b613adf91906154ef565b613af190670de0b6b3a764000061556e565b613afb919061555a565b90506000613b1463ffffffff881664e8d4a5100061556e565b9050613b2c816b033b2e3c9fd0803ce80000006155ab565b821115613b65576040517fe80fa38100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b613b6f81836154ef565b9998505050505050505050565b6001600160a01b038116331415613bd55760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016108dc565b600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60004661a4b1811480613c53575062066eed81145b80613c60575062066eee81145b15613d42576101008367ffffffffffffffff16613c7b613667565b613c8591906155ab565b1180613ca25750613c94613667565b8367ffffffffffffffff1610155b15613cb05750600092915050565b6040517f2b407a8200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152606490632b407a829060240160206040518083038186803b158015613d0a57600080fd5b505afa158015613d1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a559190614e5d565b505067ffffffffffffffff164090565b6000613d868360000151846020015185604001518660600151868860a001518960c001518a60e001518b6101000151613f20565b60038360200151604051602001613d9e9291906153e2565b60408051601f1981840301815291905280516020909101209392505050565b600b54604080517ffeaf968c0000000000000000000000000000000000000000000000000000000081529051600092670100000000000000900463ffffffff169182151591849182917f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169163feaf968c9160048083019260a0929190829003018186803b158015613e5657600080fd5b505afa158015613e6a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613e8e9190615137565b509450909250849150508015613eb25750613ea982426155ab565b8463ffffffff16105b15613ebc5750600a545b949350505050565b60004661a4b1811480613ed9575062066eed81145b15613f1857606c6001600160a01b031663c6f7de0e6040518163ffffffff1660e01b815260040160206040518083038186803b1580156136bb57600080fd5b600091505090565b613f298961415b565b613f755760405162461bcd60e51b815260206004820152601a60248201527f7075626c6963206b6579206973206e6f74206f6e20637572766500000000000060448201526064016108dc565b613f7e8861415b565b613fca5760405162461bcd60e51b815260206004820152601560248201527f67616d6d61206973206e6f74206f6e206375727665000000000000000000000060448201526064016108dc565b613fd38361415b565b61401f5760405162461bcd60e51b815260206004820152601d60248201527f6347616d6d615769746e657373206973206e6f74206f6e20637572766500000060448201526064016108dc565b6140288261415b565b6140745760405162461bcd60e51b815260206004820152601c60248201527f73486173685769746e657373206973206e6f74206f6e2063757276650000000060448201526064016108dc565b614080878a8887614234565b6140cc5760405162461bcd60e51b815260206004820152601960248201527f6164647228632a706b2b732a6729213d5f755769746e6573730000000000000060448201526064016108dc565b60006140d88a87614385565b905060006140eb898b878b8689896143e9565b905060006140fc838d8d8a86614515565b9050808a1461414d5760405162461bcd60e51b815260206004820152600d60248201527f696e76616c69642070726f6f660000000000000000000000000000000000000060448201526064016108dc565b505050505050505050505050565b80516000906401000003d019116141b45760405162461bcd60e51b815260206004820152601260248201527f696e76616c696420782d6f7264696e617465000000000000000000000000000060448201526064016108dc565b60208201516401000003d0191161420d5760405162461bcd60e51b815260206004820152601260248201527f696e76616c696420792d6f7264696e617465000000000000000000000000000060448201526064016108dc565b60208201516401000003d01990800961422d8360005b6020020151614555565b1492915050565b60006001600160a01b03821661428c5760405162461bcd60e51b815260206004820152600b60248201527f626164207769746e65737300000000000000000000000000000000000000000060448201526064016108dc565b6020840151600090600116156142a357601c6142a6565b601b5b905060007ffffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd03641418587600060200201510986517ffffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141918203925060009190890987516040805160008082526020820180845287905260ff88169282019290925260608101929092526080820183905291925060019060a0016020604051602081039080840390855afa15801561435d573d6000803e3d6000fd5b5050604051601f1901516001600160a01b039081169088161495505050505050949350505050565b61438d614ada565b6143ba600184846040516020016143a693929190615222565b604051602081830303815290604052614579565b90505b6143c68161415b565b612a105780516040805160208101929092526143e291016143a6565b90506143bd565b6143f1614ada565b825186516401000003d01990819006910614156144505760405162461bcd60e51b815260206004820152601e60248201527f706f696e747320696e2073756d206d7573742062652064697374696e6374000060448201526064016108dc565b61445b8789886145c8565b6144a75760405162461bcd60e51b815260206004820152601660248201527f4669727374206d756c20636865636b206661696c65640000000000000000000060448201526064016108dc565b6144b28486856145c8565b6144fe5760405162461bcd60e51b815260206004820152601760248201527f5365636f6e64206d756c20636865636b206661696c656400000000000000000060448201526064016108dc565b614509868484614710565b98975050505050505050565b600060028686868587604051602001614533969594939291906151b0565b60408051601f1981840301815291905280516020909101209695505050505050565b6000806401000003d01980848509840990506401000003d019600782089392505050565b614581614ada565b61458a826147d7565b815261459f61459a826000614223565b614812565b6020820181905260029006600114156145c3576020810180516401000003d0190390525b919050565b6000826146175760405162461bcd60e51b815260206004820152600b60248201527f7a65726f207363616c617200000000000000000000000000000000000000000060448201526064016108dc565b8351602085015160009061462d90600290615650565b1561463957601c61463c565b601b5b905060007ffffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd03641418387096040805160008082526020820180845281905260ff86169282019290925260608101869052608081018390529192509060019060a0016020604051602081039080840390855afa1580156146bc573d6000803e3d6000fd5b5050506020604051035190506000866040516020016146db919061519e565b60408051601f1981840301815291905280516020909101206001600160a01b0392831692169190911498975050505050505050565b614718614ada565b83516020808601518551918601516000938493849361473993909190614832565b919450925090506401000003d0198582096001146147995760405162461bcd60e51b815260206004820152601960248201527f696e765a206d75737420626520696e7665727365206f66207a0000000000000060448201526064016108dc565b60405180604001604052806401000003d019806147b8576147b8615693565b87860981526020016401000003d0198785099052979650505050505050565b805160208201205b6401000003d01981106145c3576040805160208082019390935281518082038401815290820190915280519101206147df565b6000612a1082600261482b6401000003d01960016154ef565b901c614912565b60008080600180826401000003d019896401000003d019038808905060006401000003d0198b6401000003d019038a0890506000614872838385856149d2565b909850905061488388828e886149f6565b909850905061489488828c876149f6565b909850905060006148a78d878b856149f6565b90985090506148b8888286866149d2565b90985090506148c988828e896149f6565b90985090508181146148fe576401000003d019818a0998506401000003d01982890997506401000003d0198183099650614902565b8196505b5050505050509450945094915050565b60008061491d614af8565b6020808252818101819052604082015260608101859052608081018490526401000003d01960a082015261494f614b16565b60208160c08460057ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa9250826149c85760405162461bcd60e51b815260206004820152601260248201527f6269674d6f64457870206661696c75726521000000000000000000000000000060448201526064016108dc565b5195945050505050565b6000806401000003d0198487096401000003d0198487099097909650945050505050565b600080806401000003d019878509905060006401000003d01987876401000003d019030990506401000003d0198183086401000003d01986890990999098509650505050505050565b828054828255906000526020600020908101928215614aac579160200282015b82811115614aac57825182547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03909116178255602090920191600190910190614a5f565b50614ab8929150614b34565b5090565b50805460008255906000526020600020908101906108349190614b34565b60405180604001604052806002906020820280368337509192915050565b6040518060c001604052806006906020820280368337509192915050565b60405180602001604052806001906020820280368337509192915050565b5b80821115614ab85760008155600101614b35565b80356001600160a01b03811681146145c357600080fd5b8060408101831015612a1057600080fd5b600082601f830112614b8257600080fd5b6040516040810181811067ffffffffffffffff82111715614ba557614ba5615720565b8060405250808385604086011115614bbc57600080fd5b60005b6002811015614bde578135835260209283019290910190600101614bbf565b509195945050505050565b600060a08284031215614bfb57600080fd5b60405160a0810181811067ffffffffffffffff82111715614c1e57614c1e615720565b604052905080614c2d83614cb3565b8152614c3b60208401614cb3565b6020820152614c4c60408401614c9f565b6040820152614c5d60608401614c9f565b6060820152614c6e60808401614b49565b60808201525092915050565b803561ffff811681146145c357600080fd5b803562ffffff811681146145c357600080fd5b803563ffffffff811681146145c357600080fd5b803567ffffffffffffffff811681146145c357600080fd5b805169ffffffffffffffffffff811681146145c357600080fd5b600060208284031215614cf757600080fd5b613a5582614b49565b60008060608385031215614d1357600080fd5b614d1c83614b49565b9150614d2b8460208501614b60565b90509250929050565b60008060008060608587031215614d4a57600080fd5b614d5385614b49565b935060208501359250604085013567ffffffffffffffff80821115614d7757600080fd5b818701915087601f830112614d8b57600080fd5b813581811115614d9a57600080fd5b886020828501011115614dac57600080fd5b95989497505060200194505050565b60008060408385031215614dce57600080fd5b614dd783614b49565b915060208301356bffffffffffffffffffffffff81168114614df857600080fd5b809150509250929050565b600060408284031215614e1557600080fd5b613a558383614b60565b600060408284031215614e3157600080fd5b613a558383614b71565b600060208284031215614e4d57600080fd5b81518015158114613a5557600080fd5b600060208284031215614e6f57600080fd5b5051919050565b600080600080600060a08688031215614e8e57600080fd5b85359450614e9e60208701614cb3565b9350614eac60408701614c7a565b9250614eba60608701614c9f565b9150614ec860808701614c9f565b90509295509295909350565b600080828403610240811215614ee957600080fd5b6101a080821215614ef957600080fd5b614f016154c5565b9150614f0d8686614b71565b8252614f1c8660408701614b71565b60208301526080850135604083015260a0850135606083015260c08501356080830152614f4b60e08601614b49565b60a0830152610100614f5f87828801614b71565b60c0840152614f72876101408801614b71565b60e08401526101808601358184015250819350614f9186828701614be9565b925050509250929050565b6000806000806000808688036101c0811215614fb757600080fd5b614fc088614c7a565b9650614fce60208901614c9f565b9550614fdc60408901614c9f565b9450614fea60608901614c9f565b935060808801359250610120807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff608301121561502557600080fd5b61502d6154c5565b915061503b60a08a01614c9f565b825261504960c08a01614c9f565b602083015261505a60e08a01614c9f565b604083015261010061506d818b01614c9f565b606084015261507d828b01614c9f565b608084015261508f6101408b01614c8c565b60a08401526150a16101608b01614c8c565b60c08401526150b36101808b01614c8c565b60e08401526150c56101a08b01614c8c565b818401525050809150509295509295509295565b6000602082840312156150eb57600080fd5b5035919050565b60006020828403121561510457600080fd5b613a5582614cb3565b6000806040838503121561512057600080fd5b61512983614cb3565b9150614d2b60208401614b49565b600080600080600060a0868803121561514f57600080fd5b61515886614ccb565b9450602086015193506040860151925060608601519150614ec860808701614ccb565b8060005b60028110156109e557815184526020938401939091019060010161517f565b6151a8818361517b565b604001919050565b8681526151c0602082018761517b565b6151cd606082018661517b565b6151da60a082018561517b565b6151e760e082018461517b565b60609190911b7fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166101208201526101340195945050505050565b838152615232602082018461517b565b606081019190915260800192915050565b60408101612a10828461517b565b600060208083528351808285015260005b8181101561527e57858101830151858201604001528201615262565b81811115615290576000604083870101525b50601f01601f1916929092016040019392505050565b60006060820161ffff86168352602063ffffffff86168185015260606040850152818551808452608086019150828701935060005b818110156152f7578451835293830193918301916001016152db565b509098975050505050505050565b60006101c08201905061ffff8816825263ffffffff808816602084015280871660408401528086166060840152846080840152835481811660a085015261535960c08501838360201c1663ffffffff169052565b61537060e08501838360401c1663ffffffff169052565b6153886101008501838360601c1663ffffffff169052565b6153a06101208501838360801c1663ffffffff169052565b62ffffff60a082901c811661014086015260b882901c811661016086015260d082901c1661018085015260e81c6101a090930192909252979650505050505050565b82815260608101613a55602083018461517b565b6000604082018483526020604081850152818551808452606086019150828701935060005b818110156154375784518352938301939183019160010161541b565b5090979650505050505050565b6000608082016bffffffffffffffffffffffff87168352602067ffffffffffffffff8716818501526001600160a01b0380871660408601526080606086015282865180855260a087019150838801945060005b818110156154b5578551841683529484019491840191600101615497565b50909a9950505050505050505050565b604051610120810167ffffffffffffffff811182821017156154e9576154e9615720565b60405290565b6000821982111561550257615502615664565b500190565b600067ffffffffffffffff80831681851680830382111561552a5761552a615664565b01949350505050565b60006bffffffffffffffffffffffff80831681851680830382111561552a5761552a615664565b60008261556957615569615693565b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156155a6576155a6615664565b500290565b6000828210156155bd576155bd615664565b500390565b60006bffffffffffffffffffffffff838116908316818110156155e7576155e7615664565b039392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561562157615621615664565b5060010190565b600067ffffffffffffffff8083168181141561564657615646615664565b6001019392505050565b60008261565f5761565f615693565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fdfea164736f6c6343000806000a",
}
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 00000000000..d4da270386e
--- /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: "0x60a06040523480156200001157600080fd5b506040516200615938038062006159833981016040819052620000349162000183565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000d7565b50505060601b6001600160601b031916608052620001b5565b6001600160a01b038116331415620001325760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000602082840312156200019657600080fd5b81516001600160a01b0381168114620001ae57600080fd5b9392505050565b60805160601c615f7e620001db600039600081816106150152613a860152615f7e6000f3fe6080604052600436106102dc5760003560e01c806379ba50971161017f578063b08c8795116100e1578063da2f26101161008a578063e72f6e3011610064578063e72f6e3014610964578063ee9d2d3814610984578063f2fde38b146109b157600080fd5b8063da2f2610146108dd578063dac83d2914610913578063dc311dd31461093357600080fd5b8063caf70c4a116100bb578063caf70c4a1461087d578063cb6317971461089d578063d98e620e146108bd57600080fd5b8063b08c87951461081d578063b2a7cac51461083d578063bec4c08c1461085d57600080fd5b80639b1c385e11610143578063a4c0ed361161011d578063a4c0ed36146107b0578063aa433aff146107d0578063aefb212f146107f057600080fd5b80639b1c385e146107435780639d40a6fd14610763578063a21a23e41461079b57600080fd5b806379ba5097146106bd5780638402595e146106d257806386fe91c7146106f25780638da5cb5b1461071257806395b55cfc1461073057600080fd5b8063330987b31161024357806365982744116101ec5780636b6feccc116101c65780636b6feccc146106375780636f64f03f1461067d57806372e9d5651461069d57600080fd5b806365982744146105c357806366316d8d146105e3578063689c45171461060357600080fd5b806341af6c871161021d57806341af6c871461055e5780635d06b4ab1461058e57806364d51a2a146105ae57600080fd5b8063330987b3146104f3578063405b84fa1461051357806340d6bb821461053357600080fd5b80630ae09540116102a55780631b6b6d231161027f5780631b6b6d231461047f57806329492657146104b7578063294daa49146104d757600080fd5b80630ae09540146103f857806315c48b841461041857806318e3dd271461044057600080fd5b8062012291146102e157806304104edb1461030e578063043bd6ae14610330578063088070f51461035457806308821d58146103d8575b600080fd5b3480156102ed57600080fd5b506102f66109d1565b60405161030593929190615ae2565b60405180910390f35b34801561031a57600080fd5b5061032e61032936600461542f565b610a4d565b005b34801561033c57600080fd5b5061034660115481565b604051908152602001610305565b34801561036057600080fd5b50600d546103a09061ffff81169063ffffffff62010000820481169160ff600160301b820416916701000000000000008204811691600160581b90041685565b6040805161ffff909616865263ffffffff9485166020870152921515928501929092528216606084015216608082015260a001610305565b3480156103e457600080fd5b5061032e6103f336600461556f565b610c0f565b34801561040457600080fd5b5061032e610413366004615811565b610da3565b34801561042457600080fd5b5061042d60c881565b60405161ffff9091168152602001610305565b34801561044c57600080fd5b50600a5461046790600160601b90046001600160601b031681565b6040516001600160601b039091168152602001610305565b34801561048b57600080fd5b5060025461049f906001600160a01b031681565b6040516001600160a01b039091168152602001610305565b3480156104c357600080fd5b5061032e6104d236600461544c565b610e71565b3480156104e357600080fd5b5060405160018152602001610305565b3480156104ff57600080fd5b5061046761050e366004615641565b610fee565b34801561051f57600080fd5b5061032e61052e366004615811565b6114d8565b34801561053f57600080fd5b506105496101f481565b60405163ffffffff9091168152602001610305565b34801561056a57600080fd5b5061057e6105793660046155c4565b6118ff565b6040519015158152602001610305565b34801561059a57600080fd5b5061032e6105a936600461542f565b611b00565b3480156105ba57600080fd5b5061042d606481565b3480156105cf57600080fd5b5061032e6105de366004615481565b611bbe565b3480156105ef57600080fd5b5061032e6105fe36600461544c565b611c1e565b34801561060f57600080fd5b5061049f7f000000000000000000000000000000000000000000000000000000000000000081565b34801561064357600080fd5b506012546106609063ffffffff8082169164010000000090041682565b6040805163ffffffff938416815292909116602083015201610305565b34801561068957600080fd5b5061032e6106983660046154ba565b611de6565b3480156106a957600080fd5b5060035461049f906001600160a01b031681565b3480156106c957600080fd5b5061032e611ee5565b3480156106de57600080fd5b5061032e6106ed36600461542f565b611f96565b3480156106fe57600080fd5b50600a54610467906001600160601b031681565b34801561071e57600080fd5b506000546001600160a01b031661049f565b61032e61073e3660046155c4565b6120b1565b34801561074f57600080fd5b5061034661075e36600461571e565b6121f8565b34801561076f57600080fd5b50600754610783906001600160401b031681565b6040516001600160401b039091168152602001610305565b3480156107a757600080fd5b506103466125ed565b3480156107bc57600080fd5b5061032e6107cb3660046154e7565b61283d565b3480156107dc57600080fd5b5061032e6107eb3660046155c4565b6129dd565b3480156107fc57600080fd5b5061081061080b366004615836565b612a3d565b6040516103059190615a47565b34801561082957600080fd5b5061032e610838366004615773565b612b3e565b34801561084957600080fd5b5061032e6108583660046155c4565b612cd2565b34801561086957600080fd5b5061032e610878366004615811565b612e00565b34801561088957600080fd5b5061034661089836600461558b565b612f9c565b3480156108a957600080fd5b5061032e6108b8366004615811565b612fcc565b3480156108c957600080fd5b506103466108d83660046155c4565b6132cf565b3480156108e957600080fd5b5061049f6108f83660046155c4565b600e602052600090815260409020546001600160a01b031681565b34801561091f57600080fd5b5061032e61092e366004615811565b6132f0565b34801561093f57600080fd5b5061095361094e3660046155c4565b61340f565b604051610305959493929190615c4a565b34801561097057600080fd5b5061032e61097f36600461542f565b61350a565b34801561099057600080fd5b5061034661099f3660046155c4565b60106020526000908152604090205481565b3480156109bd57600080fd5b5061032e6109cc36600461542f565b6136f2565b600d54600f805460408051602080840282018101909252828152600094859460609461ffff8316946201000090930463ffffffff16939192839190830182828015610a3b57602002820191906000526020600020905b815481526020019060010190808311610a27575b50505050509050925092509250909192565b610a55613703565b60135460005b81811015610be257826001600160a01b031660138281548110610a8057610a80615f22565b6000918252602090912001546001600160a01b03161415610bd0576013610aa8600184615e1b565b81548110610ab857610ab8615f22565b600091825260209091200154601380546001600160a01b039092169183908110610ae457610ae4615f22565b600091825260209091200180546001600160a01b0319166001600160a01b0392909216919091179055826013610b1b600185615e1b565b81548110610b2b57610b2b615f22565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506013805480610b6a57610b6a615f0c565b6000828152602090819020600019908301810180546001600160a01b03191690559091019091556040516001600160a01b03851681527ff80a1a97fd42251f3c33cda98635e7399253033a6774fe37cd3f650b5282af37910160405180910390a1505050565b80610bda81615e8a565b915050610a5b565b50604051635428d44960e01b81526001600160a01b03831660048201526024015b60405180910390fd5b50565b610c17613703565b604080518082018252600091610c46919084906002908390839080828437600092019190915250612f9c915050565b6000818152600e60205260409020549091506001600160a01b031680610c8257604051631dfd6e1360e21b815260048101839052602401610c03565b6000828152600e6020526040812080546001600160a01b03191690555b600f54811015610d5a5782600f8281548110610cbd57610cbd615f22565b90600052602060002001541415610d4857600f805460009190610ce290600190615e1b565b81548110610cf257610cf2615f22565b9060005260206000200154905080600f8381548110610d1357610d13615f22565b600091825260209091200155600f805480610d3057610d30615f0c565b60019003818190600052602060002001600090559055505b80610d5281615e8a565b915050610c9f565b50806001600160a01b03167f72be339577868f868798bac2c93e52d6f034fef4689a9848996c14ebb7416c0d83604051610d9691815260200190565b60405180910390a2505050565b60008281526005602052604090205482906001600160a01b031680610ddb57604051630fb532db60e11b815260040160405180910390fd5b336001600160a01b03821614610e0f57604051636c51fda960e11b81526001600160a01b0382166004820152602401610c03565b600d54600160301b900460ff1615610e3a5760405163769dd35360e11b815260040160405180910390fd5b610e43846118ff565b15610e6157604051631685ecdd60e31b815260040160405180910390fd5b610e6b848461375f565b50505050565b600d54600160301b900460ff1615610e9c5760405163769dd35360e11b815260040160405180910390fd5b336000908152600c60205260409020546001600160601b0380831691161015610ed857604051631e9acf1760e31b815260040160405180910390fd5b336000908152600c602052604081208054839290610f009084906001600160601b0316615e32565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555080600a600c8282829054906101000a90046001600160601b0316610f489190615e32565b92506101000a8154816001600160601b0302191690836001600160601b031602179055506000826001600160a01b0316826001600160601b031660405160006040518083038185875af1925050503d8060008114610fc2576040519150601f19603f3d011682016040523d82523d6000602084013e610fc7565b606091505b5050905080610fe95760405163950b247960e01b815260040160405180910390fd5b505050565b600d54600090600160301b900460ff161561101c5760405163769dd35360e11b815260040160405180910390fd5b60005a9050600061102d858561391b565b90506000846060015163ffffffff166001600160401b0381111561105357611053615f38565b60405190808252806020026020018201604052801561107c578160200160208202803683370190505b50905060005b856060015163ffffffff168110156110fc578260400151816040516020016110b4929190918252602082015260400190565b6040516020818303038152906040528051906020012060001c8282815181106110df576110df615f22565b6020908102919091010152806110f481615e8a565b915050611082565b5060208083018051600090815260109092526040808320839055905190518291631fe543e360e01b9161113491908690602401615b55565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252600d805466ff0000000000001916600160301b17905590880151608089015191925060009161119c9163ffffffff169084613ba8565b600d805466ff00000000000019169055602089810151600090815260069091526040902054909150600160c01b90046001600160401b03166111df816001615d9b565b6020808b0151600090815260069091526040812080546001600160401b0393909316600160c01b026001600160c01b039093169290921790915560a08a0151805161122c90600190615e1b565b8151811061123c5761123c615f22565b602091010151600d5460f89190911c600114915060009061126d908a90600160581b900463ffffffff163a85613bf6565b90508115611376576020808c01516000908152600690915260409020546001600160601b03808316600160601b9092041610156112bd57604051631e9acf1760e31b815260040160405180910390fd5b60208b81015160009081526006909152604090208054829190600c906112f4908490600160601b90046001600160601b0316615e32565b82546101009290920a6001600160601b0381810219909316918316021790915589516000908152600e60209081526040808320546001600160a01b03168352600c90915281208054859450909261134d91859116615dc6565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550611462565b6020808c01516000908152600690915260409020546001600160601b03808316911610156113b757604051631e9acf1760e31b815260040160405180910390fd5b6020808c0151600090815260069091526040812080548392906113e49084906001600160601b0316615e32565b82546101009290920a6001600160601b0381810219909316918316021790915589516000908152600e60209081526040808320546001600160a01b03168352600b90915281208054859450909261143d91859116615dc6565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505b8a6020015188602001517f49580fdfd9497e1ed5c1b1cec0495087ae8e3f1267470ec2fb015db32e3d6aa78a6040015184886040516114bf939291909283526001600160601b039190911660208301521515604082015260600190565b60405180910390a3985050505050505050505b92915050565b600d54600160301b900460ff16156115035760405163769dd35360e11b815260040160405180910390fd5b61150c81613c46565b61153457604051635428d44960e01b81526001600160a01b0382166004820152602401610c03565b6000806000806115438661340f565b945094505093509350336001600160a01b0316826001600160a01b0316146115ad5760405162461bcd60e51b815260206004820152601660248201527f4e6f7420737562736372697074696f6e206f776e6572000000000000000000006044820152606401610c03565b6115b6866118ff565b156116035760405162461bcd60e51b815260206004820152601660248201527f50656e64696e67207265717565737420657869737473000000000000000000006044820152606401610c03565b60006040518060c00160405280611618600190565b60ff168152602001888152602001846001600160a01b03168152602001838152602001866001600160601b03168152602001856001600160601b0316815250905060008160405160200161166c9190615a6d565b604051602081830303815290604052905061168688613cb0565b505060405163ce3f471960e01b81526001600160a01b0388169063ce3f4719906001600160601b038816906116bf908590600401615a5a565b6000604051808303818588803b1580156116d857600080fd5b505af11580156116ec573d6000803e3d6000fd5b50506002546001600160a01b031615801593509150611715905057506001600160601b03861615155b156117f45760025460405163a9059cbb60e01b81526001600160a01b0389811660048301526001600160601b03891660248301529091169063a9059cbb90604401602060405180830381600087803b15801561177057600080fd5b505af1158015611784573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117a891906155a7565b6117f45760405162461bcd60e51b815260206004820152601260248201527f696e73756666696369656e742066756e647300000000000000000000000000006044820152606401610c03565b600d805466ff0000000000001916600160301b17905560005b83518110156118a25783818151811061182857611828615f22565b6020908102919091010151604051638ea9811760e01b81526001600160a01b038a8116600483015290911690638ea9811790602401600060405180830381600087803b15801561187757600080fd5b505af115801561188b573d6000803e3d6000fd5b50505050808061189a90615e8a565b91505061180d565b50600d805466ff00000000000019169055604080516001600160a01b0389168152602081018a90527fd63ca8cb945956747ee69bfdc3ea754c24a4caf7418db70e46052f7850be4187910160405180910390a15050505050505050565b6000818152600560209081526040808320815160608101835281546001600160a01b039081168252600183015416818501526002820180548451818702810187018652818152879693958601939092919083018282801561198957602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161196b575b505050505081525050905060005b816040015151811015611af65760005b600f54811015611ae3576000611aac600f83815481106119c9576119c9615f22565b9060005260206000200154856040015185815181106119ea576119ea615f22565b6020026020010151886004600089604001518981518110611a0d57611a0d615f22565b6020908102919091018101516001600160a01b03908116835282820193909352604091820160009081208e82528252829020548251808301889052959093168583015260608501939093526001600160401b039091166080808501919091528151808503909101815260a08401825280519083012060c084019490945260e0808401859052815180850390910181526101009093019052815191012091565b5060008181526010602052604090205490915015611ad05750600195945050505050565b5080611adb81615e8a565b9150506119a7565b5080611aee81615e8a565b915050611997565b5060009392505050565b611b08613703565b611b1181613c46565b15611b3a5760405163ac8a27ef60e01b81526001600160a01b0382166004820152602401610c03565b601380546001810182556000919091527f66de8ffda797e3de9c05e8fc57b3bf0ec28a930d40b0d285d93c06501cf6a0900180546001600160a01b0319166001600160a01b0383169081179091556040519081527fb7cabbfc11e66731fc77de0444614282023bcbd41d16781c753a431d0af016259060200160405180910390a150565b611bc6613703565b6002546001600160a01b031615611bf057604051631688c53760e11b815260040160405180910390fd5b600280546001600160a01b039384166001600160a01b03199182161790915560038054929093169116179055565b600d54600160301b900460ff1615611c495760405163769dd35360e11b815260040160405180910390fd5b6002546001600160a01b0316611c725760405163c1f0c0a160e01b815260040160405180910390fd5b336000908152600b60205260409020546001600160601b0380831691161015611cae57604051631e9acf1760e31b815260040160405180910390fd5b336000908152600b602052604081208054839290611cd69084906001600160601b0316615e32565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555080600a60008282829054906101000a90046001600160601b0316611d1e9190615e32565b82546101009290920a6001600160601b0381810219909316918316021790915560025460405163a9059cbb60e01b81526001600160a01b03868116600483015292851660248201529116915063a9059cbb90604401602060405180830381600087803b158015611d8d57600080fd5b505af1158015611da1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dc591906155a7565b611de257604051631e9acf1760e31b815260040160405180910390fd5b5050565b611dee613703565b604080518082018252600091611e1d919084906002908390839080828437600092019190915250612f9c915050565b6000818152600e60205260409020549091506001600160a01b031615611e5957604051634a0b8fa760e01b815260048101829052602401610c03565b6000818152600e6020908152604080832080546001600160a01b0319166001600160a01b038816908117909155600f805460018101825594527f8d1108e10bcb7c27dddfc02ed9d693a074039d026cf4ea4240b40f7d581ac802909301849055518381527fe729ae16526293f74ade739043022254f1489f616295a25bf72dfb4511ed73b89101610d96565b6001546001600160a01b03163314611f3f5760405162461bcd60e51b815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610c03565b60008054336001600160a01b0319808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b611f9e613703565b600a544790600160601b90046001600160601b031681811115611fde576040516354ced18160e11b81526004810182905260248101839052604401610c03565b81811015610fe9576000611ff28284615e1b565b90506000846001600160a01b03168260405160006040518083038185875af1925050503d8060008114612041576040519150601f19603f3d011682016040523d82523d6000602084013e612046565b606091505b50509050806120685760405163950b247960e01b815260040160405180910390fd5b604080516001600160a01b0387168152602081018490527f4aed7c8eed0496c8c19ea2681fcca25741c1602342e38b045d9f1e8e905d2e9c910160405180910390a15050505050565b600d54600160301b900460ff16156120dc5760405163769dd35360e11b815260040160405180910390fd5b6000818152600560205260409020546001600160a01b031661211157604051630fb532db60e11b815260040160405180910390fd5b60008181526006602052604090208054600160601b90046001600160601b0316903490600c6121408385615dc6565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555034600a600c8282829054906101000a90046001600160601b03166121889190615dc6565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550817f7603b205d03651ee812f803fccde89f1012e545a9c99f0abfea9cedd0fd8e9028234846121db9190615d83565b604080519283526020830191909152015b60405180910390a25050565b600d54600090600160301b900460ff16156122265760405163769dd35360e11b815260040160405180910390fd5b6020808301356000908152600590915260409020546001600160a01b031661226157604051630fb532db60e11b815260040160405180910390fd5b3360009081526004602090815260408083208583013584529091529020546001600160401b0316806122b2576040516379bfd40160e01b815260208401356004820152336024820152604401610c03565b600d5461ffff166122c96060850160408601615758565b61ffff1610806122ec575060c86122e66060850160408601615758565b61ffff16115b15612332576123016060840160408501615758565b600d5460405163539c34bb60e11b815261ffff92831660048201529116602482015260c86044820152606401610c03565b600d5462010000900463ffffffff166123516080850160608601615858565b63ffffffff1611156123a15761236d6080840160608501615858565b600d54604051637aebf00f60e11b815263ffffffff9283166004820152620100009091049091166024820152604401610c03565b6101f46123b460a0850160808601615858565b63ffffffff1611156123fa576123d060a0840160808501615858565b6040516311ce1afb60e21b815263ffffffff90911660048201526101f46024820152604401610c03565b6000612407826001615d9b565b604080518635602080830182905233838501528089013560608401526001600160401b0385166080808501919091528451808503909101815260a0808501865281519183019190912060c085019390935260e0808501849052855180860390910181526101009094019094528251920191909120929350906000906124979061249290890189615c9f565b613eff565b905060006124a482613f7c565b9050836124af613fed565b60208a01356124c460808c0160608d01615858565b6124d460a08d0160808e01615858565b33866040516020016124ec9796959493929190615bad565b604051602081830303815290604052805190602001206010600086815260200190815260200160002081905550336001600160a01b0316886020013589600001357feb0e3652e0f44f417695e6e90f2f42c99b65cd7169074c5a654b16b9748c3a4e87878d60400160208101906125639190615758565b8e60600160208101906125769190615858565b8f60800160208101906125899190615858565b8960405161259c96959493929190615b6e565b60405180910390a450503360009081526004602090815260408083208983013584529091529020805467ffffffffffffffff19166001600160401b039490941693909317909255925050505b919050565b600d54600090600160301b900460ff161561261b5760405163769dd35360e11b815260040160405180910390fd5b600033612629600143615e1b565b600754604051606093841b6bffffffffffffffffffffffff199081166020830152924060348201523090931b909116605483015260c01b6001600160c01b031916606882015260700160408051601f198184030181529190528051602090910120600780549192506001600160401b039091169060006126a883615ea5565b91906101000a8154816001600160401b0302191690836001600160401b03160217905550506000806001600160401b038111156126e7576126e7615f38565b604051908082528060200260200182016040528015612710578160200160208202803683370190505b506040805160608082018352600080835260208084018281528486018381528984526006835286842095518654925191516001600160601b039182166001600160c01b031990941693909317600160601b9190921602176001600160c01b0316600160c01b6001600160401b039092169190910217909355835191820184523382528183018181528285018681528883526005855294909120825181546001600160a01b03199081166001600160a01b0392831617835592516001830180549094169116179091559251805194955090936127f19260028501920190615145565b5061280191506008905083614086565b5060405133815282907f1d3015d7ba850fa198dc7b1a3f5d42779313a681035f77c8c03764c61005518d9060200160405180910390a250905090565b600d54600160301b900460ff16156128685760405163769dd35360e11b815260040160405180910390fd5b6002546001600160a01b03163314612893576040516344b0e3c360e01b815260040160405180910390fd5b602081146128b457604051638129bbcd60e01b815260040160405180910390fd5b60006128c2828401846155c4565b6000818152600560205260409020549091506001600160a01b03166128fa57604051630fb532db60e11b815260040160405180910390fd5b600081815260066020526040812080546001600160601b0316918691906129218385615dc6565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555084600a60008282829054906101000a90046001600160601b03166129699190615dc6565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550817f1ced9348ff549fceab2ac57cd3a9de38edaaab274b725ee82c23e8fc8c4eec7a8287846129bc9190615d83565b604080519283526020830191909152015b60405180910390a2505050505050565b6129e5613703565b6000818152600560205260409020546001600160a01b0316612a1a57604051630fb532db60e11b815260040160405180910390fd5b600081815260056020526040902054610c0c9082906001600160a01b031661375f565b60606000612a4b6008614092565b9050808410612a6d57604051631390f2a160e01b815260040160405180910390fd5b6000612a798486615d83565b905081811180612a87575083155b612a915780612a93565b815b90506000612aa18683615e1b565b6001600160401b03811115612ab857612ab8615f38565b604051908082528060200260200182016040528015612ae1578160200160208202803683370190505b50905060005b8151811015612b3457612b05612afd8883615d83565b60089061409c565b828281518110612b1757612b17615f22565b602090810291909101015280612b2c81615e8a565b915050612ae7565b5095945050505050565b612b46613703565b60c861ffff87161115612b805760405163539c34bb60e11b815261ffff871660048201819052602482015260c86044820152606401610c03565b60008213612ba4576040516321ea67b360e11b815260048101839052602401610c03565b6040805160a0808201835261ffff891680835263ffffffff89811660208086018290526000868801528a831660608088018290528b85166080988901819052600d805465ffffffffffff19168817620100008702176effffffffffffffffff000000000000191667010000000000000085026effffffff0000000000000000000000191617600160581b83021790558a51601280548d87015192891667ffffffffffffffff199091161764010000000092891692909202919091179081905560118d90558a519788528785019590955298860191909152840196909652938201879052838116928201929092529190921c90911660c08201527f777357bb93f63d088f18112d3dba38457aec633eb8f1341e1d418380ad328e789060e00160405180910390a1505050505050565b600d54600160301b900460ff1615612cfd5760405163769dd35360e11b815260040160405180910390fd5b6000818152600560205260409020546001600160a01b0316612d3257604051630fb532db60e11b815260040160405180910390fd5b6000818152600560205260409020600101546001600160a01b03163314612d8b576000818152600560205260409081902060010154905163d084e97560e01b81526001600160a01b039091166004820152602401610c03565b6000818152600560209081526040918290208054336001600160a01b0319808316821784556001909301805490931690925583516001600160a01b0390911680825292810191909152909183917fd4114ab6e9af9f597c52041f32d62dc57c5c4e4c0d4427006069635e216c938691016121ec565b60008281526005602052604090205482906001600160a01b031680612e3857604051630fb532db60e11b815260040160405180910390fd5b336001600160a01b03821614612e6c57604051636c51fda960e11b81526001600160a01b0382166004820152602401610c03565b600d54600160301b900460ff1615612e975760405163769dd35360e11b815260040160405180910390fd5b60008481526005602052604090206002015460641415612eca576040516305a48e0f60e01b815260040160405180910390fd5b6001600160a01b03831660009081526004602090815260408083208784529091529020546001600160401b031615612f0157610e6b565b6001600160a01b03831660008181526004602090815260408083208884528252808320805467ffffffffffffffff19166001908117909155600583528184206002018054918201815584529282902090920180546001600160a01b03191684179055905191825285917f1e980d04aa7648e205713e5e8ea3808672ac163d10936d36f91b2c88ac1575e191015b60405180910390a250505050565b600081604051602001612faf9190615a39565b604051602081830303815290604052805190602001209050919050565b60008281526005602052604090205482906001600160a01b03168061300457604051630fb532db60e11b815260040160405180910390fd5b336001600160a01b0382161461303857604051636c51fda960e11b81526001600160a01b0382166004820152602401610c03565b600d54600160301b900460ff16156130635760405163769dd35360e11b815260040160405180910390fd5b61306c846118ff565b1561308a57604051631685ecdd60e31b815260040160405180910390fd5b6001600160a01b03831660009081526004602090815260408083208784529091529020546001600160401b03166130e6576040516379bfd40160e01b8152600481018590526001600160a01b0384166024820152604401610c03565b60008481526005602090815260408083206002018054825181850281018501909352808352919290919083018282801561314957602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161312b575b505050505090506000600182516131609190615e1b565b905060005b825181101561326c57856001600160a01b031683828151811061318a5761318a615f22565b60200260200101516001600160a01b0316141561325a5760008383815181106131b5576131b5615f22565b6020026020010151905080600560008a815260200190815260200160002060020183815481106131e7576131e7615f22565b600091825260208083209190910180546001600160a01b0319166001600160a01b03949094169390931790925589815260059091526040902060020180548061323257613232615f0c565b600082815260209020810160001990810180546001600160a01b03191690550190555061326c565b8061326481615e8a565b915050613165565b506001600160a01b03851660008181526004602090815260408083208a8452825291829020805467ffffffffffffffff19169055905191825287917f32158c6058347c1601b2d12bc696ac6901d8a9a9aa3ba10c27ab0a983e8425a791016129cd565b600f81815481106132df57600080fd5b600091825260209091200154905081565b60008281526005602052604090205482906001600160a01b03168061332857604051630fb532db60e11b815260040160405180910390fd5b336001600160a01b0382161461335c57604051636c51fda960e11b81526001600160a01b0382166004820152602401610c03565b600d54600160301b900460ff16156133875760405163769dd35360e11b815260040160405180910390fd5b6000848152600560205260409020600101546001600160a01b03848116911614610e6b5760008481526005602090815260409182902060010180546001600160a01b0319166001600160a01b03871690811790915582513381529182015285917f21a4dad170a6bf476c31bbcf4a16628295b0e450672eec25d7c93308e05344a19101612f8e565b6000818152600560205260408120548190819081906060906001600160a01b031661344d57604051630fb532db60e11b815260040160405180910390fd5b60008681526006602090815260408083205460058352928190208054600290910180548351818602810186019094528084526001600160601b0380871696600160601b810490911695600160c01b9091046001600160401b0316946001600160a01b03909416939183918301828280156134f057602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116134d2575b505050505090509450945094509450945091939590929450565b613512613703565b6002546001600160a01b031661353b5760405163c1f0c0a160e01b815260040160405180910390fd5b6002546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a082319060240160206040518083038186803b15801561357f57600080fd5b505afa158015613593573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135b791906155dd565b600a549091506001600160601b0316818111156135f1576040516354ced18160e11b81526004810182905260248101839052604401610c03565b81811015610fe95760006136058284615e1b565b60025460405163a9059cbb60e01b81526001600160a01b0387811660048301526024820184905292935091169063a9059cbb90604401602060405180830381600087803b15801561365557600080fd5b505af1158015613669573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061368d91906155a7565b6136aa57604051631f01ff1360e21b815260040160405180910390fd5b604080516001600160a01b0386168152602081018390527f59bfc682b673f8cbf945f1e454df9334834abf7dfe7f92237ca29ecb9b436600910160405180910390a150505050565b6136fa613703565b610c0c816140a8565b6000546001600160a01b0316331461375d5760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610c03565b565b60008061376b84613cb0565b60025491935091506001600160a01b03161580159061379257506001600160601b03821615155b156138425760025460405163a9059cbb60e01b81526001600160a01b0385811660048301526001600160601b03851660248301529091169063a9059cbb90604401602060405180830381600087803b1580156137ed57600080fd5b505af1158015613801573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061382591906155a7565b61384257604051631e9acf1760e31b815260040160405180910390fd5b6000836001600160a01b0316826001600160601b031660405160006040518083038185875af1925050503d8060008114613898576040519150601f19603f3d011682016040523d82523d6000602084013e61389d565b606091505b50509050806138bf5760405163950b247960e01b815260040160405180910390fd5b604080516001600160a01b03861681526001600160601b038581166020830152841681830152905186917f8c74ce8b8cf87f5eb001275c8be27eb34ea2b62bfab6814fcc62192bb63e81c4919081900360600190a25050505050565b604080516060810182526000808252602082018190529181019190915260006139478460000151612f9c565b6000818152600e60205260409020549091506001600160a01b03168061398357604051631dfd6e1360e21b815260048101839052602401610c03565b60008286608001516040516020016139a5929190918252602082015260400190565b60408051601f19818403018152918152815160209283012060008181526010909352912054909150806139eb57604051631b44092560e11b815260040160405180910390fd5b85516020808801516040808a015160608b015160808c015160a08d01519351613a1a978a979096959101615bf7565b604051602081830303815290604052805190602001208114613a4f5760405163354a450b60e21b815260040160405180910390fd5b6000613a5e8760000151614152565b905080613b36578651604051631d2827a760e31b81526001600160401b0390911660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063e9413d389060240160206040518083038186803b158015613ad057600080fd5b505afa158015613ae4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b0891906155dd565b905080613b3657865160405163175dadad60e01b81526001600160401b039091166004820152602401610c03565b6000886080015182604051602001613b58929190918252602082015260400190565b6040516020818303038152906040528051906020012060001c90506000613b7f8a83614249565b604080516060810182529889526020890196909652948701949094525093979650505050505050565b60005a611388811015613bba57600080fd5b611388810390508460408204820311613bd257600080fd5b50823b613bde57600080fd5b60008083516020850160008789f190505b9392505050565b60008115613c2457601254613c1d9086908690640100000000900463ffffffff16866142b4565b9050613c3e565b601254613c3b908690869063ffffffff168661431e565b90505b949350505050565b6000805b601354811015613ca757826001600160a01b031660138281548110613c7157613c71615f22565b6000918252602090912001546001600160a01b03161415613c955750600192915050565b80613c9f81615e8a565b915050613c4a565b50600092915050565b6000818152600560209081526040808320815160608101835281546001600160a01b03908116825260018301541681850152600282018054845181870281018701865281815287968796949594860193919290830182828015613d3c57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311613d1e575b505050919092525050506000858152600660209081526040808320815160608101835290546001600160601b03808216808452600160601b8304909116948301859052600160c01b9091046001600160401b0316928201929092529096509094509192505b826040015151811015613e19576004600084604001518381518110613dc857613dc8615f22565b6020908102919091018101516001600160a01b0316825281810192909252604090810160009081208982529092529020805467ffffffffffffffff1916905580613e1181615e8a565b915050613da1565b50600085815260056020526040812080546001600160a01b03199081168255600182018054909116905590613e5160028301826151aa565b5050600085815260066020526040812055613e6d60088661440c565b50600a8054859190600090613e8c9084906001600160601b0316615e32565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555082600a600c8282829054906101000a90046001600160601b0316613ed49190615e32565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505050915091565b60408051602081019091526000815281613f2857506040805160208101909152600081526114d2565b63125fa26760e31b613f3a8385615e5a565b6001600160e01b03191614613f6257604051632923fee760e11b815260040160405180910390fd5b613f6f8260048186615d59565b810190613bef91906155f6565b60607f92fd13387c7fe7befbc38d303d6468778fb9731bc4583f17d92989c6fcfdeaaa82604051602401613fb591511515815260200190565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915292915050565b60004661a4b1811480614002575062066eed81145b1561407f5760646001600160a01b031663a3b1b31d6040518163ffffffff1660e01b815260040160206040518083038186803b15801561404157600080fd5b505afa158015614055573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061407991906155dd565b91505090565b4391505090565b6000613bef8383614418565b60006114d2825490565b6000613bef8383614467565b6001600160a01b0381163314156141015760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610c03565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60004661a4b1811480614167575062066eed81145b80614174575062066eee81145b1561423a57610100836001600160401b031661418e613fed565b6141989190615e1b565b11806141b457506141a7613fed565b836001600160401b031610155b156141c25750600092915050565b6040516315a03d4160e11b81526001600160401b0384166004820152606490632b407a829060240160206040518083038186803b15801561420257600080fd5b505afa158015614216573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613bef91906155dd565b50506001600160401b03164090565b600061427d8360000151846020015185604001518660600151868860a001518960c001518a60e001518b6101000151614491565b60038360200151604051602001614295929190615b41565b60408051601f1981840301815291905280516020909101209392505050565b6000806142bf6146bc565b905060005a6142ce8888615d83565b6142d89190615e1b565b6142e29085615dfc565b905060006142fb63ffffffff871664e8d4a51000615dfc565b9050826143088284615d83565b6143129190615d83565b98975050505050505050565b600080614329614718565b90506000811361434f576040516321ea67b360e11b815260048101829052602401610c03565b60006143596146bc565b9050600082825a61436a8b8b615d83565b6143749190615e1b565b61437e9088615dfc565b6143889190615d83565b61439a90670de0b6b3a7640000615dfc565b6143a49190615de8565b905060006143bd63ffffffff881664e8d4a51000615dfc565b90506143d5816b033b2e3c9fd0803ce8000000615e1b565b8211156143f55760405163e80fa38160e01b815260040160405180910390fd5b6143ff8183615d83565b9998505050505050505050565b6000613bef83836147e7565b600081815260018301602052604081205461445f575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556114d2565b5060006114d2565b600082600001828154811061447e5761447e615f22565b9060005260206000200154905092915050565b61449a896148da565b6144e65760405162461bcd60e51b815260206004820152601a60248201527f7075626c6963206b6579206973206e6f74206f6e2063757276650000000000006044820152606401610c03565b6144ef886148da565b61453b5760405162461bcd60e51b815260206004820152601560248201527f67616d6d61206973206e6f74206f6e20637572766500000000000000000000006044820152606401610c03565b614544836148da565b6145905760405162461bcd60e51b815260206004820152601d60248201527f6347616d6d615769746e657373206973206e6f74206f6e2063757276650000006044820152606401610c03565b614599826148da565b6145e55760405162461bcd60e51b815260206004820152601c60248201527f73486173685769746e657373206973206e6f74206f6e206375727665000000006044820152606401610c03565b6145f1878a88876149b3565b61463d5760405162461bcd60e51b815260206004820152601960248201527f6164647228632a706b2b732a6729213d5f755769746e657373000000000000006044820152606401610c03565b60006146498a87614ad6565b9050600061465c898b878b868989614b3a565b9050600061466d838d8d8a86614c5a565b9050808a146146ae5760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b210383937b7b360991b6044820152606401610c03565b505050505050505050505050565b60004661a4b18114806146d1575062066eed81145b1561471057606c6001600160a01b031663c6f7de0e6040518163ffffffff1660e01b815260040160206040518083038186803b15801561404157600080fd5b600091505090565b600d5460035460408051633fabe5a360e21b81529051600093670100000000000000900463ffffffff169283151592859283926001600160a01b03169163feaf968c9160048083019260a0929190829003018186803b15801561477a57600080fd5b505afa15801561478e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906147b29190615873565b5094509092508491505080156147d657506147cd8242615e1b565b8463ffffffff16105b15613c3e5750601154949350505050565b600081815260018301602052604081205480156148d057600061480b600183615e1b565b855490915060009061481f90600190615e1b565b905081811461488457600086600001828154811061483f5761483f615f22565b906000526020600020015490508087600001848154811061486257614862615f22565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061489557614895615f0c565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506114d2565b60009150506114d2565b80516000906401000003d019116149335760405162461bcd60e51b815260206004820152601260248201527f696e76616c696420782d6f7264696e61746500000000000000000000000000006044820152606401610c03565b60208201516401000003d0191161498c5760405162461bcd60e51b815260206004820152601260248201527f696e76616c696420792d6f7264696e61746500000000000000000000000000006044820152606401610c03565b60208201516401000003d0199080096149ac8360005b6020020151614c9a565b1492915050565b60006001600160a01b0382166149f95760405162461bcd60e51b815260206004820152600b60248201526a626164207769746e65737360a81b6044820152606401610c03565b602084015160009060011615614a1057601c614a13565b601b5b9050600070014551231950b75fc4402da1732fc9bebe1985876000602002015109865170014551231950b75fc4402da1732fc9bebe19918203925060009190890987516040805160008082526020820180845287905260ff88169282019290925260608101929092526080820183905291925060019060a0016020604051602081039080840390855afa158015614aae573d6000803e3d6000fd5b5050604051601f1901516001600160a01b039081169088161495505050505050949350505050565b614ade6151c8565b614b0b60018484604051602001614af793929190615a18565b604051602081830303815290604052614cbe565b90505b614b17816148da565b6114d2578051604080516020810192909252614b339101614af7565b9050614b0e565b614b426151c8565b825186516401000003d0199081900691061415614ba15760405162461bcd60e51b815260206004820152601e60248201527f706f696e747320696e2073756d206d7573742062652064697374696e637400006044820152606401610c03565b614bac878988614d0c565b614bf85760405162461bcd60e51b815260206004820152601660248201527f4669727374206d756c20636865636b206661696c6564000000000000000000006044820152606401610c03565b614c03848685614d0c565b614c4f5760405162461bcd60e51b815260206004820152601760248201527f5365636f6e64206d756c20636865636b206661696c65640000000000000000006044820152606401610c03565b614312868484614e34565b600060028686868587604051602001614c78969594939291906159b9565b60408051601f1981840301815291905280516020909101209695505050505050565b6000806401000003d01980848509840990506401000003d019600782089392505050565b614cc66151c8565b614ccf82614efb565b8152614ce4614cdf8260006149a2565b614f36565b6020820181905260029006600114156125e8576020810180516401000003d019039052919050565b600082614d495760405162461bcd60e51b815260206004820152600b60248201526a3d32b9379039b1b0b630b960a91b6044820152606401610c03565b83516020850151600090614d5f90600290615ecc565b15614d6b57601c614d6e565b601b5b9050600070014551231950b75fc4402da1732fc9bebe198387096040805160008082526020820180845281905260ff86169282019290925260608101869052608081018390529192509060019060a0016020604051602081039080840390855afa158015614de0573d6000803e3d6000fd5b505050602060405103519050600086604051602001614dff91906159a7565b60408051601f1981840301815291905280516020909101206001600160a01b0392831692169190911498975050505050505050565b614e3c6151c8565b835160208086015185519186015160009384938493614e5d93909190614f56565b919450925090506401000003d019858209600114614ebd5760405162461bcd60e51b815260206004820152601960248201527f696e765a206d75737420626520696e7665727365206f66207a000000000000006044820152606401610c03565b60405180604001604052806401000003d01980614edc57614edc615ef6565b87860981526020016401000003d0198785099052979650505050505050565b805160208201205b6401000003d01981106125e857604080516020808201939093528151808203840181529082019091528051910120614f03565b60006114d2826002614f4f6401000003d0196001615d83565b901c615036565b60008080600180826401000003d019896401000003d019038808905060006401000003d0198b6401000003d019038a0890506000614f96838385856150d8565b9098509050614fa788828e886150fc565b9098509050614fb888828c876150fc565b90985090506000614fcb8d878b856150fc565b9098509050614fdc888286866150d8565b9098509050614fed88828e896150fc565b9098509050818114615022576401000003d019818a0998506401000003d01982890997506401000003d0198183099650615026565b8196505b5050505050509450945094915050565b6000806150416151e6565b6020808252818101819052604082015260608101859052608081018490526401000003d01960a0820152615073615204565b60208160c0846005600019fa9250826150ce5760405162461bcd60e51b815260206004820152601260248201527f6269674d6f64457870206661696c7572652100000000000000000000000000006044820152606401610c03565b5195945050505050565b6000806401000003d0198487096401000003d0198487099097909650945050505050565b600080806401000003d019878509905060006401000003d01987876401000003d019030990506401000003d0198183086401000003d01986890990999098509650505050505050565b82805482825590600052602060002090810192821561519a579160200282015b8281111561519a57825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190615165565b506151a6929150615222565b5090565b5080546000825590600052602060002090810190610c0c9190615222565b60405180604001604052806002906020820280368337509192915050565b6040518060c001604052806006906020820280368337509192915050565b60405180602001604052806001906020820280368337509192915050565b5b808211156151a65760008155600101615223565b80356125e881615f4e565b80604081018310156114d257600080fd5b600082601f83011261526457600080fd5b61526c615cec565b80838560408601111561527e57600080fd5b60005b60028110156152a0578135845260209384019390910190600101615281565b509095945050505050565b600082601f8301126152bc57600080fd5b81356001600160401b03808211156152d6576152d6615f38565b604051601f8301601f19908116603f011681019082821181831017156152fe576152fe615f38565b8160405283815286602085880101111561531757600080fd5b836020870160208301376000602085830101528094505050505092915050565b600060c0828403121561534957600080fd5b615351615d14565b905081356001600160401b03808216821461536b57600080fd5b81835260208401356020840152615384604085016153ea565b6040840152615395606085016153ea565b60608401526153a660808501615237565b608084015260a08401359150808211156153bf57600080fd5b506153cc848285016152ab565b60a08301525092915050565b803561ffff811681146125e857600080fd5b803563ffffffff811681146125e857600080fd5b805169ffffffffffffffffffff811681146125e857600080fd5b80356001600160601b03811681146125e857600080fd5b60006020828403121561544157600080fd5b8135613bef81615f4e565b6000806040838503121561545f57600080fd5b823561546a81615f4e565b915061547860208401615418565b90509250929050565b6000806040838503121561549457600080fd5b823561549f81615f4e565b915060208301356154af81615f4e565b809150509250929050565b600080606083850312156154cd57600080fd5b82356154d881615f4e565b91506154788460208501615242565b600080600080606085870312156154fd57600080fd5b843561550881615f4e565b93506020850135925060408501356001600160401b038082111561552b57600080fd5b818701915087601f83011261553f57600080fd5b81358181111561554e57600080fd5b88602082850101111561556057600080fd5b95989497505060200194505050565b60006040828403121561558157600080fd5b613bef8383615242565b60006040828403121561559d57600080fd5b613bef8383615253565b6000602082840312156155b957600080fd5b8151613bef81615f63565b6000602082840312156155d657600080fd5b5035919050565b6000602082840312156155ef57600080fd5b5051919050565b60006020828403121561560857600080fd5b604051602081018181106001600160401b038211171561562a5761562a615f38565b604052823561563881615f63565b81529392505050565b6000808284036101c081121561565657600080fd5b6101a08082121561566657600080fd5b61566e615d36565b915061567a8686615253565b82526156898660408701615253565b60208301526080850135604083015260a0850135606083015260c085013560808301526156b860e08601615237565b60a08301526101006156cc87828801615253565b60c08401526156df876101408801615253565b60e0840152610180860135908301529092508301356001600160401b0381111561570857600080fd5b61571485828601615337565b9150509250929050565b60006020828403121561573057600080fd5b81356001600160401b0381111561574657600080fd5b820160c08185031215613bef57600080fd5b60006020828403121561576a57600080fd5b613bef826153d8565b60008060008060008086880360e081121561578d57600080fd5b615796886153d8565b96506157a4602089016153ea565b95506157b2604089016153ea565b94506157c0606089016153ea565b9350608088013592506040609f19820112156157db57600080fd5b506157e4615cec565b6157f060a089016153ea565b81526157fe60c089016153ea565b6020820152809150509295509295509295565b6000806040838503121561582457600080fd5b8235915060208301356154af81615f4e565b6000806040838503121561584957600080fd5b50508035926020909101359150565b60006020828403121561586a57600080fd5b613bef826153ea565b600080600080600060a0868803121561588b57600080fd5b615894866153fe565b94506020860151935060408601519250606086015191506158b7608087016153fe565b90509295509295909350565b600081518084526020808501945080840160005b838110156158fc5781516001600160a01b0316875295820195908201906001016158d7565b509495945050505050565b8060005b6002811015610e6b57815184526020938401939091019060010161590b565b600081518084526020808501945080840160005b838110156158fc5781518752958201959082019060010161593e565b6000815180845260005b8181101561598057602081850181015186830182015201615964565b81811115615992576000602083870101525b50601f01601f19169290920160200192915050565b6159b18183615907565b604001919050565b8681526159c96020820187615907565b6159d66060820186615907565b6159e360a0820185615907565b6159f060e0820184615907565b60609190911b6bffffffffffffffffffffffff19166101208201526101340195945050505050565b838152615a286020820184615907565b606081019190915260800192915050565b604081016114d28284615907565b602081526000613bef602083018461592a565b602081526000613bef602083018461595a565b6020815260ff8251166020820152602082015160408201526001600160a01b0360408301511660608201526000606083015160c06080840152615ab360e08401826158c3565b905060808401516001600160601b0380821660a08601528060a08701511660c086015250508091505092915050565b60006060820161ffff86168352602063ffffffff86168185015260606040850152818551808452608086019150828701935060005b81811015615b3357845183529383019391830191600101615b17565b509098975050505050505050565b82815260608101613bef6020830184615907565b828152604060208201526000613c3e604083018461592a565b86815285602082015261ffff85166040820152600063ffffffff808616606084015280851660808401525060c060a083015261431260c083018461595a565b878152866020820152856040820152600063ffffffff80871660608401528086166080840152506001600160a01b03841660a083015260e060c08301526143ff60e083018461595a565b8781526001600160401b0387166020820152856040820152600063ffffffff80871660608401528086166080840152506001600160a01b03841660a083015260e060c08301526143ff60e083018461595a565b60006001600160601b0380881683528087166020840152506001600160401b03851660408301526001600160a01b038416606083015260a06080830152615c9460a08301846158c3565b979650505050505050565b6000808335601e19843603018112615cb657600080fd5b8301803591506001600160401b03821115615cd057600080fd5b602001915036819003821315615ce557600080fd5b9250929050565b604080519081016001600160401b0381118282101715615d0e57615d0e615f38565b60405290565b60405160c081016001600160401b0381118282101715615d0e57615d0e615f38565b60405161012081016001600160401b0381118282101715615d0e57615d0e615f38565b60008085851115615d6957600080fd5b83861115615d7657600080fd5b5050820193919092039150565b60008219821115615d9657615d96615ee0565b500190565b60006001600160401b03808316818516808303821115615dbd57615dbd615ee0565b01949350505050565b60006001600160601b03808316818516808303821115615dbd57615dbd615ee0565b600082615df757615df7615ef6565b500490565b6000816000190483118215151615615e1657615e16615ee0565b500290565b600082821015615e2d57615e2d615ee0565b500390565b60006001600160601b0383811690831681811015615e5257615e52615ee0565b039392505050565b6001600160e01b03198135818116916004851015615e825780818660040360031b1b83161692505b505092915050565b6000600019821415615e9e57615e9e615ee0565b5060010190565b60006001600160401b0380831681811415615ec257615ec2615ee0565b6001019392505050565b600082615edb57615edb615ef6565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114610c0c57600080fd5b8015158114610c0c57600080fdfea164736f6c6343000806000a",
+}
+
+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 93faeada261..dd7865fe8aa 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\":[{\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"}],\"name\":\"fulfillRandomWords\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"requestID\",\"type\":\"uint256\"}],\"name\":\"generateFakeRandomness\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"getSubscription\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"consumers\",\"type\":\"address[]\"},{\"internalType\":\"uint96\",\"name\":\"linkBalance\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"nativeBalance\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedData\",\"type\":\"bytes\"}],\"name\":\"onMigration\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"requestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"numWords\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structVRFV2PlusClient.RandomWordsRequest\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"requestRandomWords\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_link\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_prevCoordinator\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_requestConsumerMapping\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_requestId\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_subscriptions\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"linkBalance\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"nativeBalance\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_totalLinkBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_totalNativeBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]",
- Bin: "0x6080604052600060035534801561001557600080fd5b50604051610f65380380610f6583398101604081905261003491610081565b600580546001600160a01b039384166001600160a01b031991821617909155600480549290931691161790556100b4565b80516001600160a01b038116811461007c57600080fd5b919050565b6000806040838503121561009457600080fd5b61009d83610065565b91506100ab60208401610065565b90509250929050565b610ea2806100c36000396000f3fe6080604052600436106100c75760003560e01c8063ce3f471911610074578063dc311dd31161004e578063dc311dd314610325578063e89e106a14610355578063ed8b558f1461036b57600080fd5b8063ce3f4719146102c3578063d6100d1c146102d8578063da4f5e6d146102f857600080fd5b806386175f58116100a557806386175f581461022557806393f3acb6146102685780639b1c385e1461029557600080fd5b80630495f265146100cc578063086597b31461018157806318e3dd27146101d3575b600080fd5b3480156100d857600080fd5b5061013b6100e7366004610c86565b6000602081905290815260409020805460029091015473ffffffffffffffffffffffffffffffffffffffff909116906bffffffffffffffffffffffff808216916c0100000000000000000000000090041683565b6040805173ffffffffffffffffffffffffffffffffffffffff90941684526bffffffffffffffffffffffff92831660208501529116908201526060015b60405180910390f35b34801561018d57600080fd5b506004546101ae9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610178565b3480156101df57600080fd5b50600254610208906c0100000000000000000000000090046bffffffffffffffffffffffff1681565b6040516bffffffffffffffffffffffff9091168152602001610178565b34801561023157600080fd5b506101ae610240366004610c86565b60016020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b34801561027457600080fd5b50610288610283366004610c86565b610390565b6040516101789190610d63565b3480156102a157600080fd5b506102b56102b0366004610b81565b61043b565b604051908152602001610178565b6102d66102d1366004610b0f565b61044c565b005b3480156102e457600080fd5b506102d66102f3366004610c86565b610746565b34801561030457600080fd5b506005546101ae9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561033157600080fd5b50610345610340366004610c86565b6107ce565b6040516101789493929190610cda565b34801561036157600080fd5b506102b560035481565b34801561037757600080fd5b50600254610208906bffffffffffffffffffffffff1681565b6040805160018082528183019092526060916000919060208083019080368337019050509050826040516020016103fe918152604060208201819052600a908201527f6e6f742072616e646f6d00000000000000000000000000000000000000000000606082015260800190565b6040516020818303038152906040528051906020012060001c8160008151811061042a5761042a610e37565b602090810291909101015292915050565b6000610446336108f9565b92915050565b60045473ffffffffffffffffffffffffffffffffffffffff1633146104c557600480546040517ff5828f73000000000000000000000000000000000000000000000000000000008152339281019290925273ffffffffffffffffffffffffffffffffffffffff1660248201526044015b60405180910390fd5b60006104d382840184610bc3565b9050806000015160ff166001146105255780516040517f8df4607c00000000000000000000000000000000000000000000000000000000815260ff9091166004820152600160248201526044016104bc565b8060a001516bffffffffffffffffffffffff16341461058c5760a08101516040517f6acf13500000000000000000000000000000000000000000000000000000000081523460048201526bffffffffffffffffffffffff90911660248201526044016104bc565b60408051608080820183528383015173ffffffffffffffffffffffffffffffffffffffff90811683526060808601516020808601918252938701516bffffffffffffffffffffffff9081168688015260a0880151169185019190915282860151600090815280845294909420835181547fffffffffffffffffffffffff00000000000000000000000000000000000000001692169190911781559251805192939261063d9260018501920190610965565b506040820151600291820180546060909401516bffffffffffffffffffffffff9283167fffffffffffffffff000000000000000000000000000000000000000000000000909516949094176c01000000000000000000000000948316850217905560a084015182549093600c926106b8928692900416610dd8565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508060800151600260008282829054906101000a90046bffffffffffffffffffffffff166107139190610dd8565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550505050565b60008181526001602052604090205473ffffffffffffffffffffffffffffffffffffffff1680631fe543e38361077b81610390565b6040518363ffffffff1660e01b8152600401610798929190610d76565b600060405180830381600087803b1580156107b257600080fd5b505af11580156107c6573d6000803e3d6000fd5b505050505050565b6000818152602081905260408120546060908290819073ffffffffffffffffffffffffffffffffffffffff16610830576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008581526020818152604091829020805460028201546001909201805485518186028101860190965280865273ffffffffffffffffffffffffffffffffffffffff9092169490936bffffffffffffffffffffffff808516946c010000000000000000000000009004169285918301828280156108e357602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff1681526001909101906020018083116108b8575b5050505050925093509350935093509193509193565b6000600354600161090a9190610dc0565b6003819055600081815260016020526040902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff94909416939093179092555090565b8280548282559060005260206000209081019282156109df579160200282015b828111156109df57825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909116178255602090920191600190910190610985565b506109eb9291506109ef565b5090565b5b808211156109eb57600081556001016109f0565b803573ffffffffffffffffffffffffffffffffffffffff81168114610a2857600080fd5b919050565b600082601f830112610a3e57600080fd5b8135602067ffffffffffffffff80831115610a5b57610a5b610e66565b8260051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f83011681018181108482111715610a9e57610a9e610e66565b60405284815283810192508684018288018501891015610abd57600080fd5b600092505b85831015610ae757610ad381610a04565b845292840192600192909201918401610ac2565b50979650505050505050565b80356bffffffffffffffffffffffff81168114610a2857600080fd5b60008060208385031215610b2257600080fd5b823567ffffffffffffffff80821115610b3a57600080fd5b818501915085601f830112610b4e57600080fd5b813581811115610b5d57600080fd5b866020828501011115610b6f57600080fd5b60209290920196919550909350505050565b600060208284031215610b9357600080fd5b813567ffffffffffffffff811115610baa57600080fd5b820160c08185031215610bbc57600080fd5b9392505050565b600060208284031215610bd557600080fd5b813567ffffffffffffffff80821115610bed57600080fd5b9083019060c08286031215610c0157600080fd5b610c09610d97565b823560ff81168114610c1a57600080fd5b815260208381013590820152610c3260408401610a04565b6040820152606083013582811115610c4957600080fd5b610c5587828601610a2d565b606083015250610c6760808401610af3565b6080820152610c7860a08401610af3565b60a082015295945050505050565b600060208284031215610c9857600080fd5b5035919050565b600081518084526020808501945080840160005b83811015610ccf57815187529582019590820190600101610cb3565b509495945050505050565b60006080820173ffffffffffffffffffffffffffffffffffffffff8088168452602060808186015282885180855260a087019150828a01945060005b81811015610d34578551851683529483019491830191600101610d16565b50506bffffffffffffffffffffffff978816604087015295909616606090940193909352509195945050505050565b602081526000610bbc6020830184610c9f565b828152604060208201526000610d8f6040830184610c9f565b949350505050565b60405160c0810167ffffffffffffffff81118282101715610dba57610dba610e66565b60405290565b60008219821115610dd357610dd3610e08565b500190565b60006bffffffffffffffffffffffff808316818516808303821115610dff57610dff610e08565b01949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fdfea164736f6c6343000806000a",
+ 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 f4f52e85382..00000000000
--- 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\":[{\"internalType\":\"uint32\",\"name\":\"have\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"want\",\"type\":\"uint32\"}],\"name\":\"GasLimitTooBig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectCommitment\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IndexOutOfRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"have\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"want\",\"type\":\"uint256\"}],\"name\":\"InsufficientGasForConsumer\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidCalldata\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"InvalidConsumer\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidExtraArgsTag\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"linkWei\",\"type\":\"int256\"}],\"name\":\"InvalidLinkWeiPrice\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"have\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"min\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"max\",\"type\":\"uint16\"}],\"name\":\"InvalidRequestConfirmations\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSubscription\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LinkAlreadySet\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"proposedOwner\",\"type\":\"address\"}],\"name\":\"MustBeRequestedOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"MustBeSubOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoCorrespondingRequest\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"}],\"name\":\"NoSuchProvingKey\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"have\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"want\",\"type\":\"uint32\"}],\"name\":\"NumWordsTooBig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableFromLink\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PaymentTooLarge\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PendingRequestExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"}],\"name\":\"ProvingKeyAlreadyRegistered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Reentrant\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyConsumers\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"minimumRequestConfirmations\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"maxGasLimit\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"stalenessSeconds\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"gasAfterPaymentCalculation\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"int256\",\"name\":\"fallbackWeiPerUnitLink\",\"type\":\"int256\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkPPM\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeEthPPM\",\"type\":\"uint32\"}],\"indexed\":false,\"internalType\":\"structVRFCoordinatorV2Plus.FeeConfig\",\"name\":\"feeConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"coordinatorAddress\",\"type\":\"address\"}],\"name\":\"CoordinatorDeregistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"coordinatorAddress\",\"type\":\"address\"}],\"name\":\"CoordinatorRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"EthFundsRecovered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FundsRecovered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newCoordinator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"MigrationCompleted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"oracle\",\"type\":\"address\"}],\"name\":\"ProvingKeyDeregistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"oracle\",\"type\":\"address\"}],\"name\":\"ProvingKeyRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"outputSeed\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"payment\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"name\":\"RandomWordsFulfilled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"preSeed\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"minimumRequestConfirmations\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"numWords\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"RandomWordsRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountLink\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountEth\",\"type\":\"uint256\"}],\"name\":\"SubscriptionCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"SubscriptionConsumerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"SubscriptionConsumerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"SubscriptionCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newBalance\",\"type\":\"uint256\"}],\"name\":\"SubscriptionFunded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldEthBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newEthBalance\",\"type\":\"uint256\"}],\"name\":\"SubscriptionFundedWithEth\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"SubscriptionOwnerTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"SubscriptionOwnerTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BLOCKHASH_STORE\",\"outputs\":[{\"internalType\":\"contractBlockhashStoreInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"LINK\",\"outputs\":[{\"internalType\":\"contractLinkTokenInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"LINK_ETH_FEED\",\"outputs\":[{\"internalType\":\"contractAggregatorV3Interface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAX_CONSUMERS\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAX_NUM_WORDS\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAX_REQUEST_CONFIRMATIONS\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"acceptSubscriptionOwnerTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"addConsumer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"cancelSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"createSubscription\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"}],\"name\":\"deregisterMigratableCoordinator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[2]\",\"name\":\"publicProvingKey\",\"type\":\"uint256[2]\"}],\"name\":\"deregisterProvingKey\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256[2]\",\"name\":\"pk\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256[2]\",\"name\":\"gamma\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256\",\"name\":\"c\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"s\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"seed\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"uWitness\",\"type\":\"address\"},{\"internalType\":\"uint256[2]\",\"name\":\"cGammaWitness\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256[2]\",\"name\":\"sHashWitness\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256\",\"name\":\"zInv\",\"type\":\"uint256\"}],\"internalType\":\"structVRF.Proof\",\"name\":\"proof\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"blockNum\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"numWords\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structVRFCoordinatorV2Plus.RequestCommitment\",\"name\":\"rc\",\"type\":\"tuple\"}],\"name\":\"fulfillRandomWords\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"fundSubscriptionWithEth\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"startIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxCount\",\"type\":\"uint256\"}],\"name\":\"getActiveSubscriptionIds\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRequestConfig\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"},{\"internalType\":\"bytes32[]\",\"name\":\"\",\"type\":\"bytes32[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"getSubscription\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"ethBalance\",\"type\":\"uint96\"},{\"internalType\":\"uint64\",\"name\":\"reqCount\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"consumers\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[2]\",\"name\":\"publicKey\",\"type\":\"uint256[2]\"}],\"name\":\"hashOfKey\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"newCoordinator\",\"type\":\"address\"}],\"name\":\"migrate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"migrationVersion\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"onTokenTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"oracleWithdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"addresspayable\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"oracleWithdrawEth\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"ownerCancelSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"pendingRequestExists\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"addresspayable\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"recoverEthFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"recoverFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"}],\"name\":\"registerMigratableCoordinator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"oracle\",\"type\":\"address\"},{\"internalType\":\"uint256[2]\",\"name\":\"publicProvingKey\",\"type\":\"uint256[2]\"}],\"name\":\"registerProvingKey\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"removeConsumer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"requestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"numWords\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structVRFV2PlusClient.RandomWordsRequest\",\"name\":\"req\",\"type\":\"tuple\"}],\"name\":\"requestRandomWords\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"requestSubscriptionOwnerTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_config\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"minimumRequestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"reentrancyLock\",\"type\":\"bool\"},{\"internalType\":\"uint32\",\"name\":\"stalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasAfterPaymentCalculation\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_currentSubNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_fallbackWeiPerUnitLink\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_feeConfig\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkPPM\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeEthPPM\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_provingKeyHashes\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"s_provingKeys\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_requestCommitments\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_totalBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_totalEthBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"minimumRequestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"stalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasAfterPaymentCalculation\",\"type\":\"uint32\"},{\"internalType\":\"int256\",\"name\":\"fallbackWeiPerUnitLink\",\"type\":\"int256\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkPPM\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeEthPPM\",\"type\":\"uint32\"}],\"internalType\":\"structVRFCoordinatorV2Plus.FeeConfig\",\"name\":\"feeConfig\",\"type\":\"tuple\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"link\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"linkEthFeed\",\"type\":\"address\"}],\"name\":\"setLINKAndLINKETHFeed\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]",
- Bin: "0x60a06040523480156200001157600080fd5b506040516200604038038062006040833981016040819052620000349162000183565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000d7565b50505060601b6001600160601b031916608052620001b5565b6001600160a01b038116331415620001325760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000602082840312156200019657600080fd5b81516001600160a01b0381168114620001ae57600080fd5b9392505050565b60805160601c615e65620001db600039600081816105ee015261397a0152615e656000f3fe6080604052600436106102dc5760003560e01c80638da5cb5b1161017f578063bec4c08c116100e1578063dc311dd31161008a578063e95704bd11610064578063e95704bd1461095d578063ee9d2d3814610984578063f2fde38b146109b157600080fd5b8063dc311dd3146108f9578063e72f6e301461092a578063e8509bff1461094a57600080fd5b8063d98e620e116100bb578063d98e620e14610883578063da2f2610146108a3578063dac83d29146108d957600080fd5b8063bec4c08c14610823578063caf70c4a14610843578063cb6317971461086357600080fd5b8063a8cb447b11610143578063aefb212f1161011d578063aefb212f146107b6578063b08c8795146107e3578063b2a7cac51461080357600080fd5b8063a8cb447b14610756578063aa433aff14610776578063ad1783611461079657600080fd5b80638da5cb5b146106ab5780639b1c385e146106c95780639d40a6fd146106e9578063a21a23e414610721578063a4c0ed361461073657600080fd5b806340d6bb821161024357806366316d8d116101ec5780636f64f03f116101c65780636f64f03f1461065657806379ba50971461067657806386fe91c71461068b57600080fd5b806366316d8d146105bc578063689c4517146105dc5780636b6feccc1461061057600080fd5b806357133e641161021d57806357133e64146105675780635d06b4ab1461058757806364d51a2a146105a757600080fd5b806340d6bb82146104ec57806341af6c871461051757806346d8d4861461054757600080fd5b80630ae09540116102a5578063294daa491161027f578063294daa4914610478578063330987b314610494578063405b84fa146104cc57600080fd5b80630ae09540146103f857806315c48b84146104185780631b6b6d231461044057600080fd5b8062012291146102e157806304104edb1461030e578063043bd6ae14610330578063088070f51461035457806308821d58146103d8575b600080fd5b3480156102ed57600080fd5b506102f66109d1565b604051610305939291906159c9565b60405180910390f35b34801561031a57600080fd5b5061032e610329366004615316565b610a4d565b005b34801561033c57600080fd5b5061034660115481565b604051908152602001610305565b34801561036057600080fd5b50600d546103a09061ffff81169063ffffffff62010000820481169160ff600160301b820416916701000000000000008204811691600160581b90041685565b6040805161ffff909616865263ffffffff9485166020870152921515928501929092528216606084015216608082015260a001610305565b3480156103e457600080fd5b5061032e6103f3366004615456565b610c0f565b34801561040457600080fd5b5061032e6104133660046156f8565b610da3565b34801561042457600080fd5b5061042d60c881565b60405161ffff9091168152602001610305565b34801561044c57600080fd5b50600254610460906001600160a01b031681565b6040516001600160a01b039091168152602001610305565b34801561048457600080fd5b5060405160018152602001610305565b3480156104a057600080fd5b506104b46104af366004615528565b610e71565b6040516001600160601b039091168152602001610305565b3480156104d857600080fd5b5061032e6104e73660046156f8565b61135b565b3480156104f857600080fd5b506105026101f481565b60405163ffffffff9091168152602001610305565b34801561052357600080fd5b506105376105323660046154ab565b611709565b6040519015158152602001610305565b34801561055357600080fd5b5061032e610562366004615333565b61190a565b34801561057357600080fd5b5061032e610582366004615368565b611a87565b34801561059357600080fd5b5061032e6105a2366004615316565b611ae7565b3480156105b357600080fd5b5061042d606481565b3480156105c857600080fd5b5061032e6105d7366004615333565b611ba5565b3480156105e857600080fd5b506104607f000000000000000000000000000000000000000000000000000000000000000081565b34801561061c57600080fd5b506012546106399063ffffffff8082169164010000000090041682565b6040805163ffffffff938416815292909116602083015201610305565b34801561066257600080fd5b5061032e6106713660046153a1565b611d44565b34801561068257600080fd5b5061032e611e43565b34801561069757600080fd5b50600a546104b4906001600160601b031681565b3480156106b757600080fd5b506000546001600160a01b0316610460565b3480156106d557600080fd5b506103466106e4366004615605565b611ef4565b3480156106f557600080fd5b50600754610709906001600160401b031681565b6040516001600160401b039091168152602001610305565b34801561072d57600080fd5b506103466122e9565b34801561074257600080fd5b5061032e6107513660046153ce565b612539565b34801561076257600080fd5b5061032e610771366004615316565b6126d9565b34801561078257600080fd5b5061032e6107913660046154ab565b6127f4565b3480156107a257600080fd5b50600354610460906001600160a01b031681565b3480156107c257600080fd5b506107d66107d136600461571d565b612854565b604051610305919061592e565b3480156107ef57600080fd5b5061032e6107fe36600461565a565b612955565b34801561080f57600080fd5b5061032e61081e3660046154ab565b612ae9565b34801561082f57600080fd5b5061032e61083e3660046156f8565b612c1f565b34801561084f57600080fd5b5061034661085e366004615472565b612dbb565b34801561086f57600080fd5b5061032e61087e3660046156f8565b612deb565b34801561088f57600080fd5b5061034661089e3660046154ab565b6130ee565b3480156108af57600080fd5b506104606108be3660046154ab565b600e602052600090815260409020546001600160a01b031681565b3480156108e557600080fd5b5061032e6108f43660046156f8565b61310f565b34801561090557600080fd5b506109196109143660046154ab565b61322e565b604051610305959493929190615b31565b34801561093657600080fd5b5061032e610945366004615316565b613329565b61032e6109583660046154ab565b6134cc565b34801561096957600080fd5b50600a546104b490600160601b90046001600160601b031681565b34801561099057600080fd5b5061034661099f3660046154ab565b60106020526000908152604090205481565b3480156109bd57600080fd5b5061032e6109cc366004615316565b61360b565b600d54600f805460408051602080840282018101909252828152600094859460609461ffff8316946201000090930463ffffffff16939192839190830182828015610a3b57602002820191906000526020600020905b815481526020019060010190808311610a27575b50505050509050925092509250909192565b610a5561361c565b60135460005b81811015610be257826001600160a01b031660138281548110610a8057610a80615e09565b6000918252602090912001546001600160a01b03161415610bd0576013610aa8600184615d02565b81548110610ab857610ab8615e09565b600091825260209091200154601380546001600160a01b039092169183908110610ae457610ae4615e09565b600091825260209091200180546001600160a01b0319166001600160a01b0392909216919091179055826013610b1b600185615d02565b81548110610b2b57610b2b615e09565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506013805480610b6a57610b6a615df3565b6000828152602090819020600019908301810180546001600160a01b03191690559091019091556040516001600160a01b03851681527ff80a1a97fd42251f3c33cda98635e7399253033a6774fe37cd3f650b5282af37910160405180910390a1505050565b80610bda81615d71565b915050610a5b565b50604051635428d44960e01b81526001600160a01b03831660048201526024015b60405180910390fd5b50565b610c1761361c565b604080518082018252600091610c46919084906002908390839080828437600092019190915250612dbb915050565b6000818152600e60205260409020549091506001600160a01b031680610c8257604051631dfd6e1360e21b815260048101839052602401610c03565b6000828152600e6020526040812080546001600160a01b03191690555b600f54811015610d5a5782600f8281548110610cbd57610cbd615e09565b90600052602060002001541415610d4857600f805460009190610ce290600190615d02565b81548110610cf257610cf2615e09565b9060005260206000200154905080600f8381548110610d1357610d13615e09565b600091825260209091200155600f805480610d3057610d30615df3565b60019003818190600052602060002001600090559055505b80610d5281615d71565b915050610c9f565b50806001600160a01b03167f72be339577868f868798bac2c93e52d6f034fef4689a9848996c14ebb7416c0d83604051610d9691815260200190565b60405180910390a2505050565b60008281526005602052604090205482906001600160a01b031680610ddb57604051630fb532db60e11b815260040160405180910390fd5b336001600160a01b03821614610e0f57604051636c51fda960e11b81526001600160a01b0382166004820152602401610c03565b600d54600160301b900460ff1615610e3a5760405163769dd35360e11b815260040160405180910390fd5b610e4384611709565b15610e6157604051631685ecdd60e31b815260040160405180910390fd5b610e6b8484613678565b50505050565b600d54600090600160301b900460ff1615610e9f5760405163769dd35360e11b815260040160405180910390fd5b60005a90506000610eb0858561380f565b90506000846060015163ffffffff166001600160401b03811115610ed657610ed6615e1f565b604051908082528060200260200182016040528015610eff578160200160208202803683370190505b50905060005b856060015163ffffffff16811015610f7f57826040015181604051602001610f37929190918252602082015260400190565b6040516020818303038152906040528051906020012060001c828281518110610f6257610f62615e09565b602090810291909101015280610f7781615d71565b915050610f05565b5060208083018051600090815260109092526040808320839055905190518291631fe543e360e01b91610fb791908690602401615a3c565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252600d805466ff0000000000001916600160301b17905590880151608089015191925060009161101f9163ffffffff169084613a9c565b600d805466ff00000000000019169055602089810151600090815260069091526040902054909150600160c01b90046001600160401b0316611062816001615c82565b6020808b0151600090815260069091526040812080546001600160401b0393909316600160c01b026001600160c01b039093169290921790915560a08a015180516110af90600190615d02565b815181106110bf576110bf615e09565b602091010151600d5460f89190911c60011491506000906110f0908a90600160581b900463ffffffff163a85613aea565b905081156111f9576020808c01516000908152600690915260409020546001600160601b03808316600160601b90920416101561114057604051631e9acf1760e31b815260040160405180910390fd5b60208b81015160009081526006909152604090208054829190600c90611177908490600160601b90046001600160601b0316615d19565b82546101009290920a6001600160601b0381810219909316918316021790915589516000908152600e60209081526040808320546001600160a01b03168352600c9091528120805485945090926111d091859116615cad565b92506101000a8154816001600160601b0302191690836001600160601b031602179055506112e5565b6020808c01516000908152600690915260409020546001600160601b038083169116101561123a57604051631e9acf1760e31b815260040160405180910390fd5b6020808c0151600090815260069091526040812080548392906112679084906001600160601b0316615d19565b82546101009290920a6001600160601b0381810219909316918316021790915589516000908152600e60209081526040808320546001600160a01b03168352600b9091528120805485945090926112c091859116615cad565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505b8a6020015188602001517f49580fdfd9497e1ed5c1b1cec0495087ae8e3f1267470ec2fb015db32e3d6aa78a604001518488604051611342939291909283526001600160601b039190911660208301521515604082015260600190565b60405180910390a3985050505050505050505b92915050565b61136481613b3a565b61138c57604051635428d44960e01b81526001600160a01b0382166004820152602401610c03565b60008060008061139b8661322e565b945094505093509350336001600160a01b0316826001600160a01b0316146114055760405162461bcd60e51b815260206004820152601660248201527f4e6f7420737562736372697074696f6e206f776e6572000000000000000000006044820152606401610c03565b61140e86611709565b1561145b5760405162461bcd60e51b815260206004820152601660248201527f50656e64696e67207265717565737420657869737473000000000000000000006044820152606401610c03565b60006040518060c00160405280611470600190565b60ff168152602001888152602001846001600160a01b03168152602001838152602001866001600160601b03168152602001856001600160601b031681525090506000816040516020016114c49190615954565b60405160208183030381529060405290506114de88613ba4565b505060405163ce3f471960e01b81526001600160a01b0388169063ce3f4719906001600160601b03881690611517908590600401615941565b6000604051808303818588803b15801561153057600080fd5b505af1158015611544573d6000803e3d6000fd5b505060025460405163a9059cbb60e01b81526001600160a01b038c811660048301526001600160601b038c166024830152909116935063a9059cbb92506044019050602060405180830381600087803b1580156115a057600080fd5b505af11580156115b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115d8919061548e565b6116245760405162461bcd60e51b815260206004820152601260248201527f696e73756666696369656e742066756e647300000000000000000000000000006044820152606401610c03565b60005b83518110156116bc5783818151811061164257611642615e09565b6020908102919091010151604051638ea9811760e01b81526001600160a01b038a8116600483015290911690638ea9811790602401600060405180830381600087803b15801561169157600080fd5b505af11580156116a5573d6000803e3d6000fd5b5050505080806116b490615d71565b915050611627565b50604080516001600160a01b0389168152602081018a90527fd63ca8cb945956747ee69bfdc3ea754c24a4caf7418db70e46052f7850be4187910160405180910390a15050505050505050565b6000818152600560209081526040808320815160608101835281546001600160a01b039081168252600183015416818501526002820180548451818702810187018652818152879693958601939092919083018282801561179357602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611775575b505050505081525050905060005b8160400151518110156119005760005b600f548110156118ed5760006118b6600f83815481106117d3576117d3615e09565b9060005260206000200154856040015185815181106117f4576117f4615e09565b602002602001015188600460008960400151898151811061181757611817615e09565b6020908102919091018101516001600160a01b03908116835282820193909352604091820160009081208e82528252829020548251808301889052959093168583015260608501939093526001600160401b039091166080808501919091528151808503909101815260a08401825280519083012060c084019490945260e0808401859052815180850390910181526101009093019052815191012091565b50600081815260106020526040902054909150156118da5750600195945050505050565b50806118e581615d71565b9150506117b1565b50806118f881615d71565b9150506117a1565b5060009392505050565b600d54600160301b900460ff16156119355760405163769dd35360e11b815260040160405180910390fd5b336000908152600c60205260409020546001600160601b038083169116101561197157604051631e9acf1760e31b815260040160405180910390fd5b336000908152600c6020526040812080548392906119999084906001600160601b0316615d19565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555080600a600c8282829054906101000a90046001600160601b03166119e19190615d19565b92506101000a8154816001600160601b0302191690836001600160601b031602179055506000826001600160a01b0316826001600160601b031660405160006040518083038185875af1925050503d8060008114611a5b576040519150601f19603f3d011682016040523d82523d6000602084013e611a60565b606091505b5050905080611a8257604051630dcf35db60e41b815260040160405180910390fd5b505050565b611a8f61361c565b6002546001600160a01b031615611ab957604051631688c53760e11b815260040160405180910390fd5b600280546001600160a01b039384166001600160a01b03199182161790915560038054929093169116179055565b611aef61361c565b611af881613b3a565b15611b215760405163ac8a27ef60e01b81526001600160a01b0382166004820152602401610c03565b601380546001810182556000919091527f66de8ffda797e3de9c05e8fc57b3bf0ec28a930d40b0d285d93c06501cf6a0900180546001600160a01b0319166001600160a01b0383169081179091556040519081527fb7cabbfc11e66731fc77de0444614282023bcbd41d16781c753a431d0af016259060200160405180910390a150565b600d54600160301b900460ff1615611bd05760405163769dd35360e11b815260040160405180910390fd5b336000908152600b60205260409020546001600160601b0380831691161015611c0c57604051631e9acf1760e31b815260040160405180910390fd5b336000908152600b602052604081208054839290611c349084906001600160601b0316615d19565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555080600a60008282829054906101000a90046001600160601b0316611c7c9190615d19565b82546101009290920a6001600160601b0381810219909316918316021790915560025460405163a9059cbb60e01b81526001600160a01b03868116600483015292851660248201529116915063a9059cbb90604401602060405180830381600087803b158015611ceb57600080fd5b505af1158015611cff573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d23919061548e565b611d4057604051631e9acf1760e31b815260040160405180910390fd5b5050565b611d4c61361c565b604080518082018252600091611d7b919084906002908390839080828437600092019190915250612dbb915050565b6000818152600e60205260409020549091506001600160a01b031615611db757604051634a0b8fa760e01b815260048101829052602401610c03565b6000818152600e6020908152604080832080546001600160a01b0319166001600160a01b038816908117909155600f805460018101825594527f8d1108e10bcb7c27dddfc02ed9d693a074039d026cf4ea4240b40f7d581ac802909301849055518381527fe729ae16526293f74ade739043022254f1489f616295a25bf72dfb4511ed73b89101610d96565b6001546001600160a01b03163314611e9d5760405162461bcd60e51b815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610c03565b60008054336001600160a01b0319808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b600d54600090600160301b900460ff1615611f225760405163769dd35360e11b815260040160405180910390fd5b6020808301356000908152600590915260409020546001600160a01b0316611f5d57604051630fb532db60e11b815260040160405180910390fd5b3360009081526004602090815260408083208583013584529091529020546001600160401b031680611fae576040516379bfd40160e01b815260208401356004820152336024820152604401610c03565b600d5461ffff16611fc5606085016040860161563f565b61ffff161080611fe8575060c8611fe2606085016040860161563f565b61ffff16115b1561202e57611ffd606084016040850161563f565b600d5460405163539c34bb60e11b815261ffff92831660048201529116602482015260c86044820152606401610c03565b600d5462010000900463ffffffff1661204d608085016060860161573f565b63ffffffff16111561209d57612069608084016060850161573f565b600d54604051637aebf00f60e11b815263ffffffff9283166004820152620100009091049091166024820152604401610c03565b6101f46120b060a085016080860161573f565b63ffffffff1611156120f6576120cc60a084016080850161573f565b6040516311ce1afb60e21b815263ffffffff90911660048201526101f46024820152604401610c03565b6000612103826001615c82565b604080518635602080830182905233838501528089013560608401526001600160401b0385166080808501919091528451808503909101815260a0808501865281519183019190912060c085019390935260e0808501849052855180860390910181526101009094019094528251920191909120929350906000906121939061218e90890189615b86565b613df3565b905060006121a082613e70565b9050836121ab613ee1565b60208a01356121c060808c0160608d0161573f565b6121d060a08d0160808e0161573f565b33866040516020016121e89796959493929190615a94565b604051602081830303815290604052805190602001206010600086815260200190815260200160002081905550336001600160a01b0316886020013589600001357feb0e3652e0f44f417695e6e90f2f42c99b65cd7169074c5a654b16b9748c3a4e87878d604001602081019061225f919061563f565b8e6060016020810190612272919061573f565b8f6080016020810190612285919061573f565b8960405161229896959493929190615a55565b60405180910390a450503360009081526004602090815260408083208983013584529091529020805467ffffffffffffffff19166001600160401b039490941693909317909255925050505b919050565b600d54600090600160301b900460ff16156123175760405163769dd35360e11b815260040160405180910390fd5b600033612325600143615d02565b600754604051606093841b6bffffffffffffffffffffffff199081166020830152924060348201523090931b909116605483015260c01b6001600160c01b031916606882015260700160408051601f198184030181529190528051602090910120600780549192506001600160401b039091169060006123a483615d8c565b91906101000a8154816001600160401b0302191690836001600160401b03160217905550506000806001600160401b038111156123e3576123e3615e1f565b60405190808252806020026020018201604052801561240c578160200160208202803683370190505b506040805160608082018352600080835260208084018281528486018381528984526006835286842095518654925191516001600160601b039182166001600160c01b031990941693909317600160601b9190921602176001600160c01b0316600160c01b6001600160401b039092169190910217909355835191820184523382528183018181528285018681528883526005855294909120825181546001600160a01b03199081166001600160a01b0392831617835592516001830180549094169116179091559251805194955090936124ed926002850192019061502c565b506124fd91506008905083613f7a565b5060405133815282907f1d3015d7ba850fa198dc7b1a3f5d42779313a681035f77c8c03764c61005518d9060200160405180910390a250905090565b600d54600160301b900460ff16156125645760405163769dd35360e11b815260040160405180910390fd5b6002546001600160a01b0316331461258f576040516344b0e3c360e01b815260040160405180910390fd5b602081146125b057604051638129bbcd60e01b815260040160405180910390fd5b60006125be828401846154ab565b6000818152600560205260409020549091506001600160a01b03166125f657604051630fb532db60e11b815260040160405180910390fd5b600081815260066020526040812080546001600160601b03169186919061261d8385615cad565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555084600a60008282829054906101000a90046001600160601b03166126659190615cad565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550817f1ced9348ff549fceab2ac57cd3a9de38edaaab274b725ee82c23e8fc8c4eec7a8287846126b89190615c6a565b604080519283526020830191909152015b60405180910390a2505050505050565b6126e161361c565b600a544790600160601b90046001600160601b031681811115612721576040516354ced18160e11b81526004810182905260248101839052604401610c03565b81811015611a825760006127358284615d02565b90506000846001600160a01b03168260405160006040518083038185875af1925050503d8060008114612784576040519150601f19603f3d011682016040523d82523d6000602084013e612789565b606091505b50509050806127ab57604051630dcf35db60e41b815260040160405180910390fd5b604080516001600160a01b0387168152602081018490527f879c9ea2b9d5345b84ccd12610b032602808517cebdb795007f3dcb4df377317910160405180910390a15050505050565b6127fc61361c565b6000818152600560205260409020546001600160a01b031661283157604051630fb532db60e11b815260040160405180910390fd5b600081815260056020526040902054610c0c9082906001600160a01b0316613678565b606060006128626008613f86565b905080841061288457604051631390f2a160e01b815260040160405180910390fd5b60006128908486615c6a565b90508181118061289e575083155b6128a857806128aa565b815b905060006128b88683615d02565b6001600160401b038111156128cf576128cf615e1f565b6040519080825280602002602001820160405280156128f8578160200160208202803683370190505b50905060005b815181101561294b5761291c6129148883615c6a565b600890613f90565b82828151811061292e5761292e615e09565b60209081029190910101528061294381615d71565b9150506128fe565b5095945050505050565b61295d61361c565b60c861ffff871611156129975760405163539c34bb60e11b815261ffff871660048201819052602482015260c86044820152606401610c03565b600082136129bb576040516321ea67b360e11b815260048101839052602401610c03565b6040805160a0808201835261ffff891680835263ffffffff89811660208086018290526000868801528a831660608088018290528b85166080988901819052600d805465ffffffffffff19168817620100008702176effffffffffffffffff000000000000191667010000000000000085026effffffff0000000000000000000000191617600160581b83021790558a51601280548d87015192891667ffffffffffffffff199091161764010000000092891692909202919091179081905560118d90558a519788528785019590955298860191909152840196909652938201879052838116928201929092529190921c90911660c08201527f777357bb93f63d088f18112d3dba38457aec633eb8f1341e1d418380ad328e789060e00160405180910390a1505050505050565b600d54600160301b900460ff1615612b145760405163769dd35360e11b815260040160405180910390fd5b6000818152600560205260409020546001600160a01b0316612b4957604051630fb532db60e11b815260040160405180910390fd5b6000818152600560205260409020600101546001600160a01b03163314612ba2576000818152600560205260409081902060010154905163d084e97560e01b81526001600160a01b039091166004820152602401610c03565b6000818152600560209081526040918290208054336001600160a01b0319808316821784556001909301805490931690925583516001600160a01b0390911680825292810191909152909183917fd4114ab6e9af9f597c52041f32d62dc57c5c4e4c0d4427006069635e216c938691015b60405180910390a25050565b60008281526005602052604090205482906001600160a01b031680612c5757604051630fb532db60e11b815260040160405180910390fd5b336001600160a01b03821614612c8b57604051636c51fda960e11b81526001600160a01b0382166004820152602401610c03565b600d54600160301b900460ff1615612cb65760405163769dd35360e11b815260040160405180910390fd5b60008481526005602052604090206002015460641415612ce9576040516305a48e0f60e01b815260040160405180910390fd5b6001600160a01b03831660009081526004602090815260408083208784529091529020546001600160401b031615612d2057610e6b565b6001600160a01b03831660008181526004602090815260408083208884528252808320805467ffffffffffffffff19166001908117909155600583528184206002018054918201815584529282902090920180546001600160a01b03191684179055905191825285917f1e980d04aa7648e205713e5e8ea3808672ac163d10936d36f91b2c88ac1575e191015b60405180910390a250505050565b600081604051602001612dce9190615920565b604051602081830303815290604052805190602001209050919050565b60008281526005602052604090205482906001600160a01b031680612e2357604051630fb532db60e11b815260040160405180910390fd5b336001600160a01b03821614612e5757604051636c51fda960e11b81526001600160a01b0382166004820152602401610c03565b600d54600160301b900460ff1615612e825760405163769dd35360e11b815260040160405180910390fd5b612e8b84611709565b15612ea957604051631685ecdd60e31b815260040160405180910390fd5b6001600160a01b03831660009081526004602090815260408083208784529091529020546001600160401b0316612f05576040516379bfd40160e01b8152600481018590526001600160a01b0384166024820152604401610c03565b600084815260056020908152604080832060020180548251818502810185019093528083529192909190830182828015612f6857602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612f4a575b50505050509050600060018251612f7f9190615d02565b905060005b825181101561308b57856001600160a01b0316838281518110612fa957612fa9615e09565b60200260200101516001600160a01b03161415613079576000838381518110612fd457612fd4615e09565b6020026020010151905080600560008a8152602001908152602001600020600201838154811061300657613006615e09565b600091825260208083209190910180546001600160a01b0319166001600160a01b03949094169390931790925589815260059091526040902060020180548061305157613051615df3565b600082815260209020810160001990810180546001600160a01b03191690550190555061308b565b8061308381615d71565b915050612f84565b506001600160a01b03851660008181526004602090815260408083208a8452825291829020805467ffffffffffffffff19169055905191825287917f32158c6058347c1601b2d12bc696ac6901d8a9a9aa3ba10c27ab0a983e8425a791016126c9565b600f81815481106130fe57600080fd5b600091825260209091200154905081565b60008281526005602052604090205482906001600160a01b03168061314757604051630fb532db60e11b815260040160405180910390fd5b336001600160a01b0382161461317b57604051636c51fda960e11b81526001600160a01b0382166004820152602401610c03565b600d54600160301b900460ff16156131a65760405163769dd35360e11b815260040160405180910390fd5b6000848152600560205260409020600101546001600160a01b03848116911614610e6b5760008481526005602090815260409182902060010180546001600160a01b0319166001600160a01b03871690811790915582513381529182015285917f21a4dad170a6bf476c31bbcf4a16628295b0e450672eec25d7c93308e05344a19101612dad565b6000818152600560205260408120548190819081906060906001600160a01b031661326c57604051630fb532db60e11b815260040160405180910390fd5b60008681526006602090815260408083205460058352928190208054600290910180548351818602810186019094528084526001600160601b0380871696600160601b810490911695600160c01b9091046001600160401b0316946001600160a01b039094169391839183018282801561330f57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116132f1575b505050505090509450945094509450945091939590929450565b61333161361c565b6002546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a082319060240160206040518083038186803b15801561337557600080fd5b505afa158015613389573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133ad91906154c4565b600a549091506001600160601b0316818111156133e7576040516354ced18160e11b81526004810182905260248101839052604401610c03565b81811015611a825760006133fb8284615d02565b60025460405163a9059cbb60e01b81526001600160a01b0387811660048301526024820184905292935091169063a9059cbb90604401602060405180830381600087803b15801561344b57600080fd5b505af115801561345f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613483919061548e565b50604080516001600160a01b0386168152602081018390527f59bfc682b673f8cbf945f1e454df9334834abf7dfe7f92237ca29ecb9b436600910160405180910390a150505050565b600d54600160301b900460ff16156134f75760405163769dd35360e11b815260040160405180910390fd5b6000818152600560205260409020546001600160a01b031661352c57604051630fb532db60e11b815260040160405180910390fd5b60008181526006602052604090208054600160601b90046001600160601b0316903490600c61355b8385615cad565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555034600a600c8282829054906101000a90046001600160601b03166135a39190615cad565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550817f3f1ddc3ab1bdb39001ad76ca51a0e6f57ce6627c69f251d1de41622847721cde8234846135f69190615c6a565b60408051928352602083019190915201612c13565b61361361361c565b610c0c81613f9c565b6000546001600160a01b031633146136765760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610c03565b565b60008061368484613ba4565b60025460405163a9059cbb60e01b81526001600160a01b0387811660048301526001600160601b0385166024830152939550919350919091169063a9059cbb90604401602060405180830381600087803b1580156136e157600080fd5b505af11580156136f5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613719919061548e565b61373657604051631e9acf1760e31b815260040160405180910390fd5b6000836001600160a01b0316826001600160601b031660405160006040518083038185875af1925050503d806000811461378c576040519150601f19603f3d011682016040523d82523d6000602084013e613791565b606091505b50509050806137b357604051630dcf35db60e41b815260040160405180910390fd5b604080516001600160a01b03861681526001600160601b038581166020830152841681830152905186917f8c74ce8b8cf87f5eb001275c8be27eb34ea2b62bfab6814fcc62192bb63e81c4919081900360600190a25050505050565b6040805160608101825260008082526020820181905291810191909152600061383b8460000151612dbb565b6000818152600e60205260409020549091506001600160a01b03168061387757604051631dfd6e1360e21b815260048101839052602401610c03565b6000828660800151604051602001613899929190918252602082015260400190565b60408051601f19818403018152918152815160209283012060008181526010909352912054909150806138df57604051631b44092560e11b815260040160405180910390fd5b85516020808801516040808a015160608b015160808c015160a08d0151935161390e978a979096959101615ade565b6040516020818303038152906040528051906020012081146139435760405163354a450b60e21b815260040160405180910390fd5b60006139528760000151614046565b905080613a2a578651604051631d2827a760e31b81526001600160401b0390911660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063e9413d389060240160206040518083038186803b1580156139c457600080fd5b505afa1580156139d8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139fc91906154c4565b905080613a2a57865160405163175dadad60e01b81526001600160401b039091166004820152602401610c03565b6000886080015182604051602001613a4c929190918252602082015260400190565b6040516020818303038152906040528051906020012060001c90506000613a738a83614130565b604080516060810182529889526020890196909652948701949094525093979650505050505050565b60005a611388811015613aae57600080fd5b611388810390508460408204820311613ac657600080fd5b50823b613ad257600080fd5b60008083516020850160008789f190505b9392505050565b60008115613b1857601254613b119086908690640100000000900463ffffffff168661419b565b9050613b32565b601254613b2f908690869063ffffffff1686614205565b90505b949350505050565b6000805b601354811015613b9b57826001600160a01b031660138281548110613b6557613b65615e09565b6000918252602090912001546001600160a01b03161415613b895750600192915050565b80613b9381615d71565b915050613b3e565b50600092915050565b6000818152600560209081526040808320815160608101835281546001600160a01b03908116825260018301541681850152600282018054845181870281018701865281815287968796949594860193919290830182828015613c3057602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311613c12575b505050919092525050506000858152600660209081526040808320815160608101835290546001600160601b03808216808452600160601b8304909116948301859052600160c01b9091046001600160401b0316928201929092529096509094509192505b826040015151811015613d0d576004600084604001518381518110613cbc57613cbc615e09565b6020908102919091018101516001600160a01b0316825281810192909252604090810160009081208982529092529020805467ffffffffffffffff1916905580613d0581615d71565b915050613c95565b50600085815260056020526040812080546001600160a01b03199081168255600182018054909116905590613d456002830182615091565b5050600085815260066020526040812055613d616008866142f3565b50600a8054859190600090613d809084906001600160601b0316615d19565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555082600a600c8282829054906101000a90046001600160601b0316613dc89190615d19565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505050915091565b60408051602081019091526000815281613e1c5750604080516020810190915260008152611355565b63125fa26760e31b613e2e8385615d41565b6001600160e01b03191614613e5657604051632923fee760e11b815260040160405180910390fd5b613e638260048186615c40565b810190613ae391906154dd565b60607f92fd13387c7fe7befbc38d303d6468778fb9731bc4583f17d92989c6fcfdeaaa82604051602401613ea991511515815260200190565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915292915050565b60004661a4b1811480613ef6575062066eed81145b15613f735760646001600160a01b031663a3b1b31d6040518163ffffffff1660e01b815260040160206040518083038186803b158015613f3557600080fd5b505afa158015613f49573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f6d91906154c4565b91505090565b4391505090565b6000613ae383836142ff565b6000611355825490565b6000613ae3838361434e565b6001600160a01b038116331415613ff55760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610c03565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60004661a4b181148061405b575062066eed81145b1561412157610100836001600160401b0316614075613ee1565b61407f9190615d02565b118061409b575061408e613ee1565b836001600160401b031610155b156140a95750600092915050565b6040516315a03d4160e11b81526001600160401b0384166004820152606490632b407a829060240160206040518083038186803b1580156140e957600080fd5b505afa1580156140fd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ae391906154c4565b50506001600160401b03164090565b60006141648360000151846020015185604001518660600151868860a001518960c001518a60e001518b6101000151614378565b6003836020015160405160200161417c929190615a28565b60408051601f1981840301815291905280516020909101209392505050565b6000806141a66145a3565b905060005a6141b58888615c6a565b6141bf9190615d02565b6141c99085615ce3565b905060006141e263ffffffff871664e8d4a51000615ce3565b9050826141ef8284615c6a565b6141f99190615c6a565b98975050505050505050565b6000806142106145ff565b905060008113614236576040516321ea67b360e11b815260048101829052602401610c03565b60006142406145a3565b9050600082825a6142518b8b615c6a565b61425b9190615d02565b6142659088615ce3565b61426f9190615c6a565b61428190670de0b6b3a7640000615ce3565b61428b9190615ccf565b905060006142a463ffffffff881664e8d4a51000615ce3565b90506142bc816b033b2e3c9fd0803ce8000000615d02565b8211156142dc5760405163e80fa38160e01b815260040160405180910390fd5b6142e68183615c6a565b9998505050505050505050565b6000613ae383836146ce565b600081815260018301602052604081205461434657508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155611355565b506000611355565b600082600001828154811061436557614365615e09565b9060005260206000200154905092915050565b614381896147c1565b6143cd5760405162461bcd60e51b815260206004820152601a60248201527f7075626c6963206b6579206973206e6f74206f6e2063757276650000000000006044820152606401610c03565b6143d6886147c1565b6144225760405162461bcd60e51b815260206004820152601560248201527f67616d6d61206973206e6f74206f6e20637572766500000000000000000000006044820152606401610c03565b61442b836147c1565b6144775760405162461bcd60e51b815260206004820152601d60248201527f6347616d6d615769746e657373206973206e6f74206f6e2063757276650000006044820152606401610c03565b614480826147c1565b6144cc5760405162461bcd60e51b815260206004820152601c60248201527f73486173685769746e657373206973206e6f74206f6e206375727665000000006044820152606401610c03565b6144d8878a888761489a565b6145245760405162461bcd60e51b815260206004820152601960248201527f6164647228632a706b2b732a6729213d5f755769746e657373000000000000006044820152606401610c03565b60006145308a876149bd565b90506000614543898b878b868989614a21565b90506000614554838d8d8a86614b41565b9050808a146145955760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b210383937b7b360991b6044820152606401610c03565b505050505050505050505050565b60004661a4b18114806145b8575062066eed81145b156145f757606c6001600160a01b031663c6f7de0e6040518163ffffffff1660e01b815260040160206040518083038186803b158015613f3557600080fd5b600091505090565b600d5460035460408051633fabe5a360e21b81529051600093670100000000000000900463ffffffff169283151592859283926001600160a01b03169163feaf968c9160048083019260a0929190829003018186803b15801561466157600080fd5b505afa158015614675573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614699919061575a565b5094509092508491505080156146bd57506146b48242615d02565b8463ffffffff16105b15613b325750601154949350505050565b600081815260018301602052604081205480156147b75760006146f2600183615d02565b855490915060009061470690600190615d02565b905081811461476b57600086600001828154811061472657614726615e09565b906000526020600020015490508087600001848154811061474957614749615e09565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061477c5761477c615df3565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050611355565b6000915050611355565b80516000906401000003d0191161481a5760405162461bcd60e51b815260206004820152601260248201527f696e76616c696420782d6f7264696e61746500000000000000000000000000006044820152606401610c03565b60208201516401000003d019116148735760405162461bcd60e51b815260206004820152601260248201527f696e76616c696420792d6f7264696e61746500000000000000000000000000006044820152606401610c03565b60208201516401000003d0199080096148938360005b6020020151614b81565b1492915050565b60006001600160a01b0382166148e05760405162461bcd60e51b815260206004820152600b60248201526a626164207769746e65737360a81b6044820152606401610c03565b6020840151600090600116156148f757601c6148fa565b601b5b9050600070014551231950b75fc4402da1732fc9bebe1985876000602002015109865170014551231950b75fc4402da1732fc9bebe19918203925060009190890987516040805160008082526020820180845287905260ff88169282019290925260608101929092526080820183905291925060019060a0016020604051602081039080840390855afa158015614995573d6000803e3d6000fd5b5050604051601f1901516001600160a01b039081169088161495505050505050949350505050565b6149c56150af565b6149f2600184846040516020016149de939291906158ff565b604051602081830303815290604052614ba5565b90505b6149fe816147c1565b611355578051604080516020810192909252614a1a91016149de565b90506149f5565b614a296150af565b825186516401000003d0199081900691061415614a885760405162461bcd60e51b815260206004820152601e60248201527f706f696e747320696e2073756d206d7573742062652064697374696e637400006044820152606401610c03565b614a93878988614bf3565b614adf5760405162461bcd60e51b815260206004820152601660248201527f4669727374206d756c20636865636b206661696c6564000000000000000000006044820152606401610c03565b614aea848685614bf3565b614b365760405162461bcd60e51b815260206004820152601760248201527f5365636f6e64206d756c20636865636b206661696c65640000000000000000006044820152606401610c03565b6141f9868484614d1b565b600060028686868587604051602001614b5f969594939291906158a0565b60408051601f1981840301815291905280516020909101209695505050505050565b6000806401000003d01980848509840990506401000003d019600782089392505050565b614bad6150af565b614bb682614de2565b8152614bcb614bc6826000614889565b614e1d565b6020820181905260029006600114156122e4576020810180516401000003d019039052919050565b600082614c305760405162461bcd60e51b815260206004820152600b60248201526a3d32b9379039b1b0b630b960a91b6044820152606401610c03565b83516020850151600090614c4690600290615db3565b15614c5257601c614c55565b601b5b9050600070014551231950b75fc4402da1732fc9bebe198387096040805160008082526020820180845281905260ff86169282019290925260608101869052608081018390529192509060019060a0016020604051602081039080840390855afa158015614cc7573d6000803e3d6000fd5b505050602060405103519050600086604051602001614ce6919061588e565b60408051601f1981840301815291905280516020909101206001600160a01b0392831692169190911498975050505050505050565b614d236150af565b835160208086015185519186015160009384938493614d4493909190614e3d565b919450925090506401000003d019858209600114614da45760405162461bcd60e51b815260206004820152601960248201527f696e765a206d75737420626520696e7665727365206f66207a000000000000006044820152606401610c03565b60405180604001604052806401000003d01980614dc357614dc3615ddd565b87860981526020016401000003d0198785099052979650505050505050565b805160208201205b6401000003d01981106122e457604080516020808201939093528151808203840181529082019091528051910120614dea565b6000611355826002614e366401000003d0196001615c6a565b901c614f1d565b60008080600180826401000003d019896401000003d019038808905060006401000003d0198b6401000003d019038a0890506000614e7d83838585614fbf565b9098509050614e8e88828e88614fe3565b9098509050614e9f88828c87614fe3565b90985090506000614eb28d878b85614fe3565b9098509050614ec388828686614fbf565b9098509050614ed488828e89614fe3565b9098509050818114614f09576401000003d019818a0998506401000003d01982890997506401000003d0198183099650614f0d565b8196505b5050505050509450945094915050565b600080614f286150cd565b6020808252818101819052604082015260608101859052608081018490526401000003d01960a0820152614f5a6150eb565b60208160c0846005600019fa925082614fb55760405162461bcd60e51b815260206004820152601260248201527f6269674d6f64457870206661696c7572652100000000000000000000000000006044820152606401610c03565b5195945050505050565b6000806401000003d0198487096401000003d0198487099097909650945050505050565b600080806401000003d019878509905060006401000003d01987876401000003d019030990506401000003d0198183086401000003d01986890990999098509650505050505050565b828054828255906000526020600020908101928215615081579160200282015b8281111561508157825182546001600160a01b0319166001600160a01b0390911617825560209092019160019091019061504c565b5061508d929150615109565b5090565b5080546000825590600052602060002090810190610c0c9190615109565b60405180604001604052806002906020820280368337509192915050565b6040518060c001604052806006906020820280368337509192915050565b60405180602001604052806001906020820280368337509192915050565b5b8082111561508d576000815560010161510a565b80356122e481615e35565b806040810183101561135557600080fd5b600082601f83011261514b57600080fd5b615153615bd3565b80838560408601111561516557600080fd5b60005b6002811015615187578135845260209384019390910190600101615168565b509095945050505050565b600082601f8301126151a357600080fd5b81356001600160401b03808211156151bd576151bd615e1f565b604051601f8301601f19908116603f011681019082821181831017156151e5576151e5615e1f565b816040528381528660208588010111156151fe57600080fd5b836020870160208301376000602085830101528094505050505092915050565b600060c0828403121561523057600080fd5b615238615bfb565b905081356001600160401b03808216821461525257600080fd5b8183526020840135602084015261526b604085016152d1565b604084015261527c606085016152d1565b606084015261528d6080850161511e565b608084015260a08401359150808211156152a657600080fd5b506152b384828501615192565b60a08301525092915050565b803561ffff811681146122e457600080fd5b803563ffffffff811681146122e457600080fd5b805169ffffffffffffffffffff811681146122e457600080fd5b80356001600160601b03811681146122e457600080fd5b60006020828403121561532857600080fd5b8135613ae381615e35565b6000806040838503121561534657600080fd5b823561535181615e35565b915061535f602084016152ff565b90509250929050565b6000806040838503121561537b57600080fd5b823561538681615e35565b9150602083013561539681615e35565b809150509250929050565b600080606083850312156153b457600080fd5b82356153bf81615e35565b915061535f8460208501615129565b600080600080606085870312156153e457600080fd5b84356153ef81615e35565b93506020850135925060408501356001600160401b038082111561541257600080fd5b818701915087601f83011261542657600080fd5b81358181111561543557600080fd5b88602082850101111561544757600080fd5b95989497505060200194505050565b60006040828403121561546857600080fd5b613ae38383615129565b60006040828403121561548457600080fd5b613ae3838361513a565b6000602082840312156154a057600080fd5b8151613ae381615e4a565b6000602082840312156154bd57600080fd5b5035919050565b6000602082840312156154d657600080fd5b5051919050565b6000602082840312156154ef57600080fd5b604051602081018181106001600160401b038211171561551157615511615e1f565b604052823561551f81615e4a565b81529392505050565b6000808284036101c081121561553d57600080fd5b6101a08082121561554d57600080fd5b615555615c1d565b9150615561868661513a565b8252615570866040870161513a565b60208301526080850135604083015260a0850135606083015260c0850135608083015261559f60e0860161511e565b60a08301526101006155b38782880161513a565b60c08401526155c687610140880161513a565b60e0840152610180860135908301529092508301356001600160401b038111156155ef57600080fd5b6155fb8582860161521e565b9150509250929050565b60006020828403121561561757600080fd5b81356001600160401b0381111561562d57600080fd5b820160c08185031215613ae357600080fd5b60006020828403121561565157600080fd5b613ae3826152bf565b60008060008060008086880360e081121561567457600080fd5b61567d886152bf565b965061568b602089016152d1565b9550615699604089016152d1565b94506156a7606089016152d1565b9350608088013592506040609f19820112156156c257600080fd5b506156cb615bd3565b6156d760a089016152d1565b81526156e560c089016152d1565b6020820152809150509295509295509295565b6000806040838503121561570b57600080fd5b82359150602083013561539681615e35565b6000806040838503121561573057600080fd5b50508035926020909101359150565b60006020828403121561575157600080fd5b613ae3826152d1565b600080600080600060a0868803121561577257600080fd5b61577b866152e5565b945060208601519350604086015192506060860151915061579e608087016152e5565b90509295509295909350565b600081518084526020808501945080840160005b838110156157e35781516001600160a01b0316875295820195908201906001016157be565b509495945050505050565b8060005b6002811015610e6b5781518452602093840193909101906001016157f2565b600081518084526020808501945080840160005b838110156157e357815187529582019590820190600101615825565b6000815180845260005b818110156158675760208185018101518683018201520161584b565b81811115615879576000602083870101525b50601f01601f19169290920160200192915050565b61589881836157ee565b604001919050565b8681526158b060208201876157ee565b6158bd60608201866157ee565b6158ca60a08201856157ee565b6158d760e08201846157ee565b60609190911b6bffffffffffffffffffffffff19166101208201526101340195945050505050565b83815261590f60208201846157ee565b606081019190915260800192915050565b6040810161135582846157ee565b602081526000613ae36020830184615811565b602081526000613ae36020830184615841565b6020815260ff8251166020820152602082015160408201526001600160a01b0360408301511660608201526000606083015160c0608084015261599a60e08401826157aa565b905060808401516001600160601b0380821660a08601528060a08701511660c086015250508091505092915050565b60006060820161ffff86168352602063ffffffff86168185015260606040850152818551808452608086019150828701935060005b81811015615a1a578451835293830193918301916001016159fe565b509098975050505050505050565b82815260608101613ae360208301846157ee565b828152604060208201526000613b326040830184615811565b86815285602082015261ffff85166040820152600063ffffffff808616606084015280851660808401525060c060a08301526141f960c0830184615841565b878152866020820152856040820152600063ffffffff80871660608401528086166080840152506001600160a01b03841660a083015260e060c08301526142e660e0830184615841565b8781526001600160401b0387166020820152856040820152600063ffffffff80871660608401528086166080840152506001600160a01b03841660a083015260e060c08301526142e660e0830184615841565b60006001600160601b0380881683528087166020840152506001600160401b03851660408301526001600160a01b038416606083015260a06080830152615b7b60a08301846157aa565b979650505050505050565b6000808335601e19843603018112615b9d57600080fd5b8301803591506001600160401b03821115615bb757600080fd5b602001915036819003821315615bcc57600080fd5b9250929050565b604080519081016001600160401b0381118282101715615bf557615bf5615e1f565b60405290565b60405160c081016001600160401b0381118282101715615bf557615bf5615e1f565b60405161012081016001600160401b0381118282101715615bf557615bf5615e1f565b60008085851115615c5057600080fd5b83861115615c5d57600080fd5b5050820193919092039150565b60008219821115615c7d57615c7d615dc7565b500190565b60006001600160401b03808316818516808303821115615ca457615ca4615dc7565b01949350505050565b60006001600160601b03808316818516808303821115615ca457615ca4615dc7565b600082615cde57615cde615ddd565b500490565b6000816000190483118215151615615cfd57615cfd615dc7565b500290565b600082821015615d1457615d14615dc7565b500390565b60006001600160601b0383811690831681811015615d3957615d39615dc7565b039392505050565b6001600160e01b03198135818116916004851015615d695780818660040360031b1b83161692505b505092915050565b6000600019821415615d8557615d85615dc7565b5060010190565b60006001600160401b0380831681811415615da957615da9615dc7565b6001019392505050565b600082615dc257615dc2615ddd565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114610c0c57600080fd5b8015158114610c0c57600080fdfea164736f6c6343000806000a",
-}
-
-var VRFCoordinatorV2PlusABI = VRFCoordinatorV2PlusMetaData.ABI
-
-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 00000000000..9ed2e34687e
--- /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_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 e13d1b48d51..b6051bf09ff 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,8 +31,8 @@ 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\":[{\"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: "0x60806040523480156200001157600080fd5b5060405162001201380380620012018339810160408190526200003491620001cc565b8133806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf8162000103565b5050600280546001600160a01b03199081166001600160a01b0394851617909155600580548216958416959095179094555060068054909316911617905562000204565b6001600160a01b0381163314156200015e5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b0381168114620001c757600080fd5b919050565b60008060408385031215620001e057600080fd5b620001eb83620001af565b9150620001fb60208401620001af565b90509250929050565b610fed80620002146000396000f3fe608060405234801561001057600080fd5b50600436106100c95760003560e01c80638ea9811711610081578063f08c5daa1161005b578063f08c5daa1461017b578063f2fde38b14610184578063f6eaffc81461019757600080fd5b80638ea981171461014c578063cf62c8ab1461015f578063e89e106a1461017257600080fd5b80635e3b709f116100b25780635e3b709f146100f657806379ba50971461011c5780638da5cb5b1461012457600080fd5b80631fe543e3146100ce57806336bfffed146100e3575b600080fd5b6100e16100dc366004610cc1565b6101aa565b005b6100e16100f1366004610bc9565b610230565b610109610104366004610c8f565b610368565b6040519081526020015b60405180910390f35b6100e161045e565b60005460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610113565b6100e161015a366004610bae565b61055b565b6100e161016d366004610d65565b610666565b61010960045481565b61010960075481565b6100e1610192366004610bae565b61086c565b6101096101a5366004610c8f565b610880565b60025473ffffffffffffffffffffffffffffffffffffffff163314610222576002546040517f1cf993f400000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff90911660248201526044015b60405180910390fd5b61022c82826108a1565b5050565b600854610299576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f7375624944206e6f7420736574000000000000000000000000000000000000006044820152606401610219565b60005b815181101561022c57600554600854835173ffffffffffffffffffffffffffffffffffffffff9092169163bec4c08c91908590859081106102df576102df610f82565b60200260200101516040518363ffffffff1660e01b815260040161032392919091825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b600060405180830381600087803b15801561033d57600080fd5b505af1158015610351573d6000803e3d6000fd5b50505050808061036090610f22565b91505061029c565b60098190556040805160c08101825282815260085460208083019190915260018284018190526207a1206060840152608083015282519081018352600080825260a083019190915260055492517f9b1c385e000000000000000000000000000000000000000000000000000000008152909273ffffffffffffffffffffffffffffffffffffffff1690639b1c385e90610405908490600401610e4a565b602060405180830381600087803b15801561041f57600080fd5b505af1158015610433573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104579190610ca8565b9392505050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146104df576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610219565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60005473ffffffffffffffffffffffffffffffffffffffff16331480159061059b575060025473ffffffffffffffffffffffffffffffffffffffff163314155b1561061f57336105c060005473ffffffffffffffffffffffffffffffffffffffff1690565b6002546040517f061db9c100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201529183166024830152919091166044820152606401610219565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60085461079e57600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a21a23e46040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156106d757600080fd5b505af11580156106eb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061070f9190610ca8565b60088190556005546040517fbec4c08c000000000000000000000000000000000000000000000000000000008152600481019290925230602483015273ffffffffffffffffffffffffffffffffffffffff169063bec4c08c90604401600060405180830381600087803b15801561078557600080fd5b505af1158015610799573d6000803e3d6000fd5b505050505b6006546005546008546040805160208082019390935281518082039093018352808201918290527f4000aea00000000000000000000000000000000000000000000000000000000090915273ffffffffffffffffffffffffffffffffffffffff93841693634000aea09361081a93911691869190604401610dfe565b602060405180830381600087803b15801561083457600080fd5b505af1158015610848573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061022c9190610c6d565b6108746109ac565b61087d81610a2f565b50565b6003818154811061089057600080fd5b600091825260209091200154905081565b5a60075580516108b8906003906020840190610b25565b5060048281556040805160c0810182526009548152600854602080830191909152600182840181905262030d4060608401526080830152825190810183526000815260a082015260055491517f9b1c385e000000000000000000000000000000000000000000000000000000008152909273ffffffffffffffffffffffffffffffffffffffff90921691639b1c385e9161095491859101610e4a565b602060405180830381600087803b15801561096e57600080fd5b505af1158015610982573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109a69190610ca8565b50505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610a2d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610219565b565b73ffffffffffffffffffffffffffffffffffffffff8116331415610aaf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610219565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b828054828255906000526020600020908101928215610b60579160200282015b82811115610b60578251825591602001919060010190610b45565b50610b6c929150610b70565b5090565b5b80821115610b6c5760008155600101610b71565b803573ffffffffffffffffffffffffffffffffffffffff81168114610ba957600080fd5b919050565b600060208284031215610bc057600080fd5b61045782610b85565b60006020808385031215610bdc57600080fd5b823567ffffffffffffffff811115610bf357600080fd5b8301601f81018513610c0457600080fd5b8035610c17610c1282610efe565b610eaf565b80828252848201915084840188868560051b8701011115610c3757600080fd5b600094505b83851015610c6157610c4d81610b85565b835260019490940193918501918501610c3c565b50979650505050505050565b600060208284031215610c7f57600080fd5b8151801515811461045757600080fd5b600060208284031215610ca157600080fd5b5035919050565b600060208284031215610cba57600080fd5b5051919050565b60008060408385031215610cd457600080fd5b8235915060208084013567ffffffffffffffff811115610cf357600080fd5b8401601f81018613610d0457600080fd5b8035610d12610c1282610efe565b80828252848201915084840189868560051b8701011115610d3257600080fd5b600094505b83851015610d55578035835260019490940193918501918501610d37565b5080955050505050509250929050565b600060208284031215610d7757600080fd5b81356bffffffffffffffffffffffff8116811461045757600080fd5b6000815180845260005b81811015610db957602081850181015186830182015201610d9d565b81811115610dcb576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b73ffffffffffffffffffffffffffffffffffffffff841681526bffffffffffffffffffffffff83166020820152606060408201526000610e416060830184610d93565b95945050505050565b60208152815160208201526020820151604082015261ffff60408301511660608201526000606083015163ffffffff80821660808501528060808601511660a0850152505060a083015160c080840152610ea760e0840182610d93565b949350505050565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610ef657610ef6610fb1565b604052919050565b600067ffffffffffffffff821115610f1857610f18610fb1565b5060051b60200190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415610f7b577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fdfea164736f6c6343000806000a",
+ 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",
}
var VRFMaliciousConsumerV2PlusABI = VRFMaliciousConsumerV2PlusMetaData.ABI
@@ -259,6 +259,28 @@ func (_VRFMaliciousConsumerV2Plus *VRFMaliciousConsumerV2PlusCallerSession) SReq
return _VRFMaliciousConsumerV2Plus.Contract.SRequestId(&_VRFMaliciousConsumerV2Plus.CallOpts)
}
+func (_VRFMaliciousConsumerV2Plus *VRFMaliciousConsumerV2PlusCaller) SVrfCoordinator(opts *bind.CallOpts) (common.Address, error) {
+ var out []interface{}
+ err := _VRFMaliciousConsumerV2Plus.contract.Call(opts, &out, "s_vrfCoordinator")
+
+ if err != nil {
+ return *new(common.Address), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address)
+
+ return out0, err
+
+}
+
+func (_VRFMaliciousConsumerV2Plus *VRFMaliciousConsumerV2PlusSession) SVrfCoordinator() (common.Address, error) {
+ return _VRFMaliciousConsumerV2Plus.Contract.SVrfCoordinator(&_VRFMaliciousConsumerV2Plus.CallOpts)
+}
+
+func (_VRFMaliciousConsumerV2Plus *VRFMaliciousConsumerV2PlusCallerSession) SVrfCoordinator() (common.Address, error) {
+ return _VRFMaliciousConsumerV2Plus.Contract.SVrfCoordinator(&_VRFMaliciousConsumerV2Plus.CallOpts)
+}
+
func (_VRFMaliciousConsumerV2Plus *VRFMaliciousConsumerV2PlusTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) {
return _VRFMaliciousConsumerV2Plus.contract.Transact(opts, "acceptOwnership")
}
@@ -648,6 +670,8 @@ type VRFMaliciousConsumerV2PlusInterface interface {
SRequestId(opts *bind.CallOpts) (*big.Int, error)
+ SVrfCoordinator(opts *bind.CallOpts) (common.Address, error)
+
AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error)
CreateSubscriptionAndFund(opts *bind.TransactOpts, amount *big.Int) (*types.Transaction, error)
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
new file mode 100644
index 00000000000..9bb00660e12
--- /dev/null
+++ b/core/gethwrappers/generated/vrf_v2plus_load_test_with_metrics/vrf_v2plus_load_test_with_metrics.go
@@ -0,0 +1,853 @@
+// Code generated - DO NOT EDIT.
+// This file is a generated binding and any manual changes will be lost.
+
+package vrf_v2plus_load_test_with_metrics
+
+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 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\":\"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: "0x6080604052600060055560006006556103e760075534801561002057600080fd5b5060405161134738038061134783398101604081905261003f9161019b565b8033806000816100965760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b03848116919091179091558116156100c6576100c6816100f1565b5050600280546001600160a01b0319166001600160a01b039390931692909217909155506101cb9050565b6001600160a01b03811633141561014a5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161008d565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000602082840312156101ad57600080fd5b81516001600160a01b03811681146101c457600080fd5b9392505050565b61116d806101da6000396000f3fe608060405234801561001057600080fd5b50600436106101005760003560e01c80638ea9811711610097578063d826f88f11610066578063d826f88f14610252578063d8a4676f14610271578063dc1670db14610296578063f2fde38b1461029f57600080fd5b80638ea98117146101ab5780639eccacf6146101be578063a168fa89146101de578063b1e217491461024957600080fd5b8063737144bc116100d3578063737144bc1461015257806374dba1241461015b57806379ba5097146101645780638da5cb5b1461016c57600080fd5b80631757f11c146101055780631fe543e314610121578063557d2e92146101365780636846de201461013f575b600080fd5b61010e60065481565b6040519081526020015b60405180910390f35b61013461012f366004610d66565b6102b2565b005b61010e60045481565b61013461014d366004610e55565b610338565b61010e60055481565b61010e60075481565b610134610565565b60005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610118565b6101346101b9366004610cf7565b610662565b6002546101869073ffffffffffffffffffffffffffffffffffffffff1681565b61021f6101ec366004610d34565b600a602052600090815260409020805460028201546003830154600484015460059094015460ff90931693919290919085565b6040805195151586526020860194909452928401919091526060830152608082015260a001610118565b61010e60085481565b6101346000600581905560068190556103e76007556004819055600355565b61028461027f366004610d34565b61076d565b60405161011896959493929190610ed4565b61010e60035481565b6101346102ad366004610cf7565b610852565b60025473ffffffffffffffffffffffffffffffffffffffff16331461032a576002546040517f1cf993f400000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff90911660248201526044015b60405180910390fd5b6103348282610866565b5050565b610340610991565b60005b8161ffff168161ffff16101561055b5760006040518060c001604052808881526020018a81526020018961ffff1681526020018763ffffffff1681526020018563ffffffff1681526020016103a76040518060200160405280891515815250610a14565b90526002546040517f9b1c385e00000000000000000000000000000000000000000000000000000000815291925060009173ffffffffffffffffffffffffffffffffffffffff90911690639b1c385e90610405908590600401610f40565b602060405180830381600087803b15801561041f57600080fd5b505af1158015610433573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104579190610d4d565b600881905590506000610468610ad0565b6040805160c08101825260008082528251818152602080820185528084019182524284860152606084018390526080840186905260a08401839052878352600a815293909120825181547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690151517815590518051949550919390926104f6926001850192910190610c6c565b506040820151600282015560608201516003820155608082015160048083019190915560a0909201516005909101558054906000610533836110c9565b9091555050600091825260096020526040909120555080610553816110a7565b915050610343565b5050505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146105e6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610321565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60005473ffffffffffffffffffffffffffffffffffffffff1633148015906106a2575060025473ffffffffffffffffffffffffffffffffffffffff163314155b1561072657336106c760005473ffffffffffffffffffffffffffffffffffffffff1690565b6002546040517f061db9c100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201529183166024830152919091166044820152606401610321565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6000818152600a60209081526040808320815160c081018352815460ff16151581526001820180548451818702810187019095528085526060958795869586958695869591949293858401939092908301828280156107eb57602002820191906000526020600020905b8154815260200190600101908083116107d7575b505050505081526020016002820154815260200160038201548152602001600482015481526020016005820154815250509050806000015181602001518260400151836060015184608001518560a001519650965096509650965096505091939550919395565b61085a610991565b61086381610b76565b50565b6000610870610ad0565b6000848152600960205260408120549192509061088d9083611090565b9050600061089e82620f4240611053565b90506006548211156108b05760068290555b60075482106108c1576007546108c3565b815b6007556003546108d35780610906565b6003546108e1906001611000565b816003546005546108f29190611053565b6108fc9190611000565b6109069190611018565b6005556000858152600a6020908152604090912080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811782558651610958939290910191870190610c6c565b506000858152600a60205260408120426003808301919091556005909101859055805491610985836110c9565b91905055505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610a12576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610321565b565b60607f92fd13387c7fe7befbc38d303d6468778fb9731bc4583f17d92989c6fcfdeaaa82604051602401610a4d91511515815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915292915050565b60004661a4b1811480610ae5575062066eed81145b15610b6f57606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b815260040160206040518083038186803b158015610b3157600080fd5b505afa158015610b45573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b699190610d4d565b91505090565b4391505090565b73ffffffffffffffffffffffffffffffffffffffff8116331415610bf6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610321565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b828054828255906000526020600020908101928215610ca7579160200282015b82811115610ca7578251825591602001919060010190610c8c565b50610cb3929150610cb7565b5090565b5b80821115610cb35760008155600101610cb8565b803561ffff81168114610cde57600080fd5b919050565b803563ffffffff81168114610cde57600080fd5b600060208284031215610d0957600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610d2d57600080fd5b9392505050565b600060208284031215610d4657600080fd5b5035919050565b600060208284031215610d5f57600080fd5b5051919050565b60008060408385031215610d7957600080fd5b8235915060208084013567ffffffffffffffff80821115610d9957600080fd5b818601915086601f830112610dad57600080fd5b813581811115610dbf57610dbf611131565b8060051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f83011681018181108582111715610e0257610e02611131565b604052828152858101935084860182860187018b1015610e2157600080fd5b600095505b83861015610e44578035855260019590950194938601938601610e26565b508096505050505050509250929050565b600080600080600080600060e0888a031215610e7057600080fd5b87359650610e8060208901610ccc565b955060408801359450610e9560608901610ce3565b935060808801358015158114610eaa57600080fd5b9250610eb860a08901610ce3565b9150610ec660c08901610ccc565b905092959891949750929550565b600060c082018815158352602060c08185015281895180845260e086019150828b01935060005b81811015610f1757845183529383019391830191600101610efb565b505060408501989098525050506060810193909352608083019190915260a09091015292915050565b6000602080835283518184015280840151604084015261ffff6040850151166060840152606084015163ffffffff80821660808601528060808701511660a0860152505060a084015160c08085015280518060e086015260005b81811015610fb75782810184015186820161010001528301610f9a565b81811115610fca57600061010083880101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169390930161010001949350505050565b6000821982111561101357611013611102565b500190565b60008261104e577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561108b5761108b611102565b500290565b6000828210156110a2576110a2611102565b500390565b600061ffff808316818114156110bf576110bf611102565b6001019392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156110fb576110fb611102565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fdfea164736f6c6343000806000a",
+}
+
+var VRFV2PlusLoadTestWithMetricsABI = VRFV2PlusLoadTestWithMetricsMetaData.ABI
+
+var VRFV2PlusLoadTestWithMetricsBin = VRFV2PlusLoadTestWithMetricsMetaData.Bin
+
+func DeployVRFV2PlusLoadTestWithMetrics(auth *bind.TransactOpts, backend bind.ContractBackend, _vrfCoordinator common.Address) (common.Address, *types.Transaction, *VRFV2PlusLoadTestWithMetrics, error) {
+ parsed, err := VRFV2PlusLoadTestWithMetricsMetaData.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(VRFV2PlusLoadTestWithMetricsBin), backend, _vrfCoordinator)
+ if err != nil {
+ return common.Address{}, nil, nil, err
+ }
+ return address, tx, &VRFV2PlusLoadTestWithMetrics{VRFV2PlusLoadTestWithMetricsCaller: VRFV2PlusLoadTestWithMetricsCaller{contract: contract}, VRFV2PlusLoadTestWithMetricsTransactor: VRFV2PlusLoadTestWithMetricsTransactor{contract: contract}, VRFV2PlusLoadTestWithMetricsFilterer: VRFV2PlusLoadTestWithMetricsFilterer{contract: contract}}, nil
+}
+
+type VRFV2PlusLoadTestWithMetrics struct {
+ address common.Address
+ abi abi.ABI
+ VRFV2PlusLoadTestWithMetricsCaller
+ VRFV2PlusLoadTestWithMetricsTransactor
+ VRFV2PlusLoadTestWithMetricsFilterer
+}
+
+type VRFV2PlusLoadTestWithMetricsCaller struct {
+ contract *bind.BoundContract
+}
+
+type VRFV2PlusLoadTestWithMetricsTransactor struct {
+ contract *bind.BoundContract
+}
+
+type VRFV2PlusLoadTestWithMetricsFilterer struct {
+ contract *bind.BoundContract
+}
+
+type VRFV2PlusLoadTestWithMetricsSession struct {
+ Contract *VRFV2PlusLoadTestWithMetrics
+ CallOpts bind.CallOpts
+ TransactOpts bind.TransactOpts
+}
+
+type VRFV2PlusLoadTestWithMetricsCallerSession struct {
+ Contract *VRFV2PlusLoadTestWithMetricsCaller
+ CallOpts bind.CallOpts
+}
+
+type VRFV2PlusLoadTestWithMetricsTransactorSession struct {
+ Contract *VRFV2PlusLoadTestWithMetricsTransactor
+ TransactOpts bind.TransactOpts
+}
+
+type VRFV2PlusLoadTestWithMetricsRaw struct {
+ Contract *VRFV2PlusLoadTestWithMetrics
+}
+
+type VRFV2PlusLoadTestWithMetricsCallerRaw struct {
+ Contract *VRFV2PlusLoadTestWithMetricsCaller
+}
+
+type VRFV2PlusLoadTestWithMetricsTransactorRaw struct {
+ Contract *VRFV2PlusLoadTestWithMetricsTransactor
+}
+
+func NewVRFV2PlusLoadTestWithMetrics(address common.Address, backend bind.ContractBackend) (*VRFV2PlusLoadTestWithMetrics, error) {
+ abi, err := abi.JSON(strings.NewReader(VRFV2PlusLoadTestWithMetricsABI))
+ if err != nil {
+ return nil, err
+ }
+ contract, err := bindVRFV2PlusLoadTestWithMetrics(address, backend, backend, backend)
+ if err != nil {
+ return nil, err
+ }
+ return &VRFV2PlusLoadTestWithMetrics{address: address, abi: abi, VRFV2PlusLoadTestWithMetricsCaller: VRFV2PlusLoadTestWithMetricsCaller{contract: contract}, VRFV2PlusLoadTestWithMetricsTransactor: VRFV2PlusLoadTestWithMetricsTransactor{contract: contract}, VRFV2PlusLoadTestWithMetricsFilterer: VRFV2PlusLoadTestWithMetricsFilterer{contract: contract}}, nil
+}
+
+func NewVRFV2PlusLoadTestWithMetricsCaller(address common.Address, caller bind.ContractCaller) (*VRFV2PlusLoadTestWithMetricsCaller, error) {
+ contract, err := bindVRFV2PlusLoadTestWithMetrics(address, caller, nil, nil)
+ if err != nil {
+ return nil, err
+ }
+ return &VRFV2PlusLoadTestWithMetricsCaller{contract: contract}, nil
+}
+
+func NewVRFV2PlusLoadTestWithMetricsTransactor(address common.Address, transactor bind.ContractTransactor) (*VRFV2PlusLoadTestWithMetricsTransactor, error) {
+ contract, err := bindVRFV2PlusLoadTestWithMetrics(address, nil, transactor, nil)
+ if err != nil {
+ return nil, err
+ }
+ return &VRFV2PlusLoadTestWithMetricsTransactor{contract: contract}, nil
+}
+
+func NewVRFV2PlusLoadTestWithMetricsFilterer(address common.Address, filterer bind.ContractFilterer) (*VRFV2PlusLoadTestWithMetricsFilterer, error) {
+ contract, err := bindVRFV2PlusLoadTestWithMetrics(address, nil, nil, filterer)
+ if err != nil {
+ return nil, err
+ }
+ return &VRFV2PlusLoadTestWithMetricsFilterer{contract: contract}, nil
+}
+
+func bindVRFV2PlusLoadTestWithMetrics(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) {
+ parsed, err := VRFV2PlusLoadTestWithMetricsMetaData.GetAbi()
+ if err != nil {
+ return nil, err
+ }
+ return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil
+}
+
+func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
+ return _VRFV2PlusLoadTestWithMetrics.Contract.VRFV2PlusLoadTestWithMetricsCaller.contract.Call(opts, result, method, params...)
+}
+
+func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _VRFV2PlusLoadTestWithMetrics.Contract.VRFV2PlusLoadTestWithMetricsTransactor.contract.Transfer(opts)
+}
+
+func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+ return _VRFV2PlusLoadTestWithMetrics.Contract.VRFV2PlusLoadTestWithMetricsTransactor.contract.Transact(opts, method, params...)
+}
+
+func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
+ return _VRFV2PlusLoadTestWithMetrics.Contract.contract.Call(opts, result, method, params...)
+}
+
+func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _VRFV2PlusLoadTestWithMetrics.Contract.contract.Transfer(opts)
+}
+
+func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+ return _VRFV2PlusLoadTestWithMetrics.Contract.contract.Transact(opts, method, params...)
+}
+
+func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsCaller) GetRequestStatus(opts *bind.CallOpts, _requestId *big.Int) (GetRequestStatus,
+
+ error) {
+ var out []interface{}
+ err := _VRFV2PlusLoadTestWithMetrics.contract.Call(opts, &out, "getRequestStatus", _requestId)
+
+ outstruct := new(GetRequestStatus)
+ if err != nil {
+ return *outstruct, err
+ }
+
+ outstruct.Fulfilled = *abi.ConvertType(out[0], new(bool)).(*bool)
+ outstruct.RandomWords = *abi.ConvertType(out[1], new([]*big.Int)).(*[]*big.Int)
+ outstruct.RequestTimestamp = *abi.ConvertType(out[2], new(*big.Int)).(**big.Int)
+ outstruct.FulfilmentTimestamp = *abi.ConvertType(out[3], new(*big.Int)).(**big.Int)
+ outstruct.RequestBlockNumber = *abi.ConvertType(out[4], new(*big.Int)).(**big.Int)
+ outstruct.FulfilmentBlockNumber = *abi.ConvertType(out[5], new(*big.Int)).(**big.Int)
+
+ return *outstruct, err
+
+}
+
+func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsSession) GetRequestStatus(_requestId *big.Int) (GetRequestStatus,
+
+ error) {
+ return _VRFV2PlusLoadTestWithMetrics.Contract.GetRequestStatus(&_VRFV2PlusLoadTestWithMetrics.CallOpts, _requestId)
+}
+
+func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsCallerSession) GetRequestStatus(_requestId *big.Int) (GetRequestStatus,
+
+ error) {
+ return _VRFV2PlusLoadTestWithMetrics.Contract.GetRequestStatus(&_VRFV2PlusLoadTestWithMetrics.CallOpts, _requestId)
+}
+
+func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsCaller) Owner(opts *bind.CallOpts) (common.Address, error) {
+ var out []interface{}
+ err := _VRFV2PlusLoadTestWithMetrics.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 (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsSession) Owner() (common.Address, error) {
+ return _VRFV2PlusLoadTestWithMetrics.Contract.Owner(&_VRFV2PlusLoadTestWithMetrics.CallOpts)
+}
+
+func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsCallerSession) Owner() (common.Address, error) {
+ return _VRFV2PlusLoadTestWithMetrics.Contract.Owner(&_VRFV2PlusLoadTestWithMetrics.CallOpts)
+}
+
+func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsCaller) SAverageFulfillmentInMillions(opts *bind.CallOpts) (*big.Int, error) {
+ var out []interface{}
+ err := _VRFV2PlusLoadTestWithMetrics.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 (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsSession) SAverageFulfillmentInMillions() (*big.Int, error) {
+ return _VRFV2PlusLoadTestWithMetrics.Contract.SAverageFulfillmentInMillions(&_VRFV2PlusLoadTestWithMetrics.CallOpts)
+}
+
+func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsCallerSession) SAverageFulfillmentInMillions() (*big.Int, error) {
+ return _VRFV2PlusLoadTestWithMetrics.Contract.SAverageFulfillmentInMillions(&_VRFV2PlusLoadTestWithMetrics.CallOpts)
+}
+
+func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsCaller) SFastestFulfillment(opts *bind.CallOpts) (*big.Int, error) {
+ var out []interface{}
+ err := _VRFV2PlusLoadTestWithMetrics.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 (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsSession) SFastestFulfillment() (*big.Int, error) {
+ return _VRFV2PlusLoadTestWithMetrics.Contract.SFastestFulfillment(&_VRFV2PlusLoadTestWithMetrics.CallOpts)
+}
+
+func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsCallerSession) SFastestFulfillment() (*big.Int, error) {
+ return _VRFV2PlusLoadTestWithMetrics.Contract.SFastestFulfillment(&_VRFV2PlusLoadTestWithMetrics.CallOpts)
+}
+
+func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsCaller) SLastRequestId(opts *bind.CallOpts) (*big.Int, error) {
+ var out []interface{}
+ err := _VRFV2PlusLoadTestWithMetrics.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 (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsSession) SLastRequestId() (*big.Int, error) {
+ return _VRFV2PlusLoadTestWithMetrics.Contract.SLastRequestId(&_VRFV2PlusLoadTestWithMetrics.CallOpts)
+}
+
+func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsCallerSession) SLastRequestId() (*big.Int, error) {
+ return _VRFV2PlusLoadTestWithMetrics.Contract.SLastRequestId(&_VRFV2PlusLoadTestWithMetrics.CallOpts)
+}
+
+func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsCaller) SRequestCount(opts *bind.CallOpts) (*big.Int, error) {
+ var out []interface{}
+ err := _VRFV2PlusLoadTestWithMetrics.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 (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsSession) SRequestCount() (*big.Int, error) {
+ return _VRFV2PlusLoadTestWithMetrics.Contract.SRequestCount(&_VRFV2PlusLoadTestWithMetrics.CallOpts)
+}
+
+func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsCallerSession) SRequestCount() (*big.Int, error) {
+ return _VRFV2PlusLoadTestWithMetrics.Contract.SRequestCount(&_VRFV2PlusLoadTestWithMetrics.CallOpts)
+}
+
+func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsCaller) SRequests(opts *bind.CallOpts, arg0 *big.Int) (SRequests,
+
+ error) {
+ var out []interface{}
+ err := _VRFV2PlusLoadTestWithMetrics.contract.Call(opts, &out, "s_requests", arg0)
+
+ outstruct := new(SRequests)
+ if err != nil {
+ return *outstruct, err
+ }
+
+ outstruct.Fulfilled = *abi.ConvertType(out[0], new(bool)).(*bool)
+ outstruct.RequestTimestamp = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int)
+ outstruct.FulfilmentTimestamp = *abi.ConvertType(out[2], new(*big.Int)).(**big.Int)
+ outstruct.RequestBlockNumber = *abi.ConvertType(out[3], new(*big.Int)).(**big.Int)
+ outstruct.FulfilmentBlockNumber = *abi.ConvertType(out[4], new(*big.Int)).(**big.Int)
+
+ return *outstruct, err
+
+}
+
+func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsSession) SRequests(arg0 *big.Int) (SRequests,
+
+ error) {
+ return _VRFV2PlusLoadTestWithMetrics.Contract.SRequests(&_VRFV2PlusLoadTestWithMetrics.CallOpts, arg0)
+}
+
+func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsCallerSession) SRequests(arg0 *big.Int) (SRequests,
+
+ error) {
+ return _VRFV2PlusLoadTestWithMetrics.Contract.SRequests(&_VRFV2PlusLoadTestWithMetrics.CallOpts, arg0)
+}
+
+func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsCaller) SResponseCount(opts *bind.CallOpts) (*big.Int, error) {
+ var out []interface{}
+ err := _VRFV2PlusLoadTestWithMetrics.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 (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsSession) SResponseCount() (*big.Int, error) {
+ return _VRFV2PlusLoadTestWithMetrics.Contract.SResponseCount(&_VRFV2PlusLoadTestWithMetrics.CallOpts)
+}
+
+func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsCallerSession) SResponseCount() (*big.Int, error) {
+ return _VRFV2PlusLoadTestWithMetrics.Contract.SResponseCount(&_VRFV2PlusLoadTestWithMetrics.CallOpts)
+}
+
+func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsCaller) SSlowestFulfillment(opts *bind.CallOpts) (*big.Int, error) {
+ var out []interface{}
+ err := _VRFV2PlusLoadTestWithMetrics.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 (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsSession) SSlowestFulfillment() (*big.Int, error) {
+ return _VRFV2PlusLoadTestWithMetrics.Contract.SSlowestFulfillment(&_VRFV2PlusLoadTestWithMetrics.CallOpts)
+}
+
+func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsCallerSession) SSlowestFulfillment() (*big.Int, error) {
+ return _VRFV2PlusLoadTestWithMetrics.Contract.SSlowestFulfillment(&_VRFV2PlusLoadTestWithMetrics.CallOpts)
+}
+
+func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsCaller) SVrfCoordinator(opts *bind.CallOpts) (common.Address, error) {
+ var out []interface{}
+ err := _VRFV2PlusLoadTestWithMetrics.contract.Call(opts, &out, "s_vrfCoordinator")
+
+ if err != nil {
+ return *new(common.Address), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address)
+
+ return out0, err
+
+}
+
+func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsSession) SVrfCoordinator() (common.Address, error) {
+ return _VRFV2PlusLoadTestWithMetrics.Contract.SVrfCoordinator(&_VRFV2PlusLoadTestWithMetrics.CallOpts)
+}
+
+func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsCallerSession) SVrfCoordinator() (common.Address, error) {
+ return _VRFV2PlusLoadTestWithMetrics.Contract.SVrfCoordinator(&_VRFV2PlusLoadTestWithMetrics.CallOpts)
+}
+
+func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _VRFV2PlusLoadTestWithMetrics.contract.Transact(opts, "acceptOwnership")
+}
+
+func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsSession) AcceptOwnership() (*types.Transaction, error) {
+ return _VRFV2PlusLoadTestWithMetrics.Contract.AcceptOwnership(&_VRFV2PlusLoadTestWithMetrics.TransactOpts)
+}
+
+func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsTransactorSession) AcceptOwnership() (*types.Transaction, error) {
+ return _VRFV2PlusLoadTestWithMetrics.Contract.AcceptOwnership(&_VRFV2PlusLoadTestWithMetrics.TransactOpts)
+}
+
+func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsTransactor) RawFulfillRandomWords(opts *bind.TransactOpts, requestId *big.Int, randomWords []*big.Int) (*types.Transaction, error) {
+ return _VRFV2PlusLoadTestWithMetrics.contract.Transact(opts, "rawFulfillRandomWords", requestId, randomWords)
+}
+
+func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsSession) RawFulfillRandomWords(requestId *big.Int, randomWords []*big.Int) (*types.Transaction, error) {
+ return _VRFV2PlusLoadTestWithMetrics.Contract.RawFulfillRandomWords(&_VRFV2PlusLoadTestWithMetrics.TransactOpts, requestId, randomWords)
+}
+
+func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsTransactorSession) RawFulfillRandomWords(requestId *big.Int, randomWords []*big.Int) (*types.Transaction, error) {
+ return _VRFV2PlusLoadTestWithMetrics.Contract.RawFulfillRandomWords(&_VRFV2PlusLoadTestWithMetrics.TransactOpts, requestId, randomWords)
+}
+
+func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsTransactor) RequestRandomWords(opts *bind.TransactOpts, _subId *big.Int, _requestConfirmations uint16, _keyHash [32]byte, _callbackGasLimit uint32, _nativePayment bool, _numWords uint32, _requestCount uint16) (*types.Transaction, error) {
+ return _VRFV2PlusLoadTestWithMetrics.contract.Transact(opts, "requestRandomWords", _subId, _requestConfirmations, _keyHash, _callbackGasLimit, _nativePayment, _numWords, _requestCount)
+}
+
+func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsSession) RequestRandomWords(_subId *big.Int, _requestConfirmations uint16, _keyHash [32]byte, _callbackGasLimit uint32, _nativePayment bool, _numWords uint32, _requestCount uint16) (*types.Transaction, error) {
+ return _VRFV2PlusLoadTestWithMetrics.Contract.RequestRandomWords(&_VRFV2PlusLoadTestWithMetrics.TransactOpts, _subId, _requestConfirmations, _keyHash, _callbackGasLimit, _nativePayment, _numWords, _requestCount)
+}
+
+func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsTransactorSession) RequestRandomWords(_subId *big.Int, _requestConfirmations uint16, _keyHash [32]byte, _callbackGasLimit uint32, _nativePayment bool, _numWords uint32, _requestCount uint16) (*types.Transaction, error) {
+ return _VRFV2PlusLoadTestWithMetrics.Contract.RequestRandomWords(&_VRFV2PlusLoadTestWithMetrics.TransactOpts, _subId, _requestConfirmations, _keyHash, _callbackGasLimit, _nativePayment, _numWords, _requestCount)
+}
+
+func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsTransactor) Reset(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _VRFV2PlusLoadTestWithMetrics.contract.Transact(opts, "reset")
+}
+
+func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsSession) Reset() (*types.Transaction, error) {
+ return _VRFV2PlusLoadTestWithMetrics.Contract.Reset(&_VRFV2PlusLoadTestWithMetrics.TransactOpts)
+}
+
+func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsTransactorSession) Reset() (*types.Transaction, error) {
+ return _VRFV2PlusLoadTestWithMetrics.Contract.Reset(&_VRFV2PlusLoadTestWithMetrics.TransactOpts)
+}
+
+func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsTransactor) SetCoordinator(opts *bind.TransactOpts, _vrfCoordinator common.Address) (*types.Transaction, error) {
+ return _VRFV2PlusLoadTestWithMetrics.contract.Transact(opts, "setCoordinator", _vrfCoordinator)
+}
+
+func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsSession) SetCoordinator(_vrfCoordinator common.Address) (*types.Transaction, error) {
+ return _VRFV2PlusLoadTestWithMetrics.Contract.SetCoordinator(&_VRFV2PlusLoadTestWithMetrics.TransactOpts, _vrfCoordinator)
+}
+
+func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsTransactorSession) SetCoordinator(_vrfCoordinator common.Address) (*types.Transaction, error) {
+ return _VRFV2PlusLoadTestWithMetrics.Contract.SetCoordinator(&_VRFV2PlusLoadTestWithMetrics.TransactOpts, _vrfCoordinator)
+}
+
+func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) {
+ return _VRFV2PlusLoadTestWithMetrics.contract.Transact(opts, "transferOwnership", to)
+}
+
+func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsSession) TransferOwnership(to common.Address) (*types.Transaction, error) {
+ return _VRFV2PlusLoadTestWithMetrics.Contract.TransferOwnership(&_VRFV2PlusLoadTestWithMetrics.TransactOpts, to)
+}
+
+func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) {
+ return _VRFV2PlusLoadTestWithMetrics.Contract.TransferOwnership(&_VRFV2PlusLoadTestWithMetrics.TransactOpts, to)
+}
+
+type VRFV2PlusLoadTestWithMetricsOwnershipTransferRequestedIterator struct {
+ Event *VRFV2PlusLoadTestWithMetricsOwnershipTransferRequested
+
+ contract *bind.BoundContract
+ event string
+
+ logs chan types.Log
+ sub ethereum.Subscription
+ done bool
+ fail error
+}
+
+func (it *VRFV2PlusLoadTestWithMetricsOwnershipTransferRequestedIterator) Next() bool {
+
+ if it.fail != nil {
+ return false
+ }
+
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(VRFV2PlusLoadTestWithMetricsOwnershipTransferRequested)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+
+ select {
+ case log := <-it.logs:
+ it.Event = new(VRFV2PlusLoadTestWithMetricsOwnershipTransferRequested)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+func (it *VRFV2PlusLoadTestWithMetricsOwnershipTransferRequestedIterator) Error() error {
+ return it.fail
+}
+
+func (it *VRFV2PlusLoadTestWithMetricsOwnershipTransferRequestedIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+type VRFV2PlusLoadTestWithMetricsOwnershipTransferRequested struct {
+ From common.Address
+ To common.Address
+ Raw types.Log
+}
+
+func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VRFV2PlusLoadTestWithMetricsOwnershipTransferRequestedIterator, 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 := _VRFV2PlusLoadTestWithMetrics.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule)
+ if err != nil {
+ return nil, err
+ }
+ return &VRFV2PlusLoadTestWithMetricsOwnershipTransferRequestedIterator{contract: _VRFV2PlusLoadTestWithMetrics.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil
+}
+
+func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *VRFV2PlusLoadTestWithMetricsOwnershipTransferRequested, 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 := _VRFV2PlusLoadTestWithMetrics.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(VRFV2PlusLoadTestWithMetricsOwnershipTransferRequested)
+ if err := _VRFV2PlusLoadTestWithMetrics.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 (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsFilterer) ParseOwnershipTransferRequested(log types.Log) (*VRFV2PlusLoadTestWithMetricsOwnershipTransferRequested, error) {
+ event := new(VRFV2PlusLoadTestWithMetricsOwnershipTransferRequested)
+ if err := _VRFV2PlusLoadTestWithMetrics.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil {
+ return nil, err
+ }
+ event.Raw = log
+ return event, nil
+}
+
+type VRFV2PlusLoadTestWithMetricsOwnershipTransferredIterator struct {
+ Event *VRFV2PlusLoadTestWithMetricsOwnershipTransferred
+
+ contract *bind.BoundContract
+ event string
+
+ logs chan types.Log
+ sub ethereum.Subscription
+ done bool
+ fail error
+}
+
+func (it *VRFV2PlusLoadTestWithMetricsOwnershipTransferredIterator) Next() bool {
+
+ if it.fail != nil {
+ return false
+ }
+
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(VRFV2PlusLoadTestWithMetricsOwnershipTransferred)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+
+ select {
+ case log := <-it.logs:
+ it.Event = new(VRFV2PlusLoadTestWithMetricsOwnershipTransferred)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+func (it *VRFV2PlusLoadTestWithMetricsOwnershipTransferredIterator) Error() error {
+ return it.fail
+}
+
+func (it *VRFV2PlusLoadTestWithMetricsOwnershipTransferredIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+type VRFV2PlusLoadTestWithMetricsOwnershipTransferred struct {
+ From common.Address
+ To common.Address
+ Raw types.Log
+}
+
+func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VRFV2PlusLoadTestWithMetricsOwnershipTransferredIterator, 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 := _VRFV2PlusLoadTestWithMetrics.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule)
+ if err != nil {
+ return nil, err
+ }
+ return &VRFV2PlusLoadTestWithMetricsOwnershipTransferredIterator{contract: _VRFV2PlusLoadTestWithMetrics.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil
+}
+
+func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *VRFV2PlusLoadTestWithMetricsOwnershipTransferred, 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 := _VRFV2PlusLoadTestWithMetrics.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(VRFV2PlusLoadTestWithMetricsOwnershipTransferred)
+ if err := _VRFV2PlusLoadTestWithMetrics.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 (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsFilterer) ParseOwnershipTransferred(log types.Log) (*VRFV2PlusLoadTestWithMetricsOwnershipTransferred, error) {
+ event := new(VRFV2PlusLoadTestWithMetricsOwnershipTransferred)
+ if err := _VRFV2PlusLoadTestWithMetrics.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil {
+ return nil, err
+ }
+ event.Raw = log
+ return event, nil
+}
+
+type GetRequestStatus struct {
+ Fulfilled bool
+ RandomWords []*big.Int
+ RequestTimestamp *big.Int
+ FulfilmentTimestamp *big.Int
+ RequestBlockNumber *big.Int
+ FulfilmentBlockNumber *big.Int
+}
+type SRequests struct {
+ Fulfilled bool
+ RequestTimestamp *big.Int
+ FulfilmentTimestamp *big.Int
+ RequestBlockNumber *big.Int
+ FulfilmentBlockNumber *big.Int
+}
+
+func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetrics) ParseLog(log types.Log) (generated.AbigenLog, error) {
+ switch log.Topics[0] {
+ case _VRFV2PlusLoadTestWithMetrics.abi.Events["OwnershipTransferRequested"].ID:
+ return _VRFV2PlusLoadTestWithMetrics.ParseOwnershipTransferRequested(log)
+ case _VRFV2PlusLoadTestWithMetrics.abi.Events["OwnershipTransferred"].ID:
+ return _VRFV2PlusLoadTestWithMetrics.ParseOwnershipTransferred(log)
+
+ default:
+ return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0])
+ }
+}
+
+func (VRFV2PlusLoadTestWithMetricsOwnershipTransferRequested) Topic() common.Hash {
+ return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278")
+}
+
+func (VRFV2PlusLoadTestWithMetricsOwnershipTransferred) Topic() common.Hash {
+ return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0")
+}
+
+func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetrics) Address() common.Address {
+ return _VRFV2PlusLoadTestWithMetrics.address
+}
+
+type VRFV2PlusLoadTestWithMetricsInterface interface {
+ GetRequestStatus(opts *bind.CallOpts, _requestId *big.Int) (GetRequestStatus,
+
+ error)
+
+ Owner(opts *bind.CallOpts) (common.Address, error)
+
+ SAverageFulfillmentInMillions(opts *bind.CallOpts) (*big.Int, error)
+
+ SFastestFulfillment(opts *bind.CallOpts) (*big.Int, error)
+
+ SLastRequestId(opts *bind.CallOpts) (*big.Int, error)
+
+ SRequestCount(opts *bind.CallOpts) (*big.Int, error)
+
+ SRequests(opts *bind.CallOpts, arg0 *big.Int) (SRequests,
+
+ error)
+
+ SResponseCount(opts *bind.CallOpts) (*big.Int, error)
+
+ SSlowestFulfillment(opts *bind.CallOpts) (*big.Int, error)
+
+ SVrfCoordinator(opts *bind.CallOpts) (common.Address, error)
+
+ AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error)
+
+ RawFulfillRandomWords(opts *bind.TransactOpts, requestId *big.Int, randomWords []*big.Int) (*types.Transaction, error)
+
+ RequestRandomWords(opts *bind.TransactOpts, _subId *big.Int, _requestConfirmations uint16, _keyHash [32]byte, _callbackGasLimit uint32, _nativePayment bool, _numWords uint32, _requestCount uint16) (*types.Transaction, error)
+
+ Reset(opts *bind.TransactOpts) (*types.Transaction, error)
+
+ SetCoordinator(opts *bind.TransactOpts, _vrfCoordinator common.Address) (*types.Transaction, error)
+
+ TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error)
+
+ FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VRFV2PlusLoadTestWithMetricsOwnershipTransferRequestedIterator, error)
+
+ WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *VRFV2PlusLoadTestWithMetricsOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error)
+
+ ParseOwnershipTransferRequested(log types.Log) (*VRFV2PlusLoadTestWithMetricsOwnershipTransferRequested, error)
+
+ FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VRFV2PlusLoadTestWithMetricsOwnershipTransferredIterator, error)
+
+ WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *VRFV2PlusLoadTestWithMetricsOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error)
+
+ ParseOwnershipTransferred(log types.Log) (*VRFV2PlusLoadTestWithMetricsOwnershipTransferred, error)
+
+ ParseLog(log types.Log) (generated.AbigenLog, error)
+
+ Address() common.Address
+}
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 b6c1f6051e5..6e0f5f3ccd8 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,8 +31,8 @@ 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\":[{\"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: "0x60806040523480156200001157600080fd5b506040516200182138038062001821833981016040819052620000349162000464565b8633806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf81620001b4565b5050600280546001600160a01b03199081166001600160a01b03948516179091556003805482168b8516179055600480548216938a169390931790925550600b80543392169190911790556040805160c081018252600080825263ffffffff8881166020840181905261ffff8916948401859052908716606084018190526080840187905285151560a09094018490526005929092556006805465ffffffffffff19169091176401000000009094029390931763ffffffff60301b191666010000000000009091021790915560078390556008805460ff19169091179055620001a762000260565b5050505050505062000530565b6001600160a01b0381163314156200020f5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6200026a620003d4565b604080516001808252818301909252600091602080830190803683370190505090503081600081518110620002a357620002a36200051a565b6001600160a01b039283166020918202929092018101919091526003546040805163288688f960e21b81529051919093169263a21a23e49260048083019391928290030181600087803b158015620002fa57600080fd5b505af11580156200030f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000335919062000500565b600581905560035482516001600160a01b039091169163bec4c08c9184906000906200036557620003656200051a565b60200260200101516040518363ffffffff1660e01b81526004016200039d9291909182526001600160a01b0316602082015260400190565b600060405180830381600087803b158015620003b857600080fd5b505af1158015620003cd573d6000803e3d6000fd5b5050505050565b6000546001600160a01b03163314620004305760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640162000083565b565b80516001600160a01b03811681146200044a57600080fd5b919050565b805163ffffffff811681146200044a57600080fd5b600080600080600080600060e0888a0312156200048057600080fd5b6200048b8862000432565b96506200049b6020890162000432565b9550620004ab604089016200044f565b9450606088015161ffff81168114620004c357600080fd5b9350620004d3608089016200044f565b925060a0880151915060c08801518015158114620004f057600080fd5b8091505092959891949750929550565b6000602082840312156200051357600080fd5b5051919050565b634e487b7160e01b600052603260045260246000fd5b6112e180620005406000396000f3fe608060405234801561001057600080fd5b50600436106100e95760003560e01c80638da5cb5b1161008c578063e0c8628911610066578063e0c862891461021a578063e89e106a14610222578063f2fde38b14610239578063f6eaffc81461024c57600080fd5b80638da5cb5b146101d75780638ea98117146101ff5780638f449a051461021257600080fd5b80637262561c116100c85780637262561c1461012957806379ba50971461013c5780637db9263f1461014457806386850e93146101c457600080fd5b8062f714ce146100ee5780631fe543e3146101035780636fd700bb14610116575b600080fd5b6101016100fc36600461104d565b61025f565b005b610101610111366004611079565b61031a565b61010161012436600461101b565b6103a0565b610101610137366004610fd7565b6105d6565b610101610676565b600554600654600754600854610180939263ffffffff8082169361ffff6401000000008404169366010000000000009093049091169160ff1686565b6040805196875263ffffffff958616602088015261ffff90941693860193909352921660608401526080830191909152151560a082015260c0015b60405180910390f35b6101016101d236600461101b565b610773565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101bb565b61010161020d366004610fd7565b610849565b610101610954565b610101610af9565b61022b600a5481565b6040519081526020016101bb565b610101610247366004610fd7565b610c66565b61022b61025a36600461101b565b610c7a565b610267610c9b565b600480546040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff848116938201939093526024810185905291169063a9059cbb90604401602060405180830381600087803b1580156102dd57600080fd5b505af11580156102f1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103159190610ff9565b505050565b60025473ffffffffffffffffffffffffffffffffffffffff163314610392576002546040517f1cf993f400000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff90911660248201526044015b60405180910390fd5b61039c8282610d1e565b5050565b6103a8610c9b565b6040805160c08101825260055480825260065463ffffffff808216602080860191909152640100000000830461ffff16858701526601000000000000909204166060840152600754608084015260085460ff16151560a0840152600454600354855192830193909352929373ffffffffffffffffffffffffffffffffffffffff93841693634000aea09316918691016040516020818303038152906040526040518463ffffffff1660e01b8152600401610464939291906111d3565b602060405180830381600087803b15801561047e57600080fd5b505af1158015610492573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b69190610ff9565b5060006040518060c001604052808360800151815260200183600001518152602001836040015161ffff168152602001836020015163ffffffff168152602001836060015163ffffffff16815260200161052360405180602001604052808660a001511515815250610d9c565b90526003546040517f9b1c385e00000000000000000000000000000000000000000000000000000000815291925073ffffffffffffffffffffffffffffffffffffffff1690639b1c385e9061057c908490600401611211565b602060405180830381600087803b15801561059657600080fd5b505af11580156105aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105ce9190611034565b600a55505050565b6105de610c9b565b6003546005546040517f0ae09540000000000000000000000000000000000000000000000000000000008152600481019190915273ffffffffffffffffffffffffffffffffffffffff838116602483015290911690630ae0954090604401600060405180830381600087803b15801561065657600080fd5b505af115801561066a573d6000803e3d6000fd5b50506000600555505050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146106f7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610389565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b61077b610c9b565b6004546003546005546040805160208082019390935281518082039093018352808201918290527f4000aea00000000000000000000000000000000000000000000000000000000090915273ffffffffffffffffffffffffffffffffffffffff93841693634000aea0936107f7939116918691906044016111d3565b602060405180830381600087803b15801561081157600080fd5b505af1158015610825573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061039c9190610ff9565b60005473ffffffffffffffffffffffffffffffffffffffff163314801590610889575060025473ffffffffffffffffffffffffffffffffffffffff163314155b1561090d57336108ae60005473ffffffffffffffffffffffffffffffffffffffff1690565b6002546040517f061db9c100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201529183166024830152919091166044820152606401610389565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b61095c610c9b565b60408051600180825281830190925260009160208083019080368337019050509050308160008151811061099257610992611276565b73ffffffffffffffffffffffffffffffffffffffff928316602091820292909201810191909152600354604080517fa21a23e40000000000000000000000000000000000000000000000000000000081529051919093169263a21a23e49260048083019391928290030181600087803b158015610a0e57600080fd5b505af1158015610a22573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a469190611034565b6005819055600354825173ffffffffffffffffffffffffffffffffffffffff9091169163bec4c08c918490600090610a8057610a80611276565b60200260200101516040518363ffffffff1660e01b8152600401610ac492919091825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b600060405180830381600087803b158015610ade57600080fd5b505af1158015610af2573d6000803e3d6000fd5b5050505050565b610b01610c9b565b6040805160c08082018352600554825260065463ffffffff808216602080860191825261ffff640100000000850481168789019081526601000000000000909504841660608089019182526007546080808b0191825260085460ff16151560a0808d019182528d519b8c018e5292518b528b518b8801529851909416898c0152945186169088015251909316928501929092528551918201909552905115158152919260009290820190610bb490610d9c565b90526003546040517f9b1c385e00000000000000000000000000000000000000000000000000000000815291925073ffffffffffffffffffffffffffffffffffffffff1690639b1c385e90610c0d908490600401611211565b602060405180830381600087803b158015610c2757600080fd5b505af1158015610c3b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c5f9190611034565b600a555050565b610c6e610c9b565b610c7781610e58565b50565b60098181548110610c8a57600080fd5b600091825260209091200154905081565b60005473ffffffffffffffffffffffffffffffffffffffff163314610d1c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610389565b565b600a548214610d89576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f7265717565737420494420697320696e636f72726563740000000000000000006044820152606401610389565b8051610315906009906020840190610f4e565b60607f92fd13387c7fe7befbc38d303d6468778fb9731bc4583f17d92989c6fcfdeaaa82604051602401610dd591511515815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915292915050565b73ffffffffffffffffffffffffffffffffffffffff8116331415610ed8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610389565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b828054828255906000526020600020908101928215610f89579160200282015b82811115610f89578251825591602001919060010190610f6e565b50610f95929150610f99565b5090565b5b80821115610f955760008155600101610f9a565b803573ffffffffffffffffffffffffffffffffffffffff81168114610fd257600080fd5b919050565b600060208284031215610fe957600080fd5b610ff282610fae565b9392505050565b60006020828403121561100b57600080fd5b81518015158114610ff257600080fd5b60006020828403121561102d57600080fd5b5035919050565b60006020828403121561104657600080fd5b5051919050565b6000806040838503121561106057600080fd5b8235915061107060208401610fae565b90509250929050565b6000806040838503121561108c57600080fd5b8235915060208084013567ffffffffffffffff808211156110ac57600080fd5b818601915086601f8301126110c057600080fd5b8135818111156110d2576110d26112a5565b8060051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f83011681018181108582111715611115576111156112a5565b604052828152858101935084860182860187018b101561113457600080fd5b600095505b83861015611157578035855260019590950194938601938601611139565b508096505050505050509250929050565b6000815180845260005b8181101561118e57602081850181015186830182015201611172565b818111156111a0576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b73ffffffffffffffffffffffffffffffffffffffff841681528260208201526060604082015260006112086060830184611168565b95945050505050565b60208152815160208201526020820151604082015261ffff60408301511660608201526000606083015163ffffffff80821660808501528060808601511660a0850152505060a083015160c08084015261126e60e0840182611168565b949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fdfea164736f6c6343000806000a",
+ 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",
}
var VRFV2PlusSingleConsumerExampleABI = VRFV2PlusSingleConsumerExampleMetaData.ABI
@@ -271,6 +271,28 @@ func (_VRFV2PlusSingleConsumerExample *VRFV2PlusSingleConsumerExampleCallerSessi
return _VRFV2PlusSingleConsumerExample.Contract.SRequestId(&_VRFV2PlusSingleConsumerExample.CallOpts)
}
+func (_VRFV2PlusSingleConsumerExample *VRFV2PlusSingleConsumerExampleCaller) SVrfCoordinator(opts *bind.CallOpts) (common.Address, error) {
+ var out []interface{}
+ err := _VRFV2PlusSingleConsumerExample.contract.Call(opts, &out, "s_vrfCoordinator")
+
+ if err != nil {
+ return *new(common.Address), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address)
+
+ return out0, err
+
+}
+
+func (_VRFV2PlusSingleConsumerExample *VRFV2PlusSingleConsumerExampleSession) SVrfCoordinator() (common.Address, error) {
+ return _VRFV2PlusSingleConsumerExample.Contract.SVrfCoordinator(&_VRFV2PlusSingleConsumerExample.CallOpts)
+}
+
+func (_VRFV2PlusSingleConsumerExample *VRFV2PlusSingleConsumerExampleCallerSession) SVrfCoordinator() (common.Address, error) {
+ return _VRFV2PlusSingleConsumerExample.Contract.SVrfCoordinator(&_VRFV2PlusSingleConsumerExample.CallOpts)
+}
+
func (_VRFV2PlusSingleConsumerExample *VRFV2PlusSingleConsumerExampleTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) {
return _VRFV2PlusSingleConsumerExample.contract.Transact(opts, "acceptOwnership")
}
@@ -707,6 +729,8 @@ type VRFV2PlusSingleConsumerExampleInterface interface {
SRequestId(opts *bind.CallOpts) (*big.Int, error)
+ SVrfCoordinator(opts *bind.CallOpts) (common.Address, error)
+
AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error)
FundAndRequestRandomWords(opts *bind.TransactOpts, amount *big.Int) (*types.Transaction, error)
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 a3b8aed8cd5..34108bea1dc 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,8 +31,8 @@ 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\":[{\"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: "0x608060405234801561001057600080fd5b50604051610d25380380610d2583398101604081905261002f916101d0565b8133806000816100865760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b03848116919091179091558116156100b6576100b68161010a565b5050600280546001600160a01b039384166001600160a01b03199182161790915560038054958416958216959095179094555060048054929091169183169190911790556007805490911633179055610203565b6001600160a01b0381163314156101635760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161007d565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b03811681146101cb57600080fd5b919050565b600080604083850312156101e357600080fd5b6101ec836101b4565b91506101fa602084016101b4565b90509250929050565b610b13806102126000396000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c80638ea981171161005b5780638ea98117146100ea578063e89e106a146100fd578063f2fde38b14610114578063f6eaffc81461012757600080fd5b80631fe543e31461008d5780635b6c5de8146100a257806379ba5097146100b55780638da5cb5b146100bd575b600080fd5b6100a061009b3660046108b0565b61013a565b005b6100a06100b036600461099f565b6101c0565b6100a06102d3565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6100a06100f8366004610841565b6103d0565b61010660065481565b6040519081526020016100e1565b6100a0610122366004610841565b6104db565b61010661013536600461087e565b6104ef565b60025473ffffffffffffffffffffffffffffffffffffffff1633146101b2576002546040517f1cf993f400000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff90911660248201526044015b60405180910390fd5b6101bc8282610510565b5050565b6101c8610593565b60006040518060c001604052808481526020018881526020018661ffff1681526020018763ffffffff1681526020018563ffffffff16815260200161021c6040518060200160405280861515815250610616565b90526003546040517f9b1c385e00000000000000000000000000000000000000000000000000000000815291925073ffffffffffffffffffffffffffffffffffffffff1690639b1c385e90610275908490600401610a17565b602060405180830381600087803b15801561028f57600080fd5b505af11580156102a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102c79190610897565b60065550505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610354576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016101a9565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60005473ffffffffffffffffffffffffffffffffffffffff163314801590610410575060025473ffffffffffffffffffffffffffffffffffffffff163314155b15610494573361043560005473ffffffffffffffffffffffffffffffffffffffff1690565b6002546040517f061db9c100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff938416600482015291831660248301529190911660448201526064016101a9565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6104e3610593565b6104ec816106d2565b50565b600581815481106104ff57600080fd5b600091825260209091200154905081565b600654821461057b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f7265717565737420494420697320696e636f727265637400000000000000000060448201526064016101a9565b805161058e9060059060208401906107c8565b505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610614576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016101a9565b565b60607f92fd13387c7fe7befbc38d303d6468778fb9731bc4583f17d92989c6fcfdeaaa8260405160240161064f91511515815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915292915050565b73ffffffffffffffffffffffffffffffffffffffff8116331415610752576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016101a9565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b828054828255906000526020600020908101928215610803579160200282015b828111156108035782518255916020019190600101906107e8565b5061080f929150610813565b5090565b5b8082111561080f5760008155600101610814565b803563ffffffff8116811461083c57600080fd5b919050565b60006020828403121561085357600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461087757600080fd5b9392505050565b60006020828403121561089057600080fd5b5035919050565b6000602082840312156108a957600080fd5b5051919050565b600080604083850312156108c357600080fd5b8235915060208084013567ffffffffffffffff808211156108e357600080fd5b818601915086601f8301126108f757600080fd5b81358181111561090957610909610ad7565b8060051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f8301168101818110858211171561094c5761094c610ad7565b604052828152858101935084860182860187018b101561096b57600080fd5b600095505b8386101561098e578035855260019590950194938601938601610970565b508096505050505050509250929050565b60008060008060008060c087890312156109b857600080fd5b863595506109c860208801610828565b9450604087013561ffff811681146109df57600080fd5b93506109ed60608801610828565b92506080870135915060a08701358015158114610a0957600080fd5b809150509295509295509295565b6000602080835283518184015280840151604084015261ffff6040850151166060840152606084015163ffffffff80821660808601528060808701511660a0860152505060a084015160c08085015280518060e086015260005b81811015610a8e5782810184015186820161010001528301610a71565b81811115610aa157600061010083880101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169390930161010001949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fdfea164736f6c6343000806000a",
+ 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",
}
var VRFV2PlusExternalSubOwnerExampleABI = VRFV2PlusExternalSubOwnerExampleMetaData.ABI
@@ -237,6 +237,28 @@ func (_VRFV2PlusExternalSubOwnerExample *VRFV2PlusExternalSubOwnerExampleCallerS
return _VRFV2PlusExternalSubOwnerExample.Contract.SRequestId(&_VRFV2PlusExternalSubOwnerExample.CallOpts)
}
+func (_VRFV2PlusExternalSubOwnerExample *VRFV2PlusExternalSubOwnerExampleCaller) SVrfCoordinator(opts *bind.CallOpts) (common.Address, error) {
+ var out []interface{}
+ err := _VRFV2PlusExternalSubOwnerExample.contract.Call(opts, &out, "s_vrfCoordinator")
+
+ if err != nil {
+ return *new(common.Address), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address)
+
+ return out0, err
+
+}
+
+func (_VRFV2PlusExternalSubOwnerExample *VRFV2PlusExternalSubOwnerExampleSession) SVrfCoordinator() (common.Address, error) {
+ return _VRFV2PlusExternalSubOwnerExample.Contract.SVrfCoordinator(&_VRFV2PlusExternalSubOwnerExample.CallOpts)
+}
+
+func (_VRFV2PlusExternalSubOwnerExample *VRFV2PlusExternalSubOwnerExampleCallerSession) SVrfCoordinator() (common.Address, error) {
+ return _VRFV2PlusExternalSubOwnerExample.Contract.SVrfCoordinator(&_VRFV2PlusExternalSubOwnerExample.CallOpts)
+}
+
func (_VRFV2PlusExternalSubOwnerExample *VRFV2PlusExternalSubOwnerExampleTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) {
return _VRFV2PlusExternalSubOwnerExample.contract.Transact(opts, "acceptOwnership")
}
@@ -600,6 +622,8 @@ type VRFV2PlusExternalSubOwnerExampleInterface interface {
SRequestId(opts *bind.CallOpts) (*big.Int, error)
+ SVrfCoordinator(opts *bind.CallOpts) (common.Address, error)
+
AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error)
RawFulfillRandomWords(opts *bind.TransactOpts, requestId *big.Int, randomWords []*big.Int) (*types.Transaction, error)
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
new file mode 100644
index 00000000000..8d96b864642
--- /dev/null
+++ b/core/gethwrappers/generated/vrf_v2plus_upgraded_version/vrf_v2plus_upgraded_version.go
@@ -0,0 +1,3667 @@
+// Code generated - DO NOT EDIT.
+// This file is a generated binding and any manual changes will be lost.
+
+package vrf_v2plus_upgraded_version
+
+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 VRFCoordinatorV2PlusUpgradedVersionFeeConfig struct {
+ FulfillmentFlatFeeLinkPPM uint32
+ FulfillmentFlatFeeNativePPM uint32
+}
+
+type VRFCoordinatorV2PlusUpgradedVersionRequestCommitment struct {
+ BlockNum uint64
+ SubId *big.Int
+ CallbackGasLimit uint32
+ NumWords uint32
+ Sender common.Address
+ ExtraArgs []byte
+}
+
+type VRFProof struct {
+ Pk [2]*big.Int
+ Gamma [2]*big.Int
+ 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 VRFCoordinatorV2PlusUpgradedVersionMetaData = &bind.MetaData{
+ ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"blockhashStore\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"internalBalance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"externalBalance\",\"type\":\"uint256\"}],\"name\":\"BalanceInvariantViolated\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNum\",\"type\":\"uint256\"}],\"name\":\"BlockhashNotInStore\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"coordinatorAddress\",\"type\":\"address\"}],\"name\":\"CoordinatorAlreadyRegistered\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"coordinatorAddress\",\"type\":\"address\"}],\"name\":\"CoordinatorNotRegistered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedToSendNative\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedToTransferLink\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"have\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"want\",\"type\":\"uint32\"}],\"name\":\"GasLimitTooBig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectCommitment\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IndexOutOfRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[{\"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: "0x60a06040523480156200001157600080fd5b50604051620060b9380380620060b9833981016040819052620000349162000183565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000d7565b50505060601b6001600160601b031916608052620001b5565b6001600160a01b038116331415620001325760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000602082840312156200019657600080fd5b81516001600160a01b0381168114620001ae57600080fd5b9392505050565b60805160601c615ede620001db600039600081816104eb01526136f60152615ede6000f3fe6080604052600436106102015760003560e01c806201229114610206578063043bd6ae14610233578063088070f5146102575780630ae09540146102d757806315c48b84146102f957806318e3dd27146103215780631b6b6d2314610360578063294926571461038d578063294daa49146103ad578063330987b3146103c9578063405b84fa146103e957806340d6bb821461040957806341af6c87146104345780635d06b4ab1461046457806364d51a2a14610484578063659827441461049957806366316d8d146104b9578063689c4517146104d95780636b6feccc1461050d5780636f64f03f1461054357806372e9d5651461056357806379ba5097146105835780638402595e1461059857806386fe91c7146105b85780638da5cb5b146105d857806395b55cfc146105f65780639b1c385e146106095780639d40a6fd14610629578063a21a23e414610656578063a4c0ed361461066b578063aa433aff1461068b578063aefb212f146106ab578063b08c8795146106d8578063b2a7cac5146106f8578063bec4c08c14610718578063caf70c4a14610738578063cb63179714610758578063ce3f471914610778578063d98e620e1461078b578063da2f2610146107ab578063dac83d29146107e1578063dc311dd314610801578063e72f6e3014610832578063ee9d2d3814610852578063f2fde38b1461087f575b600080fd5b34801561021257600080fd5b5061021b61089f565b60405161022a939291906159d4565b60405180910390f35b34801561023f57600080fd5b5061024960115481565b60405190815260200161022a565b34801561026357600080fd5b50600d5461029f9061ffff81169063ffffffff62010000820481169160ff600160301b82041691600160381b8204811691600160581b90041685565b6040805161ffff909616865263ffffffff9485166020870152921515928501929092528216606084015216608082015260a00161022a565b3480156102e357600080fd5b506102f76102f2366004615655565b61091b565b005b34801561030557600080fd5b5061030e60c881565b60405161ffff909116815260200161022a565b34801561032d57600080fd5b50600a5461034890600160601b90046001600160601b031681565b6040516001600160601b03909116815260200161022a565b34801561036c57600080fd5b50600254610380906001600160a01b031681565b60405161022a9190615878565b34801561039957600080fd5b506102f76103a83660046151c7565b6109e9565b3480156103b957600080fd5b506040516001815260200161022a565b3480156103d557600080fd5b506103486103e43660046153c3565b610b66565b3480156103f557600080fd5b506102f7610404366004615655565b611041565b34801561041557600080fd5b5061041f6101f481565b60405163ffffffff909116815260200161022a565b34801561044057600080fd5b5061045461044f366004615305565b61142c565b604051901515815260200161022a565b34801561047057600080fd5b506102f761047f3660046151aa565b6115cd565b34801561049057600080fd5b5061030e606481565b3480156104a557600080fd5b506102f76104b43660046151fc565b611684565b3480156104c557600080fd5b506102f76104d43660046151c7565b6116e4565b3480156104e557600080fd5b506103807f000000000000000000000000000000000000000000000000000000000000000081565b34801561051957600080fd5b506012546105359063ffffffff80821691600160201b90041682565b60405161022a929190615b56565b34801561054f57600080fd5b506102f761055e366004615235565b6118ac565b34801561056f57600080fd5b50600354610380906001600160a01b031681565b34801561058f57600080fd5b506102f76119b3565b3480156105a457600080fd5b506102f76105b33660046151aa565b611a5d565b3480156105c457600080fd5b50600a54610348906001600160601b031681565b3480156105e457600080fd5b506000546001600160a01b0316610380565b6102f7610604366004615305565b611b69565b34801561061557600080fd5b506102496106243660046154a0565b611cad565b34801561063557600080fd5b50600754610649906001600160401b031681565b60405161022a9190615b6d565b34801561066257600080fd5b5061024961201d565b34801561067757600080fd5b506102f7610686366004615271565b61226b565b34801561069757600080fd5b506102f76106a6366004615305565b612408565b3480156106b757600080fd5b506106cb6106c636600461567a565b61246b565b60405161022a91906158ef565b3480156106e457600080fd5b506102f76106f33660046155b7565b61256c565b34801561070457600080fd5b506102f7610713366004615305565b6126e0565b34801561072457600080fd5b506102f7610733366004615655565b612804565b34801561074457600080fd5b506102496107533660046152cc565b61299b565b34801561076457600080fd5b506102f7610773366004615655565b6129cb565b6102f7610786366004615337565b612cb8565b34801561079757600080fd5b506102496107a6366004615305565b612fc9565b3480156107b757600080fd5b506103806107c6366004615305565b600e602052600090815260409020546001600160a01b031681565b3480156107ed57600080fd5b506102f76107fc366004615655565b612fea565b34801561080d57600080fd5b5061082161081c366004615305565b6130fa565b60405161022a959493929190615b81565b34801561083e57600080fd5b506102f761084d3660046151aa565b6131f5565b34801561085e57600080fd5b5061024961086d366004615305565b60106020526000908152604090205481565b34801561088b57600080fd5b506102f761089a3660046151aa565b6133d0565b600d54600f805460408051602080840282018101909252828152600094859460609461ffff8316946201000090930463ffffffff1693919283919083018282801561090957602002820191906000526020600020905b8154815260200190600101908083116108f5575b50505050509050925092509250909192565b60008281526005602052604090205482906001600160a01b03168061095357604051630fb532db60e11b815260040160405180910390fd5b336001600160a01b038216146109875780604051636c51fda960e11b815260040161097e9190615878565b60405180910390fd5b600d54600160301b900460ff16156109b25760405163769dd35360e11b815260040160405180910390fd5b6109bb8461142c565b156109d957604051631685ecdd60e31b815260040160405180910390fd5b6109e384846133e1565b50505050565b600d54600160301b900460ff1615610a145760405163769dd35360e11b815260040160405180910390fd5b336000908152600c60205260409020546001600160601b0380831691161015610a5057604051631e9acf1760e31b815260040160405180910390fd5b336000908152600c602052604081208054839290610a789084906001600160601b0316615d92565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555080600a600c8282829054906101000a90046001600160601b0316610ac09190615d92565b92506101000a8154816001600160601b0302191690836001600160601b031602179055506000826001600160a01b0316826001600160601b031660405160006040518083038185875af1925050503d8060008114610b3a576040519150601f19603f3d011682016040523d82523d6000602084013e610b3f565b606091505b5050905080610b615760405163950b247960e01b815260040160405180910390fd5b505050565b600d54600090600160301b900460ff1615610b945760405163769dd35360e11b815260040160405180910390fd5b60005a90506000610ba5858561359c565b90506000846060015163ffffffff166001600160401b03811115610bcb57610bcb615e98565b604051908082528060200260200182016040528015610bf4578160200160208202803683370190505b50905060005b856060015163ffffffff16811015610c6b57826040015181604051602001610c23929190615902565b6040516020818303038152906040528051906020012060001c828281518110610c4e57610c4e615e82565b602090810291909101015280610c6381615dea565b915050610bfa565b5060208083018051600090815260109092526040808320839055905190518291631fe543e360e01b91610ca391908690602401615a5e565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252600d805460ff60301b1916600160301b179055908801516080890151919250600091610d089163ffffffff16908461380f565b600d805460ff60301b19169055602089810151600090815260069091526040902054909150600160c01b90046001600160401b0316610d48816001615cfb565b6020808b0151600090815260069091526040812080546001600160401b0393909316600160c01b026001600160c01b039093169290921790915560a08a01518051610d9590600190615d7b565b81518110610da557610da5615e82565b602091010151600d5460f89190911c6001149150600090610dd6908a90600160581b900463ffffffff163a8561385d565b90508115610edf576020808c01516000908152600690915260409020546001600160601b03808316600160601b909204161015610e2657604051631e9acf1760e31b815260040160405180910390fd5b60208b81015160009081526006909152604090208054829190600c90610e5d908490600160601b90046001600160601b0316615d92565b82546101009290920a6001600160601b0381810219909316918316021790915589516000908152600e60209081526040808320546001600160a01b03168352600c909152812080548594509092610eb691859116615d26565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550610fcb565b6020808c01516000908152600690915260409020546001600160601b0380831691161015610f2057604051631e9acf1760e31b815260040160405180910390fd5b6020808c015160009081526006909152604081208054839290610f4d9084906001600160601b0316615d92565b82546101009290920a6001600160601b0381810219909316918316021790915589516000908152600e60209081526040808320546001600160a01b03168352600b909152812080548594509092610fa691859116615d26565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505b8a6020015188602001517f49580fdfd9497e1ed5c1b1cec0495087ae8e3f1267470ec2fb015db32e3d6aa78a604001518488604051611028939291909283526001600160601b039190911660208301521515604082015260600190565b60405180910390a3985050505050505050505b92915050565b600d54600160301b900460ff161561106c5760405163769dd35360e11b815260040160405180910390fd5b611075816138ac565b6110945780604051635428d44960e01b815260040161097e9190615878565b6000806000806110a3866130fa565b945094505093509350336001600160a01b0316826001600160a01b0316146111065760405162461bcd60e51b81526020600482015260166024820152752737ba1039bab139b1b934b83a34b7b71037bbb732b960511b604482015260640161097e565b61110f8661142c565b156111555760405162461bcd60e51b815260206004820152601660248201527550656e64696e6720726571756573742065786973747360501b604482015260640161097e565b60006040518060c0016040528061116a600190565b60ff168152602001888152602001846001600160a01b03168152602001838152602001866001600160601b03168152602001856001600160601b031681525090506000816040516020016111be9190615941565b60405160208183030381529060405290506111d888613916565b505060405163ce3f471960e01b81526001600160a01b0388169063ce3f4719906001600160601b0388169061121190859060040161592e565b6000604051808303818588803b15801561122a57600080fd5b505af115801561123e573d6000803e3d6000fd5b50506002546001600160a01b031615801593509150611267905057506001600160601b03861615155b156113315760025460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb9061129e908a908a906004016158bf565b602060405180830381600087803b1580156112b857600080fd5b505af11580156112cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112f091906152e8565b6113315760405162461bcd60e51b8152602060048201526012602482015271696e73756666696369656e742066756e647360701b604482015260640161097e565b600d805460ff60301b1916600160301b17905560005b83518110156113da5783818151811061136257611362615e82565b60200260200101516001600160a01b0316638ea98117896040518263ffffffff1660e01b81526004016113959190615878565b600060405180830381600087803b1580156113af57600080fd5b505af11580156113c3573d6000803e3d6000fd5b5050505080806113d290615dea565b915050611347565b50600d805460ff60301b191690556040517fd63ca8cb945956747ee69bfdc3ea754c24a4caf7418db70e46052f7850be41879061141a9089908b9061588c565b60405180910390a15050505050505050565b6000818152600560209081526040808320815160608101835281546001600160a01b03908116825260018301541681850152600282018054845181870281018701865281815287969395860193909291908301828280156114b657602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611498575b505050505081525050905060005b8160400151518110156115c35760005b600f548110156115b0576000611579600f83815481106114f6576114f6615e82565b90600052602060002001548560400151858151811061151757611517615e82565b602002602001015188600460008960400151898151811061153a5761153a615e82565b6020908102919091018101516001600160a01b0316825281810192909252604090810160009081208d82529092529020546001600160401b0316613b64565b506000818152601060205260409020549091501561159d5750600195945050505050565b50806115a881615dea565b9150506114d4565b50806115bb81615dea565b9150506114c4565b5060009392505050565b6115d5613bed565b6115de816138ac565b156115fe578060405163ac8a27ef60e01b815260040161097e9190615878565b601380546001810182556000919091527f66de8ffda797e3de9c05e8fc57b3bf0ec28a930d40b0d285d93c06501cf6a0900180546001600160a01b0319166001600160a01b0383161790556040517fb7cabbfc11e66731fc77de0444614282023bcbd41d16781c753a431d0af0162590611679908390615878565b60405180910390a150565b61168c613bed565b6002546001600160a01b0316156116b657604051631688c53760e11b815260040160405180910390fd5b600280546001600160a01b039384166001600160a01b03199182161790915560038054929093169116179055565b600d54600160301b900460ff161561170f5760405163769dd35360e11b815260040160405180910390fd5b6002546001600160a01b03166117385760405163c1f0c0a160e01b815260040160405180910390fd5b336000908152600b60205260409020546001600160601b038083169116101561177457604051631e9acf1760e31b815260040160405180910390fd5b336000908152600b60205260408120805483929061179c9084906001600160601b0316615d92565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555080600a60008282829054906101000a90046001600160601b03166117e49190615d92565b82546001600160601b039182166101009390930a92830291909202199091161790555060025460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb9061183990859085906004016158bf565b602060405180830381600087803b15801561185357600080fd5b505af1158015611867573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061188b91906152e8565b6118a857604051631e9acf1760e31b815260040160405180910390fd5b5050565b6118b4613bed565b6040805180820182526000916118e391908490600290839083908082843760009201919091525061299b915050565b6000818152600e60205260409020549091506001600160a01b03161561191f57604051634a0b8fa760e01b81526004810182905260240161097e565b6000818152600e6020908152604080832080546001600160a01b0319166001600160a01b038816908117909155600f805460018101825594527f8d1108e10bcb7c27dddfc02ed9d693a074039d026cf4ea4240b40f7d581ac802909301849055518381527fe729ae16526293f74ade739043022254f1489f616295a25bf72dfb4511ed73b8910160405180910390a2505050565b6001546001600160a01b03163314611a065760405162461bcd60e51b815260206004820152601660248201527526bab9ba10313290383937b837b9b2b21037bbb732b960511b604482015260640161097e565b60008054336001600160a01b0319808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b611a65613bed565b600a544790600160601b90046001600160601b031681811115611a9f5780826040516354ced18160e11b815260040161097e929190615902565b81811015610b61576000611ab38284615d7b565b90506000846001600160a01b03168260405160006040518083038185875af1925050503d8060008114611b02576040519150601f19603f3d011682016040523d82523d6000602084013e611b07565b606091505b5050905080611b295760405163950b247960e01b815260040160405180910390fd5b7f4aed7c8eed0496c8c19ea2681fcca25741c1602342e38b045d9f1e8e905d2e9c8583604051611b5a92919061588c565b60405180910390a15050505050565b600d54600160301b900460ff1615611b945760405163769dd35360e11b815260040160405180910390fd5b6000818152600560205260409020546001600160a01b0316611bc957604051630fb532db60e11b815260040160405180910390fd5b60008181526006602052604090208054600160601b90046001600160601b0316903490600c611bf88385615d26565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555034600a600c8282829054906101000a90046001600160601b0316611c409190615d26565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550817f7603b205d03651ee812f803fccde89f1012e545a9c99f0abfea9cedd0fd8e902823484611c939190615ce3565b604051611ca1929190615902565b60405180910390a25050565b600d54600090600160301b900460ff1615611cdb5760405163769dd35360e11b815260040160405180910390fd5b6020808301356000908152600590915260409020546001600160a01b0316611d1657604051630fb532db60e11b815260040160405180910390fd5b3360009081526004602090815260408083208583013584529091529020546001600160401b031680611d63578260200135336040516379bfd40160e01b815260040161097e929190615a33565b600d5461ffff16611d7a606085016040860161559c565b61ffff161080611d9d575060c8611d97606085016040860161559c565b61ffff16115b15611dd757611db2606084016040850161559c565b600d5460405163539c34bb60e11b815261097e929161ffff169060c8906004016159b6565b600d5462010000900463ffffffff16611df6608085016060860161569c565b63ffffffff161115611e3c57611e12608084016060850161569c565b600d54604051637aebf00f60e11b815261097e929162010000900463ffffffff1690600401615b56565b6101f4611e4f60a085016080860161569c565b63ffffffff161115611e8957611e6b60a084016080850161569c565b6101f46040516311ce1afb60e21b815260040161097e929190615b56565b6000611e96826001615cfb565b9050600080611eac863533602089013586613b64565b90925090506000611ec8611ec360a0890189615bd6565b613c42565b90506000611ed582613cbf565b905083611ee0613d30565b60208a0135611ef560808c0160608d0161569c565b611f0560a08d0160808e0161569c565b3386604051602001611f1d9796959493929190615ab6565b604051602081830303815290604052805190602001206010600086815260200190815260200160002081905550336001600160a01b0316886020013589600001357feb0e3652e0f44f417695e6e90f2f42c99b65cd7169074c5a654b16b9748c3a4e87878d6040016020810190611f94919061559c565b8e6060016020810190611fa7919061569c565b8f6080016020810190611fba919061569c565b89604051611fcd96959493929190615a77565b60405180910390a45050336000908152600460209081526040808320898301358452909152902080546001600160401b0319166001600160401b039490941693909317909255925050505b919050565b600d54600090600160301b900460ff161561204b5760405163769dd35360e11b815260040160405180910390fd5b600033612059600143615d7b565b600754604051606093841b6001600160601b03199081166020830152924060348201523090931b909116605483015260c01b6001600160c01b031916606882015260700160408051601f198184030181529190528051602090910120600780549192506001600160401b039091169060006120d383615e05565b91906101000a8154816001600160401b0302191690836001600160401b03160217905550506000806001600160401b0381111561211257612112615e98565b60405190808252806020026020018201604052801561213b578160200160208202803683370190505b506040805160608082018352600080835260208084018281528486018381528984526006835286842095518654925191516001600160601b039182166001600160c01b031990941693909317600160601b9190921602176001600160c01b0316600160c01b6001600160401b039092169190910217909355835191820184523382528183018181528285018681528883526005855294909120825181546001600160a01b03199081166001600160a01b03928316178355925160018301805490941691161790915592518051949550909361221c9260028501920190614e1b565b5061222c91506008905083613dc9565b50817f1d3015d7ba850fa198dc7b1a3f5d42779313a681035f77c8c03764c61005518d3360405161225d9190615878565b60405180910390a250905090565b600d54600160301b900460ff16156122965760405163769dd35360e11b815260040160405180910390fd5b6002546001600160a01b031633146122c1576040516344b0e3c360e01b815260040160405180910390fd5b602081146122e257604051638129bbcd60e01b815260040160405180910390fd5b60006122f082840184615305565b6000818152600560205260409020549091506001600160a01b031661232857604051630fb532db60e11b815260040160405180910390fd5b600081815260066020526040812080546001600160601b03169186919061234f8385615d26565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555084600a60008282829054906101000a90046001600160601b03166123979190615d26565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550817f1ced9348ff549fceab2ac57cd3a9de38edaaab274b725ee82c23e8fc8c4eec7a8287846123ea9190615ce3565b6040516123f8929190615902565b60405180910390a2505050505050565b612410613bed565b6000818152600560205260409020546001600160a01b031661244557604051630fb532db60e11b815260040160405180910390fd5b6000818152600560205260409020546124689082906001600160a01b03166133e1565b50565b606060006124796008613dd5565b905080841061249b57604051631390f2a160e01b815260040160405180910390fd5b60006124a78486615ce3565b9050818111806124b5575083155b6124bf57806124c1565b815b905060006124cf8683615d7b565b6001600160401b038111156124e6576124e6615e98565b60405190808252806020026020018201604052801561250f578160200160208202803683370190505b50905060005b81518110156125625761253361252b8883615ce3565b600890613ddf565b82828151811061254557612545615e82565b60209081029190910101528061255a81615dea565b915050612515565b5095945050505050565b612574613bed565b60c861ffff871611156125a157858660c860405163539c34bb60e11b815260040161097e939291906159b6565b600082136125c5576040516321ea67b360e11b81526004810183905260240161097e565b6040805160a0808201835261ffff891680835263ffffffff89811660208086018290526000868801528a831660608088018290528b85166080988901819052600d805465ffffffffffff1916881762010000870217600160301b600160781b031916600160381b850263ffffffff60581b191617600160581b83021790558a51601280548d8701519289166001600160401b031990911617600160201b92891692909202919091179081905560118d90558a519788528785019590955298860191909152840196909652938201879052838116928201929092529190921c90911660c08201527f777357bb93f63d088f18112d3dba38457aec633eb8f1341e1d418380ad328e789060e00160405180910390a1505050505050565b600d54600160301b900460ff161561270b5760405163769dd35360e11b815260040160405180910390fd5b6000818152600560205260409020546001600160a01b031661274057604051630fb532db60e11b815260040160405180910390fd5b6000818152600560205260409020600101546001600160a01b03163314612797576000818152600560205260409081902060010154905163d084e97560e01b815261097e916001600160a01b031690600401615878565b6000818152600560205260409081902080546001600160a01b031980821633908117845560019093018054909116905591516001600160a01b039092169183917fd4114ab6e9af9f597c52041f32d62dc57c5c4e4c0d4427006069635e216c938691611ca19185916158a5565b60008281526005602052604090205482906001600160a01b03168061283c57604051630fb532db60e11b815260040160405180910390fd5b336001600160a01b038216146128675780604051636c51fda960e11b815260040161097e9190615878565b600d54600160301b900460ff16156128925760405163769dd35360e11b815260040160405180910390fd5b600084815260056020526040902060020154606414156128c5576040516305a48e0f60e01b815260040160405180910390fd5b6001600160a01b03831660009081526004602090815260408083208784529091529020546001600160401b0316156128fc576109e3565b6001600160a01b0383166000818152600460209081526040808320888452825280832080546001600160401b031916600190811790915560058352818420600201805491820181558452919092200180546001600160a01b0319169092179091555184907f1e980d04aa7648e205713e5e8ea3808672ac163d10936d36f91b2c88ac1575e19061298d908690615878565b60405180910390a250505050565b6000816040516020016129ae91906158e1565b604051602081830303815290604052805190602001209050919050565b60008281526005602052604090205482906001600160a01b031680612a0357604051630fb532db60e11b815260040160405180910390fd5b336001600160a01b03821614612a2e5780604051636c51fda960e11b815260040161097e9190615878565b600d54600160301b900460ff1615612a595760405163769dd35360e11b815260040160405180910390fd5b612a628461142c565b15612a8057604051631685ecdd60e31b815260040160405180910390fd5b6001600160a01b03831660009081526004602090815260408083208784529091529020546001600160401b0316612ace5783836040516379bfd40160e01b815260040161097e929190615a33565b600084815260056020908152604080832060020180548251818502810185019093528083529192909190830182828015612b3157602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612b13575b50505050509050600060018251612b489190615d7b565b905060005b8251811015612c5457856001600160a01b0316838281518110612b7257612b72615e82565b60200260200101516001600160a01b03161415612c42576000838381518110612b9d57612b9d615e82565b6020026020010151905080600560008a81526020019081526020016000206002018381548110612bcf57612bcf615e82565b600091825260208083209190910180546001600160a01b0319166001600160a01b039490941693909317909255898152600590915260409020600201805480612c1a57612c1a615e6c565b600082815260209020810160001990810180546001600160a01b031916905501905550612c54565b80612c4c81615dea565b915050612b4d565b506001600160a01b03851660009081526004602090815260408083208984529091529081902080546001600160401b03191690555186907f32158c6058347c1601b2d12bc696ac6901d8a9a9aa3ba10c27ab0a983e8425a7906123f8908890615878565b6000612cc6828401846154da565b9050806000015160ff16600114612cff57805160405163237d181f60e21b815260ff90911660048201526001602482015260440161097e565b8060a001516001600160601b03163414612d435760a08101516040516306acf13560e41b81523460048201526001600160601b03909116602482015260440161097e565b6020808201516000908152600590915260409020546001600160a01b031615612d7f576040516326afa43560e11b815260040160405180910390fd5b60005b816060015151811015612e1f5760016004600084606001518481518110612dab57612dab615e82565b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060008460200151815260200190815260200160002060006101000a8154816001600160401b0302191690836001600160401b031602179055508080612e1790615dea565b915050612d82565b50604080516060808201835260808401516001600160601b03908116835260a0850151811660208085019182526000858701818152828901805183526006845288832097518854955192516001600160401b0316600160c01b026001600160c01b03938816600160601b026001600160c01b0319909716919097161794909417169390931790945584518084018652868601516001600160a01b03908116825281860184815294880151828801908152925184526005865295909220825181549087166001600160a01b0319918216178255935160018201805491909716941693909317909455925180519192612f1e92600285019290910190614e1b565b5050506080810151600a8054600090612f419084906001600160601b0316615d26565b92506101000a8154816001600160601b0302191690836001600160601b031602179055508060a00151600a600c8282829054906101000a90046001600160601b0316612f8d9190615d26565b92506101000a8154816001600160601b0302191690836001600160601b031602179055506109e381602001516008613dc990919063ffffffff16565b600f8181548110612fd957600080fd5b600091825260209091200154905081565b60008281526005602052604090205482906001600160a01b03168061302257604051630fb532db60e11b815260040160405180910390fd5b336001600160a01b0382161461304d5780604051636c51fda960e11b815260040161097e9190615878565b600d54600160301b900460ff16156130785760405163769dd35360e11b815260040160405180910390fd5b6000848152600560205260409020600101546001600160a01b038481169116146109e3576000848152600560205260409081902060010180546001600160a01b0319166001600160a01b0386161790555184907f21a4dad170a6bf476c31bbcf4a16628295b0e450672eec25d7c93308e05344a19061298d90339087906158a5565b6000818152600560205260408120548190819081906060906001600160a01b031661313857604051630fb532db60e11b815260040160405180910390fd5b60008681526006602090815260408083205460058352928190208054600290910180548351818602810186019094528084526001600160601b0380871696600160601b810490911695600160c01b9091046001600160401b0316946001600160a01b03909416939183918301828280156131db57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116131bd575b505050505090509450945094509450945091939590929450565b6131fd613bed565b6002546001600160a01b03166132265760405163c1f0c0a160e01b815260040160405180910390fd5b6002546040516370a0823160e01b81526000916001600160a01b0316906370a0823190613257903090600401615878565b60206040518083038186803b15801561326f57600080fd5b505afa158015613283573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132a7919061531e565b600a549091506001600160601b0316818111156132db5780826040516354ced18160e11b815260040161097e929190615902565b81811015610b615760006132ef8284615d7b565b60025460405163a9059cbb60e01b81529192506001600160a01b03169063a9059cbb90613322908790859060040161588c565b602060405180830381600087803b15801561333c57600080fd5b505af1158015613350573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061337491906152e8565b61339157604051631f01ff1360e21b815260040160405180910390fd5b7f59bfc682b673f8cbf945f1e454df9334834abf7dfe7f92237ca29ecb9b43660084826040516133c292919061588c565b60405180910390a150505050565b6133d8613bed565b61246881613deb565b6000806133ed84613916565b60025491935091506001600160a01b03161580159061341457506001600160601b03821615155b156134c35760025460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb906134549086906001600160601b0387169060040161588c565b602060405180830381600087803b15801561346e57600080fd5b505af1158015613482573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134a691906152e8565b6134c357604051631e9acf1760e31b815260040160405180910390fd5b6000836001600160a01b0316826001600160601b031660405160006040518083038185875af1925050503d8060008114613519576040519150601f19603f3d011682016040523d82523d6000602084013e61351e565b606091505b50509050806135405760405163950b247960e01b815260040160405180910390fd5b604080516001600160a01b03861681526001600160601b038581166020830152841681830152905186917f8c74ce8b8cf87f5eb001275c8be27eb34ea2b62bfab6814fcc62192bb63e81c4919081900360600190a25050505050565b604080516060810182526000808252602082018190529181019190915260006135c8846000015161299b565b6000818152600e60205260409020549091506001600160a01b03168061360457604051631dfd6e1360e21b81526004810183905260240161097e565b600082866080015160405160200161361d929190615902565b60408051601f198184030181529181528151602092830120600081815260109093529120549091508061366357604051631b44092560e11b815260040160405180910390fd5b85516020808801516040808a015160608b015160808c015160a08d01519351613692978a979096959101615b02565b6040516020818303038152906040528051906020012081146136c75760405163354a450b60e21b815260040160405180910390fd5b60006136d68760000151613e8f565b90508061379d578651604051631d2827a760e31b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169163e9413d389161372a9190600401615b6d565b60206040518083038186803b15801561374257600080fd5b505afa158015613756573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061377a919061531e565b90508061379d57865160405163175dadad60e01b815261097e9190600401615b6d565b60008860800151826040516020016137bf929190918252602082015260400190565b6040516020818303038152906040528051906020012060001c905060006137e68a83613f82565b604080516060810182529889526020890196909652948701949094525093979650505050505050565b60005a61138881101561382157600080fd5b61138881039050846040820482031161383957600080fd5b50823b61384557600080fd5b60008083516020850160008789f190505b9392505050565b6000811561388a576012546138839086908690600160201b900463ffffffff1686613fed565b90506138a4565b6012546138a1908690869063ffffffff1686614057565b90505b949350505050565b6000805b60135481101561390d57826001600160a01b0316601382815481106138d7576138d7615e82565b6000918252602090912001546001600160a01b031614156138fb5750600192915050565b8061390581615dea565b9150506138b0565b50600092915050565b6000818152600560209081526040808320815160608101835281546001600160a01b039081168252600183015416818501526002820180548451818702810187018652818152879687969495948601939192908301828280156139a257602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311613984575b505050919092525050506000858152600660209081526040808320815160608101835290546001600160601b03808216808452600160601b8304909116948301859052600160c01b9091046001600160401b0316928201929092529096509094509192505b826040015151811015613a7e576004600084604001518381518110613a2e57613a2e615e82565b6020908102919091018101516001600160a01b031682528181019290925260409081016000908120898252909252902080546001600160401b031916905580613a7681615dea565b915050613a07565b50600085815260056020526040812080546001600160a01b03199081168255600182018054909116905590613ab66002830182614e80565b5050600085815260066020526040812055613ad2600886614144565b50600a8054859190600090613af19084906001600160601b0316615d92565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555082600a600c8282829054906101000a90046001600160601b0316613b399190615d92565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505050915091565b60408051602081018690526001600160a01b03851691810191909152606081018390526001600160401b03821660808201526000908190819060a00160408051601f198184030181529082905280516020918201209250613bc9918991849101615902565b60408051808303601f19018152919052805160209091012097909650945050505050565b6000546001600160a01b03163314613c405760405162461bcd60e51b815260206004820152601660248201527527b7363c9031b0b63630b1363290313c9037bbb732b960511b604482015260640161097e565b565b60408051602081019091526000815281613c6b575060408051602081019091526000815261103b565b63125fa26760e31b613c7d8385615dba565b6001600160e01b03191614613ca557604051632923fee760e11b815260040160405180910390fd5b613cb28260048186615cb9565b8101906138569190615378565b60607f92fd13387c7fe7befbc38d303d6468778fb9731bc4583f17d92989c6fcfdeaaa82604051602401613cf891511515815260200190565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915292915050565b60004661a4b1811480613d45575062066eed81145b15613dc25760646001600160a01b031663a3b1b31d6040518163ffffffff1660e01b815260040160206040518083038186803b158015613d8457600080fd5b505afa158015613d98573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613dbc919061531e565b91505090565b4391505090565b60006138568383614150565b600061103b825490565b6000613856838361419f565b6001600160a01b038116331415613e3e5760405162461bcd60e51b815260206004820152601760248201527621b0b73737ba103a3930b739b332b9103a379039b2b63360491b604482015260640161097e565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60004661a4b1811480613ea4575062066eed81145b80613eb1575062066eee81145b15613f7357610100836001600160401b0316613ecb613d30565b613ed59190615d7b565b1180613ef15750613ee4613d30565b836001600160401b031610155b15613eff5750600092915050565b6040516315a03d4160e11b8152606490632b407a8290613f23908690600401615b6d565b60206040518083038186803b158015613f3b57600080fd5b505afa158015613f4f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613856919061531e565b50506001600160401b03164090565b6000613fb68360000151846020015185604001518660600151868860a001518960c001518a60e001518b61010001516141c9565b60038360200151604051602001613fce929190615a4a565b60408051601f1981840301815291905280516020909101209392505050565b600080613ff86143e4565b905060005a6140078888615ce3565b6140119190615d7b565b61401b9085615d5c565b9050600061403463ffffffff871664e8d4a51000615d5c565b9050826140418284615ce3565b61404b9190615ce3565b98975050505050505050565b600080614062614440565b905060008113614088576040516321ea67b360e11b81526004810182905260240161097e565b60006140926143e4565b9050600082825a6140a38b8b615ce3565b6140ad9190615d7b565b6140b79088615d5c565b6140c19190615ce3565b6140d390670de0b6b3a7640000615d5c565b6140dd9190615d48565b905060006140f663ffffffff881664e8d4a51000615d5c565b905061410d81676765c793fa10079d601b1b615d7b565b82111561412d5760405163e80fa38160e01b815260040160405180910390fd5b6141378183615ce3565b9998505050505050505050565b6000613856838361450b565b60008181526001830160205260408120546141975750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561103b565b50600061103b565b60008260000182815481106141b6576141b6615e82565b9060005260206000200154905092915050565b6141d2896145fe565b61421b5760405162461bcd60e51b815260206004820152601a6024820152797075626c6963206b6579206973206e6f74206f6e20637572766560301b604482015260640161097e565b614224886145fe565b6142685760405162461bcd60e51b815260206004820152601560248201527467616d6d61206973206e6f74206f6e20637572766560581b604482015260640161097e565b614271836145fe565b6142bd5760405162461bcd60e51b815260206004820152601d60248201527f6347616d6d615769746e657373206973206e6f74206f6e206375727665000000604482015260640161097e565b6142c6826145fe565b6143115760405162461bcd60e51b815260206004820152601c60248201527b73486173685769746e657373206973206e6f74206f6e20637572766560201b604482015260640161097e565b61431d878a88876146c1565b6143655760405162461bcd60e51b81526020600482015260196024820152786164647228632a706b2b732a6729213d5f755769746e65737360381b604482015260640161097e565b60006143718a876147d5565b90506000614384898b878b868989614839565b90506000614395838d8d8a8661494c565b9050808a146143d65760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b210383937b7b360991b604482015260640161097e565b505050505050505050505050565b60004661a4b18114806143f9575062066eed81145b1561443857606c6001600160a01b031663c6f7de0e6040518163ffffffff1660e01b815260040160206040518083038186803b158015613d8457600080fd5b600091505090565b600d5460035460408051633fabe5a360e21b81529051600093600160381b900463ffffffff169283151592859283926001600160a01b03169163feaf968c9160048083019260a0929190829003018186803b15801561449e57600080fd5b505afa1580156144b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906144d691906156b7565b5094509092508491505080156144fa57506144f18242615d7b565b8463ffffffff16105b156138a45750601154949350505050565b600081815260018301602052604081205480156145f457600061452f600183615d7b565b855490915060009061454390600190615d7b565b90508181146145a857600086600001828154811061456357614563615e82565b906000526020600020015490508087600001848154811061458657614586615e82565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806145b9576145b9615e6c565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061103b565b600091505061103b565b80516000906401000003d0191161464c5760405162461bcd60e51b8152602060048201526012602482015271696e76616c696420782d6f7264696e61746560701b604482015260640161097e565b60208201516401000003d0191161469a5760405162461bcd60e51b8152602060048201526012602482015271696e76616c696420792d6f7264696e61746560701b604482015260640161097e565b60208201516401000003d0199080096146ba8360005b602002015161498c565b1492915050565b60006001600160a01b0382166147075760405162461bcd60e51b815260206004820152600b60248201526a626164207769746e65737360a81b604482015260640161097e565b60208401516000906001161561471e57601c614721565b601b5b9050600070014551231950b75fc4402da1732fc9bebe1985876000602002015109865170014551231950b75fc4402da1732fc9bebe199182039250600091908909875160408051600080825260209091019182905292935060019161478b91869188918790615910565b6020604051602081039080840390855afa1580156147ad573d6000803e3d6000fd5b5050604051601f1901516001600160a01b039081169088161495505050505050949350505050565b6147dd614e9e565b61480a600184846040516020016147f693929190615857565b6040516020818303038152906040526149b0565b90505b614816816145fe565b61103b57805160408051602081019290925261483291016147f6565b905061480d565b614841614e9e565b825186516401000003d01990819006910614156148a05760405162461bcd60e51b815260206004820152601e60248201527f706f696e747320696e2073756d206d7573742062652064697374696e63740000604482015260640161097e565b6148ab8789886149fe565b6148f05760405162461bcd60e51b8152602060048201526016602482015275119a5c9cdd081b5d5b0818da1958dac819985a5b195960521b604482015260640161097e565b6148fb8486856149fe565b6149415760405162461bcd60e51b815260206004820152601760248201527614d958dbdb99081b5d5b0818da1958dac819985a5b1959604a1b604482015260640161097e565b61404b868484614b19565b60006002868686858760405160200161496a969594939291906157fd565b60408051601f1981840301815291905280516020909101209695505050505050565b6000806401000003d01980848509840990506401000003d019600782089392505050565b6149b8614e9e565b6149c182614bdc565b81526149d66149d18260006146b0565b614c17565b602082018190526002900660011415612018576020810180516401000003d019039052919050565b600082614a3b5760405162461bcd60e51b815260206004820152600b60248201526a3d32b9379039b1b0b630b960a91b604482015260640161097e565b83516020850151600090614a5190600290615e2c565b15614a5d57601c614a60565b601b5b9050600070014551231950b75fc4402da1732fc9bebe19838709604080516000808252602090910191829052919250600190614aa3908390869088908790615910565b6020604051602081039080840390855afa158015614ac5573d6000803e3d6000fd5b505050602060405103519050600086604051602001614ae491906157eb565b60408051601f1981840301815291905280516020909101206001600160a01b0392831692169190911498975050505050505050565b614b21614e9e565b835160208086015185519186015160009384938493614b4293909190614c37565b919450925090506401000003d019858209600114614b9e5760405162461bcd60e51b815260206004820152601960248201527834b73b2d1036bab9ba1031329034b73b32b939b29037b3103d60391b604482015260640161097e565b60405180604001604052806401000003d01980614bbd57614bbd615e56565b87860981526020016401000003d0198785099052979650505050505050565b805160208201205b6401000003d019811061201857604080516020808201939093528151808203840181529082019091528051910120614be4565b600061103b826002614c306401000003d0196001615ce3565b901c614d17565b60008080600180826401000003d019896401000003d019038808905060006401000003d0198b6401000003d019038a0890506000614c7783838585614dae565b9098509050614c8888828e88614dd2565b9098509050614c9988828c87614dd2565b90985090506000614cac8d878b85614dd2565b9098509050614cbd88828686614dae565b9098509050614cce88828e89614dd2565b9098509050818114614d03576401000003d019818a0998506401000003d01982890997506401000003d0198183099650614d07565b8196505b5050505050509450945094915050565b600080614d22614ebc565b6020808252818101819052604082015260608101859052608081018490526401000003d01960a0820152614d54614eda565b60208160c0846005600019fa925082614da45760405162461bcd60e51b81526020600482015260126024820152716269674d6f64457870206661696c7572652160701b604482015260640161097e565b5195945050505050565b6000806401000003d0198487096401000003d0198487099097909650945050505050565b600080806401000003d019878509905060006401000003d01987876401000003d019030990506401000003d0198183086401000003d01986890990999098509650505050505050565b828054828255906000526020600020908101928215614e70579160200282015b82811115614e7057825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190614e3b565b50614e7c929150614ef8565b5090565b50805460008255906000526020600020908101906124689190614ef8565b60405180604001604052806002906020820280368337509192915050565b6040518060c001604052806006906020820280368337509192915050565b60405180602001604052806001906020820280368337509192915050565b5b80821115614e7c5760008155600101614ef9565b803561201881615eae565b600082601f830112614f2957600080fd5b813560206001600160401b03821115614f4457614f44615e98565b8160051b614f53828201615c89565b838152828101908684018388018501891015614f6e57600080fd5b600093505b85841015614f9a578035614f8681615eae565b835260019390930192918401918401614f73565b50979650505050505050565b600082601f830112614fb757600080fd5b614fbf615c1c565b808385604086011115614fd157600080fd5b60005b6002811015614ff3578135845260209384019390910190600101614fd4565b509095945050505050565b60008083601f84011261501057600080fd5b5081356001600160401b0381111561502757600080fd5b60208301915083602082850101111561503f57600080fd5b9250929050565b600082601f83011261505757600080fd5b81356001600160401b0381111561507057615070615e98565b615083601f8201601f1916602001615c89565b81815284602083860101111561509857600080fd5b816020850160208301376000918101602001919091529392505050565b600060c082840312156150c757600080fd5b6150cf615c44565b905081356001600160401b0380821682146150e957600080fd5b8183526020840135602084015261510260408501615168565b604084015261511360608501615168565b606084015261512460808501614f0d565b608084015260a084013591508082111561513d57600080fd5b5061514a84828501615046565b60a08301525092915050565b803561ffff8116811461201857600080fd5b803563ffffffff8116811461201857600080fd5b80516001600160501b038116811461201857600080fd5b80356001600160601b038116811461201857600080fd5b6000602082840312156151bc57600080fd5b813561385681615eae565b600080604083850312156151da57600080fd5b82356151e581615eae565b91506151f360208401615193565b90509250929050565b6000806040838503121561520f57600080fd5b823561521a81615eae565b9150602083013561522a81615eae565b809150509250929050565b6000806060838503121561524857600080fd5b823561525381615eae565b91506060830184101561526557600080fd5b50926020919091019150565b6000806000806060858703121561528757600080fd5b843561529281615eae565b93506020850135925060408501356001600160401b038111156152b457600080fd5b6152c087828801614ffe565b95989497509550505050565b6000604082840312156152de57600080fd5b6138568383614fa6565b6000602082840312156152fa57600080fd5b815161385681615ec3565b60006020828403121561531757600080fd5b5035919050565b60006020828403121561533057600080fd5b5051919050565b6000806020838503121561534a57600080fd5b82356001600160401b0381111561536057600080fd5b61536c85828601614ffe565b90969095509350505050565b60006020828403121561538a57600080fd5b604051602081016001600160401b03811182821017156153ac576153ac615e98565b60405282356153ba81615ec3565b81529392505050565b6000808284036101c08112156153d857600080fd5b6101a0808212156153e857600080fd5b6153f0615c66565b91506153fc8686614fa6565b825261540b8660408701614fa6565b60208301526080850135604083015260a0850135606083015260c0850135608083015261543a60e08601614f0d565b60a083015261010061544e87828801614fa6565b60c0840152615461876101408801614fa6565b60e0840152610180860135908301529092508301356001600160401b0381111561548a57600080fd5b615496858286016150b5565b9150509250929050565b6000602082840312156154b257600080fd5b81356001600160401b038111156154c857600080fd5b820160c0818503121561385657600080fd5b6000602082840312156154ec57600080fd5b81356001600160401b038082111561550357600080fd5b9083019060c0828603121561551757600080fd5b61551f615c44565b823560ff8116811461553057600080fd5b81526020838101359082015261554860408401614f0d565b604082015260608301358281111561555f57600080fd5b61556b87828601614f18565b60608301525061557d60808401615193565b608082015261558e60a08401615193565b60a082015295945050505050565b6000602082840312156155ae57600080fd5b61385682615156565b60008060008060008086880360e08112156155d157600080fd5b6155da88615156565b96506155e860208901615168565b95506155f660408901615168565b945061560460608901615168565b9350608088013592506040609f198201121561561f57600080fd5b50615628615c1c565b61563460a08901615168565b815261564260c08901615168565b6020820152809150509295509295509295565b6000806040838503121561566857600080fd5b82359150602083013561522a81615eae565b6000806040838503121561568d57600080fd5b50508035926020909101359150565b6000602082840312156156ae57600080fd5b61385682615168565b600080600080600060a086880312156156cf57600080fd5b6156d88661517c565b94506020860151935060408601519250606086015191506156fb6080870161517c565b90509295509295909350565b600081518084526020808501945080840160005b838110156157405781516001600160a01b03168752958201959082019060010161571b565b509495945050505050565b8060005b60028110156109e357815184526020938401939091019060010161574f565b600081518084526020808501945080840160005b8381101561574057815187529582019590820190600101615782565b6000815180845260005b818110156157c4576020818501810151868301820152016157a8565b818111156157d6576000602083870101525b50601f01601f19169290920160200192915050565b6157f5818361574b565b604001919050565b86815261580d602082018761574b565b61581a606082018661574b565b61582760a082018561574b565b61583460e082018461574b565b60609190911b6001600160601b0319166101208201526101340195945050505050565b838152615867602082018461574b565b606081019190915260800192915050565b6001600160a01b0391909116815260200190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b039290921682526001600160601b0316602082015260400190565b6040810161103b828461574b565b602081526000613856602083018461576e565b918252602082015260400190565b93845260ff9290921660208401526040830152606082015260800190565b602081526000613856602083018461579e565b6020815260ff82511660208201526020820151604082015260018060a01b0360408301511660608201526000606083015160c0608084015261598660e0840182615707565b60808501516001600160601b0390811660a0868101919091529095015190941660c0909301929092525090919050565b61ffff93841681529183166020830152909116604082015260600190565b60006060820161ffff86168352602063ffffffff86168185015260606040850152818551808452608086019150828701935060005b81811015615a2557845183529383019391830191600101615a09565b509098975050505050505050565b9182526001600160a01b0316602082015260400190565b82815260608101613856602083018461574b565b8281526040602082015260006138a4604083018461576e565b86815285602082015261ffff85166040820152600063ffffffff808616606084015280851660808401525060c060a083015261404b60c083018461579e565b878152602081018790526040810186905263ffffffff8581166060830152841660808201526001600160a01b03831660a082015260e060c082018190526000906141379083018461579e565b8781526001600160401b03871660208201526040810186905263ffffffff8581166060830152841660808201526001600160a01b03831660a082015260e060c082018190526000906141379083018461579e565b63ffffffff92831681529116602082015260400190565b6001600160401b0391909116815260200190565b6001600160601b038681168252851660208201526001600160401b03841660408201526001600160a01b038316606082015260a060808201819052600090615bcb90830184615707565b979650505050505050565b6000808335601e19843603018112615bed57600080fd5b8301803591506001600160401b03821115615c0757600080fd5b60200191503681900382131561503f57600080fd5b604080519081016001600160401b0381118282101715615c3e57615c3e615e98565b60405290565b60405160c081016001600160401b0381118282101715615c3e57615c3e615e98565b60405161012081016001600160401b0381118282101715615c3e57615c3e615e98565b604051601f8201601f191681016001600160401b0381118282101715615cb157615cb1615e98565b604052919050565b60008085851115615cc957600080fd5b83861115615cd657600080fd5b5050820193919092039150565b60008219821115615cf657615cf6615e40565b500190565b60006001600160401b03828116848216808303821115615d1d57615d1d615e40565b01949350505050565b60006001600160601b03828116848216808303821115615d1d57615d1d615e40565b600082615d5757615d57615e56565b500490565b6000816000190483118215151615615d7657615d76615e40565b500290565b600082821015615d8d57615d8d615e40565b500390565b60006001600160601b0383811690831681811015615db257615db2615e40565b039392505050565b6001600160e01b03198135818116916004851015615de25780818660040360031b1b83161692505b505092915050565b6000600019821415615dfe57615dfe615e40565b5060010190565b60006001600160401b0382811680821415615e2257615e22615e40565b6001019392505050565b600082615e3b57615e3b615e56565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461246857600080fd5b801515811461246857600080fdfea164736f6c6343000806000a",
+}
+
+var VRFCoordinatorV2PlusUpgradedVersionABI = VRFCoordinatorV2PlusUpgradedVersionMetaData.ABI
+
+var VRFCoordinatorV2PlusUpgradedVersionBin = VRFCoordinatorV2PlusUpgradedVersionMetaData.Bin
+
+func DeployVRFCoordinatorV2PlusUpgradedVersion(auth *bind.TransactOpts, backend bind.ContractBackend, blockhashStore common.Address) (common.Address, *types.Transaction, *VRFCoordinatorV2PlusUpgradedVersion, error) {
+ parsed, err := VRFCoordinatorV2PlusUpgradedVersionMetaData.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(VRFCoordinatorV2PlusUpgradedVersionBin), backend, blockhashStore)
+ if err != nil {
+ return common.Address{}, nil, nil, err
+ }
+ return address, tx, &VRFCoordinatorV2PlusUpgradedVersion{VRFCoordinatorV2PlusUpgradedVersionCaller: VRFCoordinatorV2PlusUpgradedVersionCaller{contract: contract}, VRFCoordinatorV2PlusUpgradedVersionTransactor: VRFCoordinatorV2PlusUpgradedVersionTransactor{contract: contract}, VRFCoordinatorV2PlusUpgradedVersionFilterer: VRFCoordinatorV2PlusUpgradedVersionFilterer{contract: contract}}, nil
+}
+
+type VRFCoordinatorV2PlusUpgradedVersion struct {
+ address common.Address
+ abi abi.ABI
+ VRFCoordinatorV2PlusUpgradedVersionCaller
+ VRFCoordinatorV2PlusUpgradedVersionTransactor
+ VRFCoordinatorV2PlusUpgradedVersionFilterer
+}
+
+type VRFCoordinatorV2PlusUpgradedVersionCaller struct {
+ contract *bind.BoundContract
+}
+
+type VRFCoordinatorV2PlusUpgradedVersionTransactor struct {
+ contract *bind.BoundContract
+}
+
+type VRFCoordinatorV2PlusUpgradedVersionFilterer struct {
+ contract *bind.BoundContract
+}
+
+type VRFCoordinatorV2PlusUpgradedVersionSession struct {
+ Contract *VRFCoordinatorV2PlusUpgradedVersion
+ CallOpts bind.CallOpts
+ TransactOpts bind.TransactOpts
+}
+
+type VRFCoordinatorV2PlusUpgradedVersionCallerSession struct {
+ Contract *VRFCoordinatorV2PlusUpgradedVersionCaller
+ CallOpts bind.CallOpts
+}
+
+type VRFCoordinatorV2PlusUpgradedVersionTransactorSession struct {
+ Contract *VRFCoordinatorV2PlusUpgradedVersionTransactor
+ TransactOpts bind.TransactOpts
+}
+
+type VRFCoordinatorV2PlusUpgradedVersionRaw struct {
+ Contract *VRFCoordinatorV2PlusUpgradedVersion
+}
+
+type VRFCoordinatorV2PlusUpgradedVersionCallerRaw struct {
+ Contract *VRFCoordinatorV2PlusUpgradedVersionCaller
+}
+
+type VRFCoordinatorV2PlusUpgradedVersionTransactorRaw struct {
+ Contract *VRFCoordinatorV2PlusUpgradedVersionTransactor
+}
+
+func NewVRFCoordinatorV2PlusUpgradedVersion(address common.Address, backend bind.ContractBackend) (*VRFCoordinatorV2PlusUpgradedVersion, error) {
+ abi, err := abi.JSON(strings.NewReader(VRFCoordinatorV2PlusUpgradedVersionABI))
+ if err != nil {
+ return nil, err
+ }
+ contract, err := bindVRFCoordinatorV2PlusUpgradedVersion(address, backend, backend, backend)
+ if err != nil {
+ return nil, err
+ }
+ return &VRFCoordinatorV2PlusUpgradedVersion{address: address, abi: abi, VRFCoordinatorV2PlusUpgradedVersionCaller: VRFCoordinatorV2PlusUpgradedVersionCaller{contract: contract}, VRFCoordinatorV2PlusUpgradedVersionTransactor: VRFCoordinatorV2PlusUpgradedVersionTransactor{contract: contract}, VRFCoordinatorV2PlusUpgradedVersionFilterer: VRFCoordinatorV2PlusUpgradedVersionFilterer{contract: contract}}, nil
+}
+
+func NewVRFCoordinatorV2PlusUpgradedVersionCaller(address common.Address, caller bind.ContractCaller) (*VRFCoordinatorV2PlusUpgradedVersionCaller, error) {
+ contract, err := bindVRFCoordinatorV2PlusUpgradedVersion(address, caller, nil, nil)
+ if err != nil {
+ return nil, err
+ }
+ return &VRFCoordinatorV2PlusUpgradedVersionCaller{contract: contract}, nil
+}
+
+func NewVRFCoordinatorV2PlusUpgradedVersionTransactor(address common.Address, transactor bind.ContractTransactor) (*VRFCoordinatorV2PlusUpgradedVersionTransactor, error) {
+ contract, err := bindVRFCoordinatorV2PlusUpgradedVersion(address, nil, transactor, nil)
+ if err != nil {
+ return nil, err
+ }
+ return &VRFCoordinatorV2PlusUpgradedVersionTransactor{contract: contract}, nil
+}
+
+func NewVRFCoordinatorV2PlusUpgradedVersionFilterer(address common.Address, filterer bind.ContractFilterer) (*VRFCoordinatorV2PlusUpgradedVersionFilterer, error) {
+ contract, err := bindVRFCoordinatorV2PlusUpgradedVersion(address, nil, nil, filterer)
+ if err != nil {
+ return nil, err
+ }
+ return &VRFCoordinatorV2PlusUpgradedVersionFilterer{contract: contract}, nil
+}
+
+func bindVRFCoordinatorV2PlusUpgradedVersion(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) {
+ parsed, err := VRFCoordinatorV2PlusUpgradedVersionMetaData.GetAbi()
+ if err != nil {
+ return nil, err
+ }
+ return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.VRFCoordinatorV2PlusUpgradedVersionCaller.contract.Call(opts, result, method, params...)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.VRFCoordinatorV2PlusUpgradedVersionTransactor.contract.Transfer(opts)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.VRFCoordinatorV2PlusUpgradedVersionTransactor.contract.Transact(opts, method, params...)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.contract.Call(opts, result, method, params...)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.contract.Transfer(opts)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.contract.Transact(opts, method, params...)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionCaller) BLOCKHASHSTORE(opts *bind.CallOpts) (common.Address, error) {
+ var out []interface{}
+ err := _VRFCoordinatorV2PlusUpgradedVersion.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 (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionSession) BLOCKHASHSTORE() (common.Address, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.BLOCKHASHSTORE(&_VRFCoordinatorV2PlusUpgradedVersion.CallOpts)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionCallerSession) BLOCKHASHSTORE() (common.Address, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.BLOCKHASHSTORE(&_VRFCoordinatorV2PlusUpgradedVersion.CallOpts)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionCaller) LINK(opts *bind.CallOpts) (common.Address, error) {
+ var out []interface{}
+ err := _VRFCoordinatorV2PlusUpgradedVersion.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 (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionSession) LINK() (common.Address, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.LINK(&_VRFCoordinatorV2PlusUpgradedVersion.CallOpts)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionCallerSession) LINK() (common.Address, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.LINK(&_VRFCoordinatorV2PlusUpgradedVersion.CallOpts)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionCaller) LINKNATIVEFEED(opts *bind.CallOpts) (common.Address, error) {
+ var out []interface{}
+ err := _VRFCoordinatorV2PlusUpgradedVersion.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 (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionSession) LINKNATIVEFEED() (common.Address, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.LINKNATIVEFEED(&_VRFCoordinatorV2PlusUpgradedVersion.CallOpts)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionCallerSession) LINKNATIVEFEED() (common.Address, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.LINKNATIVEFEED(&_VRFCoordinatorV2PlusUpgradedVersion.CallOpts)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionCaller) MAXCONSUMERS(opts *bind.CallOpts) (uint16, error) {
+ var out []interface{}
+ err := _VRFCoordinatorV2PlusUpgradedVersion.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 (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionSession) MAXCONSUMERS() (uint16, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.MAXCONSUMERS(&_VRFCoordinatorV2PlusUpgradedVersion.CallOpts)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionCallerSession) MAXCONSUMERS() (uint16, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.MAXCONSUMERS(&_VRFCoordinatorV2PlusUpgradedVersion.CallOpts)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionCaller) MAXNUMWORDS(opts *bind.CallOpts) (uint32, error) {
+ var out []interface{}
+ err := _VRFCoordinatorV2PlusUpgradedVersion.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 (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionSession) MAXNUMWORDS() (uint32, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.MAXNUMWORDS(&_VRFCoordinatorV2PlusUpgradedVersion.CallOpts)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionCallerSession) MAXNUMWORDS() (uint32, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.MAXNUMWORDS(&_VRFCoordinatorV2PlusUpgradedVersion.CallOpts)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionCaller) MAXREQUESTCONFIRMATIONS(opts *bind.CallOpts) (uint16, error) {
+ var out []interface{}
+ err := _VRFCoordinatorV2PlusUpgradedVersion.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 (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionSession) MAXREQUESTCONFIRMATIONS() (uint16, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.MAXREQUESTCONFIRMATIONS(&_VRFCoordinatorV2PlusUpgradedVersion.CallOpts)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionCallerSession) MAXREQUESTCONFIRMATIONS() (uint16, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.MAXREQUESTCONFIRMATIONS(&_VRFCoordinatorV2PlusUpgradedVersion.CallOpts)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionCaller) GetActiveSubscriptionIds(opts *bind.CallOpts, startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error) {
+ var out []interface{}
+ err := _VRFCoordinatorV2PlusUpgradedVersion.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 (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionSession) GetActiveSubscriptionIds(startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.GetActiveSubscriptionIds(&_VRFCoordinatorV2PlusUpgradedVersion.CallOpts, startIndex, maxCount)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionCallerSession) GetActiveSubscriptionIds(startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.GetActiveSubscriptionIds(&_VRFCoordinatorV2PlusUpgradedVersion.CallOpts, startIndex, maxCount)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionCaller) GetRequestConfig(opts *bind.CallOpts) (uint16, uint32, [][32]byte, error) {
+ var out []interface{}
+ err := _VRFCoordinatorV2PlusUpgradedVersion.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 (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionSession) GetRequestConfig() (uint16, uint32, [][32]byte, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.GetRequestConfig(&_VRFCoordinatorV2PlusUpgradedVersion.CallOpts)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionCallerSession) GetRequestConfig() (uint16, uint32, [][32]byte, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.GetRequestConfig(&_VRFCoordinatorV2PlusUpgradedVersion.CallOpts)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionCaller) GetSubscription(opts *bind.CallOpts, subId *big.Int) (GetSubscription,
+
+ error) {
+ var out []interface{}
+ err := _VRFCoordinatorV2PlusUpgradedVersion.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 (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionSession) GetSubscription(subId *big.Int) (GetSubscription,
+
+ error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.GetSubscription(&_VRFCoordinatorV2PlusUpgradedVersion.CallOpts, subId)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionCallerSession) GetSubscription(subId *big.Int) (GetSubscription,
+
+ error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.GetSubscription(&_VRFCoordinatorV2PlusUpgradedVersion.CallOpts, subId)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionCaller) HashOfKey(opts *bind.CallOpts, publicKey [2]*big.Int) ([32]byte, error) {
+ var out []interface{}
+ err := _VRFCoordinatorV2PlusUpgradedVersion.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 (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionSession) HashOfKey(publicKey [2]*big.Int) ([32]byte, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.HashOfKey(&_VRFCoordinatorV2PlusUpgradedVersion.CallOpts, publicKey)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionCallerSession) HashOfKey(publicKey [2]*big.Int) ([32]byte, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.HashOfKey(&_VRFCoordinatorV2PlusUpgradedVersion.CallOpts, publicKey)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionCaller) MigrationVersion(opts *bind.CallOpts) (uint8, error) {
+ var out []interface{}
+ err := _VRFCoordinatorV2PlusUpgradedVersion.contract.Call(opts, &out, "migrationVersion")
+
+ if err != nil {
+ return *new(uint8), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8)
+
+ return out0, err
+
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionSession) MigrationVersion() (uint8, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.MigrationVersion(&_VRFCoordinatorV2PlusUpgradedVersion.CallOpts)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionCallerSession) MigrationVersion() (uint8, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.MigrationVersion(&_VRFCoordinatorV2PlusUpgradedVersion.CallOpts)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionCaller) Owner(opts *bind.CallOpts) (common.Address, error) {
+ var out []interface{}
+ err := _VRFCoordinatorV2PlusUpgradedVersion.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 (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionSession) Owner() (common.Address, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.Owner(&_VRFCoordinatorV2PlusUpgradedVersion.CallOpts)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionCallerSession) Owner() (common.Address, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.Owner(&_VRFCoordinatorV2PlusUpgradedVersion.CallOpts)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionCaller) PendingRequestExists(opts *bind.CallOpts, subId *big.Int) (bool, error) {
+ var out []interface{}
+ err := _VRFCoordinatorV2PlusUpgradedVersion.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 (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionSession) PendingRequestExists(subId *big.Int) (bool, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.PendingRequestExists(&_VRFCoordinatorV2PlusUpgradedVersion.CallOpts, subId)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionCallerSession) PendingRequestExists(subId *big.Int) (bool, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.PendingRequestExists(&_VRFCoordinatorV2PlusUpgradedVersion.CallOpts, subId)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionCaller) SConfig(opts *bind.CallOpts) (SConfig,
+
+ error) {
+ var out []interface{}
+ err := _VRFCoordinatorV2PlusUpgradedVersion.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 (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionSession) SConfig() (SConfig,
+
+ error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.SConfig(&_VRFCoordinatorV2PlusUpgradedVersion.CallOpts)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionCallerSession) SConfig() (SConfig,
+
+ error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.SConfig(&_VRFCoordinatorV2PlusUpgradedVersion.CallOpts)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionCaller) SCurrentSubNonce(opts *bind.CallOpts) (uint64, error) {
+ var out []interface{}
+ err := _VRFCoordinatorV2PlusUpgradedVersion.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 (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionSession) SCurrentSubNonce() (uint64, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.SCurrentSubNonce(&_VRFCoordinatorV2PlusUpgradedVersion.CallOpts)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionCallerSession) SCurrentSubNonce() (uint64, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.SCurrentSubNonce(&_VRFCoordinatorV2PlusUpgradedVersion.CallOpts)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionCaller) SFallbackWeiPerUnitLink(opts *bind.CallOpts) (*big.Int, error) {
+ var out []interface{}
+ err := _VRFCoordinatorV2PlusUpgradedVersion.contract.Call(opts, &out, "s_fallbackWeiPerUnitLink")
+
+ if err != nil {
+ return *new(*big.Int), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
+
+ return out0, err
+
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionSession) SFallbackWeiPerUnitLink() (*big.Int, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.SFallbackWeiPerUnitLink(&_VRFCoordinatorV2PlusUpgradedVersion.CallOpts)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionCallerSession) SFallbackWeiPerUnitLink() (*big.Int, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.SFallbackWeiPerUnitLink(&_VRFCoordinatorV2PlusUpgradedVersion.CallOpts)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionCaller) SFeeConfig(opts *bind.CallOpts) (SFeeConfig,
+
+ error) {
+ var out []interface{}
+ err := _VRFCoordinatorV2PlusUpgradedVersion.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 (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionSession) SFeeConfig() (SFeeConfig,
+
+ error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.SFeeConfig(&_VRFCoordinatorV2PlusUpgradedVersion.CallOpts)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionCallerSession) SFeeConfig() (SFeeConfig,
+
+ error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.SFeeConfig(&_VRFCoordinatorV2PlusUpgradedVersion.CallOpts)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionCaller) SProvingKeyHashes(opts *bind.CallOpts, arg0 *big.Int) ([32]byte, error) {
+ var out []interface{}
+ err := _VRFCoordinatorV2PlusUpgradedVersion.contract.Call(opts, &out, "s_provingKeyHashes", arg0)
+
+ if err != nil {
+ return *new([32]byte), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte)
+
+ return out0, err
+
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionSession) SProvingKeyHashes(arg0 *big.Int) ([32]byte, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.SProvingKeyHashes(&_VRFCoordinatorV2PlusUpgradedVersion.CallOpts, arg0)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionCallerSession) SProvingKeyHashes(arg0 *big.Int) ([32]byte, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.SProvingKeyHashes(&_VRFCoordinatorV2PlusUpgradedVersion.CallOpts, arg0)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionCaller) SProvingKeys(opts *bind.CallOpts, arg0 [32]byte) (common.Address, error) {
+ var out []interface{}
+ err := _VRFCoordinatorV2PlusUpgradedVersion.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 (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionSession) SProvingKeys(arg0 [32]byte) (common.Address, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.SProvingKeys(&_VRFCoordinatorV2PlusUpgradedVersion.CallOpts, arg0)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionCallerSession) SProvingKeys(arg0 [32]byte) (common.Address, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.SProvingKeys(&_VRFCoordinatorV2PlusUpgradedVersion.CallOpts, arg0)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionCaller) SRequestCommitments(opts *bind.CallOpts, arg0 *big.Int) ([32]byte, error) {
+ var out []interface{}
+ err := _VRFCoordinatorV2PlusUpgradedVersion.contract.Call(opts, &out, "s_requestCommitments", arg0)
+
+ if err != nil {
+ return *new([32]byte), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte)
+
+ return out0, err
+
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionSession) SRequestCommitments(arg0 *big.Int) ([32]byte, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.SRequestCommitments(&_VRFCoordinatorV2PlusUpgradedVersion.CallOpts, arg0)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionCallerSession) SRequestCommitments(arg0 *big.Int) ([32]byte, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.SRequestCommitments(&_VRFCoordinatorV2PlusUpgradedVersion.CallOpts, arg0)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionCaller) STotalBalance(opts *bind.CallOpts) (*big.Int, error) {
+ var out []interface{}
+ err := _VRFCoordinatorV2PlusUpgradedVersion.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 (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionSession) STotalBalance() (*big.Int, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.STotalBalance(&_VRFCoordinatorV2PlusUpgradedVersion.CallOpts)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionCallerSession) STotalBalance() (*big.Int, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.STotalBalance(&_VRFCoordinatorV2PlusUpgradedVersion.CallOpts)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionCaller) STotalNativeBalance(opts *bind.CallOpts) (*big.Int, error) {
+ var out []interface{}
+ err := _VRFCoordinatorV2PlusUpgradedVersion.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 (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionSession) STotalNativeBalance() (*big.Int, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.STotalNativeBalance(&_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) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.contract.Transact(opts, "acceptOwnership")
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionSession) AcceptOwnership() (*types.Transaction, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.AcceptOwnership(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactorSession) AcceptOwnership() (*types.Transaction, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.AcceptOwnership(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactor) AcceptSubscriptionOwnerTransfer(opts *bind.TransactOpts, subId *big.Int) (*types.Transaction, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.contract.Transact(opts, "acceptSubscriptionOwnerTransfer", subId)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionSession) AcceptSubscriptionOwnerTransfer(subId *big.Int) (*types.Transaction, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.AcceptSubscriptionOwnerTransfer(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, subId)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactorSession) AcceptSubscriptionOwnerTransfer(subId *big.Int) (*types.Transaction, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.AcceptSubscriptionOwnerTransfer(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, subId)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactor) AddConsumer(opts *bind.TransactOpts, subId *big.Int, consumer common.Address) (*types.Transaction, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.contract.Transact(opts, "addConsumer", subId, consumer)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionSession) AddConsumer(subId *big.Int, consumer common.Address) (*types.Transaction, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.AddConsumer(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, subId, consumer)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactorSession) AddConsumer(subId *big.Int, consumer common.Address) (*types.Transaction, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.AddConsumer(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, subId, consumer)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactor) CancelSubscription(opts *bind.TransactOpts, subId *big.Int, to common.Address) (*types.Transaction, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.contract.Transact(opts, "cancelSubscription", subId, to)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionSession) CancelSubscription(subId *big.Int, to common.Address) (*types.Transaction, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.CancelSubscription(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, subId, to)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactorSession) CancelSubscription(subId *big.Int, to common.Address) (*types.Transaction, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.CancelSubscription(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, subId, to)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactor) CreateSubscription(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.contract.Transact(opts, "createSubscription")
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionSession) CreateSubscription() (*types.Transaction, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.CreateSubscription(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactorSession) CreateSubscription() (*types.Transaction, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.CreateSubscription(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactor) FulfillRandomWords(opts *bind.TransactOpts, proof VRFProof, rc VRFCoordinatorV2PlusUpgradedVersionRequestCommitment) (*types.Transaction, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.contract.Transact(opts, "fulfillRandomWords", proof, rc)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionSession) FulfillRandomWords(proof VRFProof, rc VRFCoordinatorV2PlusUpgradedVersionRequestCommitment) (*types.Transaction, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.FulfillRandomWords(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, proof, rc)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactorSession) FulfillRandomWords(proof VRFProof, rc VRFCoordinatorV2PlusUpgradedVersionRequestCommitment) (*types.Transaction, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.FulfillRandomWords(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, proof, rc)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactor) FundSubscriptionWithNative(opts *bind.TransactOpts, subId *big.Int) (*types.Transaction, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.contract.Transact(opts, "fundSubscriptionWithNative", subId)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionSession) FundSubscriptionWithNative(subId *big.Int) (*types.Transaction, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.FundSubscriptionWithNative(&_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) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.contract.Transact(opts, "migrate", subId, newCoordinator)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionSession) Migrate(subId *big.Int, newCoordinator common.Address) (*types.Transaction, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.Migrate(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, subId, newCoordinator)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactorSession) Migrate(subId *big.Int, newCoordinator common.Address) (*types.Transaction, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.Migrate(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, subId, newCoordinator)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactor) OnMigration(opts *bind.TransactOpts, encodedData []byte) (*types.Transaction, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.contract.Transact(opts, "onMigration", encodedData)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionSession) OnMigration(encodedData []byte) (*types.Transaction, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.OnMigration(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, encodedData)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactorSession) OnMigration(encodedData []byte) (*types.Transaction, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.OnMigration(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, encodedData)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactor) OnTokenTransfer(opts *bind.TransactOpts, arg0 common.Address, amount *big.Int, data []byte) (*types.Transaction, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.contract.Transact(opts, "onTokenTransfer", arg0, amount, data)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionSession) OnTokenTransfer(arg0 common.Address, amount *big.Int, data []byte) (*types.Transaction, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.OnTokenTransfer(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, arg0, amount, data)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactorSession) OnTokenTransfer(arg0 common.Address, amount *big.Int, data []byte) (*types.Transaction, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.OnTokenTransfer(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, arg0, amount, data)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactor) OracleWithdraw(opts *bind.TransactOpts, recipient common.Address, amount *big.Int) (*types.Transaction, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.contract.Transact(opts, "oracleWithdraw", recipient, amount)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionSession) OracleWithdraw(recipient common.Address, amount *big.Int) (*types.Transaction, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.OracleWithdraw(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, recipient, amount)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactorSession) OracleWithdraw(recipient common.Address, amount *big.Int) (*types.Transaction, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.OracleWithdraw(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, 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) OracleWithdrawNative(recipient common.Address, amount *big.Int) (*types.Transaction, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.OracleWithdrawNative(&_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) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.contract.Transact(opts, "ownerCancelSubscription", subId)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionSession) OwnerCancelSubscription(subId *big.Int) (*types.Transaction, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.OwnerCancelSubscription(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, subId)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactorSession) OwnerCancelSubscription(subId *big.Int) (*types.Transaction, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.OwnerCancelSubscription(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, subId)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactor) RecoverFunds(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.contract.Transact(opts, "recoverFunds", to)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionSession) RecoverFunds(to common.Address) (*types.Transaction, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.RecoverFunds(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, to)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactorSession) RecoverFunds(to common.Address) (*types.Transaction, error) {
+ 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)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionSession) RegisterMigratableCoordinator(target common.Address) (*types.Transaction, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.RegisterMigratableCoordinator(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, target)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactorSession) RegisterMigratableCoordinator(target common.Address) (*types.Transaction, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.RegisterMigratableCoordinator(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, target)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactor) RegisterProvingKey(opts *bind.TransactOpts, oracle common.Address, publicProvingKey [2]*big.Int) (*types.Transaction, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.contract.Transact(opts, "registerProvingKey", oracle, publicProvingKey)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionSession) RegisterProvingKey(oracle common.Address, publicProvingKey [2]*big.Int) (*types.Transaction, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.RegisterProvingKey(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, oracle, publicProvingKey)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactorSession) RegisterProvingKey(oracle common.Address, publicProvingKey [2]*big.Int) (*types.Transaction, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.RegisterProvingKey(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, oracle, publicProvingKey)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactor) RemoveConsumer(opts *bind.TransactOpts, subId *big.Int, consumer common.Address) (*types.Transaction, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.contract.Transact(opts, "removeConsumer", subId, consumer)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionSession) RemoveConsumer(subId *big.Int, consumer common.Address) (*types.Transaction, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.RemoveConsumer(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, subId, consumer)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactorSession) RemoveConsumer(subId *big.Int, consumer common.Address) (*types.Transaction, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.RemoveConsumer(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, subId, consumer)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactor) RequestRandomWords(opts *bind.TransactOpts, req VRFV2PlusClientRandomWordsRequest) (*types.Transaction, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.contract.Transact(opts, "requestRandomWords", req)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionSession) RequestRandomWords(req VRFV2PlusClientRandomWordsRequest) (*types.Transaction, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.RequestRandomWords(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, req)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactorSession) RequestRandomWords(req VRFV2PlusClientRandomWordsRequest) (*types.Transaction, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.RequestRandomWords(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, req)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactor) RequestSubscriptionOwnerTransfer(opts *bind.TransactOpts, subId *big.Int, newOwner common.Address) (*types.Transaction, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.contract.Transact(opts, "requestSubscriptionOwnerTransfer", subId, newOwner)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionSession) RequestSubscriptionOwnerTransfer(subId *big.Int, newOwner common.Address) (*types.Transaction, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.RequestSubscriptionOwnerTransfer(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, subId, newOwner)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactorSession) RequestSubscriptionOwnerTransfer(subId *big.Int, newOwner common.Address) (*types.Transaction, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.RequestSubscriptionOwnerTransfer(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, subId, newOwner)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactor) SetConfig(opts *bind.TransactOpts, minimumRequestConfirmations uint16, maxGasLimit uint32, stalenessSeconds uint32, gasAfterPaymentCalculation uint32, fallbackWeiPerUnitLink *big.Int, feeConfig VRFCoordinatorV2PlusUpgradedVersionFeeConfig) (*types.Transaction, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.contract.Transact(opts, "setConfig", minimumRequestConfirmations, maxGasLimit, stalenessSeconds, gasAfterPaymentCalculation, fallbackWeiPerUnitLink, feeConfig)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionSession) SetConfig(minimumRequestConfirmations uint16, maxGasLimit uint32, stalenessSeconds uint32, gasAfterPaymentCalculation uint32, fallbackWeiPerUnitLink *big.Int, feeConfig VRFCoordinatorV2PlusUpgradedVersionFeeConfig) (*types.Transaction, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.SetConfig(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, minimumRequestConfirmations, maxGasLimit, stalenessSeconds, gasAfterPaymentCalculation, fallbackWeiPerUnitLink, feeConfig)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactorSession) SetConfig(minimumRequestConfirmations uint16, maxGasLimit uint32, stalenessSeconds uint32, gasAfterPaymentCalculation uint32, fallbackWeiPerUnitLink *big.Int, feeConfig VRFCoordinatorV2PlusUpgradedVersionFeeConfig) (*types.Transaction, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.SetConfig(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, minimumRequestConfirmations, maxGasLimit, stalenessSeconds, gasAfterPaymentCalculation, fallbackWeiPerUnitLink, feeConfig)
+}
+
+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) SetLINKAndLINKNativeFeed(link common.Address, linkNativeFeed common.Address) (*types.Transaction, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.SetLINKAndLINKNativeFeed(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, link, linkNativeFeed)
+}
+
+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) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.contract.Transact(opts, "transferOwnership", to)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionSession) TransferOwnership(to common.Address) (*types.Transaction, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.TransferOwnership(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, to)
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) {
+ return _VRFCoordinatorV2PlusUpgradedVersion.Contract.TransferOwnership(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, to)
+}
+
+type VRFCoordinatorV2PlusUpgradedVersionConfigSetIterator struct {
+ Event *VRFCoordinatorV2PlusUpgradedVersionConfigSet
+
+ contract *bind.BoundContract
+ event string
+
+ logs chan types.Log
+ sub ethereum.Subscription
+ done bool
+ fail error
+}
+
+func (it *VRFCoordinatorV2PlusUpgradedVersionConfigSetIterator) Next() bool {
+
+ if it.fail != nil {
+ return false
+ }
+
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(VRFCoordinatorV2PlusUpgradedVersionConfigSet)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+
+ select {
+ case log := <-it.logs:
+ it.Event = new(VRFCoordinatorV2PlusUpgradedVersionConfigSet)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+func (it *VRFCoordinatorV2PlusUpgradedVersionConfigSetIterator) Error() error {
+ return it.fail
+}
+
+func (it *VRFCoordinatorV2PlusUpgradedVersionConfigSetIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+type VRFCoordinatorV2PlusUpgradedVersionConfigSet struct {
+ MinimumRequestConfirmations uint16
+ MaxGasLimit uint32
+ StalenessSeconds uint32
+ GasAfterPaymentCalculation uint32
+ FallbackWeiPerUnitLink *big.Int
+ FeeConfig VRFCoordinatorV2PlusUpgradedVersionFeeConfig
+ Raw types.Log
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) FilterConfigSet(opts *bind.FilterOpts) (*VRFCoordinatorV2PlusUpgradedVersionConfigSetIterator, error) {
+
+ logs, sub, err := _VRFCoordinatorV2PlusUpgradedVersion.contract.FilterLogs(opts, "ConfigSet")
+ if err != nil {
+ return nil, err
+ }
+ return &VRFCoordinatorV2PlusUpgradedVersionConfigSetIterator{contract: _VRFCoordinatorV2PlusUpgradedVersion.contract, event: "ConfigSet", logs: logs, sub: sub}, nil
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) WatchConfigSet(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusUpgradedVersionConfigSet) (event.Subscription, error) {
+
+ logs, sub, err := _VRFCoordinatorV2PlusUpgradedVersion.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(VRFCoordinatorV2PlusUpgradedVersionConfigSet)
+ if err := _VRFCoordinatorV2PlusUpgradedVersion.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 (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) ParseConfigSet(log types.Log) (*VRFCoordinatorV2PlusUpgradedVersionConfigSet, error) {
+ event := new(VRFCoordinatorV2PlusUpgradedVersionConfigSet)
+ if err := _VRFCoordinatorV2PlusUpgradedVersion.contract.UnpackLog(event, "ConfigSet", log); err != nil {
+ return nil, err
+ }
+ event.Raw = log
+ return event, nil
+}
+
+type VRFCoordinatorV2PlusUpgradedVersionCoordinatorRegisteredIterator struct {
+ Event *VRFCoordinatorV2PlusUpgradedVersionCoordinatorRegistered
+
+ contract *bind.BoundContract
+ event string
+
+ logs chan types.Log
+ sub ethereum.Subscription
+ done bool
+ fail error
+}
+
+func (it *VRFCoordinatorV2PlusUpgradedVersionCoordinatorRegisteredIterator) Next() bool {
+
+ if it.fail != nil {
+ return false
+ }
+
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(VRFCoordinatorV2PlusUpgradedVersionCoordinatorRegistered)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+
+ select {
+ case log := <-it.logs:
+ it.Event = new(VRFCoordinatorV2PlusUpgradedVersionCoordinatorRegistered)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+func (it *VRFCoordinatorV2PlusUpgradedVersionCoordinatorRegisteredIterator) Error() error {
+ return it.fail
+}
+
+func (it *VRFCoordinatorV2PlusUpgradedVersionCoordinatorRegisteredIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+type VRFCoordinatorV2PlusUpgradedVersionCoordinatorRegistered struct {
+ CoordinatorAddress common.Address
+ Raw types.Log
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) FilterCoordinatorRegistered(opts *bind.FilterOpts) (*VRFCoordinatorV2PlusUpgradedVersionCoordinatorRegisteredIterator, error) {
+
+ logs, sub, err := _VRFCoordinatorV2PlusUpgradedVersion.contract.FilterLogs(opts, "CoordinatorRegistered")
+ if err != nil {
+ return nil, err
+ }
+ return &VRFCoordinatorV2PlusUpgradedVersionCoordinatorRegisteredIterator{contract: _VRFCoordinatorV2PlusUpgradedVersion.contract, event: "CoordinatorRegistered", logs: logs, sub: sub}, nil
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) WatchCoordinatorRegistered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusUpgradedVersionCoordinatorRegistered) (event.Subscription, error) {
+
+ logs, sub, err := _VRFCoordinatorV2PlusUpgradedVersion.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(VRFCoordinatorV2PlusUpgradedVersionCoordinatorRegistered)
+ if err := _VRFCoordinatorV2PlusUpgradedVersion.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 (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) ParseCoordinatorRegistered(log types.Log) (*VRFCoordinatorV2PlusUpgradedVersionCoordinatorRegistered, error) {
+ event := new(VRFCoordinatorV2PlusUpgradedVersionCoordinatorRegistered)
+ if err := _VRFCoordinatorV2PlusUpgradedVersion.contract.UnpackLog(event, "CoordinatorRegistered", log); err != nil {
+ return nil, err
+ }
+ event.Raw = log
+ return event, nil
+}
+
+type VRFCoordinatorV2PlusUpgradedVersionFundsRecoveredIterator struct {
+ Event *VRFCoordinatorV2PlusUpgradedVersionFundsRecovered
+
+ contract *bind.BoundContract
+ event string
+
+ logs chan types.Log
+ sub ethereum.Subscription
+ done bool
+ fail error
+}
+
+func (it *VRFCoordinatorV2PlusUpgradedVersionFundsRecoveredIterator) Next() bool {
+
+ if it.fail != nil {
+ return false
+ }
+
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(VRFCoordinatorV2PlusUpgradedVersionFundsRecovered)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+
+ select {
+ case log := <-it.logs:
+ it.Event = new(VRFCoordinatorV2PlusUpgradedVersionFundsRecovered)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+func (it *VRFCoordinatorV2PlusUpgradedVersionFundsRecoveredIterator) Error() error {
+ return it.fail
+}
+
+func (it *VRFCoordinatorV2PlusUpgradedVersionFundsRecoveredIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+type VRFCoordinatorV2PlusUpgradedVersionFundsRecovered struct {
+ To common.Address
+ Amount *big.Int
+ Raw types.Log
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) FilterFundsRecovered(opts *bind.FilterOpts) (*VRFCoordinatorV2PlusUpgradedVersionFundsRecoveredIterator, error) {
+
+ logs, sub, err := _VRFCoordinatorV2PlusUpgradedVersion.contract.FilterLogs(opts, "FundsRecovered")
+ if err != nil {
+ return nil, err
+ }
+ return &VRFCoordinatorV2PlusUpgradedVersionFundsRecoveredIterator{contract: _VRFCoordinatorV2PlusUpgradedVersion.contract, event: "FundsRecovered", logs: logs, sub: sub}, nil
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) WatchFundsRecovered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusUpgradedVersionFundsRecovered) (event.Subscription, error) {
+
+ logs, sub, err := _VRFCoordinatorV2PlusUpgradedVersion.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(VRFCoordinatorV2PlusUpgradedVersionFundsRecovered)
+ if err := _VRFCoordinatorV2PlusUpgradedVersion.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 (_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 VRFCoordinatorV2PlusUpgradedVersionMigrationCompletedIterator struct {
+ Event *VRFCoordinatorV2PlusUpgradedVersionMigrationCompleted
+
+ contract *bind.BoundContract
+ event string
+
+ logs chan types.Log
+ sub ethereum.Subscription
+ done bool
+ fail error
+}
+
+func (it *VRFCoordinatorV2PlusUpgradedVersionMigrationCompletedIterator) Next() bool {
+
+ if it.fail != nil {
+ return false
+ }
+
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(VRFCoordinatorV2PlusUpgradedVersionMigrationCompleted)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+
+ select {
+ case log := <-it.logs:
+ it.Event = new(VRFCoordinatorV2PlusUpgradedVersionMigrationCompleted)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+func (it *VRFCoordinatorV2PlusUpgradedVersionMigrationCompletedIterator) Error() error {
+ return it.fail
+}
+
+func (it *VRFCoordinatorV2PlusUpgradedVersionMigrationCompletedIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+type VRFCoordinatorV2PlusUpgradedVersionMigrationCompleted struct {
+ NewCoordinator common.Address
+ SubId *big.Int
+ Raw types.Log
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) FilterMigrationCompleted(opts *bind.FilterOpts) (*VRFCoordinatorV2PlusUpgradedVersionMigrationCompletedIterator, error) {
+
+ logs, sub, err := _VRFCoordinatorV2PlusUpgradedVersion.contract.FilterLogs(opts, "MigrationCompleted")
+ if err != nil {
+ return nil, err
+ }
+ return &VRFCoordinatorV2PlusUpgradedVersionMigrationCompletedIterator{contract: _VRFCoordinatorV2PlusUpgradedVersion.contract, event: "MigrationCompleted", logs: logs, sub: sub}, nil
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) WatchMigrationCompleted(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusUpgradedVersionMigrationCompleted) (event.Subscription, error) {
+
+ logs, sub, err := _VRFCoordinatorV2PlusUpgradedVersion.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(VRFCoordinatorV2PlusUpgradedVersionMigrationCompleted)
+ if err := _VRFCoordinatorV2PlusUpgradedVersion.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 (_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 VRFCoordinatorV2PlusUpgradedVersionNativeFundsRecoveredIterator struct {
+ Event *VRFCoordinatorV2PlusUpgradedVersionNativeFundsRecovered
+
+ contract *bind.BoundContract
+ event string
+
+ logs chan types.Log
+ sub ethereum.Subscription
+ done bool
+ fail error
+}
+
+func (it *VRFCoordinatorV2PlusUpgradedVersionNativeFundsRecoveredIterator) Next() bool {
+
+ if it.fail != nil {
+ return false
+ }
+
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(VRFCoordinatorV2PlusUpgradedVersionNativeFundsRecovered)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+
+ select {
+ case log := <-it.logs:
+ it.Event = new(VRFCoordinatorV2PlusUpgradedVersionNativeFundsRecovered)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+func (it *VRFCoordinatorV2PlusUpgradedVersionNativeFundsRecoveredIterator) Error() error {
+ return it.fail
+}
+
+func (it *VRFCoordinatorV2PlusUpgradedVersionNativeFundsRecoveredIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+type VRFCoordinatorV2PlusUpgradedVersionNativeFundsRecovered struct {
+ To common.Address
+ Amount *big.Int
+ Raw types.Log
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) FilterNativeFundsRecovered(opts *bind.FilterOpts) (*VRFCoordinatorV2PlusUpgradedVersionNativeFundsRecoveredIterator, error) {
+
+ logs, sub, err := _VRFCoordinatorV2PlusUpgradedVersion.contract.FilterLogs(opts, "NativeFundsRecovered")
+ if err != nil {
+ return nil, err
+ }
+ return &VRFCoordinatorV2PlusUpgradedVersionNativeFundsRecoveredIterator{contract: _VRFCoordinatorV2PlusUpgradedVersion.contract, event: "NativeFundsRecovered", logs: logs, sub: sub}, nil
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) WatchNativeFundsRecovered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusUpgradedVersionNativeFundsRecovered) (event.Subscription, error) {
+
+ logs, sub, err := _VRFCoordinatorV2PlusUpgradedVersion.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(VRFCoordinatorV2PlusUpgradedVersionNativeFundsRecovered)
+ if err := _VRFCoordinatorV2PlusUpgradedVersion.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 (_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
+ return event, nil
+}
+
+type VRFCoordinatorV2PlusUpgradedVersionOwnershipTransferRequestedIterator struct {
+ Event *VRFCoordinatorV2PlusUpgradedVersionOwnershipTransferRequested
+
+ contract *bind.BoundContract
+ event string
+
+ logs chan types.Log
+ sub ethereum.Subscription
+ done bool
+ fail error
+}
+
+func (it *VRFCoordinatorV2PlusUpgradedVersionOwnershipTransferRequestedIterator) Next() bool {
+
+ if it.fail != nil {
+ return false
+ }
+
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(VRFCoordinatorV2PlusUpgradedVersionOwnershipTransferRequested)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+
+ select {
+ case log := <-it.logs:
+ it.Event = new(VRFCoordinatorV2PlusUpgradedVersionOwnershipTransferRequested)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+func (it *VRFCoordinatorV2PlusUpgradedVersionOwnershipTransferRequestedIterator) Error() error {
+ return it.fail
+}
+
+func (it *VRFCoordinatorV2PlusUpgradedVersionOwnershipTransferRequestedIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+type VRFCoordinatorV2PlusUpgradedVersionOwnershipTransferRequested struct {
+ From common.Address
+ To common.Address
+ Raw types.Log
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VRFCoordinatorV2PlusUpgradedVersionOwnershipTransferRequestedIterator, 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 := _VRFCoordinatorV2PlusUpgradedVersion.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule)
+ if err != nil {
+ return nil, err
+ }
+ return &VRFCoordinatorV2PlusUpgradedVersionOwnershipTransferRequestedIterator{contract: _VRFCoordinatorV2PlusUpgradedVersion.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusUpgradedVersionOwnershipTransferRequested, 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 := _VRFCoordinatorV2PlusUpgradedVersion.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(VRFCoordinatorV2PlusUpgradedVersionOwnershipTransferRequested)
+ if err := _VRFCoordinatorV2PlusUpgradedVersion.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 (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) ParseOwnershipTransferRequested(log types.Log) (*VRFCoordinatorV2PlusUpgradedVersionOwnershipTransferRequested, error) {
+ event := new(VRFCoordinatorV2PlusUpgradedVersionOwnershipTransferRequested)
+ if err := _VRFCoordinatorV2PlusUpgradedVersion.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil {
+ return nil, err
+ }
+ event.Raw = log
+ return event, nil
+}
+
+type VRFCoordinatorV2PlusUpgradedVersionOwnershipTransferredIterator struct {
+ Event *VRFCoordinatorV2PlusUpgradedVersionOwnershipTransferred
+
+ contract *bind.BoundContract
+ event string
+
+ logs chan types.Log
+ sub ethereum.Subscription
+ done bool
+ fail error
+}
+
+func (it *VRFCoordinatorV2PlusUpgradedVersionOwnershipTransferredIterator) Next() bool {
+
+ if it.fail != nil {
+ return false
+ }
+
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(VRFCoordinatorV2PlusUpgradedVersionOwnershipTransferred)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+
+ select {
+ case log := <-it.logs:
+ it.Event = new(VRFCoordinatorV2PlusUpgradedVersionOwnershipTransferred)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+func (it *VRFCoordinatorV2PlusUpgradedVersionOwnershipTransferredIterator) Error() error {
+ return it.fail
+}
+
+func (it *VRFCoordinatorV2PlusUpgradedVersionOwnershipTransferredIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+type VRFCoordinatorV2PlusUpgradedVersionOwnershipTransferred struct {
+ From common.Address
+ To common.Address
+ Raw types.Log
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VRFCoordinatorV2PlusUpgradedVersionOwnershipTransferredIterator, 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 := _VRFCoordinatorV2PlusUpgradedVersion.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule)
+ if err != nil {
+ return nil, err
+ }
+ return &VRFCoordinatorV2PlusUpgradedVersionOwnershipTransferredIterator{contract: _VRFCoordinatorV2PlusUpgradedVersion.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusUpgradedVersionOwnershipTransferred, 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 := _VRFCoordinatorV2PlusUpgradedVersion.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(VRFCoordinatorV2PlusUpgradedVersionOwnershipTransferred)
+ if err := _VRFCoordinatorV2PlusUpgradedVersion.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 (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) ParseOwnershipTransferred(log types.Log) (*VRFCoordinatorV2PlusUpgradedVersionOwnershipTransferred, error) {
+ event := new(VRFCoordinatorV2PlusUpgradedVersionOwnershipTransferred)
+ if err := _VRFCoordinatorV2PlusUpgradedVersion.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil {
+ return nil, err
+ }
+ event.Raw = log
+ return event, nil
+}
+
+type VRFCoordinatorV2PlusUpgradedVersionProvingKeyRegisteredIterator struct {
+ Event *VRFCoordinatorV2PlusUpgradedVersionProvingKeyRegistered
+
+ contract *bind.BoundContract
+ event string
+
+ logs chan types.Log
+ sub ethereum.Subscription
+ done bool
+ fail error
+}
+
+func (it *VRFCoordinatorV2PlusUpgradedVersionProvingKeyRegisteredIterator) Next() bool {
+
+ if it.fail != nil {
+ return false
+ }
+
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(VRFCoordinatorV2PlusUpgradedVersionProvingKeyRegistered)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+
+ select {
+ case log := <-it.logs:
+ it.Event = new(VRFCoordinatorV2PlusUpgradedVersionProvingKeyRegistered)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+func (it *VRFCoordinatorV2PlusUpgradedVersionProvingKeyRegisteredIterator) Error() error {
+ return it.fail
+}
+
+func (it *VRFCoordinatorV2PlusUpgradedVersionProvingKeyRegisteredIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+type VRFCoordinatorV2PlusUpgradedVersionProvingKeyRegistered struct {
+ KeyHash [32]byte
+ Oracle common.Address
+ Raw types.Log
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) FilterProvingKeyRegistered(opts *bind.FilterOpts, oracle []common.Address) (*VRFCoordinatorV2PlusUpgradedVersionProvingKeyRegisteredIterator, error) {
+
+ var oracleRule []interface{}
+ for _, oracleItem := range oracle {
+ oracleRule = append(oracleRule, oracleItem)
+ }
+
+ logs, sub, err := _VRFCoordinatorV2PlusUpgradedVersion.contract.FilterLogs(opts, "ProvingKeyRegistered", oracleRule)
+ if err != nil {
+ return nil, err
+ }
+ return &VRFCoordinatorV2PlusUpgradedVersionProvingKeyRegisteredIterator{contract: _VRFCoordinatorV2PlusUpgradedVersion.contract, event: "ProvingKeyRegistered", logs: logs, sub: sub}, nil
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) WatchProvingKeyRegistered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusUpgradedVersionProvingKeyRegistered, oracle []common.Address) (event.Subscription, error) {
+
+ var oracleRule []interface{}
+ for _, oracleItem := range oracle {
+ oracleRule = append(oracleRule, oracleItem)
+ }
+
+ logs, sub, err := _VRFCoordinatorV2PlusUpgradedVersion.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(VRFCoordinatorV2PlusUpgradedVersionProvingKeyRegistered)
+ if err := _VRFCoordinatorV2PlusUpgradedVersion.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 (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) ParseProvingKeyRegistered(log types.Log) (*VRFCoordinatorV2PlusUpgradedVersionProvingKeyRegistered, error) {
+ event := new(VRFCoordinatorV2PlusUpgradedVersionProvingKeyRegistered)
+ if err := _VRFCoordinatorV2PlusUpgradedVersion.contract.UnpackLog(event, "ProvingKeyRegistered", log); err != nil {
+ return nil, err
+ }
+ event.Raw = log
+ return event, nil
+}
+
+type VRFCoordinatorV2PlusUpgradedVersionRandomWordsFulfilledIterator struct {
+ Event *VRFCoordinatorV2PlusUpgradedVersionRandomWordsFulfilled
+
+ contract *bind.BoundContract
+ event string
+
+ logs chan types.Log
+ sub ethereum.Subscription
+ done bool
+ fail error
+}
+
+func (it *VRFCoordinatorV2PlusUpgradedVersionRandomWordsFulfilledIterator) Next() bool {
+
+ if it.fail != nil {
+ return false
+ }
+
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(VRFCoordinatorV2PlusUpgradedVersionRandomWordsFulfilled)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+
+ select {
+ case log := <-it.logs:
+ it.Event = new(VRFCoordinatorV2PlusUpgradedVersionRandomWordsFulfilled)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+func (it *VRFCoordinatorV2PlusUpgradedVersionRandomWordsFulfilledIterator) Error() error {
+ return it.fail
+}
+
+func (it *VRFCoordinatorV2PlusUpgradedVersionRandomWordsFulfilledIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+type VRFCoordinatorV2PlusUpgradedVersionRandomWordsFulfilled struct {
+ RequestId *big.Int
+ OutputSeed *big.Int
+ SubID *big.Int
+ Payment *big.Int
+ Success bool
+ Raw types.Log
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) FilterRandomWordsFulfilled(opts *bind.FilterOpts, requestId []*big.Int, subID []*big.Int) (*VRFCoordinatorV2PlusUpgradedVersionRandomWordsFulfilledIterator, error) {
+
+ var requestIdRule []interface{}
+ for _, requestIdItem := range requestId {
+ requestIdRule = append(requestIdRule, requestIdItem)
+ }
+
+ var subIDRule []interface{}
+ for _, subIDItem := range subID {
+ subIDRule = append(subIDRule, subIDItem)
+ }
+
+ logs, sub, err := _VRFCoordinatorV2PlusUpgradedVersion.contract.FilterLogs(opts, "RandomWordsFulfilled", requestIdRule, subIDRule)
+ if err != nil {
+ return nil, err
+ }
+ return &VRFCoordinatorV2PlusUpgradedVersionRandomWordsFulfilledIterator{contract: _VRFCoordinatorV2PlusUpgradedVersion.contract, event: "RandomWordsFulfilled", logs: logs, sub: sub}, nil
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) WatchRandomWordsFulfilled(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusUpgradedVersionRandomWordsFulfilled, requestId []*big.Int, subID []*big.Int) (event.Subscription, error) {
+
+ 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 := _VRFCoordinatorV2PlusUpgradedVersion.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(VRFCoordinatorV2PlusUpgradedVersionRandomWordsFulfilled)
+ if err := _VRFCoordinatorV2PlusUpgradedVersion.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 (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) ParseRandomWordsFulfilled(log types.Log) (*VRFCoordinatorV2PlusUpgradedVersionRandomWordsFulfilled, error) {
+ event := new(VRFCoordinatorV2PlusUpgradedVersionRandomWordsFulfilled)
+ if err := _VRFCoordinatorV2PlusUpgradedVersion.contract.UnpackLog(event, "RandomWordsFulfilled", log); err != nil {
+ return nil, err
+ }
+ event.Raw = log
+ return event, nil
+}
+
+type VRFCoordinatorV2PlusUpgradedVersionRandomWordsRequestedIterator struct {
+ Event *VRFCoordinatorV2PlusUpgradedVersionRandomWordsRequested
+
+ contract *bind.BoundContract
+ event string
+
+ logs chan types.Log
+ sub ethereum.Subscription
+ done bool
+ fail error
+}
+
+func (it *VRFCoordinatorV2PlusUpgradedVersionRandomWordsRequestedIterator) Next() bool {
+
+ if it.fail != nil {
+ return false
+ }
+
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(VRFCoordinatorV2PlusUpgradedVersionRandomWordsRequested)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+
+ select {
+ case log := <-it.logs:
+ it.Event = new(VRFCoordinatorV2PlusUpgradedVersionRandomWordsRequested)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+func (it *VRFCoordinatorV2PlusUpgradedVersionRandomWordsRequestedIterator) Error() error {
+ return it.fail
+}
+
+func (it *VRFCoordinatorV2PlusUpgradedVersionRandomWordsRequestedIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+type VRFCoordinatorV2PlusUpgradedVersionRandomWordsRequested 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 (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) FilterRandomWordsRequested(opts *bind.FilterOpts, keyHash [][32]byte, subId []*big.Int, sender []common.Address) (*VRFCoordinatorV2PlusUpgradedVersionRandomWordsRequestedIterator, 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 := _VRFCoordinatorV2PlusUpgradedVersion.contract.FilterLogs(opts, "RandomWordsRequested", keyHashRule, subIdRule, senderRule)
+ if err != nil {
+ return nil, err
+ }
+ return &VRFCoordinatorV2PlusUpgradedVersionRandomWordsRequestedIterator{contract: _VRFCoordinatorV2PlusUpgradedVersion.contract, event: "RandomWordsRequested", logs: logs, sub: sub}, nil
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) WatchRandomWordsRequested(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusUpgradedVersionRandomWordsRequested, 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 := _VRFCoordinatorV2PlusUpgradedVersion.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(VRFCoordinatorV2PlusUpgradedVersionRandomWordsRequested)
+ if err := _VRFCoordinatorV2PlusUpgradedVersion.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 (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) ParseRandomWordsRequested(log types.Log) (*VRFCoordinatorV2PlusUpgradedVersionRandomWordsRequested, error) {
+ event := new(VRFCoordinatorV2PlusUpgradedVersionRandomWordsRequested)
+ if err := _VRFCoordinatorV2PlusUpgradedVersion.contract.UnpackLog(event, "RandomWordsRequested", log); err != nil {
+ return nil, err
+ }
+ event.Raw = log
+ return event, nil
+}
+
+type VRFCoordinatorV2PlusUpgradedVersionSubscriptionCanceledIterator struct {
+ Event *VRFCoordinatorV2PlusUpgradedVersionSubscriptionCanceled
+
+ contract *bind.BoundContract
+ event string
+
+ logs chan types.Log
+ sub ethereum.Subscription
+ done bool
+ fail error
+}
+
+func (it *VRFCoordinatorV2PlusUpgradedVersionSubscriptionCanceledIterator) Next() bool {
+
+ if it.fail != nil {
+ return false
+ }
+
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(VRFCoordinatorV2PlusUpgradedVersionSubscriptionCanceled)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+
+ select {
+ case log := <-it.logs:
+ it.Event = new(VRFCoordinatorV2PlusUpgradedVersionSubscriptionCanceled)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+func (it *VRFCoordinatorV2PlusUpgradedVersionSubscriptionCanceledIterator) Error() error {
+ return it.fail
+}
+
+func (it *VRFCoordinatorV2PlusUpgradedVersionSubscriptionCanceledIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+type VRFCoordinatorV2PlusUpgradedVersionSubscriptionCanceled struct {
+ 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) {
+
+ var subIdRule []interface{}
+ for _, subIdItem := range subId {
+ subIdRule = append(subIdRule, subIdItem)
+ }
+
+ logs, sub, err := _VRFCoordinatorV2PlusUpgradedVersion.contract.FilterLogs(opts, "SubscriptionCanceled", subIdRule)
+ if err != nil {
+ return nil, err
+ }
+ return &VRFCoordinatorV2PlusUpgradedVersionSubscriptionCanceledIterator{contract: _VRFCoordinatorV2PlusUpgradedVersion.contract, event: "SubscriptionCanceled", logs: logs, sub: sub}, nil
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) WatchSubscriptionCanceled(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusUpgradedVersionSubscriptionCanceled, subId []*big.Int) (event.Subscription, error) {
+
+ var subIdRule []interface{}
+ for _, subIdItem := range subId {
+ subIdRule = append(subIdRule, subIdItem)
+ }
+
+ logs, sub, err := _VRFCoordinatorV2PlusUpgradedVersion.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(VRFCoordinatorV2PlusUpgradedVersionSubscriptionCanceled)
+ if err := _VRFCoordinatorV2PlusUpgradedVersion.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 (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) ParseSubscriptionCanceled(log types.Log) (*VRFCoordinatorV2PlusUpgradedVersionSubscriptionCanceled, error) {
+ event := new(VRFCoordinatorV2PlusUpgradedVersionSubscriptionCanceled)
+ if err := _VRFCoordinatorV2PlusUpgradedVersion.contract.UnpackLog(event, "SubscriptionCanceled", log); err != nil {
+ return nil, err
+ }
+ event.Raw = log
+ return event, nil
+}
+
+type VRFCoordinatorV2PlusUpgradedVersionSubscriptionConsumerAddedIterator struct {
+ Event *VRFCoordinatorV2PlusUpgradedVersionSubscriptionConsumerAdded
+
+ contract *bind.BoundContract
+ event string
+
+ logs chan types.Log
+ sub ethereum.Subscription
+ done bool
+ fail error
+}
+
+func (it *VRFCoordinatorV2PlusUpgradedVersionSubscriptionConsumerAddedIterator) Next() bool {
+
+ if it.fail != nil {
+ return false
+ }
+
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(VRFCoordinatorV2PlusUpgradedVersionSubscriptionConsumerAdded)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+
+ select {
+ case log := <-it.logs:
+ it.Event = new(VRFCoordinatorV2PlusUpgradedVersionSubscriptionConsumerAdded)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+func (it *VRFCoordinatorV2PlusUpgradedVersionSubscriptionConsumerAddedIterator) Error() error {
+ return it.fail
+}
+
+func (it *VRFCoordinatorV2PlusUpgradedVersionSubscriptionConsumerAddedIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+type VRFCoordinatorV2PlusUpgradedVersionSubscriptionConsumerAdded struct {
+ SubId *big.Int
+ Consumer common.Address
+ Raw types.Log
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) FilterSubscriptionConsumerAdded(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorV2PlusUpgradedVersionSubscriptionConsumerAddedIterator, error) {
+
+ var subIdRule []interface{}
+ for _, subIdItem := range subId {
+ subIdRule = append(subIdRule, subIdItem)
+ }
+
+ logs, sub, err := _VRFCoordinatorV2PlusUpgradedVersion.contract.FilterLogs(opts, "SubscriptionConsumerAdded", subIdRule)
+ if err != nil {
+ return nil, err
+ }
+ return &VRFCoordinatorV2PlusUpgradedVersionSubscriptionConsumerAddedIterator{contract: _VRFCoordinatorV2PlusUpgradedVersion.contract, event: "SubscriptionConsumerAdded", logs: logs, sub: sub}, nil
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) WatchSubscriptionConsumerAdded(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusUpgradedVersionSubscriptionConsumerAdded, subId []*big.Int) (event.Subscription, error) {
+
+ var subIdRule []interface{}
+ for _, subIdItem := range subId {
+ subIdRule = append(subIdRule, subIdItem)
+ }
+
+ logs, sub, err := _VRFCoordinatorV2PlusUpgradedVersion.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(VRFCoordinatorV2PlusUpgradedVersionSubscriptionConsumerAdded)
+ if err := _VRFCoordinatorV2PlusUpgradedVersion.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 (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) ParseSubscriptionConsumerAdded(log types.Log) (*VRFCoordinatorV2PlusUpgradedVersionSubscriptionConsumerAdded, error) {
+ event := new(VRFCoordinatorV2PlusUpgradedVersionSubscriptionConsumerAdded)
+ if err := _VRFCoordinatorV2PlusUpgradedVersion.contract.UnpackLog(event, "SubscriptionConsumerAdded", log); err != nil {
+ return nil, err
+ }
+ event.Raw = log
+ return event, nil
+}
+
+type VRFCoordinatorV2PlusUpgradedVersionSubscriptionConsumerRemovedIterator struct {
+ Event *VRFCoordinatorV2PlusUpgradedVersionSubscriptionConsumerRemoved
+
+ contract *bind.BoundContract
+ event string
+
+ logs chan types.Log
+ sub ethereum.Subscription
+ done bool
+ fail error
+}
+
+func (it *VRFCoordinatorV2PlusUpgradedVersionSubscriptionConsumerRemovedIterator) Next() bool {
+
+ if it.fail != nil {
+ return false
+ }
+
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(VRFCoordinatorV2PlusUpgradedVersionSubscriptionConsumerRemoved)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+
+ select {
+ case log := <-it.logs:
+ it.Event = new(VRFCoordinatorV2PlusUpgradedVersionSubscriptionConsumerRemoved)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+func (it *VRFCoordinatorV2PlusUpgradedVersionSubscriptionConsumerRemovedIterator) Error() error {
+ return it.fail
+}
+
+func (it *VRFCoordinatorV2PlusUpgradedVersionSubscriptionConsumerRemovedIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+type VRFCoordinatorV2PlusUpgradedVersionSubscriptionConsumerRemoved struct {
+ SubId *big.Int
+ Consumer common.Address
+ Raw types.Log
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) FilterSubscriptionConsumerRemoved(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorV2PlusUpgradedVersionSubscriptionConsumerRemovedIterator, error) {
+
+ var subIdRule []interface{}
+ for _, subIdItem := range subId {
+ subIdRule = append(subIdRule, subIdItem)
+ }
+
+ logs, sub, err := _VRFCoordinatorV2PlusUpgradedVersion.contract.FilterLogs(opts, "SubscriptionConsumerRemoved", subIdRule)
+ if err != nil {
+ return nil, err
+ }
+ return &VRFCoordinatorV2PlusUpgradedVersionSubscriptionConsumerRemovedIterator{contract: _VRFCoordinatorV2PlusUpgradedVersion.contract, event: "SubscriptionConsumerRemoved", logs: logs, sub: sub}, nil
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) WatchSubscriptionConsumerRemoved(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusUpgradedVersionSubscriptionConsumerRemoved, subId []*big.Int) (event.Subscription, error) {
+
+ var subIdRule []interface{}
+ for _, subIdItem := range subId {
+ subIdRule = append(subIdRule, subIdItem)
+ }
+
+ logs, sub, err := _VRFCoordinatorV2PlusUpgradedVersion.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(VRFCoordinatorV2PlusUpgradedVersionSubscriptionConsumerRemoved)
+ if err := _VRFCoordinatorV2PlusUpgradedVersion.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 (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) ParseSubscriptionConsumerRemoved(log types.Log) (*VRFCoordinatorV2PlusUpgradedVersionSubscriptionConsumerRemoved, error) {
+ event := new(VRFCoordinatorV2PlusUpgradedVersionSubscriptionConsumerRemoved)
+ if err := _VRFCoordinatorV2PlusUpgradedVersion.contract.UnpackLog(event, "SubscriptionConsumerRemoved", log); err != nil {
+ return nil, err
+ }
+ event.Raw = log
+ return event, nil
+}
+
+type VRFCoordinatorV2PlusUpgradedVersionSubscriptionCreatedIterator struct {
+ Event *VRFCoordinatorV2PlusUpgradedVersionSubscriptionCreated
+
+ contract *bind.BoundContract
+ event string
+
+ logs chan types.Log
+ sub ethereum.Subscription
+ done bool
+ fail error
+}
+
+func (it *VRFCoordinatorV2PlusUpgradedVersionSubscriptionCreatedIterator) Next() bool {
+
+ if it.fail != nil {
+ return false
+ }
+
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(VRFCoordinatorV2PlusUpgradedVersionSubscriptionCreated)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+
+ select {
+ case log := <-it.logs:
+ it.Event = new(VRFCoordinatorV2PlusUpgradedVersionSubscriptionCreated)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+func (it *VRFCoordinatorV2PlusUpgradedVersionSubscriptionCreatedIterator) Error() error {
+ return it.fail
+}
+
+func (it *VRFCoordinatorV2PlusUpgradedVersionSubscriptionCreatedIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+type VRFCoordinatorV2PlusUpgradedVersionSubscriptionCreated struct {
+ SubId *big.Int
+ Owner common.Address
+ Raw types.Log
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) FilterSubscriptionCreated(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorV2PlusUpgradedVersionSubscriptionCreatedIterator, error) {
+
+ var subIdRule []interface{}
+ for _, subIdItem := range subId {
+ subIdRule = append(subIdRule, subIdItem)
+ }
+
+ logs, sub, err := _VRFCoordinatorV2PlusUpgradedVersion.contract.FilterLogs(opts, "SubscriptionCreated", subIdRule)
+ if err != nil {
+ return nil, err
+ }
+ return &VRFCoordinatorV2PlusUpgradedVersionSubscriptionCreatedIterator{contract: _VRFCoordinatorV2PlusUpgradedVersion.contract, event: "SubscriptionCreated", logs: logs, sub: sub}, nil
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) WatchSubscriptionCreated(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusUpgradedVersionSubscriptionCreated, subId []*big.Int) (event.Subscription, error) {
+
+ var subIdRule []interface{}
+ for _, subIdItem := range subId {
+ subIdRule = append(subIdRule, subIdItem)
+ }
+
+ logs, sub, err := _VRFCoordinatorV2PlusUpgradedVersion.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(VRFCoordinatorV2PlusUpgradedVersionSubscriptionCreated)
+ if err := _VRFCoordinatorV2PlusUpgradedVersion.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 (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) ParseSubscriptionCreated(log types.Log) (*VRFCoordinatorV2PlusUpgradedVersionSubscriptionCreated, error) {
+ event := new(VRFCoordinatorV2PlusUpgradedVersionSubscriptionCreated)
+ if err := _VRFCoordinatorV2PlusUpgradedVersion.contract.UnpackLog(event, "SubscriptionCreated", log); err != nil {
+ return nil, err
+ }
+ event.Raw = log
+ return event, nil
+}
+
+type VRFCoordinatorV2PlusUpgradedVersionSubscriptionFundedIterator struct {
+ Event *VRFCoordinatorV2PlusUpgradedVersionSubscriptionFunded
+
+ contract *bind.BoundContract
+ event string
+
+ logs chan types.Log
+ sub ethereum.Subscription
+ done bool
+ fail error
+}
+
+func (it *VRFCoordinatorV2PlusUpgradedVersionSubscriptionFundedIterator) Next() bool {
+
+ if it.fail != nil {
+ return false
+ }
+
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(VRFCoordinatorV2PlusUpgradedVersionSubscriptionFunded)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+
+ select {
+ case log := <-it.logs:
+ it.Event = new(VRFCoordinatorV2PlusUpgradedVersionSubscriptionFunded)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+func (it *VRFCoordinatorV2PlusUpgradedVersionSubscriptionFundedIterator) Error() error {
+ return it.fail
+}
+
+func (it *VRFCoordinatorV2PlusUpgradedVersionSubscriptionFundedIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+type VRFCoordinatorV2PlusUpgradedVersionSubscriptionFunded struct {
+ SubId *big.Int
+ OldBalance *big.Int
+ NewBalance *big.Int
+ Raw types.Log
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) FilterSubscriptionFunded(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorV2PlusUpgradedVersionSubscriptionFundedIterator, error) {
+
+ var subIdRule []interface{}
+ for _, subIdItem := range subId {
+ subIdRule = append(subIdRule, subIdItem)
+ }
+
+ logs, sub, err := _VRFCoordinatorV2PlusUpgradedVersion.contract.FilterLogs(opts, "SubscriptionFunded", subIdRule)
+ if err != nil {
+ return nil, err
+ }
+ return &VRFCoordinatorV2PlusUpgradedVersionSubscriptionFundedIterator{contract: _VRFCoordinatorV2PlusUpgradedVersion.contract, event: "SubscriptionFunded", logs: logs, sub: sub}, nil
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) WatchSubscriptionFunded(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusUpgradedVersionSubscriptionFunded, subId []*big.Int) (event.Subscription, error) {
+
+ var subIdRule []interface{}
+ for _, subIdItem := range subId {
+ subIdRule = append(subIdRule, subIdItem)
+ }
+
+ logs, sub, err := _VRFCoordinatorV2PlusUpgradedVersion.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(VRFCoordinatorV2PlusUpgradedVersionSubscriptionFunded)
+ if err := _VRFCoordinatorV2PlusUpgradedVersion.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 (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) ParseSubscriptionFunded(log types.Log) (*VRFCoordinatorV2PlusUpgradedVersionSubscriptionFunded, error) {
+ event := new(VRFCoordinatorV2PlusUpgradedVersionSubscriptionFunded)
+ if err := _VRFCoordinatorV2PlusUpgradedVersion.contract.UnpackLog(event, "SubscriptionFunded", log); err != nil {
+ return nil, err
+ }
+ event.Raw = log
+ return event, nil
+}
+
+type VRFCoordinatorV2PlusUpgradedVersionSubscriptionFundedWithNativeIterator struct {
+ Event *VRFCoordinatorV2PlusUpgradedVersionSubscriptionFundedWithNative
+
+ contract *bind.BoundContract
+ event string
+
+ logs chan types.Log
+ sub ethereum.Subscription
+ done bool
+ fail error
+}
+
+func (it *VRFCoordinatorV2PlusUpgradedVersionSubscriptionFundedWithNativeIterator) Next() bool {
+
+ if it.fail != nil {
+ return false
+ }
+
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(VRFCoordinatorV2PlusUpgradedVersionSubscriptionFundedWithNative)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+
+ select {
+ case log := <-it.logs:
+ it.Event = new(VRFCoordinatorV2PlusUpgradedVersionSubscriptionFundedWithNative)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+func (it *VRFCoordinatorV2PlusUpgradedVersionSubscriptionFundedWithNativeIterator) Error() error {
+ return it.fail
+}
+
+func (it *VRFCoordinatorV2PlusUpgradedVersionSubscriptionFundedWithNativeIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+type VRFCoordinatorV2PlusUpgradedVersionSubscriptionFundedWithNative struct {
+ SubId *big.Int
+ OldNativeBalance *big.Int
+ NewNativeBalance *big.Int
+ Raw types.Log
+}
+
+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, "SubscriptionFundedWithNative", subIdRule)
+ if err != nil {
+ return nil, err
+ }
+ return &VRFCoordinatorV2PlusUpgradedVersionSubscriptionFundedWithNativeIterator{contract: _VRFCoordinatorV2PlusUpgradedVersion.contract, event: "SubscriptionFundedWithNative", logs: logs, sub: sub}, nil
+}
+
+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, "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(VRFCoordinatorV2PlusUpgradedVersionSubscriptionFundedWithNative)
+ if err := _VRFCoordinatorV2PlusUpgradedVersion.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 (_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
+ return event, nil
+}
+
+type VRFCoordinatorV2PlusUpgradedVersionSubscriptionOwnerTransferRequestedIterator struct {
+ Event *VRFCoordinatorV2PlusUpgradedVersionSubscriptionOwnerTransferRequested
+
+ contract *bind.BoundContract
+ event string
+
+ logs chan types.Log
+ sub ethereum.Subscription
+ done bool
+ fail error
+}
+
+func (it *VRFCoordinatorV2PlusUpgradedVersionSubscriptionOwnerTransferRequestedIterator) Next() bool {
+
+ if it.fail != nil {
+ return false
+ }
+
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(VRFCoordinatorV2PlusUpgradedVersionSubscriptionOwnerTransferRequested)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+
+ select {
+ case log := <-it.logs:
+ it.Event = new(VRFCoordinatorV2PlusUpgradedVersionSubscriptionOwnerTransferRequested)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+func (it *VRFCoordinatorV2PlusUpgradedVersionSubscriptionOwnerTransferRequestedIterator) Error() error {
+ return it.fail
+}
+
+func (it *VRFCoordinatorV2PlusUpgradedVersionSubscriptionOwnerTransferRequestedIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+type VRFCoordinatorV2PlusUpgradedVersionSubscriptionOwnerTransferRequested struct {
+ SubId *big.Int
+ From common.Address
+ To common.Address
+ Raw types.Log
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) FilterSubscriptionOwnerTransferRequested(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorV2PlusUpgradedVersionSubscriptionOwnerTransferRequestedIterator, error) {
+
+ var subIdRule []interface{}
+ for _, subIdItem := range subId {
+ subIdRule = append(subIdRule, subIdItem)
+ }
+
+ logs, sub, err := _VRFCoordinatorV2PlusUpgradedVersion.contract.FilterLogs(opts, "SubscriptionOwnerTransferRequested", subIdRule)
+ if err != nil {
+ return nil, err
+ }
+ return &VRFCoordinatorV2PlusUpgradedVersionSubscriptionOwnerTransferRequestedIterator{contract: _VRFCoordinatorV2PlusUpgradedVersion.contract, event: "SubscriptionOwnerTransferRequested", logs: logs, sub: sub}, nil
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) WatchSubscriptionOwnerTransferRequested(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusUpgradedVersionSubscriptionOwnerTransferRequested, subId []*big.Int) (event.Subscription, error) {
+
+ var subIdRule []interface{}
+ for _, subIdItem := range subId {
+ subIdRule = append(subIdRule, subIdItem)
+ }
+
+ logs, sub, err := _VRFCoordinatorV2PlusUpgradedVersion.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(VRFCoordinatorV2PlusUpgradedVersionSubscriptionOwnerTransferRequested)
+ if err := _VRFCoordinatorV2PlusUpgradedVersion.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 (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) ParseSubscriptionOwnerTransferRequested(log types.Log) (*VRFCoordinatorV2PlusUpgradedVersionSubscriptionOwnerTransferRequested, error) {
+ event := new(VRFCoordinatorV2PlusUpgradedVersionSubscriptionOwnerTransferRequested)
+ if err := _VRFCoordinatorV2PlusUpgradedVersion.contract.UnpackLog(event, "SubscriptionOwnerTransferRequested", log); err != nil {
+ return nil, err
+ }
+ event.Raw = log
+ return event, nil
+}
+
+type VRFCoordinatorV2PlusUpgradedVersionSubscriptionOwnerTransferredIterator struct {
+ Event *VRFCoordinatorV2PlusUpgradedVersionSubscriptionOwnerTransferred
+
+ contract *bind.BoundContract
+ event string
+
+ logs chan types.Log
+ sub ethereum.Subscription
+ done bool
+ fail error
+}
+
+func (it *VRFCoordinatorV2PlusUpgradedVersionSubscriptionOwnerTransferredIterator) Next() bool {
+
+ if it.fail != nil {
+ return false
+ }
+
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(VRFCoordinatorV2PlusUpgradedVersionSubscriptionOwnerTransferred)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+
+ select {
+ case log := <-it.logs:
+ it.Event = new(VRFCoordinatorV2PlusUpgradedVersionSubscriptionOwnerTransferred)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+func (it *VRFCoordinatorV2PlusUpgradedVersionSubscriptionOwnerTransferredIterator) Error() error {
+ return it.fail
+}
+
+func (it *VRFCoordinatorV2PlusUpgradedVersionSubscriptionOwnerTransferredIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+type VRFCoordinatorV2PlusUpgradedVersionSubscriptionOwnerTransferred struct {
+ SubId *big.Int
+ From common.Address
+ To common.Address
+ Raw types.Log
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) FilterSubscriptionOwnerTransferred(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorV2PlusUpgradedVersionSubscriptionOwnerTransferredIterator, error) {
+
+ var subIdRule []interface{}
+ for _, subIdItem := range subId {
+ subIdRule = append(subIdRule, subIdItem)
+ }
+
+ logs, sub, err := _VRFCoordinatorV2PlusUpgradedVersion.contract.FilterLogs(opts, "SubscriptionOwnerTransferred", subIdRule)
+ if err != nil {
+ return nil, err
+ }
+ return &VRFCoordinatorV2PlusUpgradedVersionSubscriptionOwnerTransferredIterator{contract: _VRFCoordinatorV2PlusUpgradedVersion.contract, event: "SubscriptionOwnerTransferred", logs: logs, sub: sub}, nil
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) WatchSubscriptionOwnerTransferred(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusUpgradedVersionSubscriptionOwnerTransferred, subId []*big.Int) (event.Subscription, error) {
+
+ var subIdRule []interface{}
+ for _, subIdItem := range subId {
+ subIdRule = append(subIdRule, subIdItem)
+ }
+
+ logs, sub, err := _VRFCoordinatorV2PlusUpgradedVersion.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(VRFCoordinatorV2PlusUpgradedVersionSubscriptionOwnerTransferred)
+ if err := _VRFCoordinatorV2PlusUpgradedVersion.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 (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) ParseSubscriptionOwnerTransferred(log types.Log) (*VRFCoordinatorV2PlusUpgradedVersionSubscriptionOwnerTransferred, error) {
+ event := new(VRFCoordinatorV2PlusUpgradedVersionSubscriptionOwnerTransferred)
+ if err := _VRFCoordinatorV2PlusUpgradedVersion.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 (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersion) ParseLog(log types.Log) (generated.AbigenLog, error) {
+ switch log.Topics[0] {
+ case _VRFCoordinatorV2PlusUpgradedVersion.abi.Events["ConfigSet"].ID:
+ return _VRFCoordinatorV2PlusUpgradedVersion.ParseConfigSet(log)
+ case _VRFCoordinatorV2PlusUpgradedVersion.abi.Events["CoordinatorRegistered"].ID:
+ return _VRFCoordinatorV2PlusUpgradedVersion.ParseCoordinatorRegistered(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:
+ return _VRFCoordinatorV2PlusUpgradedVersion.ParseOwnershipTransferred(log)
+ case _VRFCoordinatorV2PlusUpgradedVersion.abi.Events["ProvingKeyRegistered"].ID:
+ return _VRFCoordinatorV2PlusUpgradedVersion.ParseProvingKeyRegistered(log)
+ case _VRFCoordinatorV2PlusUpgradedVersion.abi.Events["RandomWordsFulfilled"].ID:
+ return _VRFCoordinatorV2PlusUpgradedVersion.ParseRandomWordsFulfilled(log)
+ case _VRFCoordinatorV2PlusUpgradedVersion.abi.Events["RandomWordsRequested"].ID:
+ return _VRFCoordinatorV2PlusUpgradedVersion.ParseRandomWordsRequested(log)
+ case _VRFCoordinatorV2PlusUpgradedVersion.abi.Events["SubscriptionCanceled"].ID:
+ return _VRFCoordinatorV2PlusUpgradedVersion.ParseSubscriptionCanceled(log)
+ case _VRFCoordinatorV2PlusUpgradedVersion.abi.Events["SubscriptionConsumerAdded"].ID:
+ return _VRFCoordinatorV2PlusUpgradedVersion.ParseSubscriptionConsumerAdded(log)
+ case _VRFCoordinatorV2PlusUpgradedVersion.abi.Events["SubscriptionConsumerRemoved"].ID:
+ return _VRFCoordinatorV2PlusUpgradedVersion.ParseSubscriptionConsumerRemoved(log)
+ case _VRFCoordinatorV2PlusUpgradedVersion.abi.Events["SubscriptionCreated"].ID:
+ return _VRFCoordinatorV2PlusUpgradedVersion.ParseSubscriptionCreated(log)
+ case _VRFCoordinatorV2PlusUpgradedVersion.abi.Events["SubscriptionFunded"].ID:
+ return _VRFCoordinatorV2PlusUpgradedVersion.ParseSubscriptionFunded(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:
+ return _VRFCoordinatorV2PlusUpgradedVersion.ParseSubscriptionOwnerTransferred(log)
+
+ default:
+ return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0])
+ }
+}
+
+func (VRFCoordinatorV2PlusUpgradedVersionConfigSet) Topic() common.Hash {
+ return common.HexToHash("0x777357bb93f63d088f18112d3dba38457aec633eb8f1341e1d418380ad328e78")
+}
+
+func (VRFCoordinatorV2PlusUpgradedVersionCoordinatorRegistered) Topic() common.Hash {
+ return common.HexToHash("0xb7cabbfc11e66731fc77de0444614282023bcbd41d16781c753a431d0af01625")
+}
+
+func (VRFCoordinatorV2PlusUpgradedVersionFundsRecovered) Topic() common.Hash {
+ return common.HexToHash("0x59bfc682b673f8cbf945f1e454df9334834abf7dfe7f92237ca29ecb9b436600")
+}
+
+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")
+}
+
+func (VRFCoordinatorV2PlusUpgradedVersionOwnershipTransferred) Topic() common.Hash {
+ return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0")
+}
+
+func (VRFCoordinatorV2PlusUpgradedVersionProvingKeyRegistered) Topic() common.Hash {
+ return common.HexToHash("0xe729ae16526293f74ade739043022254f1489f616295a25bf72dfb4511ed73b8")
+}
+
+func (VRFCoordinatorV2PlusUpgradedVersionRandomWordsFulfilled) Topic() common.Hash {
+ return common.HexToHash("0x49580fdfd9497e1ed5c1b1cec0495087ae8e3f1267470ec2fb015db32e3d6aa7")
+}
+
+func (VRFCoordinatorV2PlusUpgradedVersionRandomWordsRequested) Topic() common.Hash {
+ return common.HexToHash("0xeb0e3652e0f44f417695e6e90f2f42c99b65cd7169074c5a654b16b9748c3a4e")
+}
+
+func (VRFCoordinatorV2PlusUpgradedVersionSubscriptionCanceled) Topic() common.Hash {
+ return common.HexToHash("0x8c74ce8b8cf87f5eb001275c8be27eb34ea2b62bfab6814fcc62192bb63e81c4")
+}
+
+func (VRFCoordinatorV2PlusUpgradedVersionSubscriptionConsumerAdded) Topic() common.Hash {
+ return common.HexToHash("0x1e980d04aa7648e205713e5e8ea3808672ac163d10936d36f91b2c88ac1575e1")
+}
+
+func (VRFCoordinatorV2PlusUpgradedVersionSubscriptionConsumerRemoved) Topic() common.Hash {
+ return common.HexToHash("0x32158c6058347c1601b2d12bc696ac6901d8a9a9aa3ba10c27ab0a983e8425a7")
+}
+
+func (VRFCoordinatorV2PlusUpgradedVersionSubscriptionCreated) Topic() common.Hash {
+ return common.HexToHash("0x1d3015d7ba850fa198dc7b1a3f5d42779313a681035f77c8c03764c61005518d")
+}
+
+func (VRFCoordinatorV2PlusUpgradedVersionSubscriptionFunded) Topic() common.Hash {
+ return common.HexToHash("0x1ced9348ff549fceab2ac57cd3a9de38edaaab274b725ee82c23e8fc8c4eec7a")
+}
+
+func (VRFCoordinatorV2PlusUpgradedVersionSubscriptionFundedWithNative) Topic() common.Hash {
+ return common.HexToHash("0x7603b205d03651ee812f803fccde89f1012e545a9c99f0abfea9cedd0fd8e902")
+}
+
+func (VRFCoordinatorV2PlusUpgradedVersionSubscriptionOwnerTransferRequested) Topic() common.Hash {
+ return common.HexToHash("0x21a4dad170a6bf476c31bbcf4a16628295b0e450672eec25d7c93308e05344a1")
+}
+
+func (VRFCoordinatorV2PlusUpgradedVersionSubscriptionOwnerTransferred) Topic() common.Hash {
+ return common.HexToHash("0xd4114ab6e9af9f597c52041f32d62dc57c5c4e4c0d4427006069635e216c9386")
+}
+
+func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersion) Address() common.Address {
+ return _VRFCoordinatorV2PlusUpgradedVersion.address
+}
+
+type VRFCoordinatorV2PlusUpgradedVersionInterface 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)
+
+ FulfillRandomWords(opts *bind.TransactOpts, proof VRFProof, rc VRFCoordinatorV2PlusUpgradedVersionRequestCommitment) (*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)
+
+ OnMigration(opts *bind.TransactOpts, encodedData []byte) (*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 VRFCoordinatorV2PlusUpgradedVersionFeeConfig) (*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) (*VRFCoordinatorV2PlusUpgradedVersionConfigSetIterator, error)
+
+ WatchConfigSet(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusUpgradedVersionConfigSet) (event.Subscription, error)
+
+ ParseConfigSet(log types.Log) (*VRFCoordinatorV2PlusUpgradedVersionConfigSet, error)
+
+ FilterCoordinatorRegistered(opts *bind.FilterOpts) (*VRFCoordinatorV2PlusUpgradedVersionCoordinatorRegisteredIterator, error)
+
+ WatchCoordinatorRegistered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusUpgradedVersionCoordinatorRegistered) (event.Subscription, error)
+
+ ParseCoordinatorRegistered(log types.Log) (*VRFCoordinatorV2PlusUpgradedVersionCoordinatorRegistered, error)
+
+ FilterFundsRecovered(opts *bind.FilterOpts) (*VRFCoordinatorV2PlusUpgradedVersionFundsRecoveredIterator, error)
+
+ WatchFundsRecovered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusUpgradedVersionFundsRecovered) (event.Subscription, error)
+
+ ParseFundsRecovered(log types.Log) (*VRFCoordinatorV2PlusUpgradedVersionFundsRecovered, error)
+
+ FilterMigrationCompleted(opts *bind.FilterOpts) (*VRFCoordinatorV2PlusUpgradedVersionMigrationCompletedIterator, error)
+
+ WatchMigrationCompleted(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusUpgradedVersionMigrationCompleted) (event.Subscription, error)
+
+ 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)
+
+ ParseOwnershipTransferRequested(log types.Log) (*VRFCoordinatorV2PlusUpgradedVersionOwnershipTransferRequested, error)
+
+ FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VRFCoordinatorV2PlusUpgradedVersionOwnershipTransferredIterator, error)
+
+ WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusUpgradedVersionOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error)
+
+ ParseOwnershipTransferred(log types.Log) (*VRFCoordinatorV2PlusUpgradedVersionOwnershipTransferred, error)
+
+ FilterProvingKeyRegistered(opts *bind.FilterOpts, oracle []common.Address) (*VRFCoordinatorV2PlusUpgradedVersionProvingKeyRegisteredIterator, error)
+
+ WatchProvingKeyRegistered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusUpgradedVersionProvingKeyRegistered, oracle []common.Address) (event.Subscription, error)
+
+ ParseProvingKeyRegistered(log types.Log) (*VRFCoordinatorV2PlusUpgradedVersionProvingKeyRegistered, error)
+
+ FilterRandomWordsFulfilled(opts *bind.FilterOpts, requestId []*big.Int, subID []*big.Int) (*VRFCoordinatorV2PlusUpgradedVersionRandomWordsFulfilledIterator, error)
+
+ WatchRandomWordsFulfilled(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusUpgradedVersionRandomWordsFulfilled, requestId []*big.Int, subID []*big.Int) (event.Subscription, error)
+
+ ParseRandomWordsFulfilled(log types.Log) (*VRFCoordinatorV2PlusUpgradedVersionRandomWordsFulfilled, error)
+
+ FilterRandomWordsRequested(opts *bind.FilterOpts, keyHash [][32]byte, subId []*big.Int, sender []common.Address) (*VRFCoordinatorV2PlusUpgradedVersionRandomWordsRequestedIterator, error)
+
+ WatchRandomWordsRequested(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusUpgradedVersionRandomWordsRequested, keyHash [][32]byte, subId []*big.Int, sender []common.Address) (event.Subscription, error)
+
+ ParseRandomWordsRequested(log types.Log) (*VRFCoordinatorV2PlusUpgradedVersionRandomWordsRequested, error)
+
+ FilterSubscriptionCanceled(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorV2PlusUpgradedVersionSubscriptionCanceledIterator, error)
+
+ WatchSubscriptionCanceled(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusUpgradedVersionSubscriptionCanceled, subId []*big.Int) (event.Subscription, error)
+
+ ParseSubscriptionCanceled(log types.Log) (*VRFCoordinatorV2PlusUpgradedVersionSubscriptionCanceled, error)
+
+ FilterSubscriptionConsumerAdded(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorV2PlusUpgradedVersionSubscriptionConsumerAddedIterator, error)
+
+ WatchSubscriptionConsumerAdded(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusUpgradedVersionSubscriptionConsumerAdded, subId []*big.Int) (event.Subscription, error)
+
+ ParseSubscriptionConsumerAdded(log types.Log) (*VRFCoordinatorV2PlusUpgradedVersionSubscriptionConsumerAdded, error)
+
+ FilterSubscriptionConsumerRemoved(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorV2PlusUpgradedVersionSubscriptionConsumerRemovedIterator, error)
+
+ WatchSubscriptionConsumerRemoved(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusUpgradedVersionSubscriptionConsumerRemoved, subId []*big.Int) (event.Subscription, error)
+
+ ParseSubscriptionConsumerRemoved(log types.Log) (*VRFCoordinatorV2PlusUpgradedVersionSubscriptionConsumerRemoved, error)
+
+ FilterSubscriptionCreated(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorV2PlusUpgradedVersionSubscriptionCreatedIterator, error)
+
+ WatchSubscriptionCreated(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusUpgradedVersionSubscriptionCreated, subId []*big.Int) (event.Subscription, error)
+
+ ParseSubscriptionCreated(log types.Log) (*VRFCoordinatorV2PlusUpgradedVersionSubscriptionCreated, error)
+
+ FilterSubscriptionFunded(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorV2PlusUpgradedVersionSubscriptionFundedIterator, error)
+
+ WatchSubscriptionFunded(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusUpgradedVersionSubscriptionFunded, subId []*big.Int) (event.Subscription, error)
+
+ ParseSubscriptionFunded(log types.Log) (*VRFCoordinatorV2PlusUpgradedVersionSubscriptionFunded, error)
+
+ FilterSubscriptionFundedWithNative(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorV2PlusUpgradedVersionSubscriptionFundedWithNativeIterator, error)
+
+ WatchSubscriptionFundedWithNative(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusUpgradedVersionSubscriptionFundedWithNative, subId []*big.Int) (event.Subscription, error)
+
+ ParseSubscriptionFundedWithNative(log types.Log) (*VRFCoordinatorV2PlusUpgradedVersionSubscriptionFundedWithNative, error)
+
+ FilterSubscriptionOwnerTransferRequested(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorV2PlusUpgradedVersionSubscriptionOwnerTransferRequestedIterator, error)
+
+ WatchSubscriptionOwnerTransferRequested(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusUpgradedVersionSubscriptionOwnerTransferRequested, subId []*big.Int) (event.Subscription, error)
+
+ ParseSubscriptionOwnerTransferRequested(log types.Log) (*VRFCoordinatorV2PlusUpgradedVersionSubscriptionOwnerTransferRequested, error)
+
+ FilterSubscriptionOwnerTransferred(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorV2PlusUpgradedVersionSubscriptionOwnerTransferredIterator, error)
+
+ WatchSubscriptionOwnerTransferred(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusUpgradedVersionSubscriptionOwnerTransferred, subId []*big.Int) (event.Subscription, error)
+
+ ParseSubscriptionOwnerTransferred(log types.Log) (*VRFCoordinatorV2PlusUpgradedVersionSubscriptionOwnerTransferred, error)
+
+ ParseLog(log types.Log) (generated.AbigenLog, error)
+
+ Address() common.Address
+}
diff --git a/core/gethwrappers/generated/vrfv2plus_client/vrfv2plus_client.go b/core/gethwrappers/generated/vrfv2plus_client/vrfv2plus_client.go
index 91112ff856f..9fd983e2cf0 100644
--- a/core/gethwrappers/generated/vrfv2plus_client/vrfv2plus_client.go
+++ b/core/gethwrappers/generated/vrfv2plus_client/vrfv2plus_client.go
@@ -30,7 +30,7 @@ var (
var VRFV2PlusClientMetaData = &bind.MetaData{
ABI: "[{\"inputs\":[],\"name\":\"EXTRA_ARGS_V1_TAG\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]",
- Bin: "0x60a0610038600b82828239805160001a607314602b57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe730000000000000000000000000000000000000000301460806040526004361060335760003560e01c8063f7514ab4146038575b600080fd5b605e7f92fd13387c7fe7befbc38d303d6468778fb9731bc4583f17d92989c6fcfdeaaa81565b6040517fffffffff00000000000000000000000000000000000000000000000000000000909116815260200160405180910390f3fea164736f6c6343000806000a",
+ Bin: "0x6088610038600b82828239805160001a607314602b57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe730000000000000000000000000000000000000000301460806040526004361060335760003560e01c8063f7514ab4146038575b600080fd5b605e7f92fd13387c7fe7befbc38d303d6468778fb9731bc4583f17d92989c6fcfdeaaa81565b6040516001600160e01b0319909116815260200160405180910390f3fea164736f6c6343000806000a",
}
var VRFV2PlusClientABI = VRFV2PlusClientMetaData.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 ce2d4fd13cc..2ad412a1223 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_vrfCoordinatorApiV1\",\"outputs\":[{\"internalType\":\"contractIVRFCoordinatorV2Plus\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_vrfCoordinator\",\"type\":\"address\"}],\"name\":\"setCoordinator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"setSubId\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"topUpSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"topUpSubscriptionNative\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"consumers\",\"type\":\"address[]\"}],\"name\":\"updateSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]",
- Bin: "0x60806040523480156200001157600080fd5b506040516200197e3803806200197e8339810160408190526200003491620001cc565b8133806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf8162000103565b5050600280546001600160a01b03199081166001600160a01b0394851617909155600580548216958416959095179094555060038054909316911617905562000204565b6001600160a01b0381163314156200015e5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b0381168114620001c757600080fd5b919050565b60008060408385031215620001e057600080fd5b620001eb83620001af565b9150620001fb60208401620001af565b90509250929050565b61176a80620002146000396000f3fe6080604052600436106101295760003560e01c806380980043116100a5578063b96dbba711610074578063de367c8e11610059578063de367c8e14610378578063eff27017146103a5578063f2fde38b146103c557600080fd5b8063b96dbba714610350578063cf62c8ab1461035857600080fd5b8063809800431461025e5780638da5cb5b1461027e5780638ea98117146102a9578063a168fa89146102c957600080fd5b806336bfffed116100fc578063706da1ca116100e1578063706da1ca146101e15780637725135b146101f757806379ba50971461024957600080fd5b806336bfffed146101ab5780635d7d53e3146101cb57600080fd5b80631d2b2afd1461012e5780631fe543e31461013857806329e5d831146101585780632fa4e4421461018b575b600080fd5b6101366103e5565b005b34801561014457600080fd5b506101366101533660046113a3565b6104e0565b34801561016457600080fd5b50610178610173366004611447565b610561565b6040519081526020015b60405180910390f35b34801561019757600080fd5b506101366101a63660046114d4565b61069e565b3480156101b757600080fd5b506101366101c63660046112b0565b6107c0565b3480156101d757600080fd5b5061017860045481565b3480156101ed57600080fd5b5061017860065481565b34801561020357600080fd5b506003546102249073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610182565b34801561025557600080fd5b506101366108f8565b34801561026a57600080fd5b50610136610279366004611371565b600655565b34801561028a57600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff16610224565b3480156102b557600080fd5b506101366102c436600461128e565b6109f5565b3480156102d557600080fd5b5061031e6102e4366004611371565b6007602052600090815260409020805460019091015460ff821691610100900473ffffffffffffffffffffffffffffffffffffffff169083565b60408051931515845273ffffffffffffffffffffffffffffffffffffffff909216602084015290820152606001610182565b610136610b00565b34801561036457600080fd5b506101366103733660046114d4565b610b66565b34801561038457600080fd5b506005546102249073ffffffffffffffffffffffffffffffffffffffff1681565b3480156103b157600080fd5b506101366103c0366004611469565b610bad565b3480156103d157600080fd5b506101366103e036600461128e565b610d98565b600654610453576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f737562206e6f742073657400000000000000000000000000000000000000000060448201526064015b60405180910390fd5b6005546006546040517fe8509bff000000000000000000000000000000000000000000000000000000008152600481019190915273ffffffffffffffffffffffffffffffffffffffff9091169063e8509bff9034906024015b6000604051808303818588803b1580156104c557600080fd5b505af11580156104d9573d6000803e3d6000fd5b5050505050565b60025473ffffffffffffffffffffffffffffffffffffffff163314610553576002546040517f1cf993f400000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff909116602482015260440161044a565b61055d8282610dac565b5050565b60008281526007602090815260408083208151608081018352815460ff811615158252610100900473ffffffffffffffffffffffffffffffffffffffff1681850152600182015481840152600282018054845181870281018701909552808552869592946060860193909291908301828280156105fd57602002820191906000526020600020905b8154815260200190600101908083116105e9575b5050505050815250509050806040015160001415610677576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f7265717565737420494420697320696e636f7272656374000000000000000000604482015260640161044a565b8060600151838151811061068d5761068d6116f1565b602002602001015191505092915050565b600654610707576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f737562206e6f7420736574000000000000000000000000000000000000000000604482015260640161044a565b60035460025460065460408051602081019290925273ffffffffffffffffffffffffffffffffffffffff93841693634000aea09316918591015b6040516020818303038152906040526040518463ffffffff1660e01b815260040161076e9392919061156d565b602060405180830381600087803b15801561078857600080fd5b505af115801561079c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061055d9190611354565b600654610829576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f7375624944206e6f742073657400000000000000000000000000000000000000604482015260640161044a565b60005b815181101561055d57600554600654835173ffffffffffffffffffffffffffffffffffffffff9092169163bec4c08c919085908590811061086f5761086f6116f1565b60200260200101516040518363ffffffff1660e01b81526004016108b392919091825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b600060405180830381600087803b1580156108cd57600080fd5b505af11580156108e1573d6000803e3d6000fd5b5050505080806108f090611691565b91505061082c565b60015473ffffffffffffffffffffffffffffffffffffffff163314610979576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e657200000000000000000000604482015260640161044a565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60005473ffffffffffffffffffffffffffffffffffffffff163314801590610a35575060025473ffffffffffffffffffffffffffffffffffffffff163314155b15610ab95733610a5a60005473ffffffffffffffffffffffffffffffffffffffff1690565b6002546040517f061db9c100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9384166004820152918316602483015291909116604482015260640161044a565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b610b08610e77565b506005546006546040517fe8509bff000000000000000000000000000000000000000000000000000000008152600481019190915273ffffffffffffffffffffffffffffffffffffffff9091169063e8509bff9034906024016104ac565b610b6e610e77565b5060035460025460065460408051602081019290925273ffffffffffffffffffffffffffffffffffffffff93841693634000aea0931691859101610741565b60006040518060c0016040528084815260200160065481526020018661ffff1681526020018763ffffffff1681526020018563ffffffff168152602001610c036040518060200160405280861515815250610fbc565b90526002546040517f9b1c385e00000000000000000000000000000000000000000000000000000000815291925060009173ffffffffffffffffffffffffffffffffffffffff90911690639b1c385e90610c619085906004016115b9565b602060405180830381600087803b158015610c7b57600080fd5b505af1158015610c8f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cb3919061138a565b604080516080810182526000808252336020808401918252838501868152855184815280830187526060860190815287855260078352959093208451815493517fffffffffffffffffffffff0000000000000000000000000000000000000000009094169015157fffffffffffffffffffffff0000000000000000000000000000000000000000ff161761010073ffffffffffffffffffffffffffffffffffffffff9094169390930292909217825591516001820155925180519495509193849392610d869260028501929101906111f1565b50505060049190915550505050505050565b610da0611078565b610da9816110fb565b50565b6004548214610e17576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f7265717565737420494420697320696e636f7272656374000000000000000000604482015260640161044a565b60008281526007602090815260409091208251610e3c926002909201918401906111f1565b5050600090815260076020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b600060065460001415610fb557600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a21a23e46040518163ffffffff1660e01b8152600401602060405180830381600087803b158015610eee57600080fd5b505af1158015610f02573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f26919061138a565b60068190556005546040517fbec4c08c000000000000000000000000000000000000000000000000000000008152600481019290925230602483015273ffffffffffffffffffffffffffffffffffffffff169063bec4c08c90604401600060405180830381600087803b158015610f9c57600080fd5b505af1158015610fb0573d6000803e3d6000fd5b505050505b5060065490565b60607f92fd13387c7fe7befbc38d303d6468778fb9731bc4583f17d92989c6fcfdeaaa82604051602401610ff591511515815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915292915050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146110f9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161044a565b565b73ffffffffffffffffffffffffffffffffffffffff811633141561117b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161044a565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b82805482825590600052602060002090810192821561122c579160200282015b8281111561122c578251825591602001919060010190611211565b5061123892915061123c565b5090565b5b80821115611238576000815560010161123d565b803573ffffffffffffffffffffffffffffffffffffffff8116811461127557600080fd5b919050565b803563ffffffff8116811461127557600080fd5b6000602082840312156112a057600080fd5b6112a982611251565b9392505050565b600060208083850312156112c357600080fd5b823567ffffffffffffffff8111156112da57600080fd5b8301601f810185136112eb57600080fd5b80356112fe6112f98261166d565b61161e565b80828252848201915084840188868560051b870101111561131e57600080fd5b600094505b838510156113485761133481611251565b835260019490940193918501918501611323565b50979650505050505050565b60006020828403121561136657600080fd5b81516112a98161174f565b60006020828403121561138357600080fd5b5035919050565b60006020828403121561139c57600080fd5b5051919050565b600080604083850312156113b657600080fd5b8235915060208084013567ffffffffffffffff8111156113d557600080fd5b8401601f810186136113e657600080fd5b80356113f46112f98261166d565b80828252848201915084840189868560051b870101111561141457600080fd5b600094505b83851015611437578035835260019490940193918501918501611419565b5080955050505050509250929050565b6000806040838503121561145a57600080fd5b50508035926020909101359150565b600080600080600060a0868803121561148157600080fd5b61148a8661127a565b9450602086013561ffff811681146114a157600080fd5b93506114af6040870161127a565b92506060860135915060808601356114c68161174f565b809150509295509295909350565b6000602082840312156114e657600080fd5b81356bffffffffffffffffffffffff811681146112a957600080fd5b6000815180845260005b818110156115285760208185018101518683018201520161150c565b8181111561153a576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b73ffffffffffffffffffffffffffffffffffffffff841681526bffffffffffffffffffffffff831660208201526060604082015260006115b06060830184611502565b95945050505050565b60208152815160208201526020820151604082015261ffff60408301511660608201526000606083015163ffffffff80821660808501528060808601511660a0850152505060a083015160c08084015261161660e0840182611502565b949350505050565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561166557611665611720565b604052919050565b600067ffffffffffffffff82111561168757611687611720565b5060051b60200190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156116ea577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b8015158114610da957600080fdfea164736f6c6343000806000a",
+ 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
@@ -312,6 +312,28 @@ func (_VRFV2PlusConsumerExample *VRFV2PlusConsumerExampleCallerSession) SSubId()
return _VRFV2PlusConsumerExample.Contract.SSubId(&_VRFV2PlusConsumerExample.CallOpts)
}
+func (_VRFV2PlusConsumerExample *VRFV2PlusConsumerExampleCaller) SVrfCoordinator(opts *bind.CallOpts) (common.Address, error) {
+ var out []interface{}
+ err := _VRFV2PlusConsumerExample.contract.Call(opts, &out, "s_vrfCoordinator")
+
+ if err != nil {
+ return *new(common.Address), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address)
+
+ return out0, err
+
+}
+
+func (_VRFV2PlusConsumerExample *VRFV2PlusConsumerExampleSession) SVrfCoordinator() (common.Address, error) {
+ return _VRFV2PlusConsumerExample.Contract.SVrfCoordinator(&_VRFV2PlusConsumerExample.CallOpts)
+}
+
+func (_VRFV2PlusConsumerExample *VRFV2PlusConsumerExampleCallerSession) SVrfCoordinator() (common.Address, error) {
+ return _VRFV2PlusConsumerExample.Contract.SVrfCoordinator(&_VRFV2PlusConsumerExample.CallOpts)
+}
+
func (_VRFV2PlusConsumerExample *VRFV2PlusConsumerExampleCaller) SVrfCoordinatorApiV1(opts *bind.CallOpts) (common.Address, error) {
var out []interface{}
err := _VRFV2PlusConsumerExample.contract.Call(opts, &out, "s_vrfCoordinatorApiV1")
@@ -783,6 +805,8 @@ type VRFV2PlusConsumerExampleInterface interface {
SSubId(opts *bind.CallOpts) (*big.Int, error)
+ SVrfCoordinator(opts *bind.CallOpts) (common.Address, error)
+
SVrfCoordinatorApiV1(opts *bind.CallOpts) (common.Address, error)
AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error)
diff --git a/core/gethwrappers/generated/vrfv2plus_malicious_migrator/vrfv2plus_malicious_migrator.go b/core/gethwrappers/generated/vrfv2plus_malicious_migrator/vrfv2plus_malicious_migrator.go
new file mode 100644
index 00000000000..043ee6e303f
--- /dev/null
+++ b/core/gethwrappers/generated/vrfv2plus_malicious_migrator/vrfv2plus_malicious_migrator.go
@@ -0,0 +1,192 @@
+// Code generated - DO NOT EDIT.
+// This file is a generated binding and any manual changes will be lost.
+
+package vrfv2plus_malicious_migrator
+
+import (
+ "errors"
+ "math/big"
+ "strings"
+
+ ethereum "github.com/ethereum/go-ethereum"
+ "github.com/ethereum/go-ethereum/accounts/abi"
+ "github.com/ethereum/go-ethereum/accounts/abi/bind"
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/core/types"
+ "github.com/ethereum/go-ethereum/event"
+)
+
+var (
+ _ = errors.New
+ _ = big.NewInt
+ _ = strings.NewReader
+ _ = ethereum.NotFound
+ _ = bind.Bind
+ _ = common.Big1
+ _ = types.BloomLookup
+ _ = event.NewSubscription
+ _ = abi.ConvertType
+)
+
+var VRFV2PlusMaliciousMigratorMetaData = &bind.MetaData{
+ ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_vrfCoordinator\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_vrfCoordinator\",\"type\":\"address\"}],\"name\":\"setCoordinator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]",
+ Bin: "0x608060405234801561001057600080fd5b506040516102e03803806102e083398101604081905261002f91610054565b600080546001600160a01b0319166001600160a01b0392909216919091179055610084565b60006020828403121561006657600080fd5b81516001600160a01b038116811461007d57600080fd5b9392505050565b61024d806100936000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c80638ea9811714610030575b600080fd5b61004361003e36600461012a565b610045565b005b600080546040805160c081018252838152602080820185905281830185905260608201859052608082018590528251908101835293845260a0810193909352517f9b1c385e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911691639b1c385e916100d49190600401610180565b602060405180830381600087803b1580156100ee57600080fd5b505af1158015610102573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101269190610167565b5050565b60006020828403121561013c57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461016057600080fd5b9392505050565b60006020828403121561017957600080fd5b5051919050565b6000602080835283518184015280840151604084015261ffff6040850151166060840152606084015163ffffffff80821660808601528060808701511660a0860152505060a084015160c08085015280518060e086015260005b818110156101f757828101840151868201610100015283016101da565b8181111561020a57600061010083880101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016939093016101000194935050505056fea164736f6c6343000806000a",
+}
+
+var VRFV2PlusMaliciousMigratorABI = VRFV2PlusMaliciousMigratorMetaData.ABI
+
+var VRFV2PlusMaliciousMigratorBin = VRFV2PlusMaliciousMigratorMetaData.Bin
+
+func DeployVRFV2PlusMaliciousMigrator(auth *bind.TransactOpts, backend bind.ContractBackend, _vrfCoordinator common.Address) (common.Address, *types.Transaction, *VRFV2PlusMaliciousMigrator, error) {
+ parsed, err := VRFV2PlusMaliciousMigratorMetaData.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(VRFV2PlusMaliciousMigratorBin), backend, _vrfCoordinator)
+ if err != nil {
+ return common.Address{}, nil, nil, err
+ }
+ return address, tx, &VRFV2PlusMaliciousMigrator{VRFV2PlusMaliciousMigratorCaller: VRFV2PlusMaliciousMigratorCaller{contract: contract}, VRFV2PlusMaliciousMigratorTransactor: VRFV2PlusMaliciousMigratorTransactor{contract: contract}, VRFV2PlusMaliciousMigratorFilterer: VRFV2PlusMaliciousMigratorFilterer{contract: contract}}, nil
+}
+
+type VRFV2PlusMaliciousMigrator struct {
+ address common.Address
+ abi abi.ABI
+ VRFV2PlusMaliciousMigratorCaller
+ VRFV2PlusMaliciousMigratorTransactor
+ VRFV2PlusMaliciousMigratorFilterer
+}
+
+type VRFV2PlusMaliciousMigratorCaller struct {
+ contract *bind.BoundContract
+}
+
+type VRFV2PlusMaliciousMigratorTransactor struct {
+ contract *bind.BoundContract
+}
+
+type VRFV2PlusMaliciousMigratorFilterer struct {
+ contract *bind.BoundContract
+}
+
+type VRFV2PlusMaliciousMigratorSession struct {
+ Contract *VRFV2PlusMaliciousMigrator
+ CallOpts bind.CallOpts
+ TransactOpts bind.TransactOpts
+}
+
+type VRFV2PlusMaliciousMigratorCallerSession struct {
+ Contract *VRFV2PlusMaliciousMigratorCaller
+ CallOpts bind.CallOpts
+}
+
+type VRFV2PlusMaliciousMigratorTransactorSession struct {
+ Contract *VRFV2PlusMaliciousMigratorTransactor
+ TransactOpts bind.TransactOpts
+}
+
+type VRFV2PlusMaliciousMigratorRaw struct {
+ Contract *VRFV2PlusMaliciousMigrator
+}
+
+type VRFV2PlusMaliciousMigratorCallerRaw struct {
+ Contract *VRFV2PlusMaliciousMigratorCaller
+}
+
+type VRFV2PlusMaliciousMigratorTransactorRaw struct {
+ Contract *VRFV2PlusMaliciousMigratorTransactor
+}
+
+func NewVRFV2PlusMaliciousMigrator(address common.Address, backend bind.ContractBackend) (*VRFV2PlusMaliciousMigrator, error) {
+ abi, err := abi.JSON(strings.NewReader(VRFV2PlusMaliciousMigratorABI))
+ if err != nil {
+ return nil, err
+ }
+ contract, err := bindVRFV2PlusMaliciousMigrator(address, backend, backend, backend)
+ if err != nil {
+ return nil, err
+ }
+ return &VRFV2PlusMaliciousMigrator{address: address, abi: abi, VRFV2PlusMaliciousMigratorCaller: VRFV2PlusMaliciousMigratorCaller{contract: contract}, VRFV2PlusMaliciousMigratorTransactor: VRFV2PlusMaliciousMigratorTransactor{contract: contract}, VRFV2PlusMaliciousMigratorFilterer: VRFV2PlusMaliciousMigratorFilterer{contract: contract}}, nil
+}
+
+func NewVRFV2PlusMaliciousMigratorCaller(address common.Address, caller bind.ContractCaller) (*VRFV2PlusMaliciousMigratorCaller, error) {
+ contract, err := bindVRFV2PlusMaliciousMigrator(address, caller, nil, nil)
+ if err != nil {
+ return nil, err
+ }
+ return &VRFV2PlusMaliciousMigratorCaller{contract: contract}, nil
+}
+
+func NewVRFV2PlusMaliciousMigratorTransactor(address common.Address, transactor bind.ContractTransactor) (*VRFV2PlusMaliciousMigratorTransactor, error) {
+ contract, err := bindVRFV2PlusMaliciousMigrator(address, nil, transactor, nil)
+ if err != nil {
+ return nil, err
+ }
+ return &VRFV2PlusMaliciousMigratorTransactor{contract: contract}, nil
+}
+
+func NewVRFV2PlusMaliciousMigratorFilterer(address common.Address, filterer bind.ContractFilterer) (*VRFV2PlusMaliciousMigratorFilterer, error) {
+ contract, err := bindVRFV2PlusMaliciousMigrator(address, nil, nil, filterer)
+ if err != nil {
+ return nil, err
+ }
+ return &VRFV2PlusMaliciousMigratorFilterer{contract: contract}, nil
+}
+
+func bindVRFV2PlusMaliciousMigrator(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) {
+ parsed, err := VRFV2PlusMaliciousMigratorMetaData.GetAbi()
+ if err != nil {
+ return nil, err
+ }
+ return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil
+}
+
+func (_VRFV2PlusMaliciousMigrator *VRFV2PlusMaliciousMigratorRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
+ return _VRFV2PlusMaliciousMigrator.Contract.VRFV2PlusMaliciousMigratorCaller.contract.Call(opts, result, method, params...)
+}
+
+func (_VRFV2PlusMaliciousMigrator *VRFV2PlusMaliciousMigratorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _VRFV2PlusMaliciousMigrator.Contract.VRFV2PlusMaliciousMigratorTransactor.contract.Transfer(opts)
+}
+
+func (_VRFV2PlusMaliciousMigrator *VRFV2PlusMaliciousMigratorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+ return _VRFV2PlusMaliciousMigrator.Contract.VRFV2PlusMaliciousMigratorTransactor.contract.Transact(opts, method, params...)
+}
+
+func (_VRFV2PlusMaliciousMigrator *VRFV2PlusMaliciousMigratorCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
+ return _VRFV2PlusMaliciousMigrator.Contract.contract.Call(opts, result, method, params...)
+}
+
+func (_VRFV2PlusMaliciousMigrator *VRFV2PlusMaliciousMigratorTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+ return _VRFV2PlusMaliciousMigrator.Contract.contract.Transfer(opts)
+}
+
+func (_VRFV2PlusMaliciousMigrator *VRFV2PlusMaliciousMigratorTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+ return _VRFV2PlusMaliciousMigrator.Contract.contract.Transact(opts, method, params...)
+}
+
+func (_VRFV2PlusMaliciousMigrator *VRFV2PlusMaliciousMigratorTransactor) SetCoordinator(opts *bind.TransactOpts, _vrfCoordinator common.Address) (*types.Transaction, error) {
+ return _VRFV2PlusMaliciousMigrator.contract.Transact(opts, "setCoordinator", _vrfCoordinator)
+}
+
+func (_VRFV2PlusMaliciousMigrator *VRFV2PlusMaliciousMigratorSession) SetCoordinator(_vrfCoordinator common.Address) (*types.Transaction, error) {
+ return _VRFV2PlusMaliciousMigrator.Contract.SetCoordinator(&_VRFV2PlusMaliciousMigrator.TransactOpts, _vrfCoordinator)
+}
+
+func (_VRFV2PlusMaliciousMigrator *VRFV2PlusMaliciousMigratorTransactorSession) SetCoordinator(_vrfCoordinator common.Address) (*types.Transaction, error) {
+ return _VRFV2PlusMaliciousMigrator.Contract.SetCoordinator(&_VRFV2PlusMaliciousMigrator.TransactOpts, _vrfCoordinator)
+}
+
+func (_VRFV2PlusMaliciousMigrator *VRFV2PlusMaliciousMigrator) Address() common.Address {
+ return _VRFV2PlusMaliciousMigrator.address
+}
+
+type VRFV2PlusMaliciousMigratorInterface interface {
+ SetCoordinator(opts *bind.TransactOpts, _vrfCoordinator common.Address) (*types.Transaction, error)
+
+ Address() common.Address
+}
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 cbfa569066a..d5a58fa0f9a 100644
--- a/core/gethwrappers/generated/vrfv2plus_reverting_example/vrfv2plus_reverting_example.go
+++ b/core/gethwrappers/generated/vrfv2plus_reverting_example/vrfv2plus_reverting_example.go
@@ -31,8 +31,8 @@ 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\":[{\"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: "0x60806040523480156200001157600080fd5b50604051620011dd380380620011dd8339810160408190526200003491620001cc565b8133806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf8162000103565b5050600280546001600160a01b03199081166001600160a01b0394851617909155600580548216958416959095179094555060068054909316911617905562000204565b6001600160a01b0381163314156200015e5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b0381168114620001c757600080fd5b919050565b60008060408385031215620001e057600080fd5b620001eb83620001af565b9150620001fb60208401620001af565b90509250929050565b610fc980620002146000396000f3fe608060405234801561001057600080fd5b50600436106100df5760003560e01c80638da5cb5b1161008c578063e89e106a11610066578063e89e106a146101a4578063f08c5daa146101ad578063f2fde38b146101b6578063f6eaffc8146101c957600080fd5b80638da5cb5b146101565780638ea981171461017e578063cf62c8ab1461019157600080fd5b806336bfffed116100bd57806336bfffed14610132578063706da1ca1461014557806379ba50971461014e57600080fd5b80631fe543e3146100e45780632e75964e146100f95780632fa4e4421461011f575b600080fd5b6100f76100f2366004610c9d565b6101dc565b005b61010c610107366004610c0b565b610262565b6040519081526020015b60405180910390f35b6100f761012d366004610d41565b61035f565b6100f7610140366004610b45565b610481565b61010c60075481565b6100f76105b9565b60005460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610116565b6100f761018c366004610b23565b6106b6565b6100f761019f366004610d41565b6107c1565b61010c60045481565b61010c60085481565b6100f76101c4366004610b23565b610938565b61010c6101d7366004610c6b565b61094c565b60025473ffffffffffffffffffffffffffffffffffffffff163314610254576002546040517f1cf993f400000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff90911660248201526044015b60405180910390fd5b61025e8282600080fd5b5050565b6040805160c081018252868152602080820187905261ffff86168284015263ffffffff80861660608401528416608083015282519081018352600080825260a083019190915260055492517f9b1c385e000000000000000000000000000000000000000000000000000000008152909273ffffffffffffffffffffffffffffffffffffffff1690639b1c385e906102fd908490600401610e26565b602060405180830381600087803b15801561031757600080fd5b505af115801561032b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061034f9190610c84565b6004819055979650505050505050565b6007546103c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f737562206e6f7420736574000000000000000000000000000000000000000000604482015260640161024b565b60065460055460075460408051602081019290925273ffffffffffffffffffffffffffffffffffffffff93841693634000aea09316918591015b6040516020818303038152906040526040518463ffffffff1660e01b815260040161042f93929190610dda565b602060405180830381600087803b15801561044957600080fd5b505af115801561045d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061025e9190610be9565b6007546104ea576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f7375624944206e6f742073657400000000000000000000000000000000000000604482015260640161024b565b60005b815181101561025e57600554600754835173ffffffffffffffffffffffffffffffffffffffff9092169163bec4c08c919085908590811061053057610530610f5e565b60200260200101516040518363ffffffff1660e01b815260040161057492919091825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b600060405180830381600087803b15801561058e57600080fd5b505af11580156105a2573d6000803e3d6000fd5b5050505080806105b190610efe565b9150506104ed565b60015473ffffffffffffffffffffffffffffffffffffffff16331461063a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e657200000000000000000000604482015260640161024b565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60005473ffffffffffffffffffffffffffffffffffffffff1633148015906106f6575060025473ffffffffffffffffffffffffffffffffffffffff163314155b1561077a573361071b60005473ffffffffffffffffffffffffffffffffffffffff1690565b6002546040517f061db9c100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9384166004820152918316602483015291909116604482015260640161024b565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6007546103c857600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a21a23e46040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561083257600080fd5b505af1158015610846573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061086a9190610c84565b60078190556005546040517fbec4c08c000000000000000000000000000000000000000000000000000000008152600481019290925230602483015273ffffffffffffffffffffffffffffffffffffffff169063bec4c08c90604401600060405180830381600087803b1580156108e057600080fd5b505af11580156108f4573d6000803e3d6000fd5b5050505060065460055460075460405173ffffffffffffffffffffffffffffffffffffffff93841693634000aea09316918591610402919060200190815260200190565b61094061096d565b610949816109f0565b50565b6003818154811061095c57600080fd5b600091825260209091200154905081565b60005473ffffffffffffffffffffffffffffffffffffffff1633146109ee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161024b565b565b73ffffffffffffffffffffffffffffffffffffffff8116331415610a70576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161024b565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b803573ffffffffffffffffffffffffffffffffffffffff81168114610b0a57600080fd5b919050565b803563ffffffff81168114610b0a57600080fd5b600060208284031215610b3557600080fd5b610b3e82610ae6565b9392505050565b60006020808385031215610b5857600080fd5b823567ffffffffffffffff811115610b6f57600080fd5b8301601f81018513610b8057600080fd5b8035610b93610b8e82610eda565b610e8b565b80828252848201915084840188868560051b8701011115610bb357600080fd5b600094505b83851015610bdd57610bc981610ae6565b835260019490940193918501918501610bb8565b50979650505050505050565b600060208284031215610bfb57600080fd5b81518015158114610b3e57600080fd5b600080600080600060a08688031215610c2357600080fd5b8535945060208601359350604086013561ffff81168114610c4357600080fd5b9250610c5160608701610b0f565b9150610c5f60808701610b0f565b90509295509295909350565b600060208284031215610c7d57600080fd5b5035919050565b600060208284031215610c9657600080fd5b5051919050565b60008060408385031215610cb057600080fd5b8235915060208084013567ffffffffffffffff811115610ccf57600080fd5b8401601f81018613610ce057600080fd5b8035610cee610b8e82610eda565b80828252848201915084840189868560051b8701011115610d0e57600080fd5b600094505b83851015610d31578035835260019490940193918501918501610d13565b5080955050505050509250929050565b600060208284031215610d5357600080fd5b81356bffffffffffffffffffffffff81168114610b3e57600080fd5b6000815180845260005b81811015610d9557602081850181015186830182015201610d79565b81811115610da7576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b73ffffffffffffffffffffffffffffffffffffffff841681526bffffffffffffffffffffffff83166020820152606060408201526000610e1d6060830184610d6f565b95945050505050565b60208152815160208201526020820151604082015261ffff60408301511660608201526000606083015163ffffffff80821660808501528060808601511660a0850152505060a083015160c080840152610e8360e0840182610d6f565b949350505050565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610ed257610ed2610f8d565b604052919050565b600067ffffffffffffffff821115610ef457610ef4610f8d565b5060051b60200190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415610f57577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fdfea164736f6c6343000806000a",
+ 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",
}
var VRFV2PlusRevertingExampleABI = VRFV2PlusRevertingExampleMetaData.ABI
@@ -281,6 +281,28 @@ func (_VRFV2PlusRevertingExample *VRFV2PlusRevertingExampleCallerSession) SSubId
return _VRFV2PlusRevertingExample.Contract.SSubId(&_VRFV2PlusRevertingExample.CallOpts)
}
+func (_VRFV2PlusRevertingExample *VRFV2PlusRevertingExampleCaller) SVrfCoordinator(opts *bind.CallOpts) (common.Address, error) {
+ var out []interface{}
+ err := _VRFV2PlusRevertingExample.contract.Call(opts, &out, "s_vrfCoordinator")
+
+ if err != nil {
+ return *new(common.Address), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address)
+
+ return out0, err
+
+}
+
+func (_VRFV2PlusRevertingExample *VRFV2PlusRevertingExampleSession) SVrfCoordinator() (common.Address, error) {
+ return _VRFV2PlusRevertingExample.Contract.SVrfCoordinator(&_VRFV2PlusRevertingExample.CallOpts)
+}
+
+func (_VRFV2PlusRevertingExample *VRFV2PlusRevertingExampleCallerSession) SVrfCoordinator() (common.Address, error) {
+ return _VRFV2PlusRevertingExample.Contract.SVrfCoordinator(&_VRFV2PlusRevertingExample.CallOpts)
+}
+
func (_VRFV2PlusRevertingExample *VRFV2PlusRevertingExampleTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) {
return _VRFV2PlusRevertingExample.contract.Transact(opts, "acceptOwnership")
}
@@ -684,6 +706,8 @@ type VRFV2PlusRevertingExampleInterface interface {
SSubId(opts *bind.CallOpts) (*big.Int, error)
+ SVrfCoordinator(opts *bind.CallOpts) (common.Address, error)
+
AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error)
CreateSubscriptionAndFund(opts *bind.TransactOpts, amount *big.Int) (*types.Transaction, error)
diff --git a/core/gethwrappers/generated/vrfv2plus_wrapper/vrfv2plus_wrapper.go b/core/gethwrappers/generated/vrfv2plus_wrapper/vrfv2plus_wrapper.go
index 9bfb4c9157d..0fa54876b7c 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\":\"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\":[{\"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: "0x60c06040526004805463ffffffff60a01b1916609160a21b1790553480156200002757600080fd5b5060405162003079380380620030798339810160408190526200004a9162000317565b803380600081620000a25760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000d557620000d5816200024e565b5050600280546001600160a01b0319166001600160a01b03938416179055508316156200011857600380546001600160a01b0319166001600160a01b0385161790555b6001600160a01b038216156200014457600480546001600160a01b0319166001600160a01b0384161790555b806001600160a01b03166080816001600160a01b031660601b815250506000816001600160a01b031663a21a23e46040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156200019f57600080fd5b505af1158015620001b4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001da919062000361565b60a0819052604051632fb1302360e21b8152600481018290523060248201529091506001600160a01b0383169063bec4c08c90604401600060405180830381600087803b1580156200022b57600080fd5b505af115801562000240573d6000803e3d6000fd5b50505050505050506200037b565b6001600160a01b038116331415620002a95760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000099565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b03811681146200031257600080fd5b919050565b6000806000606084860312156200032d57600080fd5b6200033884620002fa565b92506200034860208501620002fa565b91506200035860408501620002fa565b90509250925092565b6000602082840312156200037457600080fd5b5051919050565b60805160601c60a051612ca4620003d5600039600081816101e401528181610ceb01526115ac0152600081816102ee01528181610db5015281816116330152818161193b01528181611a1c0152611ab70152612ca46000f3fe6080604052600436106101cd5760003560e01c80638da5cb5b116100f7578063bf17e55911610095578063da4f5e6d11610064578063da4f5e6d146106c7578063f2fde38b146106f4578063f3fef3a314610714578063fc2a88c31461073457600080fd5b8063bf17e55914610595578063c15ce4d7146105b5578063c3f909d4146105d5578063cdd8d8851461067d57600080fd5b8063a02e0616116100d1578063a02e061614610521578063a3907d7114610541578063a4c0ed3614610556578063a608a1e11461057657600080fd5b80638da5cb5b146104b65780638ea98117146104e1578063981837d51461050157600080fd5b80634306d3541161016f57806361d386661161013e57806361d386661461044157806362a504fc1461046e57806379ba5097146104815780637fb5d19d1461049657600080fd5b80634306d3541461033557806348baa1c5146103555780634b160935146103f757806357a8070a1461041757600080fd5b80631fe543e3116101ab5780631fe543e3146102875780632f2770db146102a75780633255c456146102bc5780633b2bcbf1146102dc57600080fd5b8063030932bb146101d257806307b18bde14610219578063181f5a771461023b575b600080fd5b3480156101de57600080fd5b506102067f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020015b60405180910390f35b34801561022557600080fd5b506102396102343660046125cc565b61074a565b005b34801561024757600080fd5b50604080518082018252601281527f56524656325772617070657220312e302e300000000000000000000000000000602082015290516102109190612a3a565b34801561029357600080fd5b506102396102a2366004612730565b610826565b3480156102b357600080fd5b506102396108a7565b3480156102c857600080fd5b506102066102d73660046128d1565b6108dd565b3480156102e857600080fd5b506103107f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610210565b34801561034157600080fd5b50610206610350366004612869565b6109d5565b34801561036157600080fd5b506103c0610370366004612717565b600b602052600090815260409020805460019091015473ffffffffffffffffffffffffffffffffffffffff82169174010000000000000000000000000000000000000000900463ffffffff169083565b6040805173ffffffffffffffffffffffffffffffffffffffff909416845263ffffffff909216602084015290820152606001610210565b34801561040357600080fd5b50610206610412366004612869565b610adc565b34801561042357600080fd5b506006546104319060ff1681565b6040519015158152602001610210565b34801561044d57600080fd5b506004546103109073ffffffffffffffffffffffffffffffffffffffff1681565b61020661047c366004612886565b610bd3565b34801561048d57600080fd5b50610239610ee5565b3480156104a257600080fd5b506102066104b13660046128d1565b610fe2565b3480156104c257600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff16610310565b3480156104ed57600080fd5b506102396104fc3660046125b1565b6110e8565b34801561050d57600080fd5b5061023961051c3660046125b1565b6111f3565b34801561052d57600080fd5b5061023961053c3660046125b1565b611242565b34801561054d57600080fd5b506102396112e1565b34801561056257600080fd5b506102396105713660046125f6565b611313565b34801561058257600080fd5b5060065461043190610100900460ff1681565b3480156105a157600080fd5b506102396105b0366004612869565b611793565b3480156105c157600080fd5b506102396105d0366004612929565b6117ea565b3480156105e157600080fd5b50600754600854600954600a546040805194855263ffffffff808516602087015264010000000085048116918601919091526c01000000000000000000000000840481166060860152700100000000000000000000000000000000840416608085015260ff74010000000000000000000000000000000000000000909304831660a085015260c08401919091521660e082015261010001610210565b34801561068957600080fd5b506004546106b29074010000000000000000000000000000000000000000900463ffffffff1681565b60405163ffffffff9091168152602001610210565b3480156106d357600080fd5b506003546103109073ffffffffffffffffffffffffffffffffffffffff1681565b34801561070057600080fd5b5061023961070f3660046125b1565b611bc6565b34801561072057600080fd5b5061023961072f3660046125cc565b611bda565b34801561074057600080fd5b5061020660055481565b610752611c8e565b60008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d80600081146107ac576040519150601f19603f3d011682016040523d82523d6000602084013e6107b1565b606091505b5050905080610821576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f6661696c656420746f207769746864726177206e61746976650000000000000060448201526064015b60405180910390fd5b505050565b60025473ffffffffffffffffffffffffffffffffffffffff163314610899576002546040517f1cf993f400000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091166024820152604401610818565b6108a38282611d11565b5050565b6108af611c8e565b600680547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16610100179055565b60065460009060ff1661094c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f77726170706572206973206e6f7420636f6e66696775726564000000000000006044820152606401610818565b600654610100900460ff16156109be576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f777261707065722069732064697361626c6564000000000000000000000000006044820152606401610818565b6109ce8363ffffffff1683611efd565b9392505050565b60065460009060ff16610a44576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f77726170706572206973206e6f7420636f6e66696775726564000000000000006044820152606401610818565b600654610100900460ff1615610ab6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f777261707065722069732064697361626c6564000000000000000000000000006044820152606401610818565b6000610ac061200e565b9050610ad38363ffffffff163a8361215d565b9150505b919050565b60065460009060ff16610b4b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f77726170706572206973206e6f7420636f6e66696775726564000000000000006044820152606401610818565b600654610100900460ff1615610bbd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f777261707065722069732064697361626c6564000000000000000000000000006044820152606401610818565b610bcd8263ffffffff163a611efd565b92915050565b600080610bdf8561228a565b90506000610bf38663ffffffff163a611efd565b905080341015610c5f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f66656520746f6f206c6f770000000000000000000000000000000000000000006044820152606401610818565b600a5460ff1663ffffffff85161115610cd4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f6e756d576f72647320746f6f20686967680000000000000000000000000000006044820152606401610818565b60006040518060c0016040528060095481526020017f000000000000000000000000000000000000000000000000000000000000000081526020018761ffff1681526020016008600c9054906101000a900463ffffffff16858a610d389190612b10565b610d429190612b10565b63ffffffff1681526020018663ffffffff168152602001610d736040518060200160405280600115158152506122a2565b90526040517f9b1c385e00000000000000000000000000000000000000000000000000000000815290915073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690639b1c385e90610dea908490600401612a4d565b602060405180830381600087803b158015610e0457600080fd5b505af1158015610e18573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e3c919061269f565b6040805160608101825233815263ffffffff808b1660208084019182523a8486019081526000878152600b90925294902092518354915190921674010000000000000000000000000000000000000000027fffffffffffffffff00000000000000000000000000000000000000000000000090911673ffffffffffffffffffffffffffffffffffffffff9290921691909117178155905160019091015593505050509392505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610f66576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610818565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60065460009060ff16611051576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f77726170706572206973206e6f7420636f6e66696775726564000000000000006044820152606401610818565b600654610100900460ff16156110c3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f777261707065722069732064697361626c6564000000000000000000000000006044820152606401610818565b60006110cd61200e565b90506110e08463ffffffff16848361215d565b949350505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314801590611128575060025473ffffffffffffffffffffffffffffffffffffffff163314155b156111ac573361114d60005473ffffffffffffffffffffffffffffffffffffffff1690565b6002546040517f061db9c100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201529183166024830152919091166044820152606401610818565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6111fb611c8e565b600480547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b61124a611c8e565b60035473ffffffffffffffffffffffffffffffffffffffff161561129a576040517f2d118a6e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6112e9611c8e565b600680547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055565b60065460ff1661137f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f77726170706572206973206e6f7420636f6e66696775726564000000000000006044820152606401610818565b600654610100900460ff16156113f1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f777261707065722069732064697361626c6564000000000000000000000000006044820152606401610818565b60035473ffffffffffffffffffffffffffffffffffffffff163314611472576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f6f6e6c792063616c6c61626c652066726f6d204c494e4b0000000000000000006044820152606401610818565b6000808061148284860186612886565b92509250925060006114938461228a565b9050600061149f61200e565b905060006114b48663ffffffff163a8461215d565b905080891015611520576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f66656520746f6f206c6f770000000000000000000000000000000000000000006044820152606401610818565b600a5460ff1663ffffffff85161115611595576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f6e756d576f72647320746f6f20686967680000000000000000000000000000006044820152606401610818565b60006040518060c0016040528060095481526020017f000000000000000000000000000000000000000000000000000000000000000081526020018761ffff1681526020016008600c9054906101000a900463ffffffff16868a6115f99190612b10565b6116039190612b10565b63ffffffff1681526020018663ffffffff16815260200160405180602001604052806000815250815250905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16639b1c385e836040518263ffffffff1660e01b815260040161168a9190612a4d565b602060405180830381600087803b1580156116a457600080fd5b505af11580156116b8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116dc919061269f565b6040805160608101825273ffffffffffffffffffffffffffffffffffffffff9e8f16815263ffffffff9a8b1660208083019182523a8385019081526000868152600b909252939020915182549151909c1674010000000000000000000000000000000000000000027fffffffffffffffff0000000000000000000000000000000000000000000000009091169b909f169a909a179d909d1789559b5160019098019790975550505060059790975550505050505050565b61179b611c8e565b6004805463ffffffff90921674010000000000000000000000000000000000000000027fffffffffffffffff00000000ffffffffffffffffffffffffffffffffffffffff909216919091179055565b6117f2611c8e565b6008805460ff80861674010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff63ffffffff898116700100000000000000000000000000000000027fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff918c166c0100000000000000000000000002919091167fffffffffffffffffffffffff0000000000000000ffffffffffffffffffffffff909516949094179390931792909216919091179091556009839055600a80549183167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00928316179055600680549091166001179055604080517f088070f5000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169163088070f5916004828101926080929190829003018186803b15801561198157600080fd5b505afa158015611995573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119b991906126b8565b50600880547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff929092169190911790555050604080517f043bd6ae00000000000000000000000000000000000000000000000000000000815290517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169163043bd6ae916004808301926020929190829003018186803b158015611a7757600080fd5b505afa158015611a8b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611aaf919061269f565b6007819055507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636b6feccc6040518163ffffffff1660e01b8152600401604080518083038186803b158015611b1a57600080fd5b505afa158015611b2e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b5291906128ef565b600880547fffffffffffffffffffffffffffffffffffffffff0000000000000000ffffffff166801000000000000000063ffffffff938416027fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff161764010000000093909216929092021790555050505050565b611bce611c8e565b611bd78161235e565b50565b611be2611c8e565b6003546040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8481166004830152602482018490529091169063a9059cbb90604401602060405180830381600087803b158015611c5657600080fd5b505af1158015611c6a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610821919061267d565b60005473ffffffffffffffffffffffffffffffffffffffff163314611d0f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610818565b565b6000828152600b602081815260408084208151606081018352815473ffffffffffffffffffffffffffffffffffffffff808216835263ffffffff740100000000000000000000000000000000000000008304168387015260018401805495840195909552898852959094527fffffffffffffffff000000000000000000000000000000000000000000000000909316905592909255815116611e0f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f72657175657374206e6f7420666f756e640000000000000000000000000000006044820152606401610818565b600080631fe543e360e01b8585604051602401611e2d929190612aaa565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090506000611ea7846020015163ffffffff16856000015184612454565b905080611ef557835160405173ffffffffffffffffffffffffffffffffffffffff9091169087907fc551b83c151f2d1c7eeb938ac59008e0409f1c1dc1e2f112449d4d79b458902290600090a35b505050505050565b6004546000908190611f2c9074010000000000000000000000000000000000000000900463ffffffff166124a0565b60085463ffffffff7001000000000000000000000000000000008204811691611f67916c010000000000000000000000009091041687612af8565b611f719190612af8565b611f7b9085612b94565b611f859190612af8565b6008549091508190600090606490611fb89074010000000000000000000000000000000000000000900460ff1682612b38565b611fc59060ff1684612b94565b611fcf9190612b5d565b600854909150600090611ff99068010000000000000000900463ffffffff1664e8d4a51000612b94565b6120039083612af8565b979650505050505050565b60085460048054604080517ffeaf968c000000000000000000000000000000000000000000000000000000008152905160009463ffffffff161515938593849373ffffffffffffffffffffffffffffffffffffffff9091169263feaf968c928281019260a0929190829003018186803b15801561208a57600080fd5b505afa15801561209e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120c2919061298b565b5094509092508491505080156120e857506120dd8242612bd1565b60085463ffffffff16105b156120f257506007545b60008112156109ce576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f496e76616c6964204c494e4b20776569207072696365000000000000000000006044820152606401610818565b600454600090819061218c9074010000000000000000000000000000000000000000900463ffffffff166124a0565b60085463ffffffff70010000000000000000000000000000000082048116916121c7916c010000000000000000000000009091041688612af8565b6121d19190612af8565b6121db9086612b94565b6121e59190612af8565b90506000836121fc83670de0b6b3a7640000612b94565b6122069190612b5d565b6008549091506000906064906122379074010000000000000000000000000000000000000000900460ff1682612b38565b6122449060ff1684612b94565b61224e9190612b5d565b60085490915060009061227490640100000000900463ffffffff1664e8d4a51000612b94565b61227e9083612af8565b98975050505050505050565b6000612297603f83612b71565b610bcd906001612b10565b60607f92fd13387c7fe7befbc38d303d6468778fb9731bc4583f17d92989c6fcfdeaaa826040516024016122db91511515815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915292915050565b73ffffffffffffffffffffffffffffffffffffffff81163314156123de576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610818565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60005a61138881101561246657600080fd5b61138881039050846040820482031161247e57600080fd5b50823b61248a57600080fd5b60008083516020850160008789f1949350505050565b60004661a4b18114806124b5575062066eed81145b15612559576000606c73ffffffffffffffffffffffffffffffffffffffff166341b247a86040518163ffffffff1660e01b815260040160c06040518083038186803b15801561250357600080fd5b505afa158015612517573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061253b919061281f565b5050505091505083608c61254f9190612af8565b6110e09082612b94565b50600092915050565b803573ffffffffffffffffffffffffffffffffffffffff81168114610ad757600080fd5b803560ff81168114610ad757600080fd5b805169ffffffffffffffffffff81168114610ad757600080fd5b6000602082840312156125c357600080fd5b6109ce82612562565b600080604083850312156125df57600080fd5b6125e883612562565b946020939093013593505050565b6000806000806060858703121561260c57600080fd5b61261585612562565b935060208501359250604085013567ffffffffffffffff8082111561263957600080fd5b818701915087601f83011261264d57600080fd5b81358181111561265c57600080fd5b88602082850101111561266e57600080fd5b95989497505060200194505050565b60006020828403121561268f57600080fd5b815180151581146109ce57600080fd5b6000602082840312156126b157600080fd5b5051919050565b600080600080608085870312156126ce57600080fd5b84516126d981612c75565b60208601519094506126ea81612c85565b60408601519093506126fb81612c85565b606086015190925061270c81612c85565b939692955090935050565b60006020828403121561272957600080fd5b5035919050565b6000806040838503121561274357600080fd5b8235915060208084013567ffffffffffffffff8082111561276357600080fd5b818601915086601f83011261277757600080fd5b81358181111561278957612789612c46565b8060051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f830116810181811085821117156127cc576127cc612c46565b604052828152858101935084860182860187018b10156127eb57600080fd5b600095505b8386101561280e5780358552600195909501949386019386016127f0565b508096505050505050509250929050565b60008060008060008060c0878903121561283857600080fd5b865195506020870151945060408701519350606087015192506080870151915060a087015190509295509295509295565b60006020828403121561287b57600080fd5b81356109ce81612c85565b60008060006060848603121561289b57600080fd5b83356128a681612c85565b925060208401356128b681612c75565b915060408401356128c681612c85565b809150509250925092565b600080604083850312156128e457600080fd5b82356125e881612c85565b6000806040838503121561290257600080fd5b825161290d81612c85565b602084015190925061291e81612c85565b809150509250929050565b600080600080600060a0868803121561294157600080fd5b853561294c81612c85565b9450602086013561295c81612c85565b935061296a60408701612586565b92506060860135915061297f60808701612586565b90509295509295909350565b600080600080600060a086880312156129a357600080fd5b6129ac86612597565b945060208601519350604086015192506060860151915061297f60808701612597565b6000815180845260005b818110156129f5576020818501810151868301820152016129d9565b81811115612a07576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006109ce60208301846129cf565b60208152815160208201526020820151604082015261ffff60408301511660608201526000606083015163ffffffff80821660808501528060808601511660a0850152505060a083015160c0808401526110e060e08401826129cf565b6000604082018483526020604081850152818551808452606086019150828701935060005b81811015612aeb57845183529383019391830191600101612acf565b5090979650505050505050565b60008219821115612b0b57612b0b612be8565b500190565b600063ffffffff808316818516808303821115612b2f57612b2f612be8565b01949350505050565b600060ff821660ff84168060ff03821115612b5557612b55612be8565b019392505050565b600082612b6c57612b6c612c17565b500490565b600063ffffffff80841680612b8857612b88612c17565b92169190910492915050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615612bcc57612bcc612be8565b500290565b600082821015612be357612be3612be8565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61ffff81168114611bd757600080fd5b63ffffffff81168114611bd757600080fdfea164736f6c6343000806000a",
+ 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\":\"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_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\"}],\"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: "0x60c06040526004805463ffffffff60a01b1916609160a21b1790553480156200002757600080fd5b50604051620030e7380380620030e78339810160408190526200004a9162000317565b803380600081620000a25760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000d557620000d5816200024e565b5050600280546001600160a01b0319166001600160a01b03938416179055508316156200011857600380546001600160a01b0319166001600160a01b0385161790555b6001600160a01b038216156200014457600480546001600160a01b0319166001600160a01b0384161790555b806001600160a01b03166080816001600160a01b031660601b815250506000816001600160a01b031663a21a23e46040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156200019f57600080fd5b505af1158015620001b4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001da919062000361565b60a0819052604051632fb1302360e21b8152600481018290523060248201529091506001600160a01b0383169063bec4c08c90604401600060405180830381600087803b1580156200022b57600080fd5b505af115801562000240573d6000803e3d6000fd5b50505050505050506200037b565b6001600160a01b038116331415620002a95760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000099565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b03811681146200031257600080fd5b919050565b6000806000606084860312156200032d57600080fd5b6200033884620002fa565b92506200034860208501620002fa565b91506200035860408501620002fa565b90509250925092565b6000602082840312156200037457600080fd5b5051919050565b60805160601c60a051612d12620003d5600039600081816101ef01528181610d2301526115e40152600081816102f901528181610ded0152818161166b0152818161197301528181611a540152611aef0152612d126000f3fe6080604052600436106101d85760003560e01c80638da5cb5b11610102578063c15ce4d711610095578063f254bdc711610064578063f254bdc7146106ff578063f2fde38b1461072c578063f3fef3a31461074c578063fc2a88c31461076c57600080fd5b8063c15ce4d7146105c0578063c3f909d4146105e0578063cdd8d88514610688578063da4f5e6d146106d257600080fd5b8063a3907d71116100d1578063a3907d711461054c578063a4c0ed3614610561578063a608a1e114610581578063bf17e559146105a057600080fd5b80638da5cb5b146104b45780638ea98117146104df5780639eccacf6146104ff578063a02e06161461052c57600080fd5b80634306d3541161017a57806362a504fc1161014957806362a504fc1461044c578063650596541461045f57806379ba50971461047f5780637fb5d19d1461049457600080fd5b80634306d3541461034057806348baa1c5146103605780634b1609351461040257806357a8070a1461042257600080fd5b80631fe543e3116101b65780631fe543e3146102925780632f2770db146102b25780633255c456146102c75780633b2bcbf1146102e757600080fd5b8063030932bb146101dd57806307b18bde14610224578063181f5a7714610246575b600080fd5b3480156101e957600080fd5b506102117f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020015b60405180910390f35b34801561023057600080fd5b5061024461023f36600461263a565b610782565b005b34801561025257600080fd5b50604080518082018252601281527f56524656325772617070657220312e302e3000000000000000000000000000006020820152905161021b9190612aa8565b34801561029e57600080fd5b506102446102ad36600461279e565b61085e565b3480156102be57600080fd5b506102446108df565b3480156102d357600080fd5b506102116102e236600461293f565b610915565b3480156102f357600080fd5b5061031b7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161021b565b34801561034c57600080fd5b5061021161035b3660046128d7565b610a0d565b34801561036c57600080fd5b506103cb61037b366004612785565b600b602052600090815260409020805460019091015473ffffffffffffffffffffffffffffffffffffffff82169174010000000000000000000000000000000000000000900463ffffffff169083565b6040805173ffffffffffffffffffffffffffffffffffffffff909416845263ffffffff90921660208401529082015260600161021b565b34801561040e57600080fd5b5061021161041d3660046128d7565b610b14565b34801561042e57600080fd5b5060065461043c9060ff1681565b604051901515815260200161021b565b61021161045a3660046128f4565b610c0b565b34801561046b57600080fd5b5061024461047a36600461261f565b610f1d565b34801561048b57600080fd5b50610244610f6c565b3480156104a057600080fd5b506102116104af36600461293f565b611069565b3480156104c057600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff1661031b565b3480156104eb57600080fd5b506102446104fa36600461261f565b61116f565b34801561050b57600080fd5b5060025461031b9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561053857600080fd5b5061024461054736600461261f565b61127a565b34801561055857600080fd5b50610244611319565b34801561056d57600080fd5b5061024461057c366004612664565b61134b565b34801561058d57600080fd5b5060065461043c90610100900460ff1681565b3480156105ac57600080fd5b506102446105bb3660046128d7565b6117cb565b3480156105cc57600080fd5b506102446105db366004612997565b611822565b3480156105ec57600080fd5b50600754600854600954600a546040805194855263ffffffff808516602087015264010000000085048116918601919091526c01000000000000000000000000840481166060860152700100000000000000000000000000000000840416608085015260ff74010000000000000000000000000000000000000000909304831660a085015260c08401919091521660e08201526101000161021b565b34801561069457600080fd5b506004546106bd9074010000000000000000000000000000000000000000900463ffffffff1681565b60405163ffffffff909116815260200161021b565b3480156106de57600080fd5b5060035461031b9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561070b57600080fd5b5060045461031b9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561073857600080fd5b5061024461074736600461261f565b611bfe565b34801561075857600080fd5b5061024461076736600461263a565b611c12565b34801561077857600080fd5b5061021160055481565b61078a611cfc565b60008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d80600081146107e4576040519150601f19603f3d011682016040523d82523d6000602084013e6107e9565b606091505b5050905080610859576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f6661696c656420746f207769746864726177206e61746976650000000000000060448201526064015b60405180910390fd5b505050565b60025473ffffffffffffffffffffffffffffffffffffffff1633146108d1576002546040517f1cf993f400000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091166024820152604401610850565b6108db8282611d7f565b5050565b6108e7611cfc565b600680547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16610100179055565b60065460009060ff16610984576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f77726170706572206973206e6f7420636f6e66696775726564000000000000006044820152606401610850565b600654610100900460ff16156109f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f777261707065722069732064697361626c6564000000000000000000000000006044820152606401610850565b610a068363ffffffff1683611f6b565b9392505050565b60065460009060ff16610a7c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f77726170706572206973206e6f7420636f6e66696775726564000000000000006044820152606401610850565b600654610100900460ff1615610aee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f777261707065722069732064697361626c6564000000000000000000000000006044820152606401610850565b6000610af861207c565b9050610b0b8363ffffffff163a836121cb565b9150505b919050565b60065460009060ff16610b83576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f77726170706572206973206e6f7420636f6e66696775726564000000000000006044820152606401610850565b600654610100900460ff1615610bf5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f777261707065722069732064697361626c6564000000000000000000000000006044820152606401610850565b610c058263ffffffff163a611f6b565b92915050565b600080610c17856122f8565b90506000610c2b8663ffffffff163a611f6b565b905080341015610c97576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f66656520746f6f206c6f770000000000000000000000000000000000000000006044820152606401610850565b600a5460ff1663ffffffff85161115610d0c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f6e756d576f72647320746f6f20686967680000000000000000000000000000006044820152606401610850565b60006040518060c0016040528060095481526020017f000000000000000000000000000000000000000000000000000000000000000081526020018761ffff1681526020016008600c9054906101000a900463ffffffff16858a610d709190612b7e565b610d7a9190612b7e565b63ffffffff1681526020018663ffffffff168152602001610dab604051806020016040528060011515815250612310565b90526040517f9b1c385e00000000000000000000000000000000000000000000000000000000815290915073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690639b1c385e90610e22908490600401612abb565b602060405180830381600087803b158015610e3c57600080fd5b505af1158015610e50573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e74919061270d565b6040805160608101825233815263ffffffff808b1660208084019182523a8486019081526000878152600b90925294902092518354915190921674010000000000000000000000000000000000000000027fffffffffffffffff00000000000000000000000000000000000000000000000090911673ffffffffffffffffffffffffffffffffffffffff9290921691909117178155905160019091015593505050509392505050565b610f25611cfc565b600480547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60015473ffffffffffffffffffffffffffffffffffffffff163314610fed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610850565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60065460009060ff166110d8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f77726170706572206973206e6f7420636f6e66696775726564000000000000006044820152606401610850565b600654610100900460ff161561114a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f777261707065722069732064697361626c6564000000000000000000000000006044820152606401610850565b600061115461207c565b90506111678463ffffffff1684836121cb565b949350505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633148015906111af575060025473ffffffffffffffffffffffffffffffffffffffff163314155b1561123357336111d460005473ffffffffffffffffffffffffffffffffffffffff1690565b6002546040517f061db9c100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201529183166024830152919091166044820152606401610850565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b611282611cfc565b60035473ffffffffffffffffffffffffffffffffffffffff16156112d2576040517f2d118a6e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b611321611cfc565b600680547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055565b60065460ff166113b7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f77726170706572206973206e6f7420636f6e66696775726564000000000000006044820152606401610850565b600654610100900460ff1615611429576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f777261707065722069732064697361626c6564000000000000000000000000006044820152606401610850565b60035473ffffffffffffffffffffffffffffffffffffffff1633146114aa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f6f6e6c792063616c6c61626c652066726f6d204c494e4b0000000000000000006044820152606401610850565b600080806114ba848601866128f4565b92509250925060006114cb846122f8565b905060006114d761207c565b905060006114ec8663ffffffff163a846121cb565b905080891015611558576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f66656520746f6f206c6f770000000000000000000000000000000000000000006044820152606401610850565b600a5460ff1663ffffffff851611156115cd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f6e756d576f72647320746f6f20686967680000000000000000000000000000006044820152606401610850565b60006040518060c0016040528060095481526020017f000000000000000000000000000000000000000000000000000000000000000081526020018761ffff1681526020016008600c9054906101000a900463ffffffff16868a6116319190612b7e565b61163b9190612b7e565b63ffffffff1681526020018663ffffffff16815260200160405180602001604052806000815250815250905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16639b1c385e836040518263ffffffff1660e01b81526004016116c29190612abb565b602060405180830381600087803b1580156116dc57600080fd5b505af11580156116f0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611714919061270d565b6040805160608101825273ffffffffffffffffffffffffffffffffffffffff9e8f16815263ffffffff9a8b1660208083019182523a8385019081526000868152600b909252939020915182549151909c1674010000000000000000000000000000000000000000027fffffffffffffffff0000000000000000000000000000000000000000000000009091169b909f169a909a179d909d1789559b5160019098019790975550505060059790975550505050505050565b6117d3611cfc565b6004805463ffffffff90921674010000000000000000000000000000000000000000027fffffffffffffffff00000000ffffffffffffffffffffffffffffffffffffffff909216919091179055565b61182a611cfc565b6008805460ff80861674010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff63ffffffff898116700100000000000000000000000000000000027fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff918c166c0100000000000000000000000002919091167fffffffffffffffffffffffff0000000000000000ffffffffffffffffffffffff909516949094179390931792909216919091179091556009839055600a80549183167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00928316179055600680549091166001179055604080517f088070f5000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169163088070f5916004828101926080929190829003018186803b1580156119b957600080fd5b505afa1580156119cd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119f19190612726565b50600880547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff929092169190911790555050604080517f043bd6ae00000000000000000000000000000000000000000000000000000000815290517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169163043bd6ae916004808301926020929190829003018186803b158015611aaf57600080fd5b505afa158015611ac3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ae7919061270d565b6007819055507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636b6feccc6040518163ffffffff1660e01b8152600401604080518083038186803b158015611b5257600080fd5b505afa158015611b66573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b8a919061295d565b600880547fffffffffffffffffffffffffffffffffffffffff0000000000000000ffffffff166801000000000000000063ffffffff938416027fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff161764010000000093909216929092021790555050505050565b611c06611cfc565b611c0f816123cc565b50565b611c1a611cfc565b6003546040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8481166004830152602482018490529091169063a9059cbb90604401602060405180830381600087803b158015611c8e57600080fd5b505af1158015611ca2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cc691906126eb565b6108db576040517f7c07fc4c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005473ffffffffffffffffffffffffffffffffffffffff163314611d7d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610850565b565b6000828152600b602081815260408084208151606081018352815473ffffffffffffffffffffffffffffffffffffffff808216835263ffffffff740100000000000000000000000000000000000000008304168387015260018401805495840195909552898852959094527fffffffffffffffff000000000000000000000000000000000000000000000000909316905592909255815116611e7d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f72657175657374206e6f7420666f756e640000000000000000000000000000006044820152606401610850565b600080631fe543e360e01b8585604051602401611e9b929190612b18565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090506000611f15846020015163ffffffff168560000151846124c2565b905080611f6357835160405173ffffffffffffffffffffffffffffffffffffffff9091169087907fc551b83c151f2d1c7eeb938ac59008e0409f1c1dc1e2f112449d4d79b458902290600090a35b505050505050565b6004546000908190611f9a9074010000000000000000000000000000000000000000900463ffffffff1661250e565b60085463ffffffff7001000000000000000000000000000000008204811691611fd5916c010000000000000000000000009091041687612b66565b611fdf9190612b66565b611fe99085612c02565b611ff39190612b66565b60085490915081906000906064906120269074010000000000000000000000000000000000000000900460ff1682612ba6565b6120339060ff1684612c02565b61203d9190612bcb565b6008549091506000906120679068010000000000000000900463ffffffff1664e8d4a51000612c02565b6120719083612b66565b979650505050505050565b60085460048054604080517ffeaf968c000000000000000000000000000000000000000000000000000000008152905160009463ffffffff161515938593849373ffffffffffffffffffffffffffffffffffffffff9091169263feaf968c928281019260a0929190829003018186803b1580156120f857600080fd5b505afa15801561210c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061213091906129f9565b509450909250849150508015612156575061214b8242612c3f565b60085463ffffffff16105b1561216057506007545b6000811215610a06576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f496e76616c6964204c494e4b20776569207072696365000000000000000000006044820152606401610850565b60045460009081906121fa9074010000000000000000000000000000000000000000900463ffffffff1661250e565b60085463ffffffff7001000000000000000000000000000000008204811691612235916c010000000000000000000000009091041688612b66565b61223f9190612b66565b6122499086612c02565b6122539190612b66565b905060008361226a83670de0b6b3a7640000612c02565b6122749190612bcb565b6008549091506000906064906122a59074010000000000000000000000000000000000000000900460ff1682612ba6565b6122b29060ff1684612c02565b6122bc9190612bcb565b6008549091506000906122e290640100000000900463ffffffff1664e8d4a51000612c02565b6122ec9083612b66565b98975050505050505050565b6000612305603f83612bdf565b610c05906001612b7e565b60607f92fd13387c7fe7befbc38d303d6468778fb9731bc4583f17d92989c6fcfdeaaa8260405160240161234991511515815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915292915050565b73ffffffffffffffffffffffffffffffffffffffff811633141561244c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610850565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60005a6113888110156124d457600080fd5b6113888103905084604082048203116124ec57600080fd5b50823b6124f857600080fd5b60008083516020850160008789f1949350505050565b60004661a4b1811480612523575062066eed81145b156125c7576000606c73ffffffffffffffffffffffffffffffffffffffff166341b247a86040518163ffffffff1660e01b815260040160c06040518083038186803b15801561257157600080fd5b505afa158015612585573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125a9919061288d565b5050505091505083608c6125bd9190612b66565b6111679082612c02565b50600092915050565b803573ffffffffffffffffffffffffffffffffffffffff81168114610b0f57600080fd5b803560ff81168114610b0f57600080fd5b805169ffffffffffffffffffff81168114610b0f57600080fd5b60006020828403121561263157600080fd5b610a06826125d0565b6000806040838503121561264d57600080fd5b612656836125d0565b946020939093013593505050565b6000806000806060858703121561267a57600080fd5b612683856125d0565b935060208501359250604085013567ffffffffffffffff808211156126a757600080fd5b818701915087601f8301126126bb57600080fd5b8135818111156126ca57600080fd5b8860208285010111156126dc57600080fd5b95989497505060200194505050565b6000602082840312156126fd57600080fd5b81518015158114610a0657600080fd5b60006020828403121561271f57600080fd5b5051919050565b6000806000806080858703121561273c57600080fd5b845161274781612ce3565b602086015190945061275881612cf3565b604086015190935061276981612cf3565b606086015190925061277a81612cf3565b939692955090935050565b60006020828403121561279757600080fd5b5035919050565b600080604083850312156127b157600080fd5b8235915060208084013567ffffffffffffffff808211156127d157600080fd5b818601915086601f8301126127e557600080fd5b8135818111156127f7576127f7612cb4565b8060051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f8301168101818110858211171561283a5761283a612cb4565b604052828152858101935084860182860187018b101561285957600080fd5b600095505b8386101561287c57803585526001959095019493860193860161285e565b508096505050505050509250929050565b60008060008060008060c087890312156128a657600080fd5b865195506020870151945060408701519350606087015192506080870151915060a087015190509295509295509295565b6000602082840312156128e957600080fd5b8135610a0681612cf3565b60008060006060848603121561290957600080fd5b833561291481612cf3565b9250602084013561292481612ce3565b9150604084013561293481612cf3565b809150509250925092565b6000806040838503121561295257600080fd5b823561265681612cf3565b6000806040838503121561297057600080fd5b825161297b81612cf3565b602084015190925061298c81612cf3565b809150509250929050565b600080600080600060a086880312156129af57600080fd5b85356129ba81612cf3565b945060208601356129ca81612cf3565b93506129d8604087016125f4565b9250606086013591506129ed608087016125f4565b90509295509295909350565b600080600080600060a08688031215612a1157600080fd5b612a1a86612605565b94506020860151935060408601519250606086015191506129ed60808701612605565b6000815180845260005b81811015612a6357602081850181015186830182015201612a47565b81811115612a75576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610a066020830184612a3d565b60208152815160208201526020820151604082015261ffff60408301511660608201526000606083015163ffffffff80821660808501528060808601511660a0850152505060a083015160c08084015261116760e0840182612a3d565b6000604082018483526020604081850152818551808452606086019150828701935060005b81811015612b5957845183529383019391830191600101612b3d565b5090979650505050505050565b60008219821115612b7957612b79612c56565b500190565b600063ffffffff808316818516808303821115612b9d57612b9d612c56565b01949350505050565b600060ff821660ff84168060ff03821115612bc357612bc3612c56565b019392505050565b600082612bda57612bda612c85565b500490565b600063ffffffff80841680612bf657612bf6612c85565b92169190910492915050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615612c3a57612c3a612c56565b500290565b600082821015612c5157612c51612c56565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61ffff81168114611c0f57600080fd5b63ffffffff81168114611c0f57600080fdfea164736f6c6343000806000a",
}
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
}
@@ -502,9 +502,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 +516,34 @@ 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) {
+ var out []interface{}
+ err := _VRFV2PlusWrapper.contract.Call(opts, &out, "s_vrfCoordinator")
+
+ if err != nil {
+ return *new(common.Address), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address)
+
+ return out0, err
+
+}
+
+func (_VRFV2PlusWrapper *VRFV2PlusWrapperSession) SVrfCoordinator() (common.Address, error) {
+ return _VRFV2PlusWrapper.Contract.SVrfCoordinator(&_VRFV2PlusWrapper.CallOpts)
+}
+
+func (_VRFV2PlusWrapper *VRFV2PlusWrapperCallerSession) SVrfCoordinator() (common.Address, error) {
+ return _VRFV2PlusWrapper.Contract.SVrfCoordinator(&_VRFV2PlusWrapper.CallOpts)
}
func (_VRFV2PlusWrapper *VRFV2PlusWrapperCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) {
@@ -666,16 +688,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) {
@@ -1201,7 +1223,9 @@ 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)
TypeAndVersion(opts *bind.CallOpts) (string, error)
@@ -1225,7 +1249,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 00000000000..d8c85370649
--- /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: "0x6080604052600060065560006007556103e76008553480156200002157600080fd5b5060405162001dd138038062001dd18339810160408190526200004491620001f2565b3380600084846001600160a01b038216156200007657600080546001600160a01b0319166001600160a01b0384161790555b600180546001600160a01b0319166001600160a01b03928316179055831615159050620000ea5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600280546001600160a01b0319166001600160a01b03848116919091179091558116156200011d576200011d8162000128565b50505050506200022a565b6001600160a01b038116331415620001835760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401620000e1565b600380546001600160a01b0319166001600160a01b03838116918217909255600254604051919216907fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae127890600090a350565b80516001600160a01b0381168114620001ed57600080fd5b919050565b600080604083850312156200020657600080fd5b6200021183620001d5565b91506200022160208401620001d5565b90509250929050565b611b97806200023a6000396000f3fe6080604052600436106101635760003560e01c80638f6b7070116100c0578063d826f88f11610074578063dc1670db11610059578063dc1670db14610421578063f176596214610437578063f2fde38b1461045757600080fd5b8063d826f88f146103c2578063d8a4676f146103ee57600080fd5b8063a168fa89116100a5578063a168fa89146102f7578063afacbf9c1461038c578063b1e21749146103ac57600080fd5b80638f6b7070146102ac5780639c24ea40146102d757600080fd5b806374dba124116101175780637a8042bd116100fc5780637a8042bd1461022057806384276d81146102405780638da5cb5b1461026057600080fd5b806374dba124146101f557806379ba50971461020b57600080fd5b80631fe543e3116101485780631fe543e3146101a7578063557d2e92146101c9578063737144bc146101df57600080fd5b806312065fe01461016f5780631757f11c1461019157600080fd5b3661016a57005b600080fd5b34801561017b57600080fd5b50475b6040519081526020015b60405180910390f35b34801561019d57600080fd5b5061017e60075481565b3480156101b357600080fd5b506101c76101c23660046117a4565b610477565b005b3480156101d557600080fd5b5061017e60055481565b3480156101eb57600080fd5b5061017e60065481565b34801561020157600080fd5b5061017e60085481565b34801561021757600080fd5b506101c7610530565b34801561022c57600080fd5b506101c761023b366004611772565b610631565b34801561024c57600080fd5b506101c761025b366004611772565b61071b565b34801561026c57600080fd5b5060025473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610188565b3480156102b857600080fd5b5060015473ffffffffffffffffffffffffffffffffffffffff16610287565b3480156102e357600080fd5b506101c76102f2366004611713565b61080b565b34801561030357600080fd5b50610355610312366004611772565b600b602052600090815260409020805460018201546003830154600484015460058501546006860154600790960154949560ff9485169593949293919290911687565b604080519788529515156020880152948601939093526060850191909152608084015260a0830152151560c082015260e001610188565b34801561039857600080fd5b506101c76103a7366004611893565b6108a2565b3480156103b857600080fd5b5061017e60095481565b3480156103ce57600080fd5b506101c76000600681905560078190556103e76008556005819055600455565b3480156103fa57600080fd5b5061040e610409366004611772565b610b12565b60405161018897969594939291906119e3565b34801561042d57600080fd5b5061017e60045481565b34801561044357600080fd5b506101c7610452366004611893565b610c95565b34801561046357600080fd5b506101c7610472366004611713565b610efd565b60015473ffffffffffffffffffffffffffffffffffffffff163314610522576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f6f6e6c792056524620563220506c757320777261707065722063616e2066756c60448201527f66696c6c0000000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b61052c8282610f11565b5050565b60035473ffffffffffffffffffffffffffffffffffffffff1633146105b1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610519565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000008082163390811790935560038054909116905560405173ffffffffffffffffffffffffffffffffffffffff909116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a350565b6106396110f0565b60005473ffffffffffffffffffffffffffffffffffffffff1663a9059cbb61067660025473ffffffffffffffffffffffffffffffffffffffff1690565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff909116600482015260248101849052604401602060405180830381600087803b1580156106e357600080fd5b505af11580156106f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061052c9190611750565b6107236110f0565b600061074460025473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d806000811461079b576040519150601f19603f3d011682016040523d82523d6000602084013e6107a0565b606091505b505090508061052c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f77697468647261774e6174697665206661696c656400000000000000000000006044820152606401610519565b60005473ffffffffffffffffffffffffffffffffffffffff161561085b576040517f64f778ae00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6108aa6110f0565b60005b8161ffff168161ffff161015610b0b5760006108ca868686611173565b6009819055905060006108db611378565b6001546040517f4306d35400000000000000000000000000000000000000000000000000000000815263ffffffff8a16600482015291925060009173ffffffffffffffffffffffffffffffffffffffff90911690634306d3549060240160206040518083038186803b15801561095057600080fd5b505afa158015610964573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610988919061178b565b604080516101008101825282815260006020808301828152845183815280830186528486019081524260608601526080850184905260a0850189905260c0850184905260e08501849052898452600b8352949092208351815591516001830180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169115159190911790559251805194955091939092610a30926002850192910190611688565b50606082015160038201556080820151600482015560a082015160058083019190915560c0830151600683015560e090920151600790910180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169115159190911790558054906000610aa383611af3565b90915550506000838152600a6020526040908190208390555183907f5f56b4c20db9f5b294cbf6f681368de4a992a27e2de2ee702dcf2cbbfa791ec490610aed9084815260200190565b60405180910390a25050508080610b0390611ad1565b9150506108ad565b5050505050565b6000818152600b602052604081205481906060908290819081908190610b94576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f72657175657374206e6f7420666f756e640000000000000000000000000000006044820152606401610519565b6000888152600b6020908152604080832081516101008101835281548152600182015460ff16151581850152600282018054845181870281018701865281815292959394860193830182828015610c0a57602002820191906000526020600020905b815481526020019060010190808311610bf6575b50505050508152602001600382015481526020016004820154815260200160058201548152602001600682015481526020016007820160009054906101000a900460ff1615151515815250509050806000015181602001518260400151836060015184608001518560a001518660c00151975097509750975097509750975050919395979092949650565b610c9d6110f0565b60005b8161ffff168161ffff161015610b0b576000610cbd86868661141e565b600981905590506000610cce611378565b6001546040517f4b16093500000000000000000000000000000000000000000000000000000000815263ffffffff8a16600482015291925060009173ffffffffffffffffffffffffffffffffffffffff90911690634b1609359060240160206040518083038186803b158015610d4357600080fd5b505afa158015610d57573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d7b919061178b565b604080516101008101825282815260006020808301828152845183815280830186528486019081524260608601526080850184905260a0850189905260c08501849052600160e086018190528a8552600b84529590932084518155905194810180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001695151595909517909455905180519495509193610e229260028501920190611688565b50606082015160038201556080820151600482015560a082015160058083019190915560c0830151600683015560e090920151600790910180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169115159190911790558054906000610e9583611af3565b90915550506000838152600a6020526040908190208390555183907f5f56b4c20db9f5b294cbf6f681368de4a992a27e2de2ee702dcf2cbbfa791ec490610edf9084815260200190565b60405180910390a25050508080610ef590611ad1565b915050610ca0565b610f056110f0565b610f0e81611591565b50565b6000828152600b6020526040902054610f86576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f72657175657374206e6f7420666f756e640000000000000000000000000000006044820152606401610519565b6000610f90611378565b6000848152600a602052604081205491925090610fad9083611aba565b90506000610fbe82620f4240611a7d565b9050600754821115610fd05760078290555b6008548210610fe157600854610fe3565b815b600855600454610ff35780611026565b600454611001906001611a2a565b816004546006546110129190611a7d565b61101c9190611a2a565b6110269190611a42565b6006556004805490600061103983611af3565b90915550506000858152600b60209081526040909120600181810180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169091179055855161109192600290920191870190611688565b506000858152600b602052604090819020426004820155600681018590555490517f6c84e12b4c188e61f1b4727024a5cf05c025fa58467e5eedf763c0744c89da7b916110e191889188916119ba565b60405180910390a15050505050565b60025473ffffffffffffffffffffffffffffffffffffffff163314611171576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610519565b565b600080546001546040517f4306d35400000000000000000000000000000000000000000000000000000000815263ffffffff8716600482015273ffffffffffffffffffffffffffffffffffffffff92831692634000aea09216908190634306d3549060240160206040518083038186803b1580156111f057600080fd5b505afa158015611204573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611228919061178b565b6040805163ffffffff808b16602083015261ffff8a169282019290925290871660608201526080016040516020818303038152906040526040518463ffffffff1660e01b815260040161127d93929190611922565b602060405180830381600087803b15801561129757600080fd5b505af11580156112ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112cf9190611750565b50600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663fc2a88c36040518163ffffffff1660e01b815260040160206040518083038186803b15801561133857600080fd5b505afa15801561134c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611370919061178b565b949350505050565b60004661a4b181148061138d575062066eed81145b1561141757606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b815260040160206040518083038186803b1580156113d957600080fd5b505afa1580156113ed573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611411919061178b565b91505090565b4391505090565b6001546040517f4b16093500000000000000000000000000000000000000000000000000000000815263ffffffff85166004820152600091829173ffffffffffffffffffffffffffffffffffffffff90911690634b1609359060240160206040518083038186803b15801561149257600080fd5b505afa1580156114a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114ca919061178b565b6001546040517f62a504fc00000000000000000000000000000000000000000000000000000000815263ffffffff808916600483015261ffff881660248301528616604482015291925073ffffffffffffffffffffffffffffffffffffffff16906362a504fc9083906064016020604051808303818588803b15801561154f57600080fd5b505af1158015611563573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190611588919061178b565b95945050505050565b73ffffffffffffffffffffffffffffffffffffffff8116331415611611576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610519565b600380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff838116918217909255600254604051919216907fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae127890600090a350565b8280548282559060005260206000209081019282156116c3579160200282015b828111156116c35782518255916020019190600101906116a8565b506116cf9291506116d3565b5090565b5b808211156116cf57600081556001016116d4565b803561ffff811681146116fa57600080fd5b919050565b803563ffffffff811681146116fa57600080fd5b60006020828403121561172557600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461174957600080fd5b9392505050565b60006020828403121561176257600080fd5b8151801515811461174957600080fd5b60006020828403121561178457600080fd5b5035919050565b60006020828403121561179d57600080fd5b5051919050565b600080604083850312156117b757600080fd5b8235915060208084013567ffffffffffffffff808211156117d757600080fd5b818601915086601f8301126117eb57600080fd5b8135818111156117fd576117fd611b5b565b8060051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f8301168101818110858211171561184057611840611b5b565b604052828152858101935084860182860187018b101561185f57600080fd5b600095505b83861015611882578035855260019590950194938601938601611864565b508096505050505050509250929050565b600080600080608085870312156118a957600080fd5b6118b2856116ff565b93506118c0602086016116e8565b92506118ce604086016116ff565b91506118dc606086016116e8565b905092959194509250565b600081518084526020808501945080840160005b83811015611917578151875295820195908201906001016118fb565b509495945050505050565b73ffffffffffffffffffffffffffffffffffffffff8416815260006020848184015260606040840152835180606085015260005b8181101561197257858101830151858201608001528201611956565b81811115611984576000608083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160800195945050505050565b8381526060602082015260006119d360608301856118e7565b9050826040830152949350505050565b878152861515602082015260e060408201526000611a0460e08301886118e7565b90508560608301528460808301528360a08301528260c083015298975050505050505050565b60008219821115611a3d57611a3d611b2c565b500190565b600082611a78577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615611ab557611ab5611b2c565b500290565b600082821015611acc57611acc611b2c565b500390565b600061ffff80831681811415611ae957611ae9611b2c565b6001019392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415611b2557611b25611b2c565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fdfea164736f6c6343000806000a",
+}
+
+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 3f602da118c..da24539bf05 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
@@ -6,7 +6,7 @@ authorized_receiver: ../../contracts/solc/v0.7/AuthorizedReceiver.abi ../../cont
automation_consumer_benchmark: ../../contracts/solc/v0.8.16/AutomationConsumerBenchmark.abi ../../contracts/solc/v0.8.16/AutomationConsumerBenchmark.bin f52c76f1aaed4be541d82d97189d70f5aa027fc9838037dd7a7d21910c8c488e
automation_forwarder_logic: ../../contracts/solc/v0.8.16/AutomationForwarderLogic.abi ../../contracts/solc/v0.8.16/AutomationForwarderLogic.bin 15ae0c367297955fdab4b552dbb10e1f2be80a8fde0efec4a4d398693e9d72b5
automation_registrar_wrapper2_1: ../../contracts/solc/v0.8.16/AutomationRegistrar2_1.abi ../../contracts/solc/v0.8.16/AutomationRegistrar2_1.bin eb06d853aab39d3196c593b03e555851cbe8386e0fe54a74c2479f62d14b3c42
-automation_utils_2_1: ../../contracts/solc/v0.8.16/AutomationUtils2_1.abi ../../contracts/solc/v0.8.16/AutomationUtils2_1.bin 0b3006a2a1588916d22bf1ae5429bd3bce24a58904588d5ed3fe1026d64616cf
+automation_utils_2_1: ../../contracts/solc/v0.8.16/AutomationUtils2_1.abi ../../contracts/solc/v0.8.16/AutomationUtils2_1.bin 331bfa79685aee6ddf63b64c0747abee556c454cae3fb8175edff425b615d8aa
batch_blockhash_store: ../../contracts/solc/v0.8.6/BatchBlockhashStore.abi ../../contracts/solc/v0.8.6/BatchBlockhashStore.bin c5ab26709a01050402615659403f32d5cd1b85f3ad6bb6bfe021692f4233cf19
batch_vrf_coordinator_v2: ../../contracts/solc/v0.8.6/BatchVRFCoordinatorV2.abi ../../contracts/solc/v0.8.6/BatchVRFCoordinatorV2.bin d0a54963260d8c1f1bbd984b758285e6027cfb5a7e42701bcb562ab123219332
batch_vrf_coordinator_v2plus: ../../contracts/solc/v0.8.6/BatchVRFCoordinatorV2Plus.abi ../../contracts/solc/v0.8.6/BatchVRFCoordinatorV2Plus.bin 7bb76ae241cf1b37b41920830b836cb99f1ad33efd7435ca2398ff6cd2fe5d48
@@ -16,7 +16,6 @@ cron_upkeep_factory_wrapper: ../../contracts/solc/v0.8.6/CronUpkeepFactory.abi -
cron_upkeep_wrapper: ../../contracts/solc/v0.8.6/CronUpkeep.abi - 362fcfcf30a6ab3acff83095ea4b2b9056dd5e9dcb94bc5411aae58995d22709
derived_price_feed_wrapper: ../../contracts/solc/v0.8.6/DerivedPriceFeed.abi ../../contracts/solc/v0.8.6/DerivedPriceFeed.bin c8542e6c850c2d0fffb79a7f7213dc927ec64e6ddd54e1224cb2fb4a13aabdd0
dummy_protocol_wrapper: ../../contracts/solc/v0.8.16/DummyProtocol.abi ../../contracts/solc/v0.8.16/DummyProtocol.bin 583a448170b13abf7ed64e406e8177d78c9e55ab44efd141eee60de23a71ee3b
-feed_lookup_compatible_interface: ../../contracts/solc/v0.8.16/FeedLookupCompatibleInterface.abi ../../contracts/solc/v0.8.16/FeedLookupCompatibleInterface.bin 2c5c2cb669a666ab6f14e7fdbd11ea019997e3860f56ccfaf112156e412f1b15
flags_wrapper: ../../contracts/solc/v0.6/Flags.abi ../../contracts/solc/v0.6/Flags.bin 2034d1b562ca37a63068851915e3703980276e8d5f7db6db8a3351a49d69fc4a
flux_aggregator_wrapper: ../../contracts/solc/v0.6/FluxAggregator.abi ../../contracts/solc/v0.6/FluxAggregator.bin a3b0a6396c4aa3b5ee39b3c4bd45efc89789d4859379a8a92caca3a0496c5794
functions_billing_registry_events_mock: ../../contracts/solc/v0.8.6/FunctionsBillingRegistryEventsMock.abi ../../contracts/solc/v0.8.6/FunctionsBillingRegistryEventsMock.bin 50deeb883bd9c3729702be335c0388f9d8553bab4be5e26ecacac496a89e2b77
@@ -24,7 +23,7 @@ functions_oracle_events_mock: ../../contracts/solc/v0.8.6/FunctionsOracleEventsM
gas_wrapper: ../../contracts/solc/v0.8.6/KeeperRegistryCheckUpkeepGasUsageWrapper1_2.abi ../../contracts/solc/v0.8.6/KeeperRegistryCheckUpkeepGasUsageWrapper1_2.bin 4a5dcdac486d18fcd58e3488c15c1710ae76b977556a3f3191bd269a4bc75723
gas_wrapper_mock: ../../contracts/solc/v0.8.6/KeeperRegistryCheckUpkeepGasUsageWrapper1_2Mock.abi ../../contracts/solc/v0.8.6/KeeperRegistryCheckUpkeepGasUsageWrapper1_2Mock.bin a9b08f18da59125c6fc305855710241f3d35161b8b9f3e3f635a7b1d5c6da9c8
i_keeper_registry_master_wrapper_2_1: ../../contracts/solc/v0.8.16/IKeeperRegistryMaster.abi ../../contracts/solc/v0.8.16/IKeeperRegistryMaster.bin 4426a320baaef8a66692699ec008e371eb7f841b1f9f02ff817c0eee0c63c7b5
-i_log_automation: ../../contracts/solc/v0.8.16/ILogAutomation.abi ../../contracts/solc/v0.8.16/ILogAutomation.bin b9bc273ba34750073874397e7681909794d15b31da8a4449c5aafa0bb5ea1dfc
+i_log_automation: ../../contracts/solc/v0.8.16/ILogAutomation.abi ../../contracts/solc/v0.8.16/ILogAutomation.bin 296beccb6af655d6fc3a6e676b244831cce2da6688d3afc4f21f8738ae59e03e
keeper_registrar_wrapper1_2: ../../contracts/solc/v0.8.6/KeeperRegistrar.abi ../../contracts/solc/v0.8.6/KeeperRegistrar.bin e49b2f8b23da17af1ed2209b8ae0968cc04350554d636711e6c24a3ad3118692
keeper_registrar_wrapper1_2_mock: ../../contracts/solc/v0.8.6/KeeperRegistrar1_2Mock.abi ../../contracts/solc/v0.8.6/KeeperRegistrar1_2Mock.bin 5b155a7cb3def309fd7525de1d7cd364ebf8491bdc3060eac08ea0ff55ab29bc
keeper_registrar_wrapper2_0: ../../contracts/solc/v0.8.6/KeeperRegistrar2_0.abi ../../contracts/solc/v0.8.6/KeeperRegistrar2_0.bin 647f125c2f0dafabcdc545cb77b15dc2ec3ea9429357806813179b1fd555c2d2
@@ -37,17 +36,16 @@ keeper_registry_wrapper1_1_mock: ../../contracts/solc/v0.7/KeeperRegistry1_1Mock
keeper_registry_wrapper1_2: ../../contracts/solc/v0.8.6/KeeperRegistry1_2.abi ../../contracts/solc/v0.8.6/KeeperRegistry1_2.bin c08f903e7ecbdf89bbfea32c6dd334d3bf908ac809ebf63545890798a5f7a4a7
keeper_registry_wrapper1_3: ../../contracts/solc/v0.8.6/KeeperRegistry1_3.abi ../../contracts/solc/v0.8.6/KeeperRegistry1_3.bin 5e1414eacbc1880b7349a4f253b7eca176f7f6300ef3cd834c493ce795a17e25
keeper_registry_wrapper2_0: ../../contracts/solc/v0.8.6/KeeperRegistry2_0.abi ../../contracts/solc/v0.8.6/KeeperRegistry2_0.bin c32dea7d5ef66b7c58ddc84ddf69aa44df1b3ae8601fbc271c95be4ff5853056
-keeper_registry_wrapper_2_1: ../../contracts/solc/v0.8.16/KeeperRegistry2_1.abi ../../contracts/solc/v0.8.16/KeeperRegistry2_1.bin 6406f37de79d3d2efa86fb961e1462b62a5a2fff4aeb408bbdb4bc7272d91638
+keeper_registry_wrapper_2_1: ../../contracts/solc/v0.8.16/KeeperRegistry2_1.abi ../../contracts/solc/v0.8.16/KeeperRegistry2_1.bin 604e4a0cd980c713929b523b999462a3aa0ed06f96ff563a4c8566cf59c8445b
keepers_vrf_consumer: ../../contracts/solc/v0.8.6/KeepersVRFConsumer.abi ../../contracts/solc/v0.8.6/KeepersVRFConsumer.bin fa75572e689c9e84705c63e8dbe1b7b8aa1a8fe82d66356c4873d024bb9166e8
log_emitter: ../../contracts/solc/v0.8.19/LogEmitter.abi ../../contracts/solc/v0.8.19/LogEmitter.bin 244ba13730c036de0b02beef4e3d9c9a96946ce353c27f366baecc7f5be5a6fd
-log_triggered_feed_lookup_wrapper: ../../contracts/solc/v0.8.16/LogTriggeredFeedLookup.abi ../../contracts/solc/v0.8.16/LogTriggeredFeedLookup.bin 9678fec51a491bf3f4bfeb582211bf8ab0328b58b2710e45b51be0dde1155933
-log_upkeep_counter_wrapper: ../../contracts/solc/v0.8.6/LogUpkeepCounter.abi ../../contracts/solc/v0.8.6/LogUpkeepCounter.bin 13d6543329f89d06cbf3901d7f9ecdc42acc1a84d8c61db291fcbfdbe1138eb1
-mercury_upkeep_wrapper: ../../contracts/solc/v0.8.16/MercuryUpkeep.abi ../../contracts/solc/v0.8.16/MercuryUpkeep.bin 27a33050249b6c7de7236772d7960f29c69e6f8167cc736409312d0e965508a3
+log_triggered_streams_lookup_wrapper: ../../contracts/solc/v0.8.16/LogTriggeredStreamsLookup.abi ../../contracts/solc/v0.8.16/LogTriggeredStreamsLookup.bin dfe5f8800251b464cd13f7ef966698ab7f0d8f6a5387520f09b602cfbf48f123
+log_upkeep_counter_wrapper: ../../contracts/solc/v0.8.6/LogUpkeepCounter.abi ../../contracts/solc/v0.8.6/LogUpkeepCounter.bin 42426bbb83f96dfbe55fc576d6c65020eaeed690e2289cf99b0c4aa810a5f4ec
mock_aggregator_proxy: ../../contracts/solc/v0.8.6/MockAggregatorProxy.abi ../../contracts/solc/v0.8.6/MockAggregatorProxy.bin b16c108f3dd384c342ddff5e94da7c0a8d39d1be5e3d8f2cf61ecc7f0e50ff42
mock_ethlink_aggregator_wrapper: ../../contracts/solc/v0.6/MockETHLINKAggregator.abi ../../contracts/solc/v0.6/MockETHLINKAggregator.bin 1c52c24f797b8482aa12b8251dcea1c072827bd5b3426b822621261944b99ca0
mock_gas_aggregator_wrapper: ../../contracts/solc/v0.6/MockGASAggregator.abi ../../contracts/solc/v0.6/MockGASAggregator.bin bacbb1ea4dc6beac0db8a13ca5c75e2fd61b903d70feea9b3b1c8b10fe8df4f3
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
@@ -59,42 +57,50 @@ solidity_vrf_request_id_v08: ../../contracts/solc/v0.8.6/VRFRequestIDBaseTestHel
solidity_vrf_v08_verifier_wrapper: ../../contracts/solc/v0.8.6/VRFTestHelper.abi ../../contracts/solc/v0.8.6/VRFTestHelper.bin f37f8b21a81c113085c6137835a2246db6ebda07da455c4f2b5c7ec60c725c3b
solidity_vrf_verifier_wrapper: ../../contracts/solc/v0.6/VRFTestHelper.abi ../../contracts/solc/v0.6/VRFTestHelper.bin 44c2b67d8d2990ab580453deb29d63508c6147a3dc49908a1db563bef06e6474
solidity_vrf_wrapper: ../../contracts/solc/v0.6/VRF.abi ../../contracts/solc/v0.6/VRF.bin 04ede5b83c06ba5b76ef99c081c72928007d8a7aaefcf21449a46a07cbd4bfc2
+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 a85d2899892aa9fd73fc99852ccba52c3983375113580673e6c5d655bfa79909
+trusted_blockhash_store: ../../contracts/solc/v0.8.6/TrustedBlockhashStore.abi ../../contracts/solc/v0.8.6/TrustedBlockhashStore.bin 34e71c5dc94f50e21f2bef76b0daa5821634655ca3722ce1204ce43cca1b2e19
type_and_version_interface_wrapper: ../../contracts/solc/v0.8.6/TypeAndVersionInterface.abi ../../contracts/solc/v0.8.6/TypeAndVersionInterface.bin bc9c3a6e73e3ebd5b58754df0deeb3b33f4bb404d5709bb904aed51d32f4b45e
upkeep_counter_wrapper: ../../contracts/solc/v0.7/UpkeepCounter.abi ../../contracts/solc/v0.7/UpkeepCounter.bin 901961ebf18906febc1c350f02da85c7ea1c2a68da70cfd94efa27c837a48663
upkeep_perform_counter_restrictive_wrapper: ../../contracts/solc/v0.7/UpkeepPerformCounterRestrictive.abi ../../contracts/solc/v0.7/UpkeepPerformCounterRestrictive.bin 8975a058fba528e16d8414dc6f13946d17a145fcbc66cf25a32449b6fe1ce878
upkeep_transcoder: ../../contracts/solc/v0.8.6/UpkeepTranscoder.abi ../../contracts/solc/v0.8.6/UpkeepTranscoder.bin 336c92a981597be26508455f81a908a0784a817b129a59686c5b2c4afcba730a
-verifiable_load_log_trigger_upkeep_wrapper: ../../contracts/solc/v0.8.16/VerifiableLoadLogTriggerUpkeep.abi ../../contracts/solc/v0.8.16/VerifiableLoadLogTriggerUpkeep.bin 5d46568c3c468563a6e2a01554f42a49d5d39a8d475616723b4a003f8754ebfc
-verifiable_load_mercury_upkeep_wrapper: ../../contracts/solc/v0.8.16/VerifiableLoadMercuryUpkeep.abi ../../contracts/solc/v0.8.16/VerifiableLoadMercuryUpkeep.bin 1aff150cf8dfebe9f1bd6e35fdb41a39bb3bcae576a1a2d79a87c92b01b8bbaa
-verifiable_load_upkeep_wrapper: ../../contracts/solc/v0.8.16/VerifiableLoadUpkeep.abi ../../contracts/solc/v0.8.16/VerifiableLoadUpkeep.bin 2512e1e5e748bed60bf5a930351acd41c0d355a83126b56bdbf36cc62c5364fd
+verifiable_load_log_trigger_upkeep_wrapper: ../../contracts/solc/v0.8.16/VerifiableLoadLogTriggerUpkeep.abi ../../contracts/solc/v0.8.16/VerifiableLoadLogTriggerUpkeep.bin fb674ba44c0e8f3b385cd10b2f7dea5cd07b5f38df08066747e8b1542e152557
+verifiable_load_streams_lookup_upkeep_wrapper: ../../contracts/solc/v0.8.16/VerifiableLoadStreamsLookupUpkeep.abi ../../contracts/solc/v0.8.16/VerifiableLoadStreamsLookupUpkeep.bin 785f68c44bfff070505eaa65e38a1af94046e5f9afc1189bcf2c8cfcd1102d66
+verifiable_load_upkeep_wrapper: ../../contracts/solc/v0.8.16/VerifiableLoadUpkeep.abi ../../contracts/solc/v0.8.16/VerifiableLoadUpkeep.bin a3e02c43756ea91e7ce4b81e48c11648f1d12f6663c236780147e41dfa36ebee
vrf_consumer_v2: ../../contracts/solc/v0.8.6/VRFConsumerV2.abi ../../contracts/solc/v0.8.6/VRFConsumerV2.bin 9ef258bf8e9f8d880fd229ceb145593d91e24fc89366baa0bf19169c5787d15f
vrf_consumer_v2_plus_upgradeable_example: ../../contracts/solc/v0.8.6/VRFConsumerV2PlusUpgradeableExample.abi ../../contracts/solc/v0.8.6/VRFConsumerV2PlusUpgradeableExample.bin 3155c611e4d6882e9324b6e975033b31356776ea8b031ca63d63da37589d583b
vrf_consumer_v2_upgradeable_example: ../../contracts/solc/v0.8.6/VRFConsumerV2UpgradeableExample.abi ../../contracts/solc/v0.8.6/VRFConsumerV2UpgradeableExample.bin f1790a9a2f2a04c730593e483459709cb89e897f8a19d7a3ac0cfe6a97265e6e
vrf_coordinator_mock: ../../contracts/solc/v0.8.6/VRFCoordinatorMock.abi ../../contracts/solc/v0.8.6/VRFCoordinatorMock.bin 5c495cf8df1f46d8736b9150cdf174cce358cb8352f60f0d5bb9581e23920501
-vrf_coordinator_v2: ../../contracts/solc/v0.8.6/VRFCoordinatorV2.abi ../../contracts/solc/v0.8.6/VRFCoordinatorV2.bin 75c87cf1624a401ac6303df9c8e04896aa8a53849e8b0c3d7340a9d089ef6d4b
-vrf_coordinator_v2_plus_v2_example: ../../contracts/solc/v0.8.6/VRFCoordinatorV2Plus_V2Example.abi ../../contracts/solc/v0.8.6/VRFCoordinatorV2Plus_V2Example.bin 02d0ec25e4f3d72f818e7ebc2b5f5949a94889ab0da091f0d3e7f5e4a20a0bb6
-vrf_coordinator_v2plus: ../../contracts/solc/v0.8.6/VRFCoordinatorV2Plus.abi ../../contracts/solc/v0.8.6/VRFCoordinatorV2Plus.bin 912a7372a66ed8fd3a38a5b0913c8dca668ddb5d0e2de9d5352a6fac9e60f92b
+vrf_coordinator_v2: ../../contracts/solc/v0.8.6/VRFCoordinatorV2.abi ../../contracts/solc/v0.8.6/VRFCoordinatorV2.bin 906e8155db28513c64c6f828d5b8eaf586b873de4369c77c0a19b6c5adf623c1
+vrf_coordinator_v2_5: ../../contracts/solc/v0.8.6/VRFCoordinatorV2_5.abi ../../contracts/solc/v0.8.6/VRFCoordinatorV2_5.bin b3b2ed681837264ec3f180d180ef6fb4d6f4f89136673268b57d540b0d682618
+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_malicious_consumer_v2: ../../contracts/solc/v0.8.6/VRFMaliciousConsumerV2.abi ../../contracts/solc/v0.8.6/VRFMaliciousConsumerV2.bin 9755fa8ffc7f5f0b337d5d413d77b0c9f6cd6f68c31727d49acdf9d4a51bc522
-vrf_malicious_consumer_v2_plus: ../../contracts/solc/v0.8.6/VRFMaliciousConsumerV2Plus.abi ../../contracts/solc/v0.8.6/VRFMaliciousConsumerV2Plus.bin 0c8349f763bf7240127d9d1f788fbd32cae7df22489efda26df02093e3dba97e
+vrf_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_ownerless_consumer_example: ../../contracts/solc/v0.8.6/VRFOwnerlessConsumerExample.abi ../../contracts/solc/v0.8.6/VRFOwnerlessConsumerExample.bin 9893b3805863273917fb282eed32274e32aa3d5c2a67a911510133e1218132be
vrf_single_consumer_example: ../../contracts/solc/v0.8.6/VRFSingleConsumerExample.abi ../../contracts/solc/v0.8.6/VRFSingleConsumerExample.bin 892a5ed35da2e933f7fd7835cd6f7f70ef3aa63a9c03a22c5b1fd026711b0ece
-vrf_v2plus_single_consumer: ../../contracts/solc/v0.8.6/VRFV2PlusSingleConsumerExample.abi ../../contracts/solc/v0.8.6/VRFV2PlusSingleConsumerExample.bin ae52552860445980ebe6a6f38277ef2857672d41fff67ea440f4f2e1447ebdeb
-vrf_v2plus_sub_owner: ../../contracts/solc/v0.8.6/VRFV2PlusExternalSubOwnerExample.abi ../../contracts/solc/v0.8.6/VRFV2PlusExternalSubOwnerExample.bin 066cf1afa0079777f95437410c20abaef19d2898bf0675aa184212d7af7474a6
+vrf_v2plus_load_test_with_metrics: ../../contracts/solc/v0.8.6/VRFV2PlusLoadTestWithMetrics.abi ../../contracts/solc/v0.8.6/VRFV2PlusLoadTestWithMetrics.bin 41a6c14753817ef6143716082754a30653a36b1902b596f695afc1b56940c0ae
+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 24850318f2af4ad0fab64bc42f0d815bc41388902eba190720e33e4c11f2f0b9
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_consumer_example: ../../contracts/solc/v0.8.6/VRFV2WrapperConsumerExample.abi ../../contracts/solc/v0.8.6/VRFV2WrapperConsumerExample.bin 3c5c9f1c501e697a7e77e959b48767e2a0bb1372393fd7686f7aaef3eb794231
vrfv2_wrapper_interface: ../../contracts/solc/v0.8.6/VRFV2WrapperInterface.abi ../../contracts/solc/v0.8.6/VRFV2WrapperInterface.bin ff8560169de171a68b360b7438d13863682d07040d984fd0fb096b2379421003
-vrfv2plus_client: ../../contracts/solc/v0.8.6/VRFV2PlusClient.abi ../../contracts/solc/v0.8.6/VRFV2PlusClient.bin 3ffbfa4971a7e5f46051a26b1722613f265d89ea1867547ecec58500953a9501
-vrfv2plus_consumer_example: ../../contracts/solc/v0.8.6/VRFV2PlusConsumerExample.abi ../../contracts/solc/v0.8.6/VRFV2PlusConsumerExample.bin 5cfc2977029d558dc6363a5d4953bb165d94932d248ea003dbb7ebf4b8b938bf
-vrfv2plus_reverting_example: ../../contracts/solc/v0.8.6/VRFV2PlusRevertingExample.abi ../../contracts/solc/v0.8.6/VRFV2PlusRevertingExample.bin 93e8af756ad31107224560baf3472445af56300a7ad11cb8304c77707a73e082
-vrfv2plus_wrapper: ../../contracts/solc/v0.8.6/VRFV2PlusWrapper.abi ../../contracts/solc/v0.8.6/VRFV2PlusWrapper.bin 06f705f62d5f94c8315dbd680c1eb9ad0e650bfa0292de8eb5757b2fd21edb04
+vrfv2plus_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 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 34743ac1dd5e2c9d210b2bd721ebd4dff3c29c548f05582538690dde07773589
+vrfv2plus_wrapper: ../../contracts/solc/v0.8.6/VRFV2PlusWrapper.abi ../../contracts/solc/v0.8.6/VRFV2PlusWrapper.bin 9099bc6d78c20ba502e2265d88825225649fa8a3402cb238f24f344ff239231a
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 8212afe0f981cd0820f46f1e2e98219ce5d1b1eeae502730dbb52b8638f9ad44
diff --git a/core/gethwrappers/go_generate.go b/core/gethwrappers/go_generate.go
index 6249e3385e0..6b1f952961a 100644
--- a/core/gethwrappers/go_generate.go
+++ b/core/gethwrappers/go_generate.go
@@ -48,10 +48,10 @@ package gethwrappers
//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.6/KeeperRegistryLogic2_0.abi ../../contracts/solc/v0.8.6/KeeperRegistryLogic2_0.bin KeeperRegistryLogic keeper_registry_logic2_0
//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.6/UpkeepTranscoder.abi ../../contracts/solc/v0.8.6/UpkeepTranscoder.bin UpkeepTranscoder upkeep_transcoder
//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.16/VerifiableLoadUpkeep.abi ../../contracts/solc/v0.8.16/VerifiableLoadUpkeep.bin VerifiableLoadUpkeep verifiable_load_upkeep_wrapper
-//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.16/VerifiableLoadMercuryUpkeep.abi ../../contracts/solc/v0.8.16/VerifiableLoadMercuryUpkeep.bin VerifiableLoadMercuryUpkeep verifiable_load_mercury_upkeep_wrapper
+//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.16/VerifiableLoadStreamsLookupUpkeep.abi ../../contracts/solc/v0.8.16/VerifiableLoadStreamsLookupUpkeep.bin VerifiableLoadStreamsLookupUpkeep verifiable_load_streams_lookup_upkeep_wrapper
//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.16/VerifiableLoadLogTriggerUpkeep.abi ../../contracts/solc/v0.8.16/VerifiableLoadLogTriggerUpkeep.bin VerifiableLoadLogTriggerUpkeep verifiable_load_log_trigger_upkeep_wrapper
-//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.16/MercuryUpkeep.abi ../../contracts/solc/v0.8.16/MercuryUpkeep.bin MercuryUpkeep mercury_upkeep_wrapper
-//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.16/FeedLookupCompatibleInterface.abi ../../contracts/solc/v0.8.16/FeedLookupCompatibleInterface.bin FeedLookupCompatibleInterface feed_lookup_compatible_interface
+//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.16/StreamsLookupUpkeep.abi ../../contracts/solc/v0.8.16/StreamsLookupUpkeep.bin StreamsLookupUpkeep streams_lookup_upkeep_wrapper
+//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.16/StreamsLookupCompatibleInterface.abi ../../contracts/solc/v0.8.16/StreamsLookupCompatibleInterface.bin StreamsLookupCompatibleInterface streams_lookup_compatible_interface
//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.16/AutomationConsumerBenchmark.abi ../../contracts/solc/v0.8.16/AutomationConsumerBenchmark.bin AutomationConsumerBenchmark automation_consumer_benchmark
//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.16/AutomationRegistrar2_1.abi ../../contracts/solc/v0.8.16/AutomationRegistrar2_1.bin AutomationRegistrar automation_registrar_wrapper2_1
//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.16/KeeperRegistry2_1.abi ../../contracts/solc/v0.8.16/KeeperRegistry2_1.bin KeeperRegistry keeper_registry_wrapper_2_1
@@ -62,7 +62,7 @@ package gethwrappers
//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.16/AutomationUtils2_1.abi ../../contracts/solc/v0.8.16/AutomationUtils2_1.bin AutomationUtils automation_utils_2_1
//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.16/AutomationForwarderLogic.abi ../../contracts/solc/v0.8.16/AutomationForwarderLogic.bin AutomationForwarderLogic automation_forwarder_logic
//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.6/LogUpkeepCounter.abi ../../contracts/solc/v0.8.6/LogUpkeepCounter.bin LogUpkeepCounter log_upkeep_counter_wrapper
-//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.16/LogTriggeredFeedLookup.abi ../../contracts/solc/v0.8.16/LogTriggeredFeedLookup.bin LogTriggeredFeedLookup log_triggered_feed_lookup_wrapper
+//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.16/LogTriggeredStreamsLookup.abi ../../contracts/solc/v0.8.16/LogTriggeredStreamsLookup.bin LogTriggeredStreamsLookup log_triggered_streams_lookup_wrapper
//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.16/DummyProtocol.abi ../../contracts/solc/v0.8.16/DummyProtocol.bin DummyProtocol dummy_protocol_wrapper
// v0.8.6 VRFConsumer
@@ -106,9 +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
@@ -118,6 +120,10 @@ package gethwrappers
//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.6/VRFConsumerV2PlusUpgradeableExample.abi ../../contracts/solc/v0.8.6/VRFConsumerV2PlusUpgradeableExample.bin VRFConsumerV2PlusUpgradeableExample vrf_consumer_v2_plus_upgradeable_example
//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.6/VRFV2PlusClient.abi ../../contracts/solc/v0.8.6/VRFV2PlusClient.bin VRFV2PlusClient vrfv2plus_client
//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.6/VRFCoordinatorV2Plus_V2Example.abi ../../contracts/solc/v0.8.6/VRFCoordinatorV2Plus_V2Example.bin VRFCoordinatorV2Plus_V2Example vrf_coordinator_v2_plus_v2_example
+//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
@@ -144,8 +150,8 @@ package gethwrappers
// 2. Generate events mock .sol files based on ABI of compiled contracts.
// 3. Compile events mock contracts. ./generation/compile_event_mock_contract.sh calls contracts/scripts/native_solc_compile_all_events_mock to compile events mock contracts.
// 4. Generate wrappers for events mock contracts.
-//go:generate go run ./generation/generate_events_mock/create_events_mock_contract.go ../../contracts/solc/v0.8.6/functions/0_0_0/FunctionsOracle.abi ../../contracts/src/v0.8/mocks/FunctionsOracleEventsMock.sol FunctionsOracleEventsMock
-//go:generate go run ./generation/generate_events_mock/create_events_mock_contract.go ../../contracts/solc/v0.8.6/functions/0_0_0/FunctionsBillingRegistry.abi ../../contracts/src/v0.8/mocks/FunctionsBillingRegistryEventsMock.sol FunctionsBillingRegistryEventsMock
+//go:generate go run ./generation/generate_events_mock/create_events_mock_contract.go ../../contracts/solc/v0.8.6/functions/v0_0_0/FunctionsOracle.abi ../../contracts/src/v0.8/mocks/FunctionsOracleEventsMock.sol FunctionsOracleEventsMock
+//go:generate go run ./generation/generate_events_mock/create_events_mock_contract.go ../../contracts/solc/v0.8.6/functions/v0_0_0/FunctionsBillingRegistry.abi ../../contracts/src/v0.8/mocks/FunctionsBillingRegistryEventsMock.sol FunctionsBillingRegistryEventsMock
//go:generate ./generation/compile_event_mock_contract.sh
//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.6/FunctionsOracleEventsMock.abi ../../contracts/solc/v0.8.6/FunctionsOracleEventsMock.bin FunctionsOracleEventsMock functions_oracle_events_mock
//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.6/FunctionsBillingRegistryEventsMock.abi ../../contracts/solc/v0.8.6/FunctionsBillingRegistryEventsMock.bin FunctionsBillingRegistryEventsMock functions_billing_registry_events_mock
diff --git a/core/gethwrappers/llo-feeds/generated/errored_verifier/errored_verifier.go b/core/gethwrappers/llo-feeds/generated/errored_verifier/errored_verifier.go
index d6a52b74fd1..846ebb197b8 100644
--- a/core/gethwrappers/llo-feeds/generated/errored_verifier/errored_verifier.go
+++ b/core/gethwrappers/llo-feeds/generated/errored_verifier/errored_verifier.go
@@ -30,12 +30,12 @@ var (
type CommonAddressAndWeight struct {
Addr common.Address
- Weight *big.Int
+ Weight uint64
}
var ErroredVerifierMetaData = &bind.MetaData{
- ABI: "[{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"activateConfig\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"activateFeed\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"deactivateConfig\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"deactivateFeed\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"weight\",\"type\":\"uint256\"}],\"internalType\":\"structCommon.AddressAndWeight[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"weight\",\"type\":\"uint256\"}],\"internalType\":\"structCommon.AddressAndWeight[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"name\":\"setConfigFromSource\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]",
- Bin: "0x608060405234801561001057600080fd5b50610bf9806100206000396000f3fe608060405234801561001057600080fd5b50600436106100be5760003560e01c806394d9598011610076578063b70d929d1161005b578063b70d929d146101a9578063ded6307c146101df578063e84f128e146101f257600080fd5b806394d95980146101885780639b103f131461019b57600080fd5b80633dd86430116100a75780633dd864301461014d57806352ba27d614610162578063564a0a7a1461017557600080fd5b806301ffc9a7146100c35780633d3ac1b51461012d575b600080fd5b6101186100d136600461059a565b7fffffffff00000000000000000000000000000000000000000000000000000000167f3d3ac1b5000000000000000000000000000000000000000000000000000000001490565b60405190151581526020015b60405180910390f35b61014061013b366004610741565b610228565b604051610124919061078f565b61016061015b3660046107fb565b610292565b005b6101606101703660046109b4565b6102f4565b6101606101833660046107fb565b610356565b610160610196366004610ab1565b6103b8565b610160610170366004610ad3565b6101bc6101b73660046107fb565b61041a565b604080519315158452602084019290925263ffffffff1690820152606001610124565b6101606101ed366004610ab1565b6104a9565b6102056102003660046107fb565b61050b565b6040805163ffffffff948516815293909216602084015290820152606001610124565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f4661696c656420746f207665726966790000000000000000000000000000000060448201526060906064015b60405180910390fd5b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4661696c656420746f20616374697661746520666565640000000000000000006044820152606401610289565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f4661696c656420746f2073657420636f6e6669670000000000000000000000006044820152606401610289565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f4661696c656420746f20646561637469766174652066656564000000000000006044820152606401610289565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4661696c656420746f206465616374697661746520636f6e66696700000000006044820152606401610289565b60008060006040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610289906020808252602c908201527f4661696c656420746f20676574206c617465737420636f6e666967206469676560408201527f737420616e642065706f63680000000000000000000000000000000000000000606082015260800190565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f4661696c656420746f20616374697661746520636f6e666967000000000000006044820152606401610289565b60008060006040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102899060208082526023908201527f4661696c656420746f20676574206c617465737420636f6e666967206465746160408201527f696c730000000000000000000000000000000000000000000000000000000000606082015260800190565b6000602082840312156105ac57600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146105dc57600080fd5b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715610635576106356105e3565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610682576106826105e3565b604052919050565b600082601f83011261069b57600080fd5b813567ffffffffffffffff8111156106b5576106b56105e3565b6106e660207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8401160161063b565b8181528460208386010111156106fb57600080fd5b816020850160208301376000918101602001919091529392505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461073c57600080fd5b919050565b6000806040838503121561075457600080fd5b823567ffffffffffffffff81111561076b57600080fd5b6107778582860161068a565b92505061078660208401610718565b90509250929050565b600060208083528351808285015260005b818110156107bc578581018301518582016040015282016107a0565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b60006020828403121561080d57600080fd5b5035919050565b600067ffffffffffffffff82111561082e5761082e6105e3565b5060051b60200190565b600082601f83011261084957600080fd5b8135602061085e61085983610814565b61063b565b82815260059290921b8401810191818101908684111561087d57600080fd5b8286015b8481101561089f5761089281610718565b8352918301918301610881565b509695505050505050565b600082601f8301126108bb57600080fd5b813560206108cb61085983610814565b82815260059290921b840181019181810190868411156108ea57600080fd5b8286015b8481101561089f57803583529183019183016108ee565b803560ff8116811461073c57600080fd5b803567ffffffffffffffff8116811461073c57600080fd5b600082601f83011261093f57600080fd5b8135602061094f61085983610814565b82815260069290921b8401810191818101908684111561096e57600080fd5b8286015b8481101561089f576040818903121561098b5760008081fd5b610993610612565b61099c82610718565b81528185013585820152835291830191604001610972565b600080600080600080600080610100898b0312156109d157600080fd5b88359750602089013567ffffffffffffffff808211156109f057600080fd5b6109fc8c838d01610838565b985060408b0135915080821115610a1257600080fd5b610a1e8c838d016108aa565b9750610a2c60608c01610905565b965060808b0135915080821115610a4257600080fd5b610a4e8c838d0161068a565b9550610a5c60a08c01610916565b945060c08b0135915080821115610a7257600080fd5b610a7e8c838d0161068a565b935060e08b0135915080821115610a9457600080fd5b50610aa18b828c0161092e565b9150509295985092959890939650565b60008060408385031215610ac457600080fd5b50508035926020909101359150565b6000806000806000806000806000806101408b8d031215610af357600080fd5b8a35995060208b01359850610b0a60408c01610718565b975060608b013567ffffffffffffffff80821115610b2757600080fd5b610b338e838f01610838565b985060808d0135915080821115610b4957600080fd5b610b558e838f016108aa565b9750610b6360a08e01610905565b965060c08d0135915080821115610b7957600080fd5b610b858e838f0161068a565b9550610b9360e08e01610916565b94506101008d0135915080821115610baa57600080fd5b610bb68e838f0161068a565b93506101208d0135915080821115610bcd57600080fd5b50610bda8d828e0161092e565b9150509295989b9194979a509295985056fea164736f6c6343000810000a",
+ ABI: "[{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"activateConfig\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"activateFeed\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"deactivateConfig\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"deactivateFeed\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"internalType\":\"structCommon.AddressAndWeight[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"},{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"internalType\":\"structCommon.AddressAndWeight[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"name\":\"setConfigFromSource\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]",
+ Bin: "0x608060405234801561001057600080fd5b50610c2e806100206000396000f3fe608060405234801561001057600080fd5b50600436106100be5760003560e01c8063b70d929d11610076578063e7db9c2a1161005b578063e7db9c2a146101d1578063e84f128e146101e4578063f01072211461021a57600080fd5b8063b70d929d14610188578063ded6307c146101be57600080fd5b80633dd86430116100a75780633dd864301461014d578063564a0a7a1461016257806394d959801461017557600080fd5b806301ffc9a7146100c35780633d3ac1b51461012d575b600080fd5b6101186100d136600461059a565b7fffffffff00000000000000000000000000000000000000000000000000000000167f3d3ac1b5000000000000000000000000000000000000000000000000000000001490565b60405190151581526020015b60405180910390f35b61014061013b366004610741565b610228565b604051610124919061078f565b61016061015b3660046107fb565b610292565b005b6101606101703660046107fb565b6102f4565b610160610183366004610814565b610356565b61019b6101963660046107fb565b6103b8565b604080519315158452602084019290925263ffffffff1690820152606001610124565b6101606101cc366004610814565b610447565b6101606101df3660046109f1565b6104a9565b6101f76101f23660046107fb565b61050b565b6040805163ffffffff948516815293909216602084015290820152606001610124565b6101606101df366004610b24565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f4661696c656420746f207665726966790000000000000000000000000000000060448201526060906064015b60405180910390fd5b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4661696c656420746f20616374697661746520666565640000000000000000006044820152606401610289565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f4661696c656420746f20646561637469766174652066656564000000000000006044820152606401610289565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f4661696c656420746f206465616374697661746520636f6e66696700000000006044820152606401610289565b60008060006040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610289906020808252602c908201527f4661696c656420746f20676574206c617465737420636f6e666967206469676560408201527f737420616e642065706f63680000000000000000000000000000000000000000606082015260800190565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f4661696c656420746f20616374697661746520636f6e666967000000000000006044820152606401610289565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f4661696c656420746f2073657420636f6e6669670000000000000000000000006044820152606401610289565b60008060006040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102899060208082526023908201527f4661696c656420746f20676574206c617465737420636f6e666967206465746160408201527f696c730000000000000000000000000000000000000000000000000000000000606082015260800190565b6000602082840312156105ac57600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146105dc57600080fd5b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715610635576106356105e3565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610682576106826105e3565b604052919050565b600082601f83011261069b57600080fd5b813567ffffffffffffffff8111156106b5576106b56105e3565b6106e660207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8401160161063b565b8181528460208386010111156106fb57600080fd5b816020850160208301376000918101602001919091529392505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461073c57600080fd5b919050565b6000806040838503121561075457600080fd5b823567ffffffffffffffff81111561076b57600080fd5b6107778582860161068a565b92505061078660208401610718565b90509250929050565b600060208083528351808285015260005b818110156107bc578581018301518582016040015282016107a0565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b60006020828403121561080d57600080fd5b5035919050565b6000806040838503121561082757600080fd5b50508035926020909101359150565b803563ffffffff8116811461073c57600080fd5b600067ffffffffffffffff821115610864576108646105e3565b5060051b60200190565b600082601f83011261087f57600080fd5b8135602061089461088f8361084a565b61063b565b82815260059290921b840181019181810190868411156108b357600080fd5b8286015b848110156108d5576108c881610718565b83529183019183016108b7565b509695505050505050565b600082601f8301126108f157600080fd5b8135602061090161088f8361084a565b82815260059290921b8401810191818101908684111561092057600080fd5b8286015b848110156108d55780358352918301918301610924565b803560ff8116811461073c57600080fd5b803567ffffffffffffffff8116811461073c57600080fd5b600082601f83011261097557600080fd5b8135602061098561088f8361084a565b82815260069290921b840181019181810190868411156109a457600080fd5b8286015b848110156108d557604081890312156109c15760008081fd5b6109c9610612565b6109d282610718565b81526109df85830161094c565b818601528352918301916040016109a8565b60008060008060008060008060008060006101608c8e031215610a1357600080fd5b8b359a5060208c01359950610a2a60408d01610718565b9850610a3860608d01610836565b975067ffffffffffffffff8060808e01351115610a5457600080fd5b610a648e60808f01358f0161086e565b97508060a08e01351115610a7757600080fd5b610a878e60a08f01358f016108e0565b9650610a9560c08e0161093b565b95508060e08e01351115610aa857600080fd5b610ab88e60e08f01358f0161068a565b9450610ac76101008e0161094c565b9350806101208e01351115610adb57600080fd5b610aec8e6101208f01358f0161068a565b9250806101408e01351115610b0057600080fd5b50610b128d6101408e01358e01610964565b90509295989b509295989b9093969950565b600080600080600080600080610100898b031215610b4157600080fd5b88359750602089013567ffffffffffffffff80821115610b6057600080fd5b610b6c8c838d0161086e565b985060408b0135915080821115610b8257600080fd5b610b8e8c838d016108e0565b9750610b9c60608c0161093b565b965060808b0135915080821115610bb257600080fd5b610bbe8c838d0161068a565b9550610bcc60a08c0161094c565b945060c08b0135915080821115610be257600080fd5b610bee8c838d0161068a565b935060e08b0135915080821115610c0457600080fd5b50610c118b828c01610964565b915050929598509295989093965056fea164736f6c6343000810000a",
}
var ErroredVerifierABI = ErroredVerifierMetaData.ABI
@@ -322,9 +322,9 @@ func (_ErroredVerifier *ErroredVerifierCallerSession) SetConfig(arg0 [32]byte, a
return _ErroredVerifier.Contract.SetConfig(&_ErroredVerifier.CallOpts, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
}
-func (_ErroredVerifier *ErroredVerifierCaller) SetConfigFromSource(opts *bind.CallOpts, arg0 [32]byte, arg1 *big.Int, arg2 common.Address, arg3 []common.Address, arg4 [][32]byte, arg5 uint8, arg6 []byte, arg7 uint64, arg8 []byte, arg9 []CommonAddressAndWeight) error {
+func (_ErroredVerifier *ErroredVerifierCaller) SetConfigFromSource(opts *bind.CallOpts, arg0 [32]byte, arg1 *big.Int, arg2 common.Address, arg3 uint32, arg4 []common.Address, arg5 [][32]byte, arg6 uint8, arg7 []byte, arg8 uint64, arg9 []byte, arg10 []CommonAddressAndWeight) error {
var out []interface{}
- err := _ErroredVerifier.contract.Call(opts, &out, "setConfigFromSource", arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
+ err := _ErroredVerifier.contract.Call(opts, &out, "setConfigFromSource", arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10)
if err != nil {
return err
@@ -334,12 +334,12 @@ func (_ErroredVerifier *ErroredVerifierCaller) SetConfigFromSource(opts *bind.Ca
}
-func (_ErroredVerifier *ErroredVerifierSession) SetConfigFromSource(arg0 [32]byte, arg1 *big.Int, arg2 common.Address, arg3 []common.Address, arg4 [][32]byte, arg5 uint8, arg6 []byte, arg7 uint64, arg8 []byte, arg9 []CommonAddressAndWeight) error {
- return _ErroredVerifier.Contract.SetConfigFromSource(&_ErroredVerifier.CallOpts, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
+func (_ErroredVerifier *ErroredVerifierSession) SetConfigFromSource(arg0 [32]byte, arg1 *big.Int, arg2 common.Address, arg3 uint32, arg4 []common.Address, arg5 [][32]byte, arg6 uint8, arg7 []byte, arg8 uint64, arg9 []byte, arg10 []CommonAddressAndWeight) error {
+ return _ErroredVerifier.Contract.SetConfigFromSource(&_ErroredVerifier.CallOpts, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10)
}
-func (_ErroredVerifier *ErroredVerifierCallerSession) SetConfigFromSource(arg0 [32]byte, arg1 *big.Int, arg2 common.Address, arg3 []common.Address, arg4 [][32]byte, arg5 uint8, arg6 []byte, arg7 uint64, arg8 []byte, arg9 []CommonAddressAndWeight) error {
- return _ErroredVerifier.Contract.SetConfigFromSource(&_ErroredVerifier.CallOpts, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
+func (_ErroredVerifier *ErroredVerifierCallerSession) SetConfigFromSource(arg0 [32]byte, arg1 *big.Int, arg2 common.Address, arg3 uint32, arg4 []common.Address, arg5 [][32]byte, arg6 uint8, arg7 []byte, arg8 uint64, arg9 []byte, arg10 []CommonAddressAndWeight) error {
+ return _ErroredVerifier.Contract.SetConfigFromSource(&_ErroredVerifier.CallOpts, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10)
}
func (_ErroredVerifier *ErroredVerifierCaller) SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) {
@@ -405,7 +405,7 @@ type ErroredVerifierInterface interface {
SetConfig(opts *bind.CallOpts, arg0 [32]byte, arg1 []common.Address, arg2 [][32]byte, arg3 uint8, arg4 []byte, arg5 uint64, arg6 []byte, arg7 []CommonAddressAndWeight) error
- SetConfigFromSource(opts *bind.CallOpts, arg0 [32]byte, arg1 *big.Int, arg2 common.Address, arg3 []common.Address, arg4 [][32]byte, arg5 uint8, arg6 []byte, arg7 uint64, arg8 []byte, arg9 []CommonAddressAndWeight) error
+ SetConfigFromSource(opts *bind.CallOpts, arg0 [32]byte, arg1 *big.Int, arg2 common.Address, arg3 uint32, arg4 []common.Address, arg5 [][32]byte, arg6 uint8, arg7 []byte, arg8 uint64, arg9 []byte, arg10 []CommonAddressAndWeight) error
SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error)
diff --git a/core/gethwrappers/llo-feeds/generated/fee_manager/fee_manager.go b/core/gethwrappers/llo-feeds/generated/fee_manager/fee_manager.go
index 31c0a0b1a06..666edd3385d 100644
--- a/core/gethwrappers/llo-feeds/generated/fee_manager/fee_manager.go
+++ b/core/gethwrappers/llo-feeds/generated/fee_manager/fee_manager.go
@@ -32,7 +32,7 @@ var (
type CommonAddressAndWeight struct {
Addr common.Address
- Weight *big.Int
+ Weight uint64
}
type CommonAsset struct {
@@ -40,13 +40,14 @@ type CommonAsset struct {
Amount *big.Int
}
-type IFeeManagerQuote struct {
- QuoteAddress common.Address
+type IRewardManagerFeePayment struct {
+ PoolId [32]byte
+ Amount *big.Int
}
var FeeManagerMetaData = &bind.MetaData{
- ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_linkAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_nativeAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_proxyAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_rewardManagerAddress\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"ExpiredReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDeposit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDiscount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidQuote\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSurcharge\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroDeficit\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"linkQuantity\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nativeQuantity\",\"type\":\"uint256\"}],\"name\":\"InsufficientLink\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"linkQuantity\",\"type\":\"uint256\"}],\"name\":\"LinkDeficitCleared\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newSurcharge\",\"type\":\"uint256\"}],\"name\":\"NativeSurchargeUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"subscriber\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"discount\",\"type\":\"uint256\"}],\"name\":\"SubscriberDiscountUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"adminAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"quantity\",\"type\":\"uint256\"}],\"name\":\"Withdraw\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"subscriber\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"quoteAddress\",\"type\":\"address\"}],\"internalType\":\"structIFeeManager.Quote\",\"name\":\"quote\",\"type\":\"tuple\"}],\"name\":\"getFeeAndReward\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structCommon.Asset\",\"name\":\"\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structCommon.Asset\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"linkAvailableForPayment\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"payLinkDeficit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"subscriber\",\"type\":\"address\"}],\"name\":\"processFee\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"s_linkDeficit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_nativeSurcharge\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"s_subscriberDiscounts\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"weight\",\"type\":\"uint256\"}],\"internalType\":\"structCommon.AddressAndWeight[]\",\"name\":\"rewardRecipientAndWeights\",\"type\":\"tuple[]\"}],\"name\":\"setFeeRecipients\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"surcharge\",\"type\":\"uint256\"}],\"name\":\"setNativeSurcharge\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"subscriber\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"discount\",\"type\":\"uint256\"}],\"name\":\"updateSubscriberDiscount\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"quantity\",\"type\":\"uint256\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]",
- Bin: "0x6101006040523480156200001257600080fd5b506040516200296d3803806200296d833981016040819052620000359162000288565b33806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf81620001c0565b5050506001600160a01b0384161580620000e057506001600160a01b038316155b80620000f357506001600160a01b038216155b806200010657506001600160a01b038116155b15620001255760405163e6c4247b60e01b815260040160405180910390fd5b6001600160a01b03848116608081905284821660a05283821660c05290821660e081905260405163095ea7b360e01b81526004810191909152600019602482015263095ea7b3906044016020604051808303816000875af11580156200018f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001b59190620002e5565b505050505062000310565b336001600160a01b038216036200021a5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b03811681146200028357600080fd5b919050565b600080600080608085870312156200029f57600080fd5b620002aa856200026b565b9350620002ba602086016200026b565b9250620002ca604086016200026b565b9150620002da606086016200026b565b905092959194509250565b600060208284031215620002f857600080fd5b815180151581146200030957600080fd5b9392505050565b60805160a05160c05160e0516125ba620003b36000396000818161047e01528181610bc00152818161101d01526112230152600081816103e70152610caa015260008181610716015281816107690152818161095d01528181610e1501528181610edc015261138f01526000818161073b015281816107c4015281816108e801528181610a9d01528181610f9c015281816110e3015261133801526125ba6000f3fe6080604052600436106100f35760003560e01c80638da5cb5b1161008a578063f1387e1611610059578063f1387e1614610339578063f237f1a81461034c578063f2fde38b1461036c578063f3fef3a31461038c57600080fd5b80638da5cb5b146102a1578063c541cbde146102d6578063d09dc33914610304578063e389d9a41461031957600080fd5b806369fd2b34116100c657806369fd2b341461020c5780636b54d8a61461022e57806379ba50971461024e57806387d6d8431461026357600080fd5b8063013f542b146100f857806301ffc9a714610138578063181f5a77146101aa57806332f5f746146101f6575b600080fd5b34801561010457600080fd5b50610125610113366004611bb8565b60036020526000908152604090205481565b6040519081526020015b60405180910390f35b34801561014457600080fd5b5061019a610153366004611bd1565b7fffffffff00000000000000000000000000000000000000000000000000000000167ff1387e16000000000000000000000000000000000000000000000000000000001490565b604051901515815260200161012f565b3480156101b657600080fd5b50604080518082018252601081527f4665654d616e6167657220302e302e31000000000000000000000000000000006020820152905161012f9190611c37565b34801561020257600080fd5b5061012560045481565b34801561021857600080fd5b5061022c610227366004611c88565b6103ac565b005b34801561023a57600080fd5b5061022c610249366004611bb8565b6104ee565b34801561025a57600080fd5b5061022c610573565b34801561026f57600080fd5b5061012561027e366004611d29565b600260209081526000938452604080852082529284528284209052825290205481565b3480156102ad57600080fd5b5060005460405173ffffffffffffffffffffffffffffffffffffffff909116815260200161012f565b3480156102e257600080fd5b506102f66102f1366004611ea0565b610675565b60405161012f929190611f41565b34801561031057600080fd5b50610125610a6c565b34801561032557600080fd5b5061022c610334366004611bb8565b610b22565b61022c610347366004611f95565b610c6f565b34801561035857600080fd5b5061022c61036736600461200d565b6112ec565b34801561037857600080fd5b5061022c610387366004612055565b611493565b34801561039857600080fd5b5061022c6103a7366004612072565b6114a7565b60005473ffffffffffffffffffffffffffffffffffffffff16331480159061040a57503373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614155b15610441576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f633b5f6e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063633b5f6e906104b79086908690869060040161209e565b600060405180830381600087803b1580156104d157600080fd5b505af11580156104e5573d6000803e3d6000fd5b50505050505050565b6104f66115af565b670de0b6b3a7640000811115610538576040517f05e8ac2900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60048190556040518181527fa320ddc8288125050af9b9b75fd872443f8c722e70b14fc8475dbd630a4916e19060200160405180910390a150565b60015473ffffffffffffffffffffffffffffffffffffffff1633146105f9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b604080518082019091526000808252602082015260408051808201909152600080825260208201526040805180820190915260008082526020820152604080518082019091526000808252602082015260006106d08761210d565b90507fffff00000000000000000000000000000000000000000000000000000000000080821690810161076757505073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811683527f00000000000000000000000000000000000000000000000000000000000000001681529092509050610a64565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16876000015173ffffffffffffffffffffffffffffffffffffffff161415801561081757507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16876000015173ffffffffffffffffffffffffffffffffffffffff1614155b1561084e576040517ff861803000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060008a8060200190518101906108679190612193565b77ffffffffffffffffffffffffffffffffffffffffffffffff92831699509116965063ffffffff16945050504283101591506108d19050576040517fb6c405f500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116808852602088018590528b519091160361094657855173ffffffffffffffffffffffffffffffffffffffff168752602080870151908801526109b6565b73ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001687526004546109b09061099890670de0b6b3a7640000612249565b6109a2908461225c565b670de0b6b3a7640000611632565b60208801525b73ffffffffffffffffffffffffffffffffffffffff808d16600090815260026020908152604080832089845282528083208e5190941683529281529190205490880151670de0b6b3a764000090610a0e90839061225c565b610a189190612299565b8860200151610a2791906122d4565b886020018181525050610a438188602001516109a2919061225c565b8760200151610a5291906122d4565b60208801525095975093955050505050505b935093915050565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015610af9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b1d91906122e7565b905090565b610b2a6115af565b60008181526003602052604081205490819003610b73576040517f03aad31200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008281526003602052604080822091909155517fefb03fe900000000000000000000000000000000000000000000000000000000815260048101839052306024820152604481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063efb03fe990606401600060405180830381600087803b158015610c1957600080fd5b505af1158015610c2d573d6000803e3d6000fd5b50505050817f843f0b103e50b42b08f9d30f12f961845a6d02623730872e24644899c0dd989582604051610c6391815260200190565b60405180910390a25050565b60005473ffffffffffffffffffffffffffffffffffffffff163314801590610ccd57503373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614155b15610d04576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff821603610d53576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610d618385018561236e565b915050600081610d709061210d565b6040805160208101909152600081529091507e010000000000000000000000000000000000000000000000000000000000007fffff000000000000000000000000000000000000000000000000000000000000831614610df7576000610dd88688018861243d565b9550505050505080806020019051810190610df39190612505565b9150505b600080610e05338685610675565b91509150600034600014610f69577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16836000015173ffffffffffffffffffffffffffffffffffffffff1614610e9c576040517fb2e532de00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3483602001511115610eda576040517fb2e532de00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663d0e30db084602001516040518263ffffffff1660e01b81526004016000604051808303818588803b158015610f4657600080fd5b505af1158015610f5a573d6000803e3d6000fd5b50505050508260200151340390505b6000610f75898b612533565b9050836020015160001461129557835173ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000081169116036110805760208301516040517fefb03fe90000000000000000000000000000000000000000000000000000000081526004810183905273ffffffffffffffffffffffffffffffffffffffff8a8116602483015260448201929092527f00000000000000000000000000000000000000000000000000000000000000009091169063efb03fe990606401600060405180830381600087803b15801561106357600080fd5b505af1158015611077573d6000803e3d6000fd5b50505050611295565b346000036110b557602084015184516110b59173ffffffffffffffffffffffffffffffffffffffff909116908a90309061166c565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa15801561113f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061116391906122e7565b836020015111156111e15782602001516003600083815260200190815260200160002060008282546111959190612249565b909155505060208381015185820151604080519283529282015282917feb6f22018570d97db6df12dc94f202b4e2b2888a6a5d4bd179422c91b29dcdf7910160405180910390a2611295565b60208301516040517fefb03fe90000000000000000000000000000000000000000000000000000000081526004810183905230602482015260448101919091527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063efb03fe990606401600060405180830381600087803b15801561127c57600080fd5b505af1158015611290573d6000803e3d6000fd5b505050505b81156112e05760405173ffffffffffffffffffffffffffffffffffffffff89169083156108fc029084906000818181858888f193505050501580156112de573d6000803e3d6000fd5b505b50505050505050505050565b6112f46115af565b670de0b6b3a7640000811115611336576040517f997ea36000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141580156113de57507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b15611415576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff84811660008181526002602090815260408083208884528252808320948716808452948252918290208590558151938452830184905285927f41eb9ccd292d5906dc1f0ec108bed3e2b966e3071e033df938f7215f6d30ca84910160405180910390a350505050565b61149b6115af565b6114a48161174e565b50565b6114af6115af565b73ffffffffffffffffffffffffffffffffffffffff8216611515576000805460405173ffffffffffffffffffffffffffffffffffffffff9091169183156108fc02918491818181858888f19350505050158015611510573d6000803e3d6000fd5b505050565b61155561153760005473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff84169083611843565b6040805133815273ffffffffffffffffffffffffffffffffffffffff841660208201529081018290527f9b1bfa7fa9ee420a16e124f794c35ac9f90472acc99140eb2f6447c714cad8eb9060600160405180910390a15050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611630576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016105f0565b565b6000821561166057816116466001856122d4565b6116509190612299565b61165b906001612249565b611663565b60005b90505b92915050565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526117489085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611899565b50505050565b3373ffffffffffffffffffffffffffffffffffffffff8216036117cd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016105f0565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526115109084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064016116c6565b60006118fb826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166119a59092919063ffffffff16565b8051909150156115105780806020019051810190611919919061256f565b611510576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016105f0565b60606119b484846000856119be565b90505b9392505050565b606082471015611a50576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016105f0565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611a799190612591565b60006040518083038185875af1925050503d8060008114611ab6576040519150601f19603f3d011682016040523d82523d6000602084013e611abb565b606091505b5091509150611acc87838387611ad9565b925050505b949350505050565b60608315611b6f578251600003611b685773ffffffffffffffffffffffffffffffffffffffff85163b611b68576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016105f0565b5081611ad1565b611ad18383815115611b845781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105f09190611c37565b600060208284031215611bca57600080fd5b5035919050565b600060208284031215611be357600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146119b757600080fd5b60005b83811015611c2e578181015183820152602001611c16565b50506000910152565b6020815260008251806020840152611c56816040850160208701611c13565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b600080600060408486031215611c9d57600080fd5b83359250602084013567ffffffffffffffff80821115611cbc57600080fd5b818601915086601f830112611cd057600080fd5b813581811115611cdf57600080fd5b8760208260061b8501011115611cf457600080fd5b6020830194508093505050509250925092565b73ffffffffffffffffffffffffffffffffffffffff811681146114a457600080fd5b600080600060608486031215611d3e57600080fd5b8335611d4981611d07565b9250602084013591506040840135611d6081611d07565b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516020810167ffffffffffffffff81118282101715611dbd57611dbd611d6b565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611e0a57611e0a611d6b565b604052919050565b600082601f830112611e2357600080fd5b813567ffffffffffffffff811115611e3d57611e3d611d6b565b611e6e60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601611dc3565b818152846020838601011115611e8357600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008385036060811215611eb657600080fd5b8435611ec181611d07565b9350602085013567ffffffffffffffff811115611edd57600080fd5b611ee987828801611e12565b93505060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc082011215611f1c57600080fd5b50611f25611d9a565b6040850135611f3381611d07565b815292959194509192509050565b825173ffffffffffffffffffffffffffffffffffffffff1681526020808401519082015260808101825173ffffffffffffffffffffffffffffffffffffffff166040830152602083015160608301526119b7565b600080600060408486031215611faa57600080fd5b833567ffffffffffffffff80821115611fc257600080fd5b818601915086601f830112611fd657600080fd5b813581811115611fe557600080fd5b876020828501011115611ff757600080fd5b60209283019550935050840135611d6081611d07565b6000806000806080858703121561202357600080fd5b843561202e81611d07565b935060208501359250604085013561204581611d07565b9396929550929360600135925050565b60006020828403121561206757600080fd5b81356119b781611d07565b6000806040838503121561208557600080fd5b823561209081611d07565b946020939093013593505050565b8381526040602080830182905282820184905260009190859060608501845b878110156121005783356120d081611d07565b73ffffffffffffffffffffffffffffffffffffffff168252838301358383015292840192908401906001016120bd565b5098975050505050505050565b8051602080830151919081101561214c577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8160200360031b1b821691505b50919050565b805163ffffffff8116811461216657600080fd5b919050565b805177ffffffffffffffffffffffffffffffffffffffffffffffff8116811461216657600080fd5b600080600080600080600060e0888a0312156121ae57600080fd5b875196506121be60208901612152565b95506121cc60408901612152565b945060608801518060170b81146121e257600080fd5b93506121f06080890161216b565b92506121fe60a0890161216b565b915061220c60c08901612152565b905092959891949750929550565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808201808211156116665761166661221a565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156122945761229461221a565b500290565b6000826122cf577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b818103818111156116665761166661221a565b6000602082840312156122f957600080fd5b5051919050565b600082601f83011261231157600080fd5b6040516060810181811067ffffffffffffffff8211171561233457612334611d6b565b60405280606084018581111561234957600080fd5b845b8181101561236357803583526020928301920161234b565b509195945050505050565b6000806080838503121561238157600080fd5b61238b8484612300565b9150606083013567ffffffffffffffff8111156123a757600080fd5b6123b385828601611e12565b9150509250929050565b600082601f8301126123ce57600080fd5b8135602067ffffffffffffffff8211156123ea576123ea611d6b565b8160051b6123f9828201611dc3565b928352848101820192828101908785111561241357600080fd5b83870192505b8483101561243257823582529183019190830190612419565b979650505050505050565b600080600080600080610100878903121561245757600080fd5b6124618888612300565b9550606087013567ffffffffffffffff8082111561247e57600080fd5b61248a8a838b01611e12565b965060808901359150808211156124a057600080fd5b6124ac8a838b016123bd565b955060a08901359150808211156124c257600080fd5b6124ce8a838b016123bd565b945060c0890135935060e08901359150808211156124eb57600080fd5b506124f889828a01611e12565b9150509295509295509295565b60006020828403121561251757600080fd5b61251f611d9a565b825161252a81611d07565b81529392505050565b80356020831015611666577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff602084900360031b1b1692915050565b60006020828403121561258157600080fd5b815180151581146119b757600080fd5b600082516125a3818460208701611c13565b919091019291505056fea164736f6c6343000810000a",
+ ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_linkAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_nativeAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_proxyAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_rewardManagerAddress\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"ExpiredReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDeposit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidDiscount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidQuote\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidReceivingAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSurcharge\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroDeficit\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"subscriber\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"structCommon.Asset\",\"name\":\"fee\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"structCommon.Asset\",\"name\":\"reward\",\"type\":\"tuple\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"appliedDiscount\",\"type\":\"uint256\"}],\"name\":\"DiscountApplied\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"poolId\",\"type\":\"bytes32\"},{\"internalType\":\"uint192\",\"name\":\"amount\",\"type\":\"uint192\"}],\"indexed\":false,\"internalType\":\"structIRewardManager.FeePayment[]\",\"name\":\"rewards\",\"type\":\"tuple[]\"}],\"name\":\"InsufficientLink\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"linkQuantity\",\"type\":\"uint256\"}],\"name\":\"LinkDeficitCleared\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"newSurcharge\",\"type\":\"uint64\"}],\"name\":\"NativeSurchargeUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"subscriber\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"discount\",\"type\":\"uint64\"}],\"name\":\"SubscriberDiscountUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"adminAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint192\",\"name\":\"quantity\",\"type\":\"uint192\"}],\"name\":\"Withdraw\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"subscriber\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"quoteAddress\",\"type\":\"address\"}],\"name\":\"getFeeAndReward\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structCommon.Asset\",\"name\":\"\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structCommon.Asset\",\"name\":\"\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_linkAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_nativeAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_proxyAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_rewardManager\",\"outputs\":[{\"internalType\":\"contractIRewardManager\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"linkAvailableForPayment\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"payLinkDeficit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"parameterPayload\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"subscriber\",\"type\":\"address\"}],\"name\":\"processFee\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes[]\",\"name\":\"payloads\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"parameterPayload\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"subscriber\",\"type\":\"address\"}],\"name\":\"processFeeBulk\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"s_linkDeficit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_nativeSurcharge\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"s_subscriberDiscounts\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"internalType\":\"structCommon.AddressAndWeight[]\",\"name\":\"rewardRecipientAndWeights\",\"type\":\"tuple[]\"}],\"name\":\"setFeeRecipients\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"surcharge\",\"type\":\"uint64\"}],\"name\":\"setNativeSurcharge\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"subscriber\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"discount\",\"type\":\"uint64\"}],\"name\":\"updateSubscriberDiscount\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"assetAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint192\",\"name\":\"quantity\",\"type\":\"uint192\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]",
+ Bin: "0x6101006040523480156200001257600080fd5b506040516200349938038062003499833981016040819052620000359162000288565b33806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf81620001c0565b5050506001600160a01b0384161580620000e057506001600160a01b038316155b80620000f357506001600160a01b038216155b806200010657506001600160a01b038116155b15620001255760405163e6c4247b60e01b815260040160405180910390fd5b6001600160a01b03848116608081905284821660a05283821660c05290821660e081905260405163095ea7b360e01b81526004810191909152600019602482015263095ea7b3906044016020604051808303816000875af11580156200018f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001b59190620002e5565b505050505062000310565b336001600160a01b038216036200021a5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b03811681146200028357600080fd5b919050565b600080600080608085870312156200029f57600080fd5b620002aa856200026b565b9350620002ba602086016200026b565b9250620002ca604086016200026b565b9150620002da606086016200026b565b905092959194509250565b600060208284031215620002f857600080fd5b815180151581146200030957600080fd5b9392505050565b60805160a05160c05160e0516130a7620003f26000396000818161027501528181611462015281816115f001528181611e0b0152612059015260008181610335015281816107fb01528181610db601526115360152600081816102ee01528181610bd901528181610fd30152818161102a015281816112d701528181611d310152611dda0152600081816104ba0152818161097601528181610b8201528181610d1901528181610ec201528181610ff801528181611081015281816111c60152818161123301528181611273015281816119ac0152611ecc01526130a76000f3fe60806040526004361061016a5760003560e01c806379ba5097116100cb578063dba45fe01161007f578063ea4b861b11610059578063ea4b861b146104a8578063f2fde38b146104dc578063f65df962146104fc57600080fd5b8063dba45fe01461040a578063e03dab1a1461041d578063e389d9a41461048857600080fd5b80638da5cb5b116100b05780638da5cb5b146103aa578063ce7817d1146103d5578063d09dc339146103f557600080fd5b806379ba50971461035757806387d6d8431461036c57600080fd5b80633aa5ac0711610122578063638786681161010757806363878668146102dc5780636c2f1a17146103105780636d1342cb1461032357600080fd5b80633aa5ac071461026357806350538094146102bc57600080fd5b8063181f5a7711610153578063181f5a77146101df5780631d4d84a21461022b57806332f5f7461461024d57600080fd5b8063013f542b1461016f57806301ffc9a7146101af575b600080fd5b34801561017b57600080fd5b5061019c61018a36600461265b565b60036020526000908152604090205481565b6040519081526020015b60405180910390f35b3480156101bb57600080fd5b506101cf6101ca366004612674565b61051c565b60405190151581526020016101a6565b3480156101eb57600080fd5b50604080518082018252601081527f4665654d616e6167657220322e302e3000000000000000000000000000000000602082015290516101a691906126da565b34801561023757600080fd5b5061024b610246366004612783565b6105b5565b005b34801561025957600080fd5b5061019c60045481565b34801561026f57600080fd5b506102977f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101a6565b3480156102c857600080fd5b5061024b6102d73660046127e6565b610749565b3480156102e857600080fd5b506102977f000000000000000000000000000000000000000000000000000000000000000081565b61024b61031e36600461284a565b6107e3565b34801561032f57600080fd5b506102977f000000000000000000000000000000000000000000000000000000000000000081565b34801561036357600080fd5b5061024b610a2a565b34801561037857600080fd5b5061019c6103873660046128f9565b600260209081526000938452604080852082529284528284209052825290205481565b3480156103b657600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff16610297565b3480156103e157600080fd5b5061024b6103f0366004612930565b610b2c565b34801561040157600080fd5b5061019c610ce8565b61024b610418366004612981565b610d9e565b34801561042957600080fd5b5061043d610438366004612adf565b610f3a565b60408051845173ffffffffffffffffffffffffffffffffffffffff9081168252602095860151868301528451169181019190915292909101516060830152608082015260a0016101a6565b34801561049457600080fd5b5061024b6104a336600461265b565b611339565b3480156104b457600080fd5b506102977f000000000000000000000000000000000000000000000000000000000000000081565b3480156104e857600080fd5b5061024b6104f7366004612b38565b61150a565b34801561050857600080fd5b5061024b610517366004612b55565b61151e565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fdba45fe00000000000000000000000000000000000000000000000000000000014806105af57507fffffffff0000000000000000000000000000000000000000000000000000000082167f6c2f1a1700000000000000000000000000000000000000000000000000000000145b92915050565b6105bd611660565b73ffffffffffffffffffffffffffffffffffffffff83166106925760008273ffffffffffffffffffffffffffffffffffffffff168277ffffffffffffffffffffffffffffffffffffffffffffffff1660405160006040518083038185875af1925050503d806000811461064c576040519150601f19603f3d011682016040523d82523d6000602084013e610651565b606091505b505090508061068c576040517fef2af20100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050565b6106cd73ffffffffffffffffffffffffffffffffffffffff84168377ffffffffffffffffffffffffffffffffffffffffffffffff84166116e3565b6040805133815273ffffffffffffffffffffffffffffffffffffffff848116602083015285168183015277ffffffffffffffffffffffffffffffffffffffffffffffff8316606082015290517f7ff78a71698bdb18dcca96f52ab25e0a1b146fb6a49adf8e6845299e49021f299181900360800190a15b505050565b610751611660565b670de0b6b3a764000067ffffffffffffffff8216111561079d576040517f05e8ac2900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff811660048190556040519081527f08f7c0d17932ddb8523bc06754d42ff19ebc77d76a8b9bfde02c28ab1ed3d6399060200160405180910390a150565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610852576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008467ffffffffffffffff81111561086d5761086d612a05565b6040519080825280602002602001820160405280156108a657816020015b6108936125ce565b81526020019060019003908161088b5790505b5090506000806000805b888110156109f15760008060006108ec8d8d868181106108d2576108d2612bd4565b90506020028101906108e49190612c03565b8d8d8d6117b7565b92509250925082602001516000146109dd5760405180608001604052808e8e8781811061091b5761091b612bd4565b905060200281019061092d9190612c03565b61093691612c68565b81526020018481526020018381526020018281525088868061095790612cd3565b97508151811061096957610969612bd4565b60200260200101819052507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16836000015173ffffffffffffffffffffffffffffffffffffffff16036109d6578660010196506109dd565b8560010195505b505050806109ea90612cd3565b90506108b0565b50821515806109ff57508115155b15610a1557610a10858585856118c7565b610a1f565b610a1f85346120db565b505050505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610ab0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610b34611660565b670de0b6b3a764000067ffffffffffffffff82161115610b80576040517f997ea36000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614158015610c2857507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b15610c5f576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff848116600081815260026020908152604080832088845282528083209487168084529482529182902067ffffffffffffffff86169081905582519485529084015285927f5eba5a8afa39780f0f99b6cbeb95f3da6a7040ca00abd46bdc91a0a060134139910160405180910390a350505050565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015610d75573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d999190612d0b565b905090565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610e0d576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000806000610e1f88888888886117b7565b9250925092508260200151600003610e4357610e3b84346120db565b505050610f33565b604080516001808252818301909252600091816020015b610e626125ce565b815260200190600190039081610e5a575050604080516080810190915290915080610e8d8a8c612c68565b81526020018581526020018481526020018381525081600081518110610eb557610eb5612bd4565b60200260200101819052507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16846000015173ffffffffffffffffffffffffffffffffffffffff1603610f2557610a108582600160006118c7565b610a1f8582600060016118c7565b5050505050565b6040805180820182526000808252602080830182905283518085018552828152808201839052845180860186528381528083018490528551808701909652838652918501839052929382610f8d88612d24565b90507fffff00000000000000000000000000000000000000000000000000000000000080821690810161102857505073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811683527f0000000000000000000000000000000000000000000000000000000000000000168152909350915060009050611330565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff16141580156110d057507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff1614155b15611107576040517ff861803000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008060008b8060200190518101906111209190612d7d565b77ffffffffffffffffffffffffffffffffffffffffffffffff91821698509116955063ffffffff1693505050428210159050611188576040517fb6c405f500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff808e16600090815260026020908152604080832089845282528083208f851684529091529020547f000000000000000000000000000000000000000000000000000000000000000090911687526112176111ff82670de0b6b3a7640000612def565b6112099086612e02565b670de0b6b3a7640000612128565b602088015273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116908d16036112a45773ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016885260208088015190890152611321565b6004546000906112c0906111ff90670de0b6b3a7640000612e3f565b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168a52905061131a61131083670de0b6b3a7640000612def565b6112099083612e02565b60208a0152505b96995094975094955050505050505b93509350939050565b611341611660565b6000818152600360205260408120549081900361138a576040517f03aad31200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828152600360205260408082208290558051600180825281830190925290816020015b60408051808201909152600080825260208201528152602001906001900390816113af57905050905060405180604001604052808481526020018377ffffffffffffffffffffffffffffffffffffffffffffffff168152508160008151811061141a5761141a612bd4565b60209081029190910101526040517fb0d9fa1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063b0d9fa19906114999084903090600401612eb2565b600060405180830381600087803b1580156114b357600080fd5b505af11580156114c7573d6000803e3d6000fd5b50505050827f843f0b103e50b42b08f9d30f12f961845a6d02623730872e24644899c0dd9895836040516114fd91815260200190565b60405180910390a2505050565b611512611660565b61151b81612160565b50565b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161480159061157c575060005473ffffffffffffffffffffffffffffffffffffffff163314155b156115b3576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f14060f2300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906314060f239061162990869086908690600401612eea565b600060405180830381600087803b15801561164357600080fd5b505af1158015611657573d6000803e3d6000fd5b50505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146116e1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610aa7565b565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526107449084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152612255565b6040805180820190915260008082526020820152604080518082019091526000808252602082015260003073ffffffffffffffffffffffffffffffffffffffff851603611830576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061183e888a018a612f6a565b91505060008161184d90612d24565b905060007e010000000000000000000000000000000000000000000000000000000000007fffff0000000000000000000000000000000000000000000000000000000000008316146118a8576118a5888a018a612b38565b90505b6118b3878483610f3a565b955095509550505050955095509592505050565b60008267ffffffffffffffff8111156118e2576118e2612a05565b60405190808252806020026020018201604052801561192757816020015b60408051808201909152600080825260208201528152602001906001900390816119005790505b50905060008267ffffffffffffffff81111561194557611945612a05565b60405190808252806020026020018201604052801561198a57816020015b60408051808201909152600080825260208201528152602001906001900390816119635790505b50905060008080808061199d888a612e3f565b905060005b81811015611cec577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168b82815181106119f3576119f3612bd4565b6020026020010151602001516000015173ffffffffffffffffffffffffffffffffffffffff1603611ab95760405180604001604052808c8381518110611a3b57611a3b612bd4565b60200260200101516000015181526020018c8381518110611a5e57611a5e612bd4565b6020026020010151604001516020015177ffffffffffffffffffffffffffffffffffffffffffffffff16815250888580611a9790612cd3565b965081518110611aa957611aa9612bd4565b6020026020010181905250611bae565b60405180604001604052808c8381518110611ad657611ad6612bd4565b60200260200101516000015181526020018c8381518110611af957611af9612bd4565b6020026020010151604001516020015177ffffffffffffffffffffffffffffffffffffffffffffffff16815250878480611b3290612cd3565b955081518110611b4457611b44612bd4565b60200260200101819052508a8181518110611b6157611b61612bd4565b6020026020010151602001516020015186611b7c9190612e3f565b95508a8181518110611b9057611b90612bd4565b6020026020010151604001516020015185611bab9190612e3f565b94505b8a8181518110611bc057611bc0612bd4565b602002602001015160600151600014611cdc578b73ffffffffffffffffffffffffffffffffffffffff168b8281518110611bfc57611bfc612bd4565b6020026020010151600001517f88b15eb682210089cddf967648e2cb2a4535aeadc8f8f36050922e33c04e71258d8481518110611c3b57611c3b612bd4565b6020026020010151602001518e8581518110611c5957611c59612bd4565b6020026020010151604001518f8681518110611c7757611c77612bd4565b602002602001015160600151604051611cd393929190835173ffffffffffffffffffffffffffffffffffffffff908116825260209485015185830152835116604082015291909201516060820152608081019190915260a00190565b60405180910390a35b611ce581612cd3565b90506119a2565b5060003415611dba5734861115611d2f576040517fb2e532de00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0876040518263ffffffff1660e01b81526004016000604051808303818588803b158015611d9757600080fd5b505af1158015611dab573d6000803e3d6000fd5b50505050508534039050611e02565b8515611e0257611e0273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168d3089612361565b875115611e97577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b0d9fa19898e6040518363ffffffff1660e01b8152600401611e64929190612eb2565b600060405180830381600087803b158015611e7e57600080fd5b505af1158015611e92573d6000803e3d6000fd5b505050505b8651156120c3576040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015611f28573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f4c9190612d0b565b85111561201c5760005b8751811015611fdf57878181518110611f7157611f71612bd4565b60200260200101516020015177ffffffffffffffffffffffffffffffffffffffffffffffff16600360008a8481518110611fad57611fad612bd4565b60209081029190910181015151825281019190915260400160002080549091019055611fd881612cd3565b9050611f56565b507ff52e5907b69d97c33392936c12d78b494463b78c5b72df50b4c497eee5720b678760405161200f919061300e565b60405180910390a16120c3565b6040517fb0d9fa1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063b0d9fa1990612090908a903090600401612eb2565b600060405180830381600087803b1580156120aa57600080fd5b505af11580156120be573d6000803e3d6000fd5b505050505b6120cd8c826120db565b505050505050505050505050565b80156121245760405173ffffffffffffffffffffffffffffffffffffffff83169082156108fc029083906000818181858888f19350505050158015610744573d6000803e3d6000fd5b5050565b60008215612156578161213c600185612def565b6121469190613021565b612151906001612e3f565b612159565b60005b9392505050565b3373ffffffffffffffffffffffffffffffffffffffff8216036121df576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610aa7565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60006122b7826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166123bf9092919063ffffffff16565b80519091501561074457808060200190518101906122d5919061305c565b610744576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610aa7565b60405173ffffffffffffffffffffffffffffffffffffffff8085166024830152831660448201526064810182905261068c9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401611735565b60606123ce84846000856123d6565b949350505050565b606082471015612468576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610aa7565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051612491919061307e565b60006040518083038185875af1925050503d80600081146124ce576040519150601f19603f3d011682016040523d82523d6000602084013e6124d3565b606091505b50915091506124e4878383876124ef565b979650505050505050565b6060831561258557825160000361257e5773ffffffffffffffffffffffffffffffffffffffff85163b61257e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610aa7565b50816123ce565b6123ce838381511561259a5781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aa791906126da565b6040518060800160405280600080191681526020016126166040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600081525090565b815260200161264e6040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600081525090565b8152602001600081525090565b60006020828403121561266d57600080fd5b5035919050565b60006020828403121561268657600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461215957600080fd5b60005b838110156126d15781810151838201526020016126b9565b50506000910152565b60208152600082518060208401526126f98160408501602087016126b6565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b73ffffffffffffffffffffffffffffffffffffffff8116811461151b57600080fd5b80356127588161272b565b919050565b77ffffffffffffffffffffffffffffffffffffffffffffffff8116811461151b57600080fd5b60008060006060848603121561279857600080fd5b83356127a38161272b565b925060208401356127b38161272b565b915060408401356127c38161275d565b809150509250925092565b803567ffffffffffffffff8116811461275857600080fd5b6000602082840312156127f857600080fd5b612159826127ce565b60008083601f84011261281357600080fd5b50813567ffffffffffffffff81111561282b57600080fd5b60208301915083602082850101111561284357600080fd5b9250929050565b60008060008060006060868803121561286257600080fd5b853567ffffffffffffffff8082111561287a57600080fd5b818801915088601f83011261288e57600080fd5b81358181111561289d57600080fd5b8960208260051b85010111156128b257600080fd5b6020928301975095509087013590808211156128cd57600080fd5b506128da88828901612801565b90945092506128ed90506040870161274d565b90509295509295909350565b60008060006060848603121561290e57600080fd5b83356129198161272b565b92506020840135915060408401356127c38161272b565b6000806000806080858703121561294657600080fd5b84356129518161272b565b93506020850135925060408501356129688161272b565b9150612976606086016127ce565b905092959194509250565b60008060008060006060868803121561299957600080fd5b853567ffffffffffffffff808211156129b157600080fd5b6129bd89838a01612801565b909750955060208801359150808211156129d657600080fd5b506129e388828901612801565b90945092505060408601356129f78161272b565b809150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112612a4557600080fd5b813567ffffffffffffffff80821115612a6057612a60612a05565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715612aa657612aa6612a05565b81604052838152866020858801011115612abf57600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600060608486031215612af457600080fd5b8335612aff8161272b565b9250602084013567ffffffffffffffff811115612b1b57600080fd5b612b2786828701612a34565b92505060408401356127c38161272b565b600060208284031215612b4a57600080fd5b81356121598161272b565b600080600060408486031215612b6a57600080fd5b83359250602084013567ffffffffffffffff80821115612b8957600080fd5b818601915086601f830112612b9d57600080fd5b813581811115612bac57600080fd5b8760208260061b8501011115612bc157600080fd5b6020830194508093505050509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112612c3857600080fd5b83018035915067ffffffffffffffff821115612c5357600080fd5b60200191503681900382131561284357600080fd5b803560208310156105af577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff602084900360031b1b1692915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612d0457612d04612ca4565b5060010190565b600060208284031215612d1d57600080fd5b5051919050565b80516020808301519190811015612d63577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8160200360031b1b821691505b50919050565b805163ffffffff8116811461275857600080fd5b60008060008060008060c08789031215612d9657600080fd5b86519550612da660208801612d69565b9450612db460408801612d69565b93506060870151612dc48161275d565b6080880151909350612dd58161275d565b9150612de360a08801612d69565b90509295509295509295565b818103818111156105af576105af612ca4565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615612e3a57612e3a612ca4565b500290565b808201808211156105af576105af612ca4565b600081518084526020808501945080840160005b83811015612ea75781518051885283015177ffffffffffffffffffffffffffffffffffffffffffffffff168388015260409096019590820190600101612e66565b509495945050505050565b604081526000612ec56040830185612e52565b905073ffffffffffffffffffffffffffffffffffffffff831660208301529392505050565b8381526040602080830182905282820184905260009190859060608501845b87811015612f5d578335612f1c8161272b565b73ffffffffffffffffffffffffffffffffffffffff16825267ffffffffffffffff612f488585016127ce565b16828401529284019290840190600101612f09565b5098975050505050505050565b60008060808385031215612f7d57600080fd5b83601f840112612f8c57600080fd5b6040516060810167ffffffffffffffff8282108183111715612fb057612fb0612a05565b816040528291506060860187811115612fc857600080fd5b865b81811015612fe2578035845260209384019301612fca565b5092945091359180831115612ff657600080fd5b505061300485828601612a34565b9150509250929050565b6020815260006121596020830184612e52565b600082613057577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60006020828403121561306e57600080fd5b8151801515811461215957600080fd5b600082516130908184602087016126b6565b919091019291505056fea164736f6c6343000810000a",
}
var FeeManagerABI = FeeManagerMetaData.ABI
@@ -185,27 +186,116 @@ func (_FeeManager *FeeManagerTransactorRaw) Transact(opts *bind.TransactOpts, me
return _FeeManager.Contract.contract.Transact(opts, method, params...)
}
-func (_FeeManager *FeeManagerCaller) GetFeeAndReward(opts *bind.CallOpts, subscriber common.Address, report []byte, quote IFeeManagerQuote) (CommonAsset, CommonAsset, error) {
+func (_FeeManager *FeeManagerCaller) GetFeeAndReward(opts *bind.CallOpts, subscriber common.Address, report []byte, quoteAddress common.Address) (CommonAsset, CommonAsset, *big.Int, error) {
var out []interface{}
- err := _FeeManager.contract.Call(opts, &out, "getFeeAndReward", subscriber, report, quote)
+ err := _FeeManager.contract.Call(opts, &out, "getFeeAndReward", subscriber, report, quoteAddress)
if err != nil {
- return *new(CommonAsset), *new(CommonAsset), err
+ return *new(CommonAsset), *new(CommonAsset), *new(*big.Int), err
}
out0 := *abi.ConvertType(out[0], new(CommonAsset)).(*CommonAsset)
out1 := *abi.ConvertType(out[1], new(CommonAsset)).(*CommonAsset)
+ out2 := *abi.ConvertType(out[2], new(*big.Int)).(**big.Int)
- return out0, out1, err
+ return out0, out1, out2, err
}
-func (_FeeManager *FeeManagerSession) GetFeeAndReward(subscriber common.Address, report []byte, quote IFeeManagerQuote) (CommonAsset, CommonAsset, error) {
- return _FeeManager.Contract.GetFeeAndReward(&_FeeManager.CallOpts, subscriber, report, quote)
+func (_FeeManager *FeeManagerSession) GetFeeAndReward(subscriber common.Address, report []byte, quoteAddress common.Address) (CommonAsset, CommonAsset, *big.Int, error) {
+ return _FeeManager.Contract.GetFeeAndReward(&_FeeManager.CallOpts, subscriber, report, quoteAddress)
}
-func (_FeeManager *FeeManagerCallerSession) GetFeeAndReward(subscriber common.Address, report []byte, quote IFeeManagerQuote) (CommonAsset, CommonAsset, error) {
- return _FeeManager.Contract.GetFeeAndReward(&_FeeManager.CallOpts, subscriber, report, quote)
+func (_FeeManager *FeeManagerCallerSession) GetFeeAndReward(subscriber common.Address, report []byte, quoteAddress common.Address) (CommonAsset, CommonAsset, *big.Int, error) {
+ return _FeeManager.Contract.GetFeeAndReward(&_FeeManager.CallOpts, subscriber, report, quoteAddress)
+}
+
+func (_FeeManager *FeeManagerCaller) ILinkAddress(opts *bind.CallOpts) (common.Address, error) {
+ var out []interface{}
+ err := _FeeManager.contract.Call(opts, &out, "i_linkAddress")
+
+ if err != nil {
+ return *new(common.Address), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address)
+
+ return out0, err
+
+}
+
+func (_FeeManager *FeeManagerSession) ILinkAddress() (common.Address, error) {
+ return _FeeManager.Contract.ILinkAddress(&_FeeManager.CallOpts)
+}
+
+func (_FeeManager *FeeManagerCallerSession) ILinkAddress() (common.Address, error) {
+ return _FeeManager.Contract.ILinkAddress(&_FeeManager.CallOpts)
+}
+
+func (_FeeManager *FeeManagerCaller) INativeAddress(opts *bind.CallOpts) (common.Address, error) {
+ var out []interface{}
+ err := _FeeManager.contract.Call(opts, &out, "i_nativeAddress")
+
+ if err != nil {
+ return *new(common.Address), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address)
+
+ return out0, err
+
+}
+
+func (_FeeManager *FeeManagerSession) INativeAddress() (common.Address, error) {
+ return _FeeManager.Contract.INativeAddress(&_FeeManager.CallOpts)
+}
+
+func (_FeeManager *FeeManagerCallerSession) INativeAddress() (common.Address, error) {
+ return _FeeManager.Contract.INativeAddress(&_FeeManager.CallOpts)
+}
+
+func (_FeeManager *FeeManagerCaller) IProxyAddress(opts *bind.CallOpts) (common.Address, error) {
+ var out []interface{}
+ err := _FeeManager.contract.Call(opts, &out, "i_proxyAddress")
+
+ if err != nil {
+ return *new(common.Address), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address)
+
+ return out0, err
+
+}
+
+func (_FeeManager *FeeManagerSession) IProxyAddress() (common.Address, error) {
+ return _FeeManager.Contract.IProxyAddress(&_FeeManager.CallOpts)
+}
+
+func (_FeeManager *FeeManagerCallerSession) IProxyAddress() (common.Address, error) {
+ return _FeeManager.Contract.IProxyAddress(&_FeeManager.CallOpts)
+}
+
+func (_FeeManager *FeeManagerCaller) IRewardManager(opts *bind.CallOpts) (common.Address, error) {
+ var out []interface{}
+ err := _FeeManager.contract.Call(opts, &out, "i_rewardManager")
+
+ if err != nil {
+ return *new(common.Address), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address)
+
+ return out0, err
+
+}
+
+func (_FeeManager *FeeManagerSession) IRewardManager() (common.Address, error) {
+ return _FeeManager.Contract.IRewardManager(&_FeeManager.CallOpts)
+}
+
+func (_FeeManager *FeeManagerCallerSession) IRewardManager() (common.Address, error) {
+ return _FeeManager.Contract.IRewardManager(&_FeeManager.CallOpts)
}
func (_FeeManager *FeeManagerCaller) LinkAvailableForPayment(opts *bind.CallOpts) (*big.Int, error) {
@@ -386,16 +476,28 @@ func (_FeeManager *FeeManagerTransactorSession) PayLinkDeficit(configDigest [32]
return _FeeManager.Contract.PayLinkDeficit(&_FeeManager.TransactOpts, configDigest)
}
-func (_FeeManager *FeeManagerTransactor) ProcessFee(opts *bind.TransactOpts, payload []byte, subscriber common.Address) (*types.Transaction, error) {
- return _FeeManager.contract.Transact(opts, "processFee", payload, subscriber)
+func (_FeeManager *FeeManagerTransactor) ProcessFee(opts *bind.TransactOpts, payload []byte, parameterPayload []byte, subscriber common.Address) (*types.Transaction, error) {
+ return _FeeManager.contract.Transact(opts, "processFee", payload, parameterPayload, subscriber)
}
-func (_FeeManager *FeeManagerSession) ProcessFee(payload []byte, subscriber common.Address) (*types.Transaction, error) {
- return _FeeManager.Contract.ProcessFee(&_FeeManager.TransactOpts, payload, subscriber)
+func (_FeeManager *FeeManagerSession) ProcessFee(payload []byte, parameterPayload []byte, subscriber common.Address) (*types.Transaction, error) {
+ return _FeeManager.Contract.ProcessFee(&_FeeManager.TransactOpts, payload, parameterPayload, subscriber)
}
-func (_FeeManager *FeeManagerTransactorSession) ProcessFee(payload []byte, subscriber common.Address) (*types.Transaction, error) {
- return _FeeManager.Contract.ProcessFee(&_FeeManager.TransactOpts, payload, subscriber)
+func (_FeeManager *FeeManagerTransactorSession) ProcessFee(payload []byte, parameterPayload []byte, subscriber common.Address) (*types.Transaction, error) {
+ return _FeeManager.Contract.ProcessFee(&_FeeManager.TransactOpts, payload, parameterPayload, subscriber)
+}
+
+func (_FeeManager *FeeManagerTransactor) ProcessFeeBulk(opts *bind.TransactOpts, payloads [][]byte, parameterPayload []byte, subscriber common.Address) (*types.Transaction, error) {
+ return _FeeManager.contract.Transact(opts, "processFeeBulk", payloads, parameterPayload, subscriber)
+}
+
+func (_FeeManager *FeeManagerSession) ProcessFeeBulk(payloads [][]byte, parameterPayload []byte, subscriber common.Address) (*types.Transaction, error) {
+ return _FeeManager.Contract.ProcessFeeBulk(&_FeeManager.TransactOpts, payloads, parameterPayload, subscriber)
+}
+
+func (_FeeManager *FeeManagerTransactorSession) ProcessFeeBulk(payloads [][]byte, parameterPayload []byte, subscriber common.Address) (*types.Transaction, error) {
+ return _FeeManager.Contract.ProcessFeeBulk(&_FeeManager.TransactOpts, payloads, parameterPayload, subscriber)
}
func (_FeeManager *FeeManagerTransactor) SetFeeRecipients(opts *bind.TransactOpts, configDigest [32]byte, rewardRecipientAndWeights []CommonAddressAndWeight) (*types.Transaction, error) {
@@ -410,15 +512,15 @@ func (_FeeManager *FeeManagerTransactorSession) SetFeeRecipients(configDigest [3
return _FeeManager.Contract.SetFeeRecipients(&_FeeManager.TransactOpts, configDigest, rewardRecipientAndWeights)
}
-func (_FeeManager *FeeManagerTransactor) SetNativeSurcharge(opts *bind.TransactOpts, surcharge *big.Int) (*types.Transaction, error) {
+func (_FeeManager *FeeManagerTransactor) SetNativeSurcharge(opts *bind.TransactOpts, surcharge uint64) (*types.Transaction, error) {
return _FeeManager.contract.Transact(opts, "setNativeSurcharge", surcharge)
}
-func (_FeeManager *FeeManagerSession) SetNativeSurcharge(surcharge *big.Int) (*types.Transaction, error) {
+func (_FeeManager *FeeManagerSession) SetNativeSurcharge(surcharge uint64) (*types.Transaction, error) {
return _FeeManager.Contract.SetNativeSurcharge(&_FeeManager.TransactOpts, surcharge)
}
-func (_FeeManager *FeeManagerTransactorSession) SetNativeSurcharge(surcharge *big.Int) (*types.Transaction, error) {
+func (_FeeManager *FeeManagerTransactorSession) SetNativeSurcharge(surcharge uint64) (*types.Transaction, error) {
return _FeeManager.Contract.SetNativeSurcharge(&_FeeManager.TransactOpts, surcharge)
}
@@ -434,32 +536,32 @@ func (_FeeManager *FeeManagerTransactorSession) TransferOwnership(to common.Addr
return _FeeManager.Contract.TransferOwnership(&_FeeManager.TransactOpts, to)
}
-func (_FeeManager *FeeManagerTransactor) UpdateSubscriberDiscount(opts *bind.TransactOpts, subscriber common.Address, feedId [32]byte, token common.Address, discount *big.Int) (*types.Transaction, error) {
+func (_FeeManager *FeeManagerTransactor) UpdateSubscriberDiscount(opts *bind.TransactOpts, subscriber common.Address, feedId [32]byte, token common.Address, discount uint64) (*types.Transaction, error) {
return _FeeManager.contract.Transact(opts, "updateSubscriberDiscount", subscriber, feedId, token, discount)
}
-func (_FeeManager *FeeManagerSession) UpdateSubscriberDiscount(subscriber common.Address, feedId [32]byte, token common.Address, discount *big.Int) (*types.Transaction, error) {
+func (_FeeManager *FeeManagerSession) UpdateSubscriberDiscount(subscriber common.Address, feedId [32]byte, token common.Address, discount uint64) (*types.Transaction, error) {
return _FeeManager.Contract.UpdateSubscriberDiscount(&_FeeManager.TransactOpts, subscriber, feedId, token, discount)
}
-func (_FeeManager *FeeManagerTransactorSession) UpdateSubscriberDiscount(subscriber common.Address, feedId [32]byte, token common.Address, discount *big.Int) (*types.Transaction, error) {
+func (_FeeManager *FeeManagerTransactorSession) UpdateSubscriberDiscount(subscriber common.Address, feedId [32]byte, token common.Address, discount uint64) (*types.Transaction, error) {
return _FeeManager.Contract.UpdateSubscriberDiscount(&_FeeManager.TransactOpts, subscriber, feedId, token, discount)
}
-func (_FeeManager *FeeManagerTransactor) Withdraw(opts *bind.TransactOpts, assetAddress common.Address, quantity *big.Int) (*types.Transaction, error) {
- return _FeeManager.contract.Transact(opts, "withdraw", assetAddress, quantity)
+func (_FeeManager *FeeManagerTransactor) Withdraw(opts *bind.TransactOpts, assetAddress common.Address, recipient common.Address, quantity *big.Int) (*types.Transaction, error) {
+ return _FeeManager.contract.Transact(opts, "withdraw", assetAddress, recipient, quantity)
}
-func (_FeeManager *FeeManagerSession) Withdraw(assetAddress common.Address, quantity *big.Int) (*types.Transaction, error) {
- return _FeeManager.Contract.Withdraw(&_FeeManager.TransactOpts, assetAddress, quantity)
+func (_FeeManager *FeeManagerSession) Withdraw(assetAddress common.Address, recipient common.Address, quantity *big.Int) (*types.Transaction, error) {
+ return _FeeManager.Contract.Withdraw(&_FeeManager.TransactOpts, assetAddress, recipient, quantity)
}
-func (_FeeManager *FeeManagerTransactorSession) Withdraw(assetAddress common.Address, quantity *big.Int) (*types.Transaction, error) {
- return _FeeManager.Contract.Withdraw(&_FeeManager.TransactOpts, assetAddress, quantity)
+func (_FeeManager *FeeManagerTransactorSession) Withdraw(assetAddress common.Address, recipient common.Address, quantity *big.Int) (*types.Transaction, error) {
+ return _FeeManager.Contract.Withdraw(&_FeeManager.TransactOpts, assetAddress, recipient, quantity)
}
-type FeeManagerInsufficientLinkIterator struct {
- Event *FeeManagerInsufficientLink
+type FeeManagerDiscountAppliedIterator struct {
+ Event *FeeManagerDiscountApplied
contract *bind.BoundContract
event string
@@ -470,7 +572,7 @@ type FeeManagerInsufficientLinkIterator struct {
fail error
}
-func (it *FeeManagerInsufficientLinkIterator) Next() bool {
+func (it *FeeManagerDiscountAppliedIterator) Next() bool {
if it.fail != nil {
return false
@@ -479,7 +581,7 @@ func (it *FeeManagerInsufficientLinkIterator) Next() bool {
if it.done {
select {
case log := <-it.logs:
- it.Event = new(FeeManagerInsufficientLink)
+ it.Event = new(FeeManagerDiscountApplied)
if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
it.fail = err
return false
@@ -494,7 +596,7 @@ func (it *FeeManagerInsufficientLinkIterator) Next() bool {
select {
case log := <-it.logs:
- it.Event = new(FeeManagerInsufficientLink)
+ it.Event = new(FeeManagerDiscountApplied)
if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
it.fail = err
return false
@@ -509,44 +611,171 @@ func (it *FeeManagerInsufficientLinkIterator) Next() bool {
}
}
-func (it *FeeManagerInsufficientLinkIterator) Error() error {
+func (it *FeeManagerDiscountAppliedIterator) Error() error {
return it.fail
}
-func (it *FeeManagerInsufficientLinkIterator) Close() error {
+func (it *FeeManagerDiscountAppliedIterator) Close() error {
it.sub.Unsubscribe()
return nil
}
-type FeeManagerInsufficientLink struct {
- ConfigDigest [32]byte
- LinkQuantity *big.Int
- NativeQuantity *big.Int
- Raw types.Log
+type FeeManagerDiscountApplied struct {
+ ConfigDigest [32]byte
+ Subscriber common.Address
+ Fee CommonAsset
+ Reward CommonAsset
+ AppliedDiscount *big.Int
+ Raw types.Log
}
-func (_FeeManager *FeeManagerFilterer) FilterInsufficientLink(opts *bind.FilterOpts, configDigest [][32]byte) (*FeeManagerInsufficientLinkIterator, error) {
+func (_FeeManager *FeeManagerFilterer) FilterDiscountApplied(opts *bind.FilterOpts, configDigest [][32]byte, subscriber []common.Address) (*FeeManagerDiscountAppliedIterator, error) {
var configDigestRule []interface{}
for _, configDigestItem := range configDigest {
configDigestRule = append(configDigestRule, configDigestItem)
}
+ var subscriberRule []interface{}
+ for _, subscriberItem := range subscriber {
+ subscriberRule = append(subscriberRule, subscriberItem)
+ }
- logs, sub, err := _FeeManager.contract.FilterLogs(opts, "InsufficientLink", configDigestRule)
+ logs, sub, err := _FeeManager.contract.FilterLogs(opts, "DiscountApplied", configDigestRule, subscriberRule)
if err != nil {
return nil, err
}
- return &FeeManagerInsufficientLinkIterator{contract: _FeeManager.contract, event: "InsufficientLink", logs: logs, sub: sub}, nil
+ return &FeeManagerDiscountAppliedIterator{contract: _FeeManager.contract, event: "DiscountApplied", logs: logs, sub: sub}, nil
}
-func (_FeeManager *FeeManagerFilterer) WatchInsufficientLink(opts *bind.WatchOpts, sink chan<- *FeeManagerInsufficientLink, configDigest [][32]byte) (event.Subscription, error) {
+func (_FeeManager *FeeManagerFilterer) WatchDiscountApplied(opts *bind.WatchOpts, sink chan<- *FeeManagerDiscountApplied, configDigest [][32]byte, subscriber []common.Address) (event.Subscription, error) {
var configDigestRule []interface{}
for _, configDigestItem := range configDigest {
configDigestRule = append(configDigestRule, configDigestItem)
}
+ var subscriberRule []interface{}
+ for _, subscriberItem := range subscriber {
+ subscriberRule = append(subscriberRule, subscriberItem)
+ }
- logs, sub, err := _FeeManager.contract.WatchLogs(opts, "InsufficientLink", configDigestRule)
+ logs, sub, err := _FeeManager.contract.WatchLogs(opts, "DiscountApplied", configDigestRule, subscriberRule)
+ if err != nil {
+ return nil, err
+ }
+ return event.NewSubscription(func(quit <-chan struct{}) error {
+ defer sub.Unsubscribe()
+ for {
+ select {
+ case log := <-logs:
+
+ event := new(FeeManagerDiscountApplied)
+ if err := _FeeManager.contract.UnpackLog(event, "DiscountApplied", log); err != nil {
+ return err
+ }
+ event.Raw = log
+
+ select {
+ case sink <- event:
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ case err := <-sub.Err():
+ return err
+ case <-quit:
+ return nil
+ }
+ }
+ }), nil
+}
+
+func (_FeeManager *FeeManagerFilterer) ParseDiscountApplied(log types.Log) (*FeeManagerDiscountApplied, error) {
+ event := new(FeeManagerDiscountApplied)
+ if err := _FeeManager.contract.UnpackLog(event, "DiscountApplied", log); err != nil {
+ return nil, err
+ }
+ event.Raw = log
+ return event, nil
+}
+
+type FeeManagerInsufficientLinkIterator struct {
+ Event *FeeManagerInsufficientLink
+
+ contract *bind.BoundContract
+ event string
+
+ logs chan types.Log
+ sub ethereum.Subscription
+ done bool
+ fail error
+}
+
+func (it *FeeManagerInsufficientLinkIterator) Next() bool {
+
+ if it.fail != nil {
+ return false
+ }
+
+ if it.done {
+ select {
+ case log := <-it.logs:
+ it.Event = new(FeeManagerInsufficientLink)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ default:
+ return false
+ }
+ }
+
+ select {
+ case log := <-it.logs:
+ it.Event = new(FeeManagerInsufficientLink)
+ if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+ it.fail = err
+ return false
+ }
+ it.Event.Raw = log
+ return true
+
+ case err := <-it.sub.Err():
+ it.done = true
+ it.fail = err
+ return it.Next()
+ }
+}
+
+func (it *FeeManagerInsufficientLinkIterator) Error() error {
+ return it.fail
+}
+
+func (it *FeeManagerInsufficientLinkIterator) Close() error {
+ it.sub.Unsubscribe()
+ return nil
+}
+
+type FeeManagerInsufficientLink struct {
+ Rewards []IRewardManagerFeePayment
+ Raw types.Log
+}
+
+func (_FeeManager *FeeManagerFilterer) FilterInsufficientLink(opts *bind.FilterOpts) (*FeeManagerInsufficientLinkIterator, error) {
+
+ logs, sub, err := _FeeManager.contract.FilterLogs(opts, "InsufficientLink")
+ if err != nil {
+ return nil, err
+ }
+ return &FeeManagerInsufficientLinkIterator{contract: _FeeManager.contract, event: "InsufficientLink", logs: logs, sub: sub}, nil
+}
+
+func (_FeeManager *FeeManagerFilterer) WatchInsufficientLink(opts *bind.WatchOpts, sink chan<- *FeeManagerInsufficientLink) (event.Subscription, error) {
+
+ logs, sub, err := _FeeManager.contract.WatchLogs(opts, "InsufficientLink")
if err != nil {
return nil, err
}
@@ -776,7 +1005,7 @@ func (it *FeeManagerNativeSurchargeUpdatedIterator) Close() error {
}
type FeeManagerNativeSurchargeUpdated struct {
- NewSurcharge *big.Int
+ NewSurcharge uint64
Raw types.Log
}
@@ -1168,7 +1397,7 @@ type FeeManagerSubscriberDiscountUpdated struct {
Subscriber common.Address
FeedId [32]byte
Token common.Address
- Discount *big.Int
+ Discount uint64
Raw types.Log
}
@@ -1304,6 +1533,7 @@ func (it *FeeManagerWithdrawIterator) Close() error {
type FeeManagerWithdraw struct {
AdminAddress common.Address
+ Recipient common.Address
AssetAddress common.Address
Quantity *big.Int
Raw types.Log
@@ -1363,6 +1593,8 @@ func (_FeeManager *FeeManagerFilterer) ParseWithdraw(log types.Log) (*FeeManager
func (_FeeManager *FeeManager) ParseLog(log types.Log) (generated.AbigenLog, error) {
switch log.Topics[0] {
+ case _FeeManager.abi.Events["DiscountApplied"].ID:
+ return _FeeManager.ParseDiscountApplied(log)
case _FeeManager.abi.Events["InsufficientLink"].ID:
return _FeeManager.ParseInsufficientLink(log)
case _FeeManager.abi.Events["LinkDeficitCleared"].ID:
@@ -1383,8 +1615,12 @@ func (_FeeManager *FeeManager) ParseLog(log types.Log) (generated.AbigenLog, err
}
}
+func (FeeManagerDiscountApplied) Topic() common.Hash {
+ return common.HexToHash("0x88b15eb682210089cddf967648e2cb2a4535aeadc8f8f36050922e33c04e7125")
+}
+
func (FeeManagerInsufficientLink) Topic() common.Hash {
- return common.HexToHash("0xeb6f22018570d97db6df12dc94f202b4e2b2888a6a5d4bd179422c91b29dcdf7")
+ return common.HexToHash("0xf52e5907b69d97c33392936c12d78b494463b78c5b72df50b4c497eee5720b67")
}
func (FeeManagerLinkDeficitCleared) Topic() common.Hash {
@@ -1392,7 +1628,7 @@ func (FeeManagerLinkDeficitCleared) Topic() common.Hash {
}
func (FeeManagerNativeSurchargeUpdated) Topic() common.Hash {
- return common.HexToHash("0xa320ddc8288125050af9b9b75fd872443f8c722e70b14fc8475dbd630a4916e1")
+ return common.HexToHash("0x08f7c0d17932ddb8523bc06754d42ff19ebc77d76a8b9bfde02c28ab1ed3d639")
}
func (FeeManagerOwnershipTransferRequested) Topic() common.Hash {
@@ -1404,11 +1640,11 @@ func (FeeManagerOwnershipTransferred) Topic() common.Hash {
}
func (FeeManagerSubscriberDiscountUpdated) Topic() common.Hash {
- return common.HexToHash("0x41eb9ccd292d5906dc1f0ec108bed3e2b966e3071e033df938f7215f6d30ca84")
+ return common.HexToHash("0x5eba5a8afa39780f0f99b6cbeb95f3da6a7040ca00abd46bdc91a0a060134139")
}
func (FeeManagerWithdraw) Topic() common.Hash {
- return common.HexToHash("0x9b1bfa7fa9ee420a16e124f794c35ac9f90472acc99140eb2f6447c714cad8eb")
+ return common.HexToHash("0x7ff78a71698bdb18dcca96f52ab25e0a1b146fb6a49adf8e6845299e49021f29")
}
func (_FeeManager *FeeManager) Address() common.Address {
@@ -1416,7 +1652,15 @@ func (_FeeManager *FeeManager) Address() common.Address {
}
type FeeManagerInterface interface {
- GetFeeAndReward(opts *bind.CallOpts, subscriber common.Address, report []byte, quote IFeeManagerQuote) (CommonAsset, CommonAsset, error)
+ GetFeeAndReward(opts *bind.CallOpts, subscriber common.Address, report []byte, quoteAddress common.Address) (CommonAsset, CommonAsset, *big.Int, error)
+
+ ILinkAddress(opts *bind.CallOpts) (common.Address, error)
+
+ INativeAddress(opts *bind.CallOpts) (common.Address, error)
+
+ IProxyAddress(opts *bind.CallOpts) (common.Address, error)
+
+ IRewardManager(opts *bind.CallOpts) (common.Address, error)
LinkAvailableForPayment(opts *bind.CallOpts) (*big.Int, error)
@@ -1436,21 +1680,29 @@ type FeeManagerInterface interface {
PayLinkDeficit(opts *bind.TransactOpts, configDigest [32]byte) (*types.Transaction, error)
- ProcessFee(opts *bind.TransactOpts, payload []byte, subscriber common.Address) (*types.Transaction, error)
+ ProcessFee(opts *bind.TransactOpts, payload []byte, parameterPayload []byte, subscriber common.Address) (*types.Transaction, error)
+
+ ProcessFeeBulk(opts *bind.TransactOpts, payloads [][]byte, parameterPayload []byte, subscriber common.Address) (*types.Transaction, error)
SetFeeRecipients(opts *bind.TransactOpts, configDigest [32]byte, rewardRecipientAndWeights []CommonAddressAndWeight) (*types.Transaction, error)
- SetNativeSurcharge(opts *bind.TransactOpts, surcharge *big.Int) (*types.Transaction, error)
+ SetNativeSurcharge(opts *bind.TransactOpts, surcharge uint64) (*types.Transaction, error)
TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error)
- UpdateSubscriberDiscount(opts *bind.TransactOpts, subscriber common.Address, feedId [32]byte, token common.Address, discount *big.Int) (*types.Transaction, error)
+ UpdateSubscriberDiscount(opts *bind.TransactOpts, subscriber common.Address, feedId [32]byte, token common.Address, discount uint64) (*types.Transaction, error)
+
+ Withdraw(opts *bind.TransactOpts, assetAddress common.Address, recipient common.Address, quantity *big.Int) (*types.Transaction, error)
+
+ FilterDiscountApplied(opts *bind.FilterOpts, configDigest [][32]byte, subscriber []common.Address) (*FeeManagerDiscountAppliedIterator, error)
+
+ WatchDiscountApplied(opts *bind.WatchOpts, sink chan<- *FeeManagerDiscountApplied, configDigest [][32]byte, subscriber []common.Address) (event.Subscription, error)
- Withdraw(opts *bind.TransactOpts, assetAddress common.Address, quantity *big.Int) (*types.Transaction, error)
+ ParseDiscountApplied(log types.Log) (*FeeManagerDiscountApplied, error)
- FilterInsufficientLink(opts *bind.FilterOpts, configDigest [][32]byte) (*FeeManagerInsufficientLinkIterator, error)
+ FilterInsufficientLink(opts *bind.FilterOpts) (*FeeManagerInsufficientLinkIterator, error)
- WatchInsufficientLink(opts *bind.WatchOpts, sink chan<- *FeeManagerInsufficientLink, configDigest [][32]byte) (event.Subscription, error)
+ WatchInsufficientLink(opts *bind.WatchOpts, sink chan<- *FeeManagerInsufficientLink) (event.Subscription, error)
ParseInsufficientLink(log types.Log) (*FeeManagerInsufficientLink, error)
diff --git a/core/gethwrappers/llo-feeds/generated/reward_manager/reward_manager.go b/core/gethwrappers/llo-feeds/generated/reward_manager/reward_manager.go
index 3ea1bee3e8b..224fb37ef63 100644
--- a/core/gethwrappers/llo-feeds/generated/reward_manager/reward_manager.go
+++ b/core/gethwrappers/llo-feeds/generated/reward_manager/reward_manager.go
@@ -32,12 +32,17 @@ var (
type CommonAddressAndWeight struct {
Addr common.Address
- Weight *big.Int
+ Weight uint64
+}
+
+type IRewardManagerFeePayment struct {
+ PoolId [32]byte
+ Amount *big.Int
}
var RewardManagerMetaData = &bind.MetaData{
- ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"linkAddress\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"InvalidAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPoolId\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidWeights\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newFeeManagerAddress\",\"type\":\"address\"}],\"name\":\"FeeManagerUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"poolId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"payee\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"quantity\",\"type\":\"uint256\"}],\"name\":\"FeePaid\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"poolId\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"weight\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"structCommon.AddressAndWeight[]\",\"name\":\"newRewardRecipients\",\"type\":\"tuple[]\"}],\"name\":\"RewardRecipientsUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"poolId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"quantity\",\"type\":\"uint256\"}],\"name\":\"RewardsClaimed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"poolIds\",\"type\":\"bytes32[]\"}],\"name\":\"claimRewards\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"getAvailableRewardPoolIds\",\"outputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"\",\"type\":\"bytes32[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"poolId\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"payee\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"onFeePaid\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"poolId\",\"type\":\"bytes32\"},{\"internalType\":\"address[]\",\"name\":\"recipients\",\"type\":\"address[]\"}],\"name\":\"payRecipients\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_feeManagerAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_registeredPoolIds\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"s_rewardRecipientWeights\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"s_totalRewardRecipientFees\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newFeeManagerAddress\",\"type\":\"address\"}],\"name\":\"setFeeManager\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"poolId\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"weight\",\"type\":\"uint256\"}],\"internalType\":\"structCommon.AddressAndWeight[]\",\"name\":\"rewardRecipientAndWeights\",\"type\":\"tuple[]\"}],\"name\":\"setRewardRecipients\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"poolId\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"weight\",\"type\":\"uint256\"}],\"internalType\":\"structCommon.AddressAndWeight[]\",\"name\":\"newRewardRecipients\",\"type\":\"tuple[]\"}],\"name\":\"updateRewardRecipients\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]",
- Bin: "0x60a06040523480156200001157600080fd5b5060405162001d5338038062001d538339810160408190526200003491620001a6565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000fb565b5050506001600160a01b038116620000e95760405163e6c4247b60e01b815260040160405180910390fd5b6001600160a01b0316608052620001d8565b336001600160a01b03821603620001555760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600060208284031215620001b957600080fd5b81516001600160a01b0381168114620001d157600080fd5b9392505050565b608051611b58620001fb600039600081816109b90152610d2a0152611b586000f3fe608060405234801561001057600080fd5b50600436106101005760003560e01c80636992922f11610097578063cd5f729211610066578063cd5f7292146102e0578063efb03fe9146102f3578063f2fde38b14610306578063f34517aa1461031957600080fd5b80636992922f1461026f57806379ba50971461028f5780638ac85a5c146102975780638da5cb5b146102c257600080fd5b806339ee81e1116100d357806339ee81e114610208578063472d35b9146102365780634d32208414610249578063633b5f6e1461025c57600080fd5b806301ffc9a7146101055780630f3c34d11461016f578063181f5a7714610184578063276e7660146101c3575b600080fd5b61015a6101133660046115da565b7fffffffff00000000000000000000000000000000000000000000000000000000167fefb03fe9000000000000000000000000000000000000000000000000000000001490565b60405190151581526020015b60405180910390f35b61018261017d36600461169a565b61032c565b005b604080518082018252601381527f5265776172644d616e6167657220302e302e3100000000000000000000000000602082015290516101669190611764565b6007546101e39073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610166565b6102286102163660046117b5565b60026020526000908152604090205481565b604051908152602001610166565b6101826102443660046117f7565b61033a565b610182610257366004611819565b610408565b61018261026a366004611898565b61053f565b61028261027d3660046117f7565b6106f5565b6040516101669190611904565b6101826107f1565b6102286102a5366004611948565b600460209081526000928352604080842090915290825290205481565b60005473ffffffffffffffffffffffffffffffffffffffff166101e3565b6102286102ee3660046117b5565b6108f3565b610182610301366004611974565b610914565b6101826103143660046117f7565b610a3c565b610182610327366004611898565b610a50565b6103363382610bca565b5050565b610342610d5a565b73ffffffffffffffffffffffffffffffffffffffff811661038f576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600780547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527fe45f5e140399b0a7e12971ab020724b828fbed8ac408c420884dc7d1bbe506b49060200160405180910390a150565b8261042860005473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415801561047a57506000818152600460209081526040808320338452909152902054155b156104b1576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160018082528183019092526000916020808301908036833701905050905084816000815181106104e7576104e76119a9565b60200260200101818152505060005b838110156105375761052e858583818110610513576105136119a9565b905060200201602081019061052891906117f7565b83610bca565b506001016104f6565b505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff16331480159061057f575060075473ffffffffffffffffffffffffffffffffffffffff163314155b156105b6576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008190036105f1576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008381526005602052604090205460ff161561063a576040517f0afa7ee800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006805460018181019092557ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f01849055600084815260056020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690911790556106b6838383670de0b6b3a7640000610ddd565b827fe5ca4131deaeb848b5d6a9c0f85795efc54e8a0252eb38d3e77a1efc2b38419683836040516106e89291906119d8565b60405180910390a2505050565b60065460609060008167ffffffffffffffff8111156107165761071661161c565b60405190808252806020026020018201604052801561073f578160200160208202803683370190505b5090506000805b838110156107e757600060068281548110610763576107636119a9565b600091825260208083209091015480835260048252604080842073ffffffffffffffffffffffffffffffffffffffff8c168552909252912054909150156107de57600081815260026020526040902054156107de57808484815181106107cb576107cb6119a9565b6020026020010181815250508260010192505b50600101610746565b5090949350505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610877576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6006818154811061090357600080fd5b600091825260209091200154905081565b60005473ffffffffffffffffffffffffffffffffffffffff163314801590610954575060075473ffffffffffffffffffffffffffffffffffffffff163314155b1561098b576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008381526002602052604090208054820190556109e173ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016833084610fd6565b6040805184815273ffffffffffffffffffffffffffffffffffffffff841660208201529081018290527f0ae7c9bfbc7dfc3426a34852f9a1cdd2f750abec8190abbff0bbe13d8118c30c9060600160405180910390a1505050565b610a44610d5a565b610a4d816110b8565b50565b610a58610d5a565b604080516001808252818301909252600091602080830190803683370190505090508381600081518110610a8e57610a8e6119a9565b6020026020010181815250506000805b83811015610b7c576000858583818110610aba57610aba6119a9565b610ad092602060409092020190810191506117f7565b600088815260046020908152604080832073ffffffffffffffffffffffffffffffffffffffff85168452909152812054919250819003610b3c576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610b6d878785818110610b5157610b516119a9565b610b6792602060409092020190810191506117f7565b86610bca565b50929092019150600101610a9e565b50610b8985858584610ddd565b847fe5ca4131deaeb848b5d6a9c0f85795efc54e8a0252eb38d3e77a1efc2b3841968585604051610bbb9291906119d8565b60405180910390a25050505050565b60008060005b8351811015610d09576000848281518110610bed57610bed6119a9565b6020908102919091018101516000818152600283526040808220546003855281832073ffffffffffffffffffffffffffffffffffffffff8c16808552908652828420548585526004875283852091855295529082205492945092830391670de0b6b3a76400009083020490819003610c685750505050610cf9565b600084815260036020908152604080832073ffffffffffffffffffffffffffffffffffffffff8d168085529252909120849055885196820196899087908110610cb357610cb36119a9565b60200260200101517ffec539b3c42d74cd492c3ecf7966bf014b327beef98e935cdc3ec5e54a6901c783604051610cec91815260200190565b60405180910390a3505050505b610d0281611a6b565b9050610bd0565b508015610d5157610d5173ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001685836111ad565b90505b92915050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610ddb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161086e565b565b610e388383808060200260200160405190810160405280939291908181526020016000905b82821015610e2e57610e1f60408302860136819003810190611aa3565b81526020019060010190610e02565b5050505050611208565b15610e6f576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805b83811015610f95576000858583818110610e8f57610e8f6119a9565b9050604002016020013590506000868684818110610eaf57610eaf6119a9565b610ec592602060409092020190810191506117f7565b905073ffffffffffffffffffffffffffffffffffffffff8116610f14576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81600003610f4e576040517f84677ce800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600088815260046020908152604080832073ffffffffffffffffffffffffffffffffffffffff9094168352929052208190559190910190610f8e81611a6b565b9050610e73565b50818114610fcf576040517f84677ce800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526110b29085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526112bf565b50505050565b3373ffffffffffffffffffffffffffffffffffffffff821603611137576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161086e565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526112039084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401611030565b505050565b6000805b82518110156112b6576000611222826001611afa565b90505b83518110156112ad57838181518110611240576112406119a9565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff16848381518110611274576112746119a9565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff16036112a5575060019392505050565b600101611225565b5060010161120c565b50600092915050565b6000611321826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166113cb9092919063ffffffff16565b805190915015611203578080602001905181019061133f9190611b0d565b611203576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840161086e565b60606113da84846000856113e2565b949350505050565b606082471015611474576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161086e565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161149d9190611b2f565b60006040518083038185875af1925050503d80600081146114da576040519150601f19603f3d011682016040523d82523d6000602084013e6114df565b606091505b50915091506114f0878383876114fb565b979650505050505050565b6060831561159157825160000361158a5773ffffffffffffffffffffffffffffffffffffffff85163b61158a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161086e565b50816113da565b6113da83838151156115a65781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161086e9190611764565b6000602082840312156115ec57600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610d5157600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156116925761169261161c565b604052919050565b600060208083850312156116ad57600080fd5b823567ffffffffffffffff808211156116c557600080fd5b818501915085601f8301126116d957600080fd5b8135818111156116eb576116eb61161c565b8060051b91506116fc84830161164b565b818152918301840191848101908884111561171657600080fd5b938501935b838510156117345784358252938501939085019061171b565b98975050505050505050565b60005b8381101561175b578181015183820152602001611743565b50506000910152565b6020815260008251806020840152611783816040850160208701611740565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b6000602082840312156117c757600080fd5b5035919050565b803573ffffffffffffffffffffffffffffffffffffffff811681146117f257600080fd5b919050565b60006020828403121561180957600080fd5b611812826117ce565b9392505050565b60008060006040848603121561182e57600080fd5b83359250602084013567ffffffffffffffff8082111561184d57600080fd5b818601915086601f83011261186157600080fd5b81358181111561187057600080fd5b8760208260051b850101111561188557600080fd5b6020830194508093505050509250925092565b6000806000604084860312156118ad57600080fd5b83359250602084013567ffffffffffffffff808211156118cc57600080fd5b818601915086601f8301126118e057600080fd5b8135818111156118ef57600080fd5b8760208260061b850101111561188557600080fd5b6020808252825182820181905260009190848201906040850190845b8181101561193c57835183529284019291840191600101611920565b50909695505050505050565b6000806040838503121561195b57600080fd5b8235915061196b602084016117ce565b90509250929050565b60008060006060848603121561198957600080fd5b83359250611999602085016117ce565b9150604084013590509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020808252818101839052600090604080840186845b87811015611a2f5773ffffffffffffffffffffffffffffffffffffffff611a14836117ce565b168352818501358584015291830191908301906001016119ee565b5090979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611a9c57611a9c611a3c565b5060010190565b600060408284031215611ab557600080fd5b6040516040810181811067ffffffffffffffff82111715611ad857611ad861161c565b604052611ae4836117ce565b8152602083013560208201528091505092915050565b80820180821115610d5457610d54611a3c565b600060208284031215611b1f57600080fd5b81518015158114610d5157600080fd5b60008251611b41818460208701611740565b919091019291505056fea164736f6c6343000810000a",
+ ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"linkAddress\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"InvalidAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPoolId\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidPoolLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidWeights\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newFeeManagerAddress\",\"type\":\"address\"}],\"name\":\"FeeManagerUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"poolId\",\"type\":\"bytes32\"},{\"internalType\":\"uint192\",\"name\":\"amount\",\"type\":\"uint192\"}],\"indexed\":false,\"internalType\":\"structIRewardManager.FeePayment[]\",\"name\":\"payments\",\"type\":\"tuple[]\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"payer\",\"type\":\"address\"}],\"name\":\"FeePaid\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"poolId\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"indexed\":false,\"internalType\":\"structCommon.AddressAndWeight[]\",\"name\":\"newRewardRecipients\",\"type\":\"tuple[]\"}],\"name\":\"RewardRecipientsUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"poolId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint192\",\"name\":\"quantity\",\"type\":\"uint192\"}],\"name\":\"RewardsClaimed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"poolIds\",\"type\":\"bytes32[]\"}],\"name\":\"claimRewards\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"startIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"endIndex\",\"type\":\"uint256\"}],\"name\":\"getAvailableRewardPoolIds\",\"outputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"\",\"type\":\"bytes32[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_linkAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"poolId\",\"type\":\"bytes32\"},{\"internalType\":\"uint192\",\"name\":\"amount\",\"type\":\"uint192\"}],\"internalType\":\"structIRewardManager.FeePayment[]\",\"name\":\"payments\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"payer\",\"type\":\"address\"}],\"name\":\"onFeePaid\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"poolId\",\"type\":\"bytes32\"},{\"internalType\":\"address[]\",\"name\":\"recipients\",\"type\":\"address[]\"}],\"name\":\"payRecipients\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_feeManagerAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_registeredPoolIds\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"s_rewardRecipientWeights\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"s_rewardRecipientWeightsSet\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"s_totalRewardRecipientFees\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"s_totalRewardRecipientFeesLastClaimedAmounts\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newFeeManagerAddress\",\"type\":\"address\"}],\"name\":\"setFeeManager\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"poolId\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"internalType\":\"structCommon.AddressAndWeight[]\",\"name\":\"rewardRecipientAndWeights\",\"type\":\"tuple[]\"}],\"name\":\"setRewardRecipients\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"poolId\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"internalType\":\"structCommon.AddressAndWeight[]\",\"name\":\"newRewardRecipients\",\"type\":\"tuple[]\"}],\"name\":\"updateRewardRecipients\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]",
+ Bin: "0x60a06040523480156200001157600080fd5b50604051620020c2380380620020c28339810160408190526200003491620001a6565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000fb565b5050506001600160a01b038116620000e95760405163e6c4247b60e01b815260040160405180910390fd5b6001600160a01b0316608052620001d8565b336001600160a01b03821603620001555760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600060208284031215620001b957600080fd5b81516001600160a01b0381168114620001d157600080fd5b9392505050565b608051611ec062000202600039600081816103bd01528181610ce30152610f1e0152611ec06000f3fe608060405234801561001057600080fd5b50600436106101515760003560e01c80634d322084116100cd5780638da5cb5b11610081578063cd5f729211610066578063cd5f7292146103a5578063ea4b861b146103b8578063f2fde38b146103df57600080fd5b80638da5cb5b14610374578063b0d9fa191461039257600080fd5b806360122608116100b2578063601226081461031657806379ba5097146103415780638ac85a5c1461034957600080fd5b80634d322084146102e057806359256201146102f357600080fd5b8063276e7660116101245780634722647511610109578063472264751461029a578063472d35b9146102ba5780634944832f146102cd57600080fd5b8063276e76601461022757806339ee81e11461026c57600080fd5b806301ffc9a7146101565780630f3c34d1146101c057806314060f23146101d5578063181f5a77146101e8575b600080fd5b6101ab6101643660046117ac565b7fffffffff00000000000000000000000000000000000000000000000000000000167fb0d9fa19000000000000000000000000000000000000000000000000000000001490565b60405190151581526020015b60405180910390f35b6101d36101ce36600461186c565b6103f2565b005b6101d36101e336600461195e565b610400565b604080518082018252601381527f5265776172644d616e6167657220312e312e3000000000000000000000000000602082015290516101b791906119ce565b6007546102479073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101b7565b61028c61027a366004611a1f565b60026020526000908152604090205481565b6040519081526020016101b7565b6102ad6102a8366004611a61565b6105b6565b6040516101b79190611a94565b6101d36102c8366004611ad8565b610740565b6101d36102db36600461195e565b61080e565b6101d36102ee366004611afa565b610957565b6101ab610301366004611a1f565b60056020526000908152604090205460ff1681565b61028c610324366004611b79565b600360209081526000928352604080842090915290825290205481565b6101d3610a96565b61028c610357366004611b79565b600460209081526000928352604080842090915290825290205481565b60005473ffffffffffffffffffffffffffffffffffffffff16610247565b6101d36103a0366004611ba5565b610b98565b61028c6103b3366004611a1f565b610d4c565b6102477f000000000000000000000000000000000000000000000000000000000000000081565b6101d36103ed366004611ad8565b610d6d565b6103fc3382610d81565b5050565b60005473ffffffffffffffffffffffffffffffffffffffff163314801590610440575060075473ffffffffffffffffffffffffffffffffffffffff163314155b15610477576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008190036104b2576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008381526005602052604090205460ff16156104fb576040517f0afa7ee800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006805460018181019092557ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f01849055600084815260056020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169091179055610577838383670de0b6b3a7640000610f4e565b827f8f668d6090683f98b3373a8b83d214da45737f7486cb7de554cc07b54e61cfe683836040516105a9929190611c11565b60405180910390a2505050565b60065460609060008184116105cb57836105cd565b815b905080851115610609576040517fa22caccc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006106158683611ca8565b67ffffffffffffffff81111561062d5761062d6117ee565b604051908082528060200260200182016040528015610656578160200160208202803683370190505b5090506000865b838110156107335760006006828154811061067a5761067a611cbb565b600091825260208083209091015480835260048252604080842073ffffffffffffffffffffffffffffffffffffffff8f16855290925291205490915015610722576000818152600260209081526040808320546003835281842073ffffffffffffffffffffffffffffffffffffffff8f168552909252909120548114610720578185858060010196508151811061071357610713611cbb565b6020026020010181815250505b505b5061072c81611cea565b905061065d565b5090979650505050505050565b610748611125565b73ffffffffffffffffffffffffffffffffffffffff8116610795576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600780547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527fe45f5e140399b0a7e12971ab020724b828fbed8ac408c420884dc7d1bbe506b49060200160405180910390a150565b610816611125565b60408051600180825281830190925260009160208083019080368337019050509050838160008151811061084c5761084c611cbb565b6020026020010181815250506000805b8381101561090957600085858381811061087857610878611cbb565b61088e9260206040909202019081019150611ad8565b600088815260046020908152604080832073ffffffffffffffffffffffffffffffffffffffff851684529091529020549091506108f28787858181106108d6576108d6611cbb565b6108ec9260206040909202019081019150611ad8565b86610d81565b5092909201915061090281611cea565b905061085c565b5061091685858584610f4e565b847f8f668d6090683f98b3373a8b83d214da45737f7486cb7de554cc07b54e61cfe68585604051610948929190611c11565b60405180910390a25050505050565b8261097760005473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141580156109c957506000818152600460209081526040808320338452909152902054155b15610a00576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516001808252818301909252600091602080830190803683370190505090508481600081518110610a3657610a36611cbb565b60200260200101818152505060005b83811015610a8e57610a7d858583818110610a6257610a62611cbb565b9050602002016020810190610a779190611ad8565b83610d81565b50610a8781611cea565b9050610a45565b505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610b1c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60075473ffffffffffffffffffffffffffffffffffffffff163314610be9576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805b83811015610cc857848482818110610c0757610c07611cbb565b9050604002016020016020810190610c1f9190611d4a565b77ffffffffffffffffffffffffffffffffffffffffffffffff1660026000878785818110610c4f57610c4f611cbb565b6040908102929092013583525060208201929092520160002080549091019055848482818110610c8157610c81611cbb565b9050604002016020016020810190610c999190611d4a565b77ffffffffffffffffffffffffffffffffffffffffffffffff168201915080610cc190611cea565b9050610bed565b50610d0b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168330846111a8565b7fa1cc025ea76bacce5d740ee4bc331899375dc2c5f2ab33933aaacbd9ba001b66848484604051610d3e93929190611d65565b60405180910390a150505050565b60068181548110610d5c57600080fd5b600091825260209091200154905081565b610d75611125565b610d7e8161128a565b50565b60008060005b8351811015610efd576000848281518110610da457610da4611cbb565b6020026020010151905060006002600083815260200190815260200160002054905080600003610dd5575050610eed565b600082815260036020908152604080832073ffffffffffffffffffffffffffffffffffffffff8b16808552908352818420548685526004845282852091855292528220549083039190670de0b6b3a764000090830204905080600003610e3e5750505050610eed565b600084815260036020908152604080832073ffffffffffffffffffffffffffffffffffffffff8d168085529252909120849055885196820196899087908110610e8957610e89611cbb565b60200260200101517f989969655bc1d593922527fe85d71347bb8e12fa423cc71f362dd8ef7cb10ef283604051610ee0919077ffffffffffffffffffffffffffffffffffffffffffffffff91909116815260200190565b60405180910390a3505050505b610ef681611cea565b9050610d87565b508015610f4557610f4573ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016858361137f565b90505b92915050565b610fa98383808060200260200160405190810160405280939291908181526020016000905b82821015610f9f57610f9060408302860136819003810190611dec565b81526020019060010190610f73565b50505050506113da565b15610fe0576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805b838110156110e457600085858381811061100057611000611cbb565b90506040020160200160208101906110189190611e47565b67ffffffffffffffff169050600086868481811061103857611038611cbb565b61104e9260206040909202019081019150611ad8565b905073ffffffffffffffffffffffffffffffffffffffff811661109d576040517fe6c4247b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600088815260046020908152604080832073ffffffffffffffffffffffffffffffffffffffff90941683529290522081905591909101906110dd81611cea565b9050610fe4565b5081811461111e576040517f84677ce800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146111a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610b13565b565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526112849085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611491565b50505050565b3373ffffffffffffffffffffffffffffffffffffffff821603611309576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610b13565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526113d59084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401611202565b505050565b6000805b82518110156114885760006113f4826001611e62565b90505b835181101561147f5783818151811061141257611412611cbb565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1684838151811061144657611446611cbb565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1603611477575060019392505050565b6001016113f7565b506001016113de565b50600092915050565b60006114f3826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff1661159d9092919063ffffffff16565b8051909150156113d557808060200190518101906115119190611e75565b6113d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610b13565b60606115ac84846000856115b4565b949350505050565b606082471015611646576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610b13565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161166f9190611e97565b60006040518083038185875af1925050503d80600081146116ac576040519150601f19603f3d011682016040523d82523d6000602084013e6116b1565b606091505b50915091506116c2878383876116cd565b979650505050505050565b6060831561176357825160000361175c5773ffffffffffffffffffffffffffffffffffffffff85163b61175c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610b13565b50816115ac565b6115ac83838151156117785781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b1391906119ce565b6000602082840312156117be57600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610f4557600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611864576118646117ee565b604052919050565b6000602080838503121561187f57600080fd5b823567ffffffffffffffff8082111561189757600080fd5b818501915085601f8301126118ab57600080fd5b8135818111156118bd576118bd6117ee565b8060051b91506118ce84830161181d565b81815291830184019184810190888411156118e857600080fd5b938501935b83851015611906578435825293850193908501906118ed565b98975050505050505050565b60008083601f84011261192457600080fd5b50813567ffffffffffffffff81111561193c57600080fd5b6020830191508360208260061b850101111561195757600080fd5b9250929050565b60008060006040848603121561197357600080fd5b83359250602084013567ffffffffffffffff81111561199157600080fd5b61199d86828701611912565b9497909650939450505050565b60005b838110156119c55781810151838201526020016119ad565b50506000910152565b60208152600082518060208401526119ed8160408501602087016119aa565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b600060208284031215611a3157600080fd5b5035919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114611a5c57600080fd5b919050565b600080600060608486031215611a7657600080fd5b611a7f84611a38565b95602085013595506040909401359392505050565b6020808252825182820181905260009190848201906040850190845b81811015611acc57835183529284019291840191600101611ab0565b50909695505050505050565b600060208284031215611aea57600080fd5b611af382611a38565b9392505050565b600080600060408486031215611b0f57600080fd5b83359250602084013567ffffffffffffffff80821115611b2e57600080fd5b818601915086601f830112611b4257600080fd5b813581811115611b5157600080fd5b8760208260051b8501011115611b6657600080fd5b6020830194508093505050509250925092565b60008060408385031215611b8c57600080fd5b82359150611b9c60208401611a38565b90509250929050565b600080600060408486031215611bba57600080fd5b833567ffffffffffffffff811115611bd157600080fd5b611bdd86828701611912565b9094509250611bf0905060208501611a38565b90509250925092565b803567ffffffffffffffff81168114611a5c57600080fd5b6020808252818101839052600090604080840186845b878110156107335773ffffffffffffffffffffffffffffffffffffffff611c4d83611a38565b16835267ffffffffffffffff611c64868401611bf9565b16838601529183019190830190600101611c27565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610f4857610f48611c79565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611d1b57611d1b611c79565b5060010190565b803577ffffffffffffffffffffffffffffffffffffffffffffffff81168114611a5c57600080fd5b600060208284031215611d5c57600080fd5b611af382611d22565b60408082528181018490526000908560608401835b87811015611dc15782358252602077ffffffffffffffffffffffffffffffffffffffffffffffff611dac828601611d22565b16908301529183019190830190600101611d7a565b5080935050505073ffffffffffffffffffffffffffffffffffffffff83166020830152949350505050565b600060408284031215611dfe57600080fd5b6040516040810181811067ffffffffffffffff82111715611e2157611e216117ee565b604052611e2d83611a38565b8152611e3b60208401611bf9565b60208201529392505050565b600060208284031215611e5957600080fd5b611af382611bf9565b80820180821115610f4857610f48611c79565b600060208284031215611e8757600080fd5b81518015158114610f4557600080fd5b60008251611ea98184602087016119aa565b919091019291505056fea164736f6c6343000810000a",
}
var RewardManagerABI = RewardManagerMetaData.ABI
@@ -176,9 +181,9 @@ func (_RewardManager *RewardManagerTransactorRaw) Transact(opts *bind.TransactOp
return _RewardManager.Contract.contract.Transact(opts, method, params...)
}
-func (_RewardManager *RewardManagerCaller) GetAvailableRewardPoolIds(opts *bind.CallOpts, recipient common.Address) ([][32]byte, error) {
+func (_RewardManager *RewardManagerCaller) GetAvailableRewardPoolIds(opts *bind.CallOpts, recipient common.Address, startIndex *big.Int, endIndex *big.Int) ([][32]byte, error) {
var out []interface{}
- err := _RewardManager.contract.Call(opts, &out, "getAvailableRewardPoolIds", recipient)
+ err := _RewardManager.contract.Call(opts, &out, "getAvailableRewardPoolIds", recipient, startIndex, endIndex)
if err != nil {
return *new([][32]byte), err
@@ -190,12 +195,34 @@ func (_RewardManager *RewardManagerCaller) GetAvailableRewardPoolIds(opts *bind.
}
-func (_RewardManager *RewardManagerSession) GetAvailableRewardPoolIds(recipient common.Address) ([][32]byte, error) {
- return _RewardManager.Contract.GetAvailableRewardPoolIds(&_RewardManager.CallOpts, recipient)
+func (_RewardManager *RewardManagerSession) GetAvailableRewardPoolIds(recipient common.Address, startIndex *big.Int, endIndex *big.Int) ([][32]byte, error) {
+ return _RewardManager.Contract.GetAvailableRewardPoolIds(&_RewardManager.CallOpts, recipient, startIndex, endIndex)
+}
+
+func (_RewardManager *RewardManagerCallerSession) GetAvailableRewardPoolIds(recipient common.Address, startIndex *big.Int, endIndex *big.Int) ([][32]byte, error) {
+ return _RewardManager.Contract.GetAvailableRewardPoolIds(&_RewardManager.CallOpts, recipient, startIndex, endIndex)
}
-func (_RewardManager *RewardManagerCallerSession) GetAvailableRewardPoolIds(recipient common.Address) ([][32]byte, error) {
- return _RewardManager.Contract.GetAvailableRewardPoolIds(&_RewardManager.CallOpts, recipient)
+func (_RewardManager *RewardManagerCaller) ILinkAddress(opts *bind.CallOpts) (common.Address, error) {
+ var out []interface{}
+ err := _RewardManager.contract.Call(opts, &out, "i_linkAddress")
+
+ if err != nil {
+ return *new(common.Address), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address)
+
+ return out0, err
+
+}
+
+func (_RewardManager *RewardManagerSession) ILinkAddress() (common.Address, error) {
+ return _RewardManager.Contract.ILinkAddress(&_RewardManager.CallOpts)
+}
+
+func (_RewardManager *RewardManagerCallerSession) ILinkAddress() (common.Address, error) {
+ return _RewardManager.Contract.ILinkAddress(&_RewardManager.CallOpts)
}
func (_RewardManager *RewardManagerCaller) Owner(opts *bind.CallOpts) (common.Address, error) {
@@ -286,6 +313,28 @@ func (_RewardManager *RewardManagerCallerSession) SRewardRecipientWeights(arg0 [
return _RewardManager.Contract.SRewardRecipientWeights(&_RewardManager.CallOpts, arg0, arg1)
}
+func (_RewardManager *RewardManagerCaller) SRewardRecipientWeightsSet(opts *bind.CallOpts, arg0 [32]byte) (bool, error) {
+ var out []interface{}
+ err := _RewardManager.contract.Call(opts, &out, "s_rewardRecipientWeightsSet", arg0)
+
+ if err != nil {
+ return *new(bool), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(bool)).(*bool)
+
+ return out0, err
+
+}
+
+func (_RewardManager *RewardManagerSession) SRewardRecipientWeightsSet(arg0 [32]byte) (bool, error) {
+ return _RewardManager.Contract.SRewardRecipientWeightsSet(&_RewardManager.CallOpts, arg0)
+}
+
+func (_RewardManager *RewardManagerCallerSession) SRewardRecipientWeightsSet(arg0 [32]byte) (bool, error) {
+ return _RewardManager.Contract.SRewardRecipientWeightsSet(&_RewardManager.CallOpts, arg0)
+}
+
func (_RewardManager *RewardManagerCaller) STotalRewardRecipientFees(opts *bind.CallOpts, arg0 [32]byte) (*big.Int, error) {
var out []interface{}
err := _RewardManager.contract.Call(opts, &out, "s_totalRewardRecipientFees", arg0)
@@ -308,6 +357,28 @@ func (_RewardManager *RewardManagerCallerSession) STotalRewardRecipientFees(arg0
return _RewardManager.Contract.STotalRewardRecipientFees(&_RewardManager.CallOpts, arg0)
}
+func (_RewardManager *RewardManagerCaller) STotalRewardRecipientFeesLastClaimedAmounts(opts *bind.CallOpts, arg0 [32]byte, arg1 common.Address) (*big.Int, error) {
+ var out []interface{}
+ err := _RewardManager.contract.Call(opts, &out, "s_totalRewardRecipientFeesLastClaimedAmounts", arg0, arg1)
+
+ if err != nil {
+ return *new(*big.Int), err
+ }
+
+ out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
+
+ return out0, err
+
+}
+
+func (_RewardManager *RewardManagerSession) STotalRewardRecipientFeesLastClaimedAmounts(arg0 [32]byte, arg1 common.Address) (*big.Int, error) {
+ return _RewardManager.Contract.STotalRewardRecipientFeesLastClaimedAmounts(&_RewardManager.CallOpts, arg0, arg1)
+}
+
+func (_RewardManager *RewardManagerCallerSession) STotalRewardRecipientFeesLastClaimedAmounts(arg0 [32]byte, arg1 common.Address) (*big.Int, error) {
+ return _RewardManager.Contract.STotalRewardRecipientFeesLastClaimedAmounts(&_RewardManager.CallOpts, arg0, arg1)
+}
+
func (_RewardManager *RewardManagerCaller) SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) {
var out []interface{}
err := _RewardManager.contract.Call(opts, &out, "supportsInterface", interfaceId)
@@ -376,16 +447,16 @@ func (_RewardManager *RewardManagerTransactorSession) ClaimRewards(poolIds [][32
return _RewardManager.Contract.ClaimRewards(&_RewardManager.TransactOpts, poolIds)
}
-func (_RewardManager *RewardManagerTransactor) OnFeePaid(opts *bind.TransactOpts, poolId [32]byte, payee common.Address, amount *big.Int) (*types.Transaction, error) {
- return _RewardManager.contract.Transact(opts, "onFeePaid", poolId, payee, amount)
+func (_RewardManager *RewardManagerTransactor) OnFeePaid(opts *bind.TransactOpts, payments []IRewardManagerFeePayment, payer common.Address) (*types.Transaction, error) {
+ return _RewardManager.contract.Transact(opts, "onFeePaid", payments, payer)
}
-func (_RewardManager *RewardManagerSession) OnFeePaid(poolId [32]byte, payee common.Address, amount *big.Int) (*types.Transaction, error) {
- return _RewardManager.Contract.OnFeePaid(&_RewardManager.TransactOpts, poolId, payee, amount)
+func (_RewardManager *RewardManagerSession) OnFeePaid(payments []IRewardManagerFeePayment, payer common.Address) (*types.Transaction, error) {
+ return _RewardManager.Contract.OnFeePaid(&_RewardManager.TransactOpts, payments, payer)
}
-func (_RewardManager *RewardManagerTransactorSession) OnFeePaid(poolId [32]byte, payee common.Address, amount *big.Int) (*types.Transaction, error) {
- return _RewardManager.Contract.OnFeePaid(&_RewardManager.TransactOpts, poolId, payee, amount)
+func (_RewardManager *RewardManagerTransactorSession) OnFeePaid(payments []IRewardManagerFeePayment, payer common.Address) (*types.Transaction, error) {
+ return _RewardManager.Contract.OnFeePaid(&_RewardManager.TransactOpts, payments, payer)
}
func (_RewardManager *RewardManagerTransactor) PayRecipients(opts *bind.TransactOpts, poolId [32]byte, recipients []common.Address) (*types.Transaction, error) {
@@ -626,9 +697,8 @@ func (it *RewardManagerFeePaidIterator) Close() error {
}
type RewardManagerFeePaid struct {
- PoolId [32]byte
- Payee common.Address
- Quantity *big.Int
+ Payments []IRewardManagerFeePayment
+ Payer common.Address
Raw types.Log
}
@@ -1246,7 +1316,7 @@ func (RewardManagerFeeManagerUpdated) Topic() common.Hash {
}
func (RewardManagerFeePaid) Topic() common.Hash {
- return common.HexToHash("0x0ae7c9bfbc7dfc3426a34852f9a1cdd2f750abec8190abbff0bbe13d8118c30c")
+ return common.HexToHash("0xa1cc025ea76bacce5d740ee4bc331899375dc2c5f2ab33933aaacbd9ba001b66")
}
func (RewardManagerOwnershipTransferRequested) Topic() common.Hash {
@@ -1258,11 +1328,11 @@ func (RewardManagerOwnershipTransferred) Topic() common.Hash {
}
func (RewardManagerRewardRecipientsUpdated) Topic() common.Hash {
- return common.HexToHash("0xe5ca4131deaeb848b5d6a9c0f85795efc54e8a0252eb38d3e77a1efc2b384196")
+ return common.HexToHash("0x8f668d6090683f98b3373a8b83d214da45737f7486cb7de554cc07b54e61cfe6")
}
func (RewardManagerRewardsClaimed) Topic() common.Hash {
- return common.HexToHash("0xfec539b3c42d74cd492c3ecf7966bf014b327beef98e935cdc3ec5e54a6901c7")
+ return common.HexToHash("0x989969655bc1d593922527fe85d71347bb8e12fa423cc71f362dd8ef7cb10ef2")
}
func (_RewardManager *RewardManager) Address() common.Address {
@@ -1270,7 +1340,9 @@ func (_RewardManager *RewardManager) Address() common.Address {
}
type RewardManagerInterface interface {
- GetAvailableRewardPoolIds(opts *bind.CallOpts, recipient common.Address) ([][32]byte, error)
+ GetAvailableRewardPoolIds(opts *bind.CallOpts, recipient common.Address, startIndex *big.Int, endIndex *big.Int) ([][32]byte, error)
+
+ ILinkAddress(opts *bind.CallOpts) (common.Address, error)
Owner(opts *bind.CallOpts) (common.Address, error)
@@ -1280,8 +1352,12 @@ type RewardManagerInterface interface {
SRewardRecipientWeights(opts *bind.CallOpts, arg0 [32]byte, arg1 common.Address) (*big.Int, error)
+ SRewardRecipientWeightsSet(opts *bind.CallOpts, arg0 [32]byte) (bool, error)
+
STotalRewardRecipientFees(opts *bind.CallOpts, arg0 [32]byte) (*big.Int, error)
+ STotalRewardRecipientFeesLastClaimedAmounts(opts *bind.CallOpts, arg0 [32]byte, arg1 common.Address) (*big.Int, error)
+
SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error)
TypeAndVersion(opts *bind.CallOpts) (string, error)
@@ -1290,7 +1366,7 @@ type RewardManagerInterface interface {
ClaimRewards(opts *bind.TransactOpts, poolIds [][32]byte) (*types.Transaction, error)
- OnFeePaid(opts *bind.TransactOpts, poolId [32]byte, payee common.Address, amount *big.Int) (*types.Transaction, error)
+ OnFeePaid(opts *bind.TransactOpts, payments []IRewardManagerFeePayment, payer common.Address) (*types.Transaction, error)
PayRecipients(opts *bind.TransactOpts, poolId [32]byte, recipients []common.Address) (*types.Transaction, error)
diff --git a/core/gethwrappers/llo-feeds/generated/verifier/verifier.go b/core/gethwrappers/llo-feeds/generated/verifier/verifier.go
index 7830951f646..993de18eb57 100644
--- a/core/gethwrappers/llo-feeds/generated/verifier/verifier.go
+++ b/core/gethwrappers/llo-feeds/generated/verifier/verifier.go
@@ -32,12 +32,12 @@ var (
type CommonAddressAndWeight struct {
Addr common.Address
- Weight *big.Int
+ Weight uint64
}
var VerifierMetaData = &bind.MetaData{
- ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"verifierProxyAddr\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"AccessForbidden\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BadVerification\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"CannotDeactivateLatestConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DigestEmpty\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"DigestInactive\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"DigestNotSet\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"numSigners\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxSigners\",\"type\":\"uint256\"}],\"name\":\"ExcessSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FaultToleranceMustBePositive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FeedIdEmpty\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"}],\"name\":\"InactiveFeed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"numSigners\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"expectedNumSigners\",\"type\":\"uint256\"}],\"name\":\"IncorrectSignatureCount\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"numSigners\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"minSigners\",\"type\":\"uint256\"}],\"name\":\"InsufficientSigners\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"}],\"name\":\"InvalidFeed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"rsLength\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"ssLength\",\"type\":\"uint256\"}],\"name\":\"MismatchedSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonUniqueSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"ConfigActivated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"ConfigDeactivated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"bytes32[]\",\"name\":\"offchainTransmitters\",\"type\":\"bytes32[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"}],\"name\":\"FeedActivated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"}],\"name\":\"FeedDeactivated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"requester\",\"type\":\"address\"}],\"name\":\"ReportVerified\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"activateConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"}],\"name\":\"activateFeed\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"deactivateConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"}],\"name\":\"deactivateFeed\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"}],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"}],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"offchainTransmitters\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"weight\",\"type\":\"uint256\"}],\"internalType\":\"structCommon.AddressAndWeight[]\",\"name\":\"recipientAddressesAndWeights\",\"type\":\"tuple[]\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"sourceChainId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"sourceAddress\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"offchainTransmitters\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"weight\",\"type\":\"uint256\"}],\"internalType\":\"structCommon.AddressAndWeight[]\",\"name\":\"recipientAddressesAndWeights\",\"type\":\"tuple[]\"}],\"name\":\"setConfigFromSource\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isVerifier\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"signedReport\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]",
- Bin: "0x60a06040523480156200001157600080fd5b5060405162002362380380620023628339810160408190526200003491620001a6565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000fb565b5050506001600160a01b038116620000e95760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b0316608052620001d8565b336001600160a01b03821603620001555760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600060208284031215620001b957600080fd5b81516001600160a01b0381168114620001d157600080fd5b9392505050565b608051612167620001fb6000396000818161033b01526112cf01526121676000f3fe608060405234801561001057600080fd5b50600436106100ea5760003560e01c80638da5cb5b1161008c578063b70d929d11610066578063b70d929d1461023f578063ded6307c1461029e578063e84f128e146102b1578063f2fde38b1461030e57600080fd5b80638da5cb5b146101f157806394d95980146102195780639b103f131461022c57600080fd5b80633dd86430116100c85780633dd86430146101ae57806352ba27d6146101c3578063564a0a7a146101d657806379ba5097146101e957600080fd5b806301ffc9a7146100ef578063181f5a77146101595780633d3ac1b51461019b575b600080fd5b6101446100fd366004611580565b7fffffffff00000000000000000000000000000000000000000000000000000000167f3d3ac1b5000000000000000000000000000000000000000000000000000000001490565b60405190151581526020015b60405180910390f35b60408051808201909152600e81527f566572696669657220312e312e3000000000000000000000000000000000000060208201525b604051610150919061162d565b61018e6101a9366004611669565b610321565b6101c16101bc3660046116ea565b6104bb565b005b6101c16101d13660046119fb565b61056d565b6101c16101e43660046116ea565b61067b565b6101c161073c565b60005460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610150565b6101c1610227366004611af8565b610839565b6101c161023a366004611b1a565b61099a565b61027b61024d3660046116ea565b6000908152600260205260408120600181015490549192909168010000000000000000900463ffffffff1690565b604080519315158452602084019290925263ffffffff1690820152606001610150565b6101c16102ac366004611af8565b610a64565b6102eb6102bf3660046116ea565b6000908152600260205260409020805460019091015463ffffffff808316936401000000009093041691565b6040805163ffffffff948516815293909216602084015290820152606001610150565b6101c161031c366004611c33565b610b75565b60603373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610392576040517fef67f5d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000808080806103a4888a018a611c4e565b945094509450945094506000846103ba90611d29565b60008181526002602052604090208054919250906c01000000000000000000000000900460ff1615610420576040517f36dbe748000000000000000000000000000000000000000000000000000000008152600481018390526024015b60405180910390fd5b86516000818152600283016020526040902061043f8483898985610b89565b6104498984610c85565b8751602089012061045e818b8a8a8a87610ced565b60405173ffffffffffffffffffffffffffffffffffffffff8d16815285907f58ca9502e98a536e06e72d680fcc251e5d10b72291a281665a2c2dc0ac30fcc59060200160405180910390a250969c9b505050505050505050505050565b6104c3610f69565b60008181526002602052604081208054909163ffffffff9091169003610518576040517fa25b0b9600000000000000000000000000000000000000000000000000000000815260048101839052602401610417565b80547fffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffff16815560405182907ff438564f793525caa89c6e3a26d41e16aa39d1e589747595751e3f3df75cb2b490600090a25050565b86518560ff16806000036105ad576040517f0743bae600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601f8211156105f2576040517f61750f4000000000000000000000000000000000000000000000000000000000815260048101839052601f6024820152604401610417565b6105fd816003611dcc565b8211610655578161060f826003611dcc565b61061a906001611e09565b6040517f9dd9e6d800000000000000000000000000000000000000000000000000000000815260048101929092526024820152604401610417565b61065d610f69565b61066f8a46308c8c8c8c8c8c8c610fec565b50505050505050505050565b610683610f69565b60008181526002602052604081208054909163ffffffff90911690036106d8576040517fa25b0b9600000000000000000000000000000000000000000000000000000000815260048101839052602401610417565b80547fffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffff166c0100000000000000000000000017815560405182907ffc4f79b8c65b6be1773063461984c0974400d1e99654c79477a092ace83fd06190600090a25050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146107bd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610417565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610841610f69565b600082815260026020526040902081610886576040517fe332262700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260028201602052604081205460ff1690036108dc576040517f8bca63110000000000000000000000000000000000000000000000000000000081526004810184905260248101839052604401610417565b80600101548203610923576040517fa403c0160000000000000000000000000000000000000000000000000000000081526004810184905260248101839052604401610417565b60008281526002820160205260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1690555183907f0e173bea63a8c59ec70bf87043f2a729693790183f16a1a54b705de9e989cc4c9061098d9085815260200190565b60405180910390a2505050565b86518560ff16806000036109da576040517f0743bae600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601f821115610a1f576040517f61750f4000000000000000000000000000000000000000000000000000000000815260048101839052601f6024820152604401610417565b610a2a816003611dcc565b8211610a3c578161060f826003611dcc565b610a44610f69565b610a568c8c8c8c8c8c8c8c8c8c610fec565b505050505050505050505050565b610a6c610f69565b600082815260026020526040902081610ab1576040517fe332262700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260028201602052604081205460ff169003610b07576040517f8bca63110000000000000000000000000000000000000000000000000000000081526004810184905260248101839052604401610417565b60008281526002820160205260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555183907f54f8872b9b94ebea6577f33576d55847bd8ea22641ccc886b965f6e50bfe77469061098d9085815260200190565b610b7d610f69565b610b86816113dd565b50565b8054600090610b9c9060ff166001611e22565b8254909150610100900460ff16610be9576040517ffc10a2830000000000000000000000000000000000000000000000000000000081526004810187905260248101869052604401610417565b8060ff16845114610c355783516040517f5348a282000000000000000000000000000000000000000000000000000000008152600481019190915260ff82166024820152604401610417565b8251845114610c7d57835183516040517ff0d3140800000000000000000000000000000000000000000000000000000000815260048101929092526024820152604401610417565b505050505050565b6020820151815463ffffffff600883901c81169168010000000000000000900416811115610ce75782547fffffffffffffffffffffffffffffffffffffffff00000000ffffffffffffffff166801000000000000000063ffffffff8316021783555b50505050565b60008686604051602001610d02929190611e3b565b6040516020818303038152906040528051906020012090506000610d36604080518082019091526000808252602082015290565b8651600090815b81811015610f0157600186898360208110610d5a57610d5a611d6e565b610d6791901a601b611e22565b8c8481518110610d7957610d79611d6e565b60200260200101518c8581518110610d9357610d93611d6e565b602002602001015160405160008152602001604052604051610dd1949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015610df3573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff811660009081526001808d01602090815291859020848601909552845460ff808216865293995093955090850192610100900490911690811115610e7857610e78611e77565b6001811115610e8957610e89611e77565b9052509350600184602001516001811115610ea657610ea6611e77565b14610edd576040517f4df18f0700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b836000015160080260ff166001901b8501945080610efa90611ea6565b9050610d3d565b50837e01010101010101010101010101010101010101010101010101010101010101851614610f5c576040517f4df18f0700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610fea576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610417565b565b60008a81526002602052604081208054909163ffffffff90911690829061101283611ede565b82546101009290920a63ffffffff81810219909316918316021790915582546000925061104b918e918e918e91168d8d8d8d8d8d6114d2565b6000818152600284016020526040812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff8b16176101001790559091505b89518160ff16101561128c5760008a8260ff16815181106110b1576110b1611d6e565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611121576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000806000858152600287016020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168452600190810190925290912054610100900460ff169081111561117457611174611e77565b14801591506111af576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff8416815260208101600190526000858152600287016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684526001908101835292208351815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00821681178355928501519193919284927fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909216179061010090849081111561127157611271611e77565b021790555090505050508061128590611f01565b905061108e565b5060018201546040517f589ede2800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169163589ede2891611307919085908890600401611f20565b600060405180830381600087803b15801561132157600080fd5b505af1158015611335573d6000803e3d6000fd5b505083546040518f93507fa23a88453230b183877098801ff5a8f771a120e2573eea559ce6c4c2e305a4da925061138e9163ffffffff6401000000008204811692879291909116908f908f908f908f908f908f90612017565b60405180910390a281547fffffffffffffffffffffffffffffffffffffffff0000000000000000ffffffff1664010000000063ffffffff43160217825560019091015550505050505050505050565b3373ffffffffffffffffffffffffffffffffffffffff82160361145c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610417565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000808b8b8b8b8b8b8b8b8b8b6040516020016114f89a999897969594939291906120ad565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e06000000000000000000000000000000000000000000000000000000000000179150509a9950505050505050505050565b60006020828403121561159257600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146115c257600080fd5b9392505050565b6000815180845260005b818110156115ef576020818501810151868301820152016115d3565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b6020815260006115c260208301846115c9565b803573ffffffffffffffffffffffffffffffffffffffff8116811461166457600080fd5b919050565b60008060006040848603121561167e57600080fd5b833567ffffffffffffffff8082111561169657600080fd5b818601915086601f8301126116aa57600080fd5b8135818111156116b957600080fd5b8760208285010111156116cb57600080fd5b6020928301955093506116e19186019050611640565b90509250925092565b6000602082840312156116fc57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff8111828210171561175557611755611703565b60405290565b6040516060810167ffffffffffffffff8111828210171561175557611755611703565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156117c5576117c5611703565b604052919050565b600067ffffffffffffffff8211156117e7576117e7611703565b5060051b60200190565b600082601f83011261180257600080fd5b81356020611817611812836117cd565b61177e565b82815260059290921b8401810191818101908684111561183657600080fd5b8286015b848110156118585761184b81611640565b835291830191830161183a565b509695505050505050565b600082601f83011261187457600080fd5b81356020611884611812836117cd565b82815260059290921b840181019181810190868411156118a357600080fd5b8286015b8481101561185857803583529183019183016118a7565b803560ff8116811461166457600080fd5b600082601f8301126118e057600080fd5b813567ffffffffffffffff8111156118fa576118fa611703565b61192b60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8401160161177e565b81815284602083860101111561194057600080fd5b816020850160208301376000918101602001919091529392505050565b803567ffffffffffffffff8116811461166457600080fd5b600082601f83011261198657600080fd5b81356020611996611812836117cd565b82815260069290921b840181019181810190868411156119b557600080fd5b8286015b8481101561185857604081890312156119d25760008081fd5b6119da611732565b6119e382611640565b815281850135858201528352918301916040016119b9565b600080600080600080600080610100898b031215611a1857600080fd5b88359750602089013567ffffffffffffffff80821115611a3757600080fd5b611a438c838d016117f1565b985060408b0135915080821115611a5957600080fd5b611a658c838d01611863565b9750611a7360608c016118be565b965060808b0135915080821115611a8957600080fd5b611a958c838d016118cf565b9550611aa360a08c0161195d565b945060c08b0135915080821115611ab957600080fd5b611ac58c838d016118cf565b935060e08b0135915080821115611adb57600080fd5b50611ae88b828c01611975565b9150509295985092959890939650565b60008060408385031215611b0b57600080fd5b50508035926020909101359150565b6000806000806000806000806000806101408b8d031215611b3a57600080fd5b8a35995060208b01359850611b5160408c01611640565b975060608b013567ffffffffffffffff80821115611b6e57600080fd5b611b7a8e838f016117f1565b985060808d0135915080821115611b9057600080fd5b611b9c8e838f01611863565b9750611baa60a08e016118be565b965060c08d0135915080821115611bc057600080fd5b611bcc8e838f016118cf565b9550611bda60e08e0161195d565b94506101008d0135915080821115611bf157600080fd5b611bfd8e838f016118cf565b93506101208d0135915080821115611c1457600080fd5b50611c218d828e01611975565b9150509295989b9194979a5092959850565b600060208284031215611c4557600080fd5b6115c282611640565b600080600080600060e08688031215611c6657600080fd5b86601f870112611c7557600080fd5b611c7d61175b565b806060880189811115611c8f57600080fd5b885b81811015611ca9578035845260209384019301611c91565b5090965035905067ffffffffffffffff80821115611cc657600080fd5b611cd289838a016118cf565b95506080880135915080821115611ce857600080fd5b611cf489838a01611863565b945060a0880135915080821115611d0a57600080fd5b50611d1788828901611863565b9598949750929560c001359392505050565b80516020808301519190811015611d68577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8160200360031b1b821691505b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615611e0457611e04611d9d565b500290565b80820180821115611e1c57611e1c611d9d565b92915050565b60ff8181168382160190811115611e1c57611e1c611d9d565b828152600060208083018460005b6003811015611e6657815183529183019190830190600101611e49565b505050506080820190509392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611ed757611ed7611d9d565b5060010190565b600063ffffffff808316818103611ef757611ef7611d9d565b6001019392505050565b600060ff821660ff8103611f1757611f17611d9d565b60010192915050565b600060608201858352602085818501526040606081860152828651808552608087019150838801945060005b81811015611f87578551805173ffffffffffffffffffffffffffffffffffffffff168452850151858401529484019491830191600101611f4c565b50909998505050505050505050565b600081518084526020808501945080840160005b83811015611fdc57815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101611faa565b509495945050505050565b600081518084526020808501945080840160005b83811015611fdc57815187529582019590820190600101611ffb565b600061012063ffffffff808d1684528b6020850152808b166040850152508060608401526120478184018a611f96565b9050828103608084015261205b8189611fe7565b905060ff871660a084015282810360c084015261207881876115c9565b905067ffffffffffffffff851660e084015282810361010084015261209d81856115c9565b9c9b505050505050505050505050565b60006101408c83528b602084015273ffffffffffffffffffffffffffffffffffffffff8b16604084015267ffffffffffffffff808b1660608501528160808501526120fa8285018b611f96565b915083820360a085015261210e828a611fe7565b915060ff881660c085015283820360e085015261212b82886115c9565b908616610100850152838103610120850152905061214981856115c9565b9d9c5050505050505050505050505056fea164736f6c6343000810000a",
+ ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"verifierProxyAddr\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"AccessForbidden\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BadVerification\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"CannotDeactivateLatestConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DigestEmpty\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"DigestInactive\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"DigestNotSet\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"numSigners\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxSigners\",\"type\":\"uint256\"}],\"name\":\"ExcessSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FaultToleranceMustBePositive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FeedIdEmpty\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"}],\"name\":\"InactiveFeed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"numSigners\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"expectedNumSigners\",\"type\":\"uint256\"}],\"name\":\"IncorrectSignatureCount\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"numSigners\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"minSigners\",\"type\":\"uint256\"}],\"name\":\"InsufficientSigners\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"}],\"name\":\"InvalidFeed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"rsLength\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"ssLength\",\"type\":\"uint256\"}],\"name\":\"MismatchedSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonUniqueSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"ConfigActivated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"ConfigDeactivated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"bytes32[]\",\"name\":\"offchainTransmitters\",\"type\":\"bytes32[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"}],\"name\":\"FeedActivated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"}],\"name\":\"FeedDeactivated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"requester\",\"type\":\"address\"}],\"name\":\"ReportVerified\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"activateConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"}],\"name\":\"activateFeed\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"deactivateConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"}],\"name\":\"deactivateFeed\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"}],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"}],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"offchainTransmitters\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"internalType\":\"structCommon.AddressAndWeight[]\",\"name\":\"recipientAddressesAndWeights\",\"type\":\"tuple[]\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"feedId\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"sourceChainId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"sourceAddress\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"newConfigCount\",\"type\":\"uint32\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"offchainTransmitters\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"internalType\":\"structCommon.AddressAndWeight[]\",\"name\":\"recipientAddressesAndWeights\",\"type\":\"tuple[]\"}],\"name\":\"setConfigFromSource\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isVerifier\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"signedReport\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"verifierResponse\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]",
+ Bin: "0x60a06040523480156200001157600080fd5b50604051620023fb380380620023fb8339810160408190526200003491620001a6565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000fb565b5050506001600160a01b038116620000e95760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b0316608052620001d8565b336001600160a01b03821603620001555760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600060208284031215620001b957600080fd5b81516001600160a01b0381168114620001d157600080fd5b9392505050565b608051612200620001fb6000396000818161033b015261131501526122006000f3fe608060405234801561001057600080fd5b50600436106100ea5760003560e01c806394d959801161008c578063e7db9c2a11610066578063e7db9c2a1461028b578063e84f128e1461029e578063f0107221146102fb578063f2fde38b1461030e57600080fd5b806394d9598014610206578063b70d929d14610219578063ded6307c1461027857600080fd5b80633dd86430116100c85780633dd86430146101ae578063564a0a7a146101c357806379ba5097146101d65780638da5cb5b146101de57600080fd5b806301ffc9a7146100ef578063181f5a77146101595780633d3ac1b51461019b575b600080fd5b6101446100fd3660046115da565b7fffffffff00000000000000000000000000000000000000000000000000000000167f3d3ac1b5000000000000000000000000000000000000000000000000000000001490565b60405190151581526020015b60405180910390f35b60408051808201909152600e81527f566572696669657220312e322e3000000000000000000000000000000000000060208201525b6040516101509190611687565b61018e6101a93660046116c3565b610321565b6101c16101bc366004611744565b6104bb565b005b6101c16101d1366004611744565b61056d565b6101c161062e565b60005460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610150565b6101c161021436600461175d565b61072b565b610255610227366004611744565b6000908152600260205260408120600181015490549192909168010000000000000000900463ffffffff1690565b604080519315158452602084019290925263ffffffff1690820152606001610150565b6101c161028636600461175d565b61088c565b6101c1610299366004611a92565b61099d565b6102d86102ac366004611744565b6000908152600260205260409020805460019091015463ffffffff808316936401000000009093041691565b6040805163ffffffff948516815293909216602084015290820152606001610150565b6101c1610309366004611bc5565b610aaf565b6101c161031c366004611cc2565b610b79565b60603373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610392576040517fef67f5d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000808080806103a4888a018a611cdd565b945094509450945094506000846103ba90611db8565b60008181526002602052604090208054919250906c01000000000000000000000000900460ff1615610420576040517f36dbe748000000000000000000000000000000000000000000000000000000008152600481018390526024015b60405180910390fd5b86516000818152600283016020526040902061043f8483898985610b8d565b6104498984610c89565b8751602089012061045e818b8a8a8a87610cf1565b60405173ffffffffffffffffffffffffffffffffffffffff8d16815285907f58ca9502e98a536e06e72d680fcc251e5d10b72291a281665a2c2dc0ac30fcc59060200160405180910390a250969c9b505050505050505050505050565b6104c3610f6d565b60008181526002602052604081208054909163ffffffff9091169003610518576040517fa25b0b9600000000000000000000000000000000000000000000000000000000815260048101839052602401610417565b80547fffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffff16815560405182907ff438564f793525caa89c6e3a26d41e16aa39d1e589747595751e3f3df75cb2b490600090a25050565b610575610f6d565b60008181526002602052604081208054909163ffffffff90911690036105ca576040517fa25b0b9600000000000000000000000000000000000000000000000000000000815260048101839052602401610417565b80547fffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffff166c0100000000000000000000000017815560405182907ffc4f79b8c65b6be1773063461984c0974400d1e99654c79477a092ace83fd06190600090a25050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146106af576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610417565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610733610f6d565b600082815260026020526040902081610778576040517fe332262700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260028201602052604081205460ff1690036107ce576040517f8bca63110000000000000000000000000000000000000000000000000000000081526004810184905260248101839052604401610417565b80600101548203610815576040517fa403c0160000000000000000000000000000000000000000000000000000000081526004810184905260248101839052604401610417565b60008281526002820160205260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1690555183907f0e173bea63a8c59ec70bf87043f2a729693790183f16a1a54b705de9e989cc4c9061087f9085815260200190565b60405180910390a2505050565b610894610f6d565b6000828152600260205260409020816108d9576040517fe332262700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260028201602052604081205460ff16900361092f576040517f8bca63110000000000000000000000000000000000000000000000000000000081526004810184905260248101839052604401610417565b60008281526002820160205260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555183907f54f8872b9b94ebea6577f33576d55847bd8ea22641ccc886b965f6e50bfe77469061087f9085815260200190565b86518560ff16806000036109dd576040517f0743bae600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601f821115610a22576040517f61750f4000000000000000000000000000000000000000000000000000000000815260048101839052601f6024820152604401610417565b610a2d816003611e5b565b8211610a855781610a3f826003611e5b565b610a4a906001611e98565b6040517f9dd9e6d800000000000000000000000000000000000000000000000000000000815260048101929092526024820152604401610417565b610a8d610f6d565b610aa08d8d8d8d8d8d8d8d8d8d8d610ff0565b50505050505050505050505050565b86518560ff1680600003610aef576040517f0743bae600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601f821115610b34576040517f61750f4000000000000000000000000000000000000000000000000000000000815260048101839052601f6024820152604401610417565b610b3f816003611e5b565b8211610b515781610a3f826003611e5b565b610b59610f6d565b610b6d8a463060008d8d8d8d8d8d8d610ff0565b50505050505050505050565b610b81610f6d565b610b8a81611437565b50565b8054600090610ba09060ff166001611eb1565b8254909150610100900460ff16610bed576040517ffc10a2830000000000000000000000000000000000000000000000000000000081526004810187905260248101869052604401610417565b8060ff16845114610c395783516040517f5348a282000000000000000000000000000000000000000000000000000000008152600481019190915260ff82166024820152604401610417565b8251845114610c8157835183516040517ff0d3140800000000000000000000000000000000000000000000000000000000815260048101929092526024820152604401610417565b505050505050565b6020820151815463ffffffff600883901c81169168010000000000000000900416811115610ceb5782547fffffffffffffffffffffffffffffffffffffffff00000000ffffffffffffffff166801000000000000000063ffffffff8316021783555b50505050565b60008686604051602001610d06929190611eca565b6040516020818303038152906040528051906020012090506000610d3a604080518082019091526000808252602082015290565b8651600090815b81811015610f0557600186898360208110610d5e57610d5e611dfd565b610d6b91901a601b611eb1565b8c8481518110610d7d57610d7d611dfd565b60200260200101518c8581518110610d9757610d97611dfd565b602002602001015160405160008152602001604052604051610dd5949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015610df7573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff811660009081526001808d01602090815291859020848601909552845460ff808216865293995093955090850192610100900490911690811115610e7c57610e7c611f06565b6001811115610e8d57610e8d611f06565b9052509350600184602001516001811115610eaa57610eaa611f06565b14610ee1576040517f4df18f0700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b836000015160080260ff166001901b8501945080610efe90611f35565b9050610d41565b50837e01010101010101010101010101010101010101010101010101010101010101851614610f60576040517f4df18f0700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610fee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610417565b565b60008b815260026020526040902063ffffffff89161561103d5780547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff8a16178155611071565b805463ffffffff1681600061105183611f6d565b91906101000a81548163ffffffff021916908363ffffffff160217905550505b8054600090611091908e908e908e9063ffffffff168d8d8d8d8d8d61152c565b6000818152600284016020526040812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff8b16176101001790559091505b89518160ff1610156112d25760008a8260ff16815181106110f7576110f7611dfd565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611167576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000806000858152600287016020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168452600190810190925290912054610100900460ff16908111156111ba576111ba611f06565b14801591506111f5576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff8416815260208101600190526000858152600287016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684526001908101835292208351815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00821681178355928501519193919284927fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000090921617906101009084908111156112b7576112b7611f06565b02179055509050505050806112cb90611f90565b90506110d4565b5060018201546040517fb011b24700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169163b011b2479161134d919085908890600401611faf565b600060405180830381600087803b15801561136757600080fd5b505af115801561137b573d6000803e3d6000fd5b505050508c7fa23a88453230b183877098801ff5a8f771a120e2573eea559ce6c4c2e305a4da8360000160049054906101000a900463ffffffff16838560000160009054906101000a900463ffffffff168d8d8d8d8d8d6040516113e7999897969594939291906120b0565b60405180910390a281547fffffffffffffffffffffffffffffffffffffffff0000000000000000ffffffff1664010000000063ffffffff4316021782556001909101555050505050505050505050565b3373ffffffffffffffffffffffffffffffffffffffff8216036114b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610417565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000808b8b8b8b8b8b8b8b8b8b6040516020016115529a99989796959493929190612146565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e06000000000000000000000000000000000000000000000000000000000000179150509a9950505050505050505050565b6000602082840312156115ec57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461161c57600080fd5b9392505050565b6000815180845260005b818110156116495760208185018101518683018201520161162d565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152600061161c6020830184611623565b803573ffffffffffffffffffffffffffffffffffffffff811681146116be57600080fd5b919050565b6000806000604084860312156116d857600080fd5b833567ffffffffffffffff808211156116f057600080fd5b818601915086601f83011261170457600080fd5b81358181111561171357600080fd5b87602082850101111561172557600080fd5b60209283019550935061173b918601905061169a565b90509250925092565b60006020828403121561175657600080fd5b5035919050565b6000806040838503121561177057600080fd5b50508035926020909101359150565b803563ffffffff811681146116be57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156117e5576117e5611793565b60405290565b6040516060810167ffffffffffffffff811182821017156117e5576117e5611793565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561185557611855611793565b604052919050565b600067ffffffffffffffff82111561187757611877611793565b5060051b60200190565b600082601f83011261189257600080fd5b813560206118a76118a28361185d565b61180e565b82815260059290921b840181019181810190868411156118c657600080fd5b8286015b848110156118e8576118db8161169a565b83529183019183016118ca565b509695505050505050565b600082601f83011261190457600080fd5b813560206119146118a28361185d565b82815260059290921b8401810191818101908684111561193357600080fd5b8286015b848110156118e85780358352918301918301611937565b803560ff811681146116be57600080fd5b600082601f83011261197057600080fd5b813567ffffffffffffffff81111561198a5761198a611793565b6119bb60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8401160161180e565b8181528460208386010111156119d057600080fd5b816020850160208301376000918101602001919091529392505050565b803567ffffffffffffffff811681146116be57600080fd5b600082601f830112611a1657600080fd5b81356020611a266118a28361185d565b82815260069290921b84018101918181019086841115611a4557600080fd5b8286015b848110156118e85760408189031215611a625760008081fd5b611a6a6117c2565b611a738261169a565b8152611a808583016119ed565b81860152835291830191604001611a49565b60008060008060008060008060008060006101608c8e031215611ab457600080fd5b8b359a5060208c01359950611acb60408d0161169a565b9850611ad960608d0161177f565b975067ffffffffffffffff8060808e01351115611af557600080fd5b611b058e60808f01358f01611881565b97508060a08e01351115611b1857600080fd5b611b288e60a08f01358f016118f3565b9650611b3660c08e0161194e565b95508060e08e01351115611b4957600080fd5b611b598e60e08f01358f0161195f565b9450611b686101008e016119ed565b9350806101208e01351115611b7c57600080fd5b611b8d8e6101208f01358f0161195f565b9250806101408e01351115611ba157600080fd5b50611bb38d6101408e01358e01611a05565b90509295989b509295989b9093969950565b600080600080600080600080610100898b031215611be257600080fd5b88359750602089013567ffffffffffffffff80821115611c0157600080fd5b611c0d8c838d01611881565b985060408b0135915080821115611c2357600080fd5b611c2f8c838d016118f3565b9750611c3d60608c0161194e565b965060808b0135915080821115611c5357600080fd5b611c5f8c838d0161195f565b9550611c6d60a08c016119ed565b945060c08b0135915080821115611c8357600080fd5b611c8f8c838d0161195f565b935060e08b0135915080821115611ca557600080fd5b50611cb28b828c01611a05565b9150509295985092959890939650565b600060208284031215611cd457600080fd5b61161c8261169a565b600080600080600060e08688031215611cf557600080fd5b86601f870112611d0457600080fd5b611d0c6117eb565b806060880189811115611d1e57600080fd5b885b81811015611d38578035845260209384019301611d20565b5090965035905067ffffffffffffffff80821115611d5557600080fd5b611d6189838a0161195f565b95506080880135915080821115611d7757600080fd5b611d8389838a016118f3565b945060a0880135915080821115611d9957600080fd5b50611da6888289016118f3565b9598949750929560c001359392505050565b80516020808301519190811015611df7577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8160200360031b1b821691505b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615611e9357611e93611e2c565b500290565b80820180821115611eab57611eab611e2c565b92915050565b60ff8181168382160190811115611eab57611eab611e2c565b828152600060208083018460005b6003811015611ef557815183529183019190830190600101611ed8565b505050506080820190509392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611f6657611f66611e2c565b5060010190565b600063ffffffff808316818103611f8657611f86611e2c565b6001019392505050565b600060ff821660ff8103611fa657611fa6611e2c565b60010192915050565b600060608201858352602085818501526040606081860152828651808552608087019150838801945060005b81811015612020578551805173ffffffffffffffffffffffffffffffffffffffff16845285015167ffffffffffffffff16858401529484019491830191600101611fdb565b50909998505050505050505050565b600081518084526020808501945080840160005b8381101561207557815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101612043565b509495945050505050565b600081518084526020808501945080840160005b8381101561207557815187529582019590820190600101612094565b600061012063ffffffff808d1684528b6020850152808b166040850152508060608401526120e08184018a61202f565b905082810360808401526120f48189612080565b905060ff871660a084015282810360c08401526121118187611623565b905067ffffffffffffffff851660e08401528281036101008401526121368185611623565b9c9b505050505050505050505050565b60006101408c83528b602084015273ffffffffffffffffffffffffffffffffffffffff8b16604084015267ffffffffffffffff808b1660608501528160808501526121938285018b61202f565b915083820360a08501526121a7828a612080565b915060ff881660c085015283820360e08501526121c48288611623565b90861661010085015283810361012085015290506121e28185611623565b9d9c5050505050505050505050505056fea164736f6c6343000810000a",
}
var VerifierABI = VerifierMetaData.ABI
@@ -376,16 +376,16 @@ func (_Verifier *VerifierTransactorSession) SetConfig(feedId [32]byte, signers [
return _Verifier.Contract.SetConfig(&_Verifier.TransactOpts, feedId, signers, offchainTransmitters, f, onchainConfig, offchainConfigVersion, offchainConfig, recipientAddressesAndWeights)
}
-func (_Verifier *VerifierTransactor) SetConfigFromSource(opts *bind.TransactOpts, feedId [32]byte, sourceChainId *big.Int, sourceAddress common.Address, signers []common.Address, offchainTransmitters [][32]byte, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte, recipientAddressesAndWeights []CommonAddressAndWeight) (*types.Transaction, error) {
- return _Verifier.contract.Transact(opts, "setConfigFromSource", feedId, sourceChainId, sourceAddress, signers, offchainTransmitters, f, onchainConfig, offchainConfigVersion, offchainConfig, recipientAddressesAndWeights)
+func (_Verifier *VerifierTransactor) SetConfigFromSource(opts *bind.TransactOpts, feedId [32]byte, sourceChainId *big.Int, sourceAddress common.Address, newConfigCount uint32, signers []common.Address, offchainTransmitters [][32]byte, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte, recipientAddressesAndWeights []CommonAddressAndWeight) (*types.Transaction, error) {
+ return _Verifier.contract.Transact(opts, "setConfigFromSource", feedId, sourceChainId, sourceAddress, newConfigCount, signers, offchainTransmitters, f, onchainConfig, offchainConfigVersion, offchainConfig, recipientAddressesAndWeights)
}
-func (_Verifier *VerifierSession) SetConfigFromSource(feedId [32]byte, sourceChainId *big.Int, sourceAddress common.Address, signers []common.Address, offchainTransmitters [][32]byte, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte, recipientAddressesAndWeights []CommonAddressAndWeight) (*types.Transaction, error) {
- return _Verifier.Contract.SetConfigFromSource(&_Verifier.TransactOpts, feedId, sourceChainId, sourceAddress, signers, offchainTransmitters, f, onchainConfig, offchainConfigVersion, offchainConfig, recipientAddressesAndWeights)
+func (_Verifier *VerifierSession) SetConfigFromSource(feedId [32]byte, sourceChainId *big.Int, sourceAddress common.Address, newConfigCount uint32, signers []common.Address, offchainTransmitters [][32]byte, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte, recipientAddressesAndWeights []CommonAddressAndWeight) (*types.Transaction, error) {
+ return _Verifier.Contract.SetConfigFromSource(&_Verifier.TransactOpts, feedId, sourceChainId, sourceAddress, newConfigCount, signers, offchainTransmitters, f, onchainConfig, offchainConfigVersion, offchainConfig, recipientAddressesAndWeights)
}
-func (_Verifier *VerifierTransactorSession) SetConfigFromSource(feedId [32]byte, sourceChainId *big.Int, sourceAddress common.Address, signers []common.Address, offchainTransmitters [][32]byte, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte, recipientAddressesAndWeights []CommonAddressAndWeight) (*types.Transaction, error) {
- return _Verifier.Contract.SetConfigFromSource(&_Verifier.TransactOpts, feedId, sourceChainId, sourceAddress, signers, offchainTransmitters, f, onchainConfig, offchainConfigVersion, offchainConfig, recipientAddressesAndWeights)
+func (_Verifier *VerifierTransactorSession) SetConfigFromSource(feedId [32]byte, sourceChainId *big.Int, sourceAddress common.Address, newConfigCount uint32, signers []common.Address, offchainTransmitters [][32]byte, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte, recipientAddressesAndWeights []CommonAddressAndWeight) (*types.Transaction, error) {
+ return _Verifier.Contract.SetConfigFromSource(&_Verifier.TransactOpts, feedId, sourceChainId, sourceAddress, newConfigCount, signers, offchainTransmitters, f, onchainConfig, offchainConfigVersion, offchainConfig, recipientAddressesAndWeights)
}
func (_Verifier *VerifierTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) {
@@ -1556,7 +1556,7 @@ type VerifierInterface interface {
SetConfig(opts *bind.TransactOpts, feedId [32]byte, signers []common.Address, offchainTransmitters [][32]byte, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte, recipientAddressesAndWeights []CommonAddressAndWeight) (*types.Transaction, error)
- SetConfigFromSource(opts *bind.TransactOpts, feedId [32]byte, sourceChainId *big.Int, sourceAddress common.Address, signers []common.Address, offchainTransmitters [][32]byte, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte, recipientAddressesAndWeights []CommonAddressAndWeight) (*types.Transaction, error)
+ SetConfigFromSource(opts *bind.TransactOpts, feedId [32]byte, sourceChainId *big.Int, sourceAddress common.Address, newConfigCount uint32, signers []common.Address, offchainTransmitters [][32]byte, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte, recipientAddressesAndWeights []CommonAddressAndWeight) (*types.Transaction, error)
TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error)
diff --git a/core/gethwrappers/llo-feeds/generated/verifier_proxy/verifier_proxy.go b/core/gethwrappers/llo-feeds/generated/verifier_proxy/verifier_proxy.go
index 40a6d24221b..5ed70fef20a 100644
--- a/core/gethwrappers/llo-feeds/generated/verifier_proxy/verifier_proxy.go
+++ b/core/gethwrappers/llo-feeds/generated/verifier_proxy/verifier_proxy.go
@@ -32,12 +32,12 @@ var (
type CommonAddressAndWeight struct {
Addr common.Address
- Weight *big.Int
+ Weight uint64
}
var VerifierProxyMetaData = &bind.MetaData{
- ABI: "[{\"inputs\":[{\"internalType\":\"contractAccessControllerInterface\",\"name\":\"accessController\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"AccessForbidden\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BadVerification\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"verifier\",\"type\":\"address\"}],\"name\":\"ConfigDigestAlreadySet\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"verifier\",\"type\":\"address\"}],\"name\":\"VerifierAlreadyInitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerifierInvalid\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"VerifierNotFound\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldAccessController\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAccessController\",\"type\":\"address\"}],\"name\":\"AccessControllerSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldFeeManager\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newFeeManager\",\"type\":\"address\"}],\"name\":\"FeeManagerSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"verifierAddress\",\"type\":\"address\"}],\"name\":\"VerifierInitialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"oldConfigDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"newConfigDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"verifierAddress\",\"type\":\"address\"}],\"name\":\"VerifierSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"verifierAddress\",\"type\":\"address\"}],\"name\":\"VerifierUnset\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"getVerifier\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"verifierAddress\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"verifierAddress\",\"type\":\"address\"}],\"name\":\"initializeVerifier\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_accessController\",\"outputs\":[{\"internalType\":\"contractAccessControllerInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_feeManager\",\"outputs\":[{\"internalType\":\"contractIVerifierFeeManager\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractAccessControllerInterface\",\"name\":\"accessController\",\"type\":\"address\"}],\"name\":\"setAccessController\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIVerifierFeeManager\",\"name\":\"feeManager\",\"type\":\"address\"}],\"name\":\"setFeeManager\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"currentConfigDigest\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"newConfigDigest\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"weight\",\"type\":\"uint256\"}],\"internalType\":\"structCommon.AddressAndWeight[]\",\"name\":\"addressesAndWeights\",\"type\":\"tuple[]\"}],\"name\":\"setVerifier\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"unsetVerifier\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"}],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"verifierResponse\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}]",
- Bin: "0x608060405234801561001057600080fd5b50604051620015333803806200153383398101604081905261003191610189565b33806000816100875760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b03848116919091179091558116156100b7576100b7816100e0565b5050600480546001600160a01b0319166001600160a01b039390931692909217909155506101b9565b336001600160a01b038216036101385760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161007e565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60006020828403121561019b57600080fd5b81516001600160a01b03811681146101b257600080fd5b9392505050565b61136a80620001c96000396000f3fe6080604052600436106100d25760003560e01c80638c2a4d531161007f57806394ba28461161005957806394ba284614610256578063eeb7b24814610283578063f08391d8146102c6578063f2fde38b146102e657600080fd5b80638c2a4d53146101f85780638da5cb5b146102185780638e760afe1461024357600080fd5b8063589ede28116100b0578063589ede28146101a35780636e914094146101c357806379ba5097146101e357600080fd5b8063181f5a77146100d757806338416b5b1461012f578063472d35b914610181575b600080fd5b3480156100e357600080fd5b5060408051808201909152601381527f566572696669657250726f787920312e312e300000000000000000000000000060208201525b6040516101269190610f7d565b60405180910390f35b34801561013b57600080fd5b5060055461015c9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610126565b34801561018d57600080fd5b506101a161019c366004610fb9565b610306565b005b3480156101af57600080fd5b506101a16101be366004610fd6565b6103e2565b3480156101cf57600080fd5b506101a16101de366004611059565b61060d565b3480156101ef57600080fd5b506101a16106f9565b34801561020457600080fd5b506101a1610213366004610fb9565b6107f6565b34801561022457600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff1661015c565b610119610251366004611072565b610a27565b34801561026257600080fd5b5060045461015c9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561028f57600080fd5b5061015c61029e366004611059565b60009081526003602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b3480156102d257600080fd5b506101a16102e1366004610fb9565b610cfc565b3480156102f257600080fd5b506101a1610301366004610fb9565b610d83565b61030e610d97565b73ffffffffffffffffffffffffffffffffffffffff811661035b576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6005805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f04628abcaa6b1674651352125cb94b65b289145bc2bc4d67720bb7d966372f0391015b60405180910390a15050565b600083815260036020526040902054839073ffffffffffffffffffffffffffffffffffffffff168015610465576040517f375d1fe60000000000000000000000000000000000000000000000000000000081526004810183905273ffffffffffffffffffffffffffffffffffffffff821660248201526044015b60405180910390fd5b3360009081526002602052604090205460ff166104ae576040517fef67f5d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600085815260036020526040902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000163317905582156105c65760055473ffffffffffffffffffffffffffffffffffffffff16610539576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6005546040517f69fd2b3400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116906369fd2b3490610593908890889088906004016110e4565b600060405180830381600087803b1580156105ad57600080fd5b505af11580156105c1573d6000803e3d6000fd5b505050505b6040805187815260208101879052338183015290517fbeb513e532542a562ac35699e7cd9ae7d198dcd3eee15bada6c857d28ceaddcf9181900360600190a1505050505050565b610615610d97565b60008181526003602052604090205473ffffffffffffffffffffffffffffffffffffffff1680610674576040517fb151802b0000000000000000000000000000000000000000000000000000000081526004810183905260240161045c565b6000828152600360205260409081902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055517f11dc15c4b8ac2b183166cc8427e5385a5ece8308217a4217338c6a7614845c4c906103d6908490849091825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b60015473ffffffffffffffffffffffffffffffffffffffff16331461077a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e657200000000000000000000604482015260640161045c565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6107fe610d97565b8073ffffffffffffffffffffffffffffffffffffffff811661084c576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527f3d3ac1b500000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff8216906301ffc9a790602401602060405180830381865afa1580156108d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108fa9190611153565b610930576040517f75b0527a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff821660009081526002602052604090205460ff16156109a8576040517f4e01ccfd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8316600482015260240161045c565b73ffffffffffffffffffffffffffffffffffffffff821660008181526002602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905590519182527f1f2cd7c97f4d801b5efe26cc409617c1fd6c5ef786e79aacb90af40923e4e8e991016103d6565b60045460609073ffffffffffffffffffffffffffffffffffffffff168015801590610ae757506040517f6b14daf800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821690636b14daf890610aa490339060009036906004016111be565b602060405180830381865afa158015610ac1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ae59190611153565b155b15610b1e576040517fef67f5d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610b2a84866111f7565b60008181526003602052604090205490915073ffffffffffffffffffffffffffffffffffffffff1680610b8c576040517fb151802b0000000000000000000000000000000000000000000000000000000081526004810183905260240161045c565b60055473ffffffffffffffffffffffffffffffffffffffff168015610c36576040517ff1387e1600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82169063f1387e16903490610c03908b908b903390600401611234565b6000604051808303818588803b158015610c1c57600080fd5b505af1158015610c30573d6000803e3d6000fd5b50505050505b6040517f3d3ac1b500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831690633d3ac1b590610c8c908a908a903390600401611234565b6000604051808303816000875af1158015610cab573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610cf1919081019061129d565b979650505050505050565b610d04610d97565b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f953e92b1a6442e9c3242531154a3f6f6eb00b4e9c719ba8118fa6235e4ce89b691016103d6565b610d8b610d97565b610d9481610e1a565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314610e18576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161045c565b565b3373ffffffffffffffffffffffffffffffffffffffff821603610e99576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161045c565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60005b83811015610f2a578181015183820152602001610f12565b50506000910152565b60008151808452610f4b816020860160208601610f0f565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610f906020830184610f33565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff81168114610d9457600080fd5b600060208284031215610fcb57600080fd5b8135610f9081610f97565b60008060008060608587031215610fec57600080fd5b8435935060208501359250604085013567ffffffffffffffff8082111561101257600080fd5b818701915087601f83011261102657600080fd5b81358181111561103557600080fd5b8860208260061b850101111561104a57600080fd5b95989497505060200194505050565b60006020828403121561106b57600080fd5b5035919050565b6000806020838503121561108557600080fd5b823567ffffffffffffffff8082111561109d57600080fd5b818501915085601f8301126110b157600080fd5b8135818111156110c057600080fd5b8660208285010111156110d257600080fd5b60209290920196919550909350505050565b8381526040602080830182905282820184905260009190859060608501845b8781101561114657833561111681610f97565b73ffffffffffffffffffffffffffffffffffffffff16825283830135838301529284019290840190600101611103565b5098975050505050505050565b60006020828403121561116557600080fd5b81518015158114610f9057600080fd5b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b73ffffffffffffffffffffffffffffffffffffffff841681526040602082015260006111ee604083018486611175565b95945050505050565b8035602083101561122e577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff602084900360031b1b165b92915050565b604081526000611248604083018587611175565b905073ffffffffffffffffffffffffffffffffffffffff83166020830152949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000602082840312156112af57600080fd5b815167ffffffffffffffff808211156112c757600080fd5b818401915084601f8301126112db57600080fd5b8151818111156112ed576112ed61126e565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156113335761133361126e565b8160405282815287602084870101111561134c57600080fd5b610cf1836020830160208801610f0f56fea164736f6c6343000810000a",
+ ABI: "[{\"inputs\":[{\"internalType\":\"contractAccessControllerInterface\",\"name\":\"accessController\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"AccessForbidden\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BadVerification\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"verifier\",\"type\":\"address\"}],\"name\":\"ConfigDigestAlreadySet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FeeManagerInvalid\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"verifier\",\"type\":\"address\"}],\"name\":\"VerifierAlreadyInitialized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"VerifierInvalid\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"VerifierNotFound\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldAccessController\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAccessController\",\"type\":\"address\"}],\"name\":\"AccessControllerSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldFeeManager\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newFeeManager\",\"type\":\"address\"}],\"name\":\"FeeManagerSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"verifierAddress\",\"type\":\"address\"}],\"name\":\"VerifierInitialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"oldConfigDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"newConfigDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"verifierAddress\",\"type\":\"address\"}],\"name\":\"VerifierSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"verifierAddress\",\"type\":\"address\"}],\"name\":\"VerifierUnset\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"getVerifier\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"verifierAddress\",\"type\":\"address\"}],\"name\":\"initializeVerifier\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_accessController\",\"outputs\":[{\"internalType\":\"contractAccessControllerInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_feeManager\",\"outputs\":[{\"internalType\":\"contractIVerifierFeeManager\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractAccessControllerInterface\",\"name\":\"accessController\",\"type\":\"address\"}],\"name\":\"setAccessController\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIVerifierFeeManager\",\"name\":\"feeManager\",\"type\":\"address\"}],\"name\":\"setFeeManager\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"currentConfigDigest\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"newConfigDigest\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"weight\",\"type\":\"uint64\"}],\"internalType\":\"structCommon.AddressAndWeight[]\",\"name\":\"addressesAndWeights\",\"type\":\"tuple[]\"}],\"name\":\"setVerifier\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"name\":\"unsetVerifier\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"parameterPayload\",\"type\":\"bytes\"}],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes[]\",\"name\":\"payloads\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes\",\"name\":\"parameterPayload\",\"type\":\"bytes\"}],\"name\":\"verifyBulk\",\"outputs\":[{\"internalType\":\"bytes[]\",\"name\":\"verifiedReports\",\"type\":\"bytes[]\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}]",
+ Bin: "0x60806040523480156200001157600080fd5b5060405162001d3638038062001d36833981016040819052620000349162000193565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000e8565b5050600480546001600160a01b0319166001600160a01b03939093169290921790915550620001c5565b336001600160a01b03821603620001425760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600060208284031215620001a657600080fd5b81516001600160a01b0381168114620001be57600080fd5b9392505050565b611b6180620001d56000396000f3fe6080604052600436106100dd5760003560e01c806394ba28461161007f578063f08391d811610059578063f08391d8146102be578063f2fde38b146102de578063f7e83aee146102fe578063f873a61c1461031157600080fd5b806394ba28461461022e578063b011b2471461025b578063eeb7b2481461027b57600080fd5b80636e914094116100bb5780636e914094146101ae57806379ba5097146101ce5780638c2a4d53146101e35780638da5cb5b1461020357600080fd5b8063181f5a77146100e257806338416b5b1461013a578063472d35b91461018c575b600080fd5b3480156100ee57600080fd5b5060408051808201909152601381527f566572696669657250726f787920322e302e300000000000000000000000000060208201525b60405161013191906113c3565b60405180910390f35b34801561014657600080fd5b506005546101679073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610131565b34801561019857600080fd5b506101ac6101a73660046113ff565b610331565b005b3480156101ba57600080fd5b506101ac6101c936600461141c565b6105a9565b3480156101da57600080fd5b506101ac61069a565b3480156101ef57600080fd5b506101ac6101fe3660046113ff565b610797565b34801561020f57600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff16610167565b34801561023a57600080fd5b506004546101679073ffffffffffffffffffffffffffffffffffffffff1681565b34801561026757600080fd5b506101ac610276366004611435565b6109c8565b34801561028757600080fd5b5061016761029636600461141c565b60009081526003602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b3480156102ca57600080fd5b506101ac6102d93660046113ff565b610bee565b3480156102ea57600080fd5b506101ac6102f93660046113ff565b610c75565b61012461030c366004611501565b610c89565b61032461031f36600461156d565b610e43565b60405161013191906115ee565b6103396110a7565b73ffffffffffffffffffffffffffffffffffffffff8116610386576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527fdba45fe000000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff8216906301ffc9a790602401602060405180830381865afa158015610410573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610434919061166e565b15806104eb57506040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527f6c2f1a1700000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff8216906301ffc9a790602401602060405180830381865afa1580156104c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104e9919061166e565b155b15610522576040517f8238941900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6005805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f04628abcaa6b1674651352125cb94b65b289145bc2bc4d67720bb7d966372f0391015b60405180910390a15050565b6105b16110a7565b60008181526003602052604090205473ffffffffffffffffffffffffffffffffffffffff1680610615576040517fb151802b000000000000000000000000000000000000000000000000000000008152600481018390526024015b60405180910390fd5b6000828152600360205260409081902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055517f11dc15c4b8ac2b183166cc8427e5385a5ece8308217a4217338c6a7614845c4c9061059d908490849091825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b60015473ffffffffffffffffffffffffffffffffffffffff16331461071b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e657200000000000000000000604482015260640161060c565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b61079f6110a7565b8073ffffffffffffffffffffffffffffffffffffffff81166107ed576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527f3d3ac1b500000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff8216906301ffc9a790602401602060405180830381865afa158015610877573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061089b919061166e565b6108d1576040517f75b0527a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff821660009081526002602052604090205460ff1615610949576040517f4e01ccfd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8316600482015260240161060c565b73ffffffffffffffffffffffffffffffffffffffff821660008181526002602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905590519182527f1f2cd7c97f4d801b5efe26cc409617c1fd6c5ef786e79aacb90af40923e4e8e9910161059d565b600083815260036020526040902054839073ffffffffffffffffffffffffffffffffffffffff168015610a46576040517f375d1fe60000000000000000000000000000000000000000000000000000000081526004810183905273ffffffffffffffffffffffffffffffffffffffff8216602482015260440161060c565b3360009081526002602052604090205460ff16610a8f576040517fef67f5d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600085815260036020526040902080547fffffffffffffffffffffffff000000000000000000000000000000000000000016331790558215610ba75760055473ffffffffffffffffffffffffffffffffffffffff16610b1a576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6005546040517ff65df96200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063f65df96290610b7490889088908890600401611690565b600060405180830381600087803b158015610b8e57600080fd5b505af1158015610ba2573d6000803e3d6000fd5b505050505b6040805187815260208101879052338183015290517fbeb513e532542a562ac35699e7cd9ae7d198dcd3eee15bada6c857d28ceaddcf9181900360600190a1505050505050565b610bf66110a7565b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f953e92b1a6442e9c3242531154a3f6f6eb00b4e9c719ba8118fa6235e4ce89b6910161059d565b610c7d6110a7565b610c868161112a565b50565b60045460609073ffffffffffffffffffffffffffffffffffffffff168015801590610d4957506040517f6b14daf800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821690636b14daf890610d069033906000903690600401611762565b602060405180830381865afa158015610d23573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d47919061166e565b155b15610d80576040517fef67f5d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60055473ffffffffffffffffffffffffffffffffffffffff168015610e2e576040517fdba45fe000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82169063dba45fe0903490610dfb908b908b908b908b90339060040161179b565b6000604051808303818588803b158015610e1457600080fd5b505af1158015610e28573d6000803e3d6000fd5b50505050505b610e38878761121f565b979650505050505050565b60045460609073ffffffffffffffffffffffffffffffffffffffff168015801590610f0357506040517f6b14daf800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821690636b14daf890610ec09033906000903690600401611762565b602060405180830381865afa158015610edd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f01919061166e565b155b15610f3a576040517fef67f5d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60055473ffffffffffffffffffffffffffffffffffffffff168015610fe8576040517f6c2f1a1700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821690636c2f1a17903490610fb5908b908b908b908b9033906004016117eb565b6000604051808303818588803b158015610fce57600080fd5b505af1158015610fe2573d6000803e3d6000fd5b50505050505b8567ffffffffffffffff811115611001576110016118fc565b60405190808252806020026020018201604052801561103457816020015b606081526020019060019003908161101f5790505b50925060005b8681101561109c5761106e8888838181106110575761105761192b565b9050602002810190611069919061195a565b61121f565b8482815181106110805761108061192b565b602002602001018190525080611095906119bf565b905061103a565b505050949350505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611128576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161060c565b565b3373ffffffffffffffffffffffffffffffffffffffff8216036111a9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161060c565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6060600061122d8385611a1e565b60008181526003602052604090205490915073ffffffffffffffffffffffffffffffffffffffff168061128f576040517fb151802b0000000000000000000000000000000000000000000000000000000081526004810183905260240161060c565b6040517f3d3ac1b500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821690633d3ac1b5906112e590889088903390600401611a5a565b6000604051808303816000875af1158015611304573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261134a9190810190611a94565b925050505b92915050565b60005b83811015611370578181015183820152602001611358565b50506000910152565b60008151808452611391816020860160208601611355565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006113d66020830184611379565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff81168114610c8657600080fd5b60006020828403121561141157600080fd5b81356113d6816113dd565b60006020828403121561142e57600080fd5b5035919050565b6000806000806060858703121561144b57600080fd5b8435935060208501359250604085013567ffffffffffffffff8082111561147157600080fd5b818701915087601f83011261148557600080fd5b81358181111561149457600080fd5b8860208260061b85010111156114a957600080fd5b95989497505060200194505050565b60008083601f8401126114ca57600080fd5b50813567ffffffffffffffff8111156114e257600080fd5b6020830191508360208285010111156114fa57600080fd5b9250929050565b6000806000806040858703121561151757600080fd5b843567ffffffffffffffff8082111561152f57600080fd5b61153b888389016114b8565b9096509450602087013591508082111561155457600080fd5b50611561878288016114b8565b95989497509550505050565b6000806000806040858703121561158357600080fd5b843567ffffffffffffffff8082111561159b57600080fd5b818701915087601f8301126115af57600080fd5b8135818111156115be57600080fd5b8860208260051b85010111156115d357600080fd5b60209283019650945090860135908082111561155457600080fd5b6000602080830181845280855180835260408601915060408160051b870101925083870160005b82811015611661577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc088860301845261164f858351611379565b94509285019290850190600101611615565b5092979650505050505050565b60006020828403121561168057600080fd5b815180151581146113d657600080fd5b838152604060208083018290528282018490526000919085906060850184805b8881101561170a5784356116c3816113dd565b73ffffffffffffffffffffffffffffffffffffffff1683528484013567ffffffffffffffff81168082146116f5578384fd5b848601525093850193918501916001016116b0565b50909998505050505050505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b73ffffffffffffffffffffffffffffffffffffffff84168152604060208201526000611792604083018486611719565b95945050505050565b6060815260006117af606083018789611719565b82810360208401526117c2818688611719565b91505073ffffffffffffffffffffffffffffffffffffffff831660408301529695505050505050565b6060808252810185905260006080600587901b8301810190830188835b898110156118b7577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8086850301835281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18c360301811261186957600080fd5b8b01602081810191359067ffffffffffffffff82111561188857600080fd5b81360383131561189757600080fd5b6118a2878385611719565b96509485019493909301925050600101611808565b50505082810360208401526118cd818688611719565b9150506118f2604083018473ffffffffffffffffffffffffffffffffffffffff169052565b9695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261198f57600080fd5b83018035915067ffffffffffffffff8211156119aa57600080fd5b6020019150368190038213156114fa57600080fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611a17577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5060010190565b8035602083101561134f577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff602084900360031b1b1692915050565b604081526000611a6e604083018587611719565b905073ffffffffffffffffffffffffffffffffffffffff83166020830152949350505050565b600060208284031215611aa657600080fd5b815167ffffffffffffffff80821115611abe57600080fd5b818401915084601f830112611ad257600080fd5b815181811115611ae457611ae46118fc565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715611b2a57611b2a6118fc565b81604052828152876020848701011115611b4357600080fd5b610e3883602083016020880161135556fea164736f6c6343000810000a",
}
var VerifierProxyABI = VerifierProxyMetaData.ABI
@@ -370,16 +370,28 @@ func (_VerifierProxy *VerifierProxyTransactorSession) UnsetVerifier(configDigest
return _VerifierProxy.Contract.UnsetVerifier(&_VerifierProxy.TransactOpts, configDigest)
}
-func (_VerifierProxy *VerifierProxyTransactor) Verify(opts *bind.TransactOpts, payload []byte) (*types.Transaction, error) {
- return _VerifierProxy.contract.Transact(opts, "verify", payload)
+func (_VerifierProxy *VerifierProxyTransactor) Verify(opts *bind.TransactOpts, payload []byte, parameterPayload []byte) (*types.Transaction, error) {
+ return _VerifierProxy.contract.Transact(opts, "verify", payload, parameterPayload)
}
-func (_VerifierProxy *VerifierProxySession) Verify(payload []byte) (*types.Transaction, error) {
- return _VerifierProxy.Contract.Verify(&_VerifierProxy.TransactOpts, payload)
+func (_VerifierProxy *VerifierProxySession) Verify(payload []byte, parameterPayload []byte) (*types.Transaction, error) {
+ return _VerifierProxy.Contract.Verify(&_VerifierProxy.TransactOpts, payload, parameterPayload)
}
-func (_VerifierProxy *VerifierProxyTransactorSession) Verify(payload []byte) (*types.Transaction, error) {
- return _VerifierProxy.Contract.Verify(&_VerifierProxy.TransactOpts, payload)
+func (_VerifierProxy *VerifierProxyTransactorSession) Verify(payload []byte, parameterPayload []byte) (*types.Transaction, error) {
+ return _VerifierProxy.Contract.Verify(&_VerifierProxy.TransactOpts, payload, parameterPayload)
+}
+
+func (_VerifierProxy *VerifierProxyTransactor) VerifyBulk(opts *bind.TransactOpts, payloads [][]byte, parameterPayload []byte) (*types.Transaction, error) {
+ return _VerifierProxy.contract.Transact(opts, "verifyBulk", payloads, parameterPayload)
+}
+
+func (_VerifierProxy *VerifierProxySession) VerifyBulk(payloads [][]byte, parameterPayload []byte) (*types.Transaction, error) {
+ return _VerifierProxy.Contract.VerifyBulk(&_VerifierProxy.TransactOpts, payloads, parameterPayload)
+}
+
+func (_VerifierProxy *VerifierProxyTransactorSession) VerifyBulk(payloads [][]byte, parameterPayload []byte) (*types.Transaction, error) {
+ return _VerifierProxy.Contract.VerifyBulk(&_VerifierProxy.TransactOpts, payloads, parameterPayload)
}
type VerifierProxyAccessControllerSetIterator struct {
@@ -1323,7 +1335,9 @@ type VerifierProxyInterface interface {
UnsetVerifier(opts *bind.TransactOpts, configDigest [32]byte) (*types.Transaction, error)
- Verify(opts *bind.TransactOpts, payload []byte) (*types.Transaction, error)
+ Verify(opts *bind.TransactOpts, payload []byte, parameterPayload []byte) (*types.Transaction, error)
+
+ VerifyBulk(opts *bind.TransactOpts, payloads [][]byte, parameterPayload []byte) (*types.Transaction, error)
FilterAccessControllerSet(opts *bind.FilterOpts) (*VerifierProxyAccessControllerSetIterator, error)
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 13b0f9ba040..4bb84a770a1 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
@@ -1,9 +1,9 @@
GETH_VERSION: 1.12.0
-errored_verifier: ../../../contracts/solc/v0.8.16/ErroredVerifier.abi ../../../contracts/solc/v0.8.16/ErroredVerifier.bin 1b0a03b90137d31fceb340b80ade65a4ed52fa63c5caf24183ce3f63567d818f
+errored_verifier: ../../../contracts/solc/v0.8.16/ErroredVerifier.abi ../../../contracts/solc/v0.8.16/ErroredVerifier.bin 510d18a58bfda646be35e46491baf73041eb333a349615465b20e2b5b41c5f73
exposed_verifier: ../../../contracts/solc/v0.8.16/ExposedVerifier.abi ../../../contracts/solc/v0.8.16/ExposedVerifier.bin 6932cea8f2738e874d3ec9e1a4231d2421704030c071d9e15dd2f7f08482c246
-fee_manager: ../../../contracts/solc/v0.8.16/FeeManager.abi ../../../contracts/solc/v0.8.16/FeeManager.bin 0fca974f9243402e60e1420382efe594a4eed910a849711a86b76bde01bba184
+fee_manager: ../../../contracts/solc/v0.8.16/FeeManager.abi ../../../contracts/solc/v0.8.16/FeeManager.bin 1b852df75bfabcc2b57539e84309cd57f9e693a2bb6b25a50e4a6101ccf32c49
llo_feeds: ../../../contracts/solc/v0.8.16/FeeManager.abi ../../../contracts/solc/v0.8.16/FeeManager.bin cb71e018f67e49d7bc0e194c822204dfd59f79ff42e4fc8fd8ab63f3acd71361
llo_feeds_test: ../../../contracts/solc/v0.8.16/ExposedVerifier.abi ../../../contracts/solc/v0.8.16/ExposedVerifier.bin 6932cea8f2738e874d3ec9e1a4231d2421704030c071d9e15dd2f7f08482c246
-reward_manager: ../../../contracts/solc/v0.8.16/RewardManager.abi ../../../contracts/solc/v0.8.16/RewardManager.bin b8a37ed1b1eb92004a5e9d6936877bf7254d04799c594824764bab5e52233d2c
-verifier: ../../../contracts/solc/v0.8.16/Verifier.abi ../../../contracts/solc/v0.8.16/Verifier.bin 3c9b047bd96056a8bf85c0a1e928044c1166c58c4bd6986975100877ff43f1ec
-verifier_proxy: ../../../contracts/solc/v0.8.16/VerifierProxy.abi ../../../contracts/solc/v0.8.16/VerifierProxy.bin 64c61227ccc947171c35c5cd5dc664c492fbe2139fdfee70d4941a0109261341
+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
diff --git a/core/internal/cltest/cltest.go b/core/internal/cltest/cltest.go
index c57e35d46f6..671d4072816 100644
--- a/core/internal/cltest/cltest.go
+++ b/core/internal/cltest/cltest.go
@@ -213,7 +213,7 @@ func NewEthConfirmer(t testing.TB, txStore txmgr.EvmTxStore, ethClient evmclient
t.Helper()
lggr := logger.TestLogger(t)
ge := config.EVM().GasEstimator()
- estimator := gas.NewWrappedEvmEstimator(gas.NewFixedPriceEstimator(ge, ge.BlockHistory(), lggr), ge.EIP1559DynamicFees())
+ estimator := gas.NewWrappedEvmEstimator(gas.NewFixedPriceEstimator(ge, ge.BlockHistory(), lggr), ge.EIP1559DynamicFees(), nil)
txBuilder := txmgr.NewEvmTxAttemptBuilder(*ethClient.ConfiguredChainID(), ge, ks, estimator)
ec := txmgr.NewEvmConfirmer(txStore, txmgr.NewEvmTxmClient(ethClient), txmgr.NewEvmTxmConfig(config.EVM()), txmgr.NewEvmTxmFeeConfig(ge), config.EVM().Transactions(), config.Database(), ks, txBuilder, lggr)
ec.SetResumeCallback(fn)
@@ -378,39 +378,41 @@ func NewApplicationWithConfig(t testing.TB, cfg chainlink.GeneralConfig, flagsAn
}
}
- if ethClient == nil {
- ethClient = evmclient.NewNullClient(cfg.DefaultChainID(), lggr)
- }
keyStore := keystore.New(db, utils.FastScryptParams, lggr, cfg.Database())
mailMon := utils.NewMailboxMonitor(cfg.AppID().String())
- loopRegistry := plugins.NewLoopRegistry(lggr.Named("LoopRegistry"))
+ loopRegistry := plugins.NewLoopRegistry(lggr)
relayerFactory := chainlink.RelayerFactory{
Logger: lggr,
- DB: db,
- QConfig: cfg.Database(),
LoopRegistry: loopRegistry,
GRPCOpts: loop.GRPCOpts{},
}
- chainId := ethClient.ConfiguredChainID()
evmOpts := chainlink.EVMFactoryConfig{
- RelayerConfig: evm.RelayerConfig{
+ ChainOpts: evm.ChainOpts{
AppConfig: cfg,
EventBroadcaster: eventBroadcaster,
MailMon: mailMon,
- GenEthClient: func(_ *big.Int) evmclient.Client {
- if chainId.Cmp(cfg.DefaultChainID()) != 0 {
- t.Fatalf("expected eth client ChainID %d to match configured DefaultChainID %d", chainId, cfg.DefaultChainID())
- }
- return ethClient
- },
+ DB: db,
},
CSAETHKeystore: keyStore,
}
+ if cfg.EVMEnabled() {
+ if ethClient == nil {
+ ethClient = evmclient.NewNullClient(evmtest.MustGetDefaultChainID(t, cfg.EVMConfigs()), lggr)
+ }
+ chainId := ethClient.ConfiguredChainID()
+ evmOpts.GenEthClient = func(_ *big.Int) evmclient.Client {
+ if chainId.Cmp(evmtest.MustGetDefaultChainID(t, cfg.EVMConfigs())) != 0 {
+ t.Fatalf("expected eth client ChainID %d to match evm config chain id %d", chainId, evmtest.MustGetDefaultChainID(t, cfg.EVMConfigs()))
+ }
+ return ethClient
+ }
+ }
+
testCtx := testutils.Context(t)
// evm alway enabled for backward compatibility
initOps := []chainlink.CoreRelayerChainInitFunc{chainlink.InitEVM(testCtx, relayerFactory, evmOpts)}
@@ -420,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))
}
@@ -530,15 +534,19 @@ func NewEthMocksWithTransactionsOnBlocksAssertions(t testing.TB) *evmclimocks.Cl
c.On("HeadByHash", mock.Anything, h0.Hash).Maybe().Return(h0, nil)
c.On("BatchCallContext", mock.Anything, mock.Anything).Maybe().Return(nil).Run(func(args mock.Arguments) {
elems := args.Get(1).([]rpc.BatchElem)
- elems[0].Result = &evmtypes.Block{
- Number: 42,
- Hash: utils.NewHash(),
- Transactions: LegacyTransactionsFromGasPrices(9001, 9002),
+ if len(elems) > 0 {
+ elems[0].Result = &evmtypes.Block{
+ Number: 42,
+ Hash: utils.NewHash(),
+ Transactions: LegacyTransactionsFromGasPrices(9001, 9002),
+ }
}
- elems[1].Result = &evmtypes.Block{
- Number: 41,
- Hash: utils.NewHash(),
- Transactions: LegacyTransactionsFromGasPrices(9003, 9004),
+ if len(elems) > 1 {
+ elems[1].Result = &evmtypes.Block{
+ Number: 41,
+ Hash: utils.NewHash(),
+ Transactions: LegacyTransactionsFromGasPrices(9003, 9004),
+ }
}
})
c.On("ConfiguredChainID").Maybe().Return(&FixtureChainID)
@@ -588,10 +596,10 @@ func (ta *TestApplication) Stop() error {
return err
}
-func (ta *TestApplication) MustSeedNewSession(roleFixtureUserAPIEmail string) (id string) {
+func (ta *TestApplication) MustSeedNewSession(email string) (id string) {
session := NewSession()
- ta.Logger.Infof("TestApplication creating session (id: %s, email: %s, last used: %s)", session.ID, roleFixtureUserAPIEmail, session.LastUsed.String())
- err := ta.GetSqlxDB().Get(&id, `INSERT INTO sessions (id, email, last_used, created_at) VALUES ($1, $2, $3, NOW()) RETURNING id`, session.ID, roleFixtureUserAPIEmail, session.LastUsed)
+ ta.Logger.Infof("TestApplication creating session (id: %s, email: %s, last used: %s)", session.ID, email, session.LastUsed.String())
+ err := ta.GetSqlxDB().Get(&id, `INSERT INTO sessions (id, email, last_used, created_at) VALUES ($1, $2, $3, NOW()) RETURNING id`, session.ID, email, session.LastUsed)
require.NoError(ta.t, err)
return id
}
@@ -603,10 +611,29 @@ func (ta *TestApplication) Import(content string) {
require.NoError(ta.t, err)
}
-func (ta *TestApplication) NewHTTPClient(roleFixtureUserAPIEmail string) HTTPClientCleaner {
+type User struct {
+ Email string
+ Role clsessions.UserRole
+}
+
+func (ta *TestApplication) NewHTTPClient(user *User) HTTPClientCleaner {
ta.t.Helper()
- sessionID := ta.MustSeedNewSession(roleFixtureUserAPIEmail)
+ if user.Email == "" {
+ user.Email = fmt.Sprintf("%s@chainlink.test", uuid.New())
+ }
+
+ if user.Role == "" {
+ user.Role = clsessions.UserRoleAdmin
+ }
+
+ u, err := clsessions.NewUser(user.Email, Password, user.Role)
+ require.NoError(ta.t, err)
+
+ err = ta.SessionORM().CreateUser(&u)
+ require.NoError(ta.t, err)
+
+ sessionID := ta.MustSeedNewSession(user.Email)
return HTTPClientCleaner{
HTTPClient: NewMockAuthenticatedHTTPClient(ta.Logger, ta.NewClientOpts(), sessionID),
@@ -620,7 +647,7 @@ func (ta *TestApplication) NewClientOpts() cmd.ClientOpts {
// NewShellAndRenderer creates a new cmd.Shell for the test application
func (ta *TestApplication) NewShellAndRenderer() (*cmd.Shell, *RendererMock) {
- sessionID := ta.MustSeedNewSession(APIEmailAdmin)
+ hc := ta.NewHTTPClient(&User{})
r := &RendererMock{}
lggr := logger.TestLogger(ta.t)
client := &cmd.Shell{
@@ -630,7 +657,7 @@ func (ta *TestApplication) NewShellAndRenderer() (*cmd.Shell, *RendererMock) {
AppFactory: seededAppFactory{ta.ChainlinkApplication},
FallbackAPIInitializer: NewMockAPIInitializer(ta.t),
Runner: EmptyRunner{},
- HTTP: NewMockAuthenticatedHTTPClient(ta.Logger, ta.NewClientOpts(), sessionID),
+ HTTP: hc.HTTPClient,
CookieAuthenticator: MockCookieAuthenticator{t: ta.t},
FileSessionRequestBuilder: &MockSessionRequestBuilder{},
PromptingSessionRequestBuilder: &MockSessionRequestBuilder{},
@@ -782,7 +809,7 @@ func ParseJSONAPIResponseMetaCount(input []byte) (int, error) {
func CreateJobViaWeb(t testing.TB, app *TestApplication, request []byte) job.Job {
t.Helper()
- client := app.NewHTTPClient(APIEmailAdmin)
+ client := app.NewHTTPClient(&User{})
resp, cleanup := client.Post("/v2/jobs", bytes.NewBuffer(request))
defer cleanup()
AssertServerResponse(t, resp, http.StatusOK)
@@ -796,7 +823,7 @@ func CreateJobViaWeb(t testing.TB, app *TestApplication, request []byte) job.Job
func CreateJobViaWeb2(t testing.TB, app *TestApplication, spec string) webpresenters.JobResource {
t.Helper()
- client := app.NewHTTPClient(APIEmailAdmin)
+ client := app.NewHTTPClient(&User{})
resp, cleanup := client.Post("/v2/jobs", bytes.NewBufferString(spec))
defer cleanup()
AssertServerResponse(t, resp, http.StatusOK)
@@ -810,7 +837,7 @@ func CreateJobViaWeb2(t testing.TB, app *TestApplication, spec string) webpresen
func DeleteJobViaWeb(t testing.TB, app *TestApplication, jobID int32) {
t.Helper()
- client := app.NewHTTPClient(APIEmailAdmin)
+ client := app.NewHTTPClient(&User{})
resp, cleanup := client.Delete(fmt.Sprintf("/v2/jobs/%v", jobID))
defer cleanup()
AssertServerResponse(t, resp, http.StatusNoContent)
@@ -859,7 +886,7 @@ func CreateJobRunViaUser(
t.Helper()
bodyBuf := bytes.NewBufferString(body)
- client := app.NewHTTPClient(APIEmailAdmin)
+ client := app.NewHTTPClient(&User{})
resp, cleanup := client.Post("/v2/jobs/"+jobID.String()+"/runs", bodyBuf)
defer cleanup()
AssertServerResponse(t, resp, 200)
@@ -878,7 +905,7 @@ func CreateExternalInitiatorViaWeb(
) *webpresenters.ExternalInitiatorAuthentication {
t.Helper()
- client := app.NewHTTPClient(APIEmailAdmin)
+ client := app.NewHTTPClient(&User{})
resp, cleanup := client.Post(
"/v2/external_initiators",
bytes.NewBufferString(payload),
@@ -983,7 +1010,7 @@ func AssertEthTxAttemptCountStays(t testing.TB, db *sqlx.DB, want int) []int64 {
var err error
g.Consistently(func() []int64 {
txaIds = make([]int64, 0)
- err = db.Select(&txaIds, `SELECT ID FROM eth_tx_attempts ORDER BY id ASC`)
+ err = db.Select(&txaIds, `SELECT ID FROM evm.tx_attempts ORDER BY id ASC`)
assert.NoError(t, err)
return txaIds
}, AssertNoActionTimeout, DBPollingInterval).Should(gomega.HaveLen(want))
@@ -1286,7 +1313,7 @@ func MockApplicationEthCalls(t *testing.T, app *TestApplication, ethClient *evmc
// Start
ethClient.On("Dial", mock.Anything).Return(nil)
ethClient.On("SubscribeNewHead", mock.Anything, mock.Anything).Return(sub, nil).Maybe()
- ethClient.On("ConfiguredChainID", mock.Anything).Return(app.GetConfig().DefaultChainID(), nil)
+ ethClient.On("ConfiguredChainID", mock.Anything).Return(evmtest.MustGetDefaultChainID(t, app.GetConfig().EVMConfigs()), nil)
ethClient.On("PendingNonceAt", mock.Anything, mock.Anything).Return(uint64(0), nil).Maybe()
ethClient.On("HeadByNumber", mock.Anything, mock.Anything).Return(nil, nil).Maybe()
ethClient.On("Close").Return().Maybe()
@@ -1536,7 +1563,7 @@ func AssertCountStays(t testing.TB, db *sqlx.DB, tableName string, want int64) {
var count int64
var err error
g.Consistently(func() int64 {
- err = db.Get(&count, fmt.Sprintf(`SELECT count(*) FROM %q`, tableName))
+ err = db.Get(&count, fmt.Sprintf(`SELECT count(*) FROM %s`, tableName))
assert.NoError(t, err)
return count
}, AssertNoActionTimeout, DBPollingInterval).Should(gomega.Equal(want))
@@ -1634,10 +1661,8 @@ func FlagSetApplyFromAction(action interface{}, flagSet *flag.FlagSet, parentCom
for _, command := range app.Commands {
flags := recursiveFindFlagsWithName(actionFuncName, command, parentCommand, foundName)
- if flags != nil {
- for _, flag := range flags {
- flag.Apply(flagSet)
- }
+ for _, flag := range flags {
+ flag.Apply(flagSet)
}
}
diff --git a/core/internal/cltest/factories.go b/core/internal/cltest/factories.go
index 800731f74a4..cb0b51743e4 100644
--- a/core/internal/cltest/factories.go
+++ b/core/internal/cltest/factories.go
@@ -348,6 +348,12 @@ func EvmTxRequestWithValue(value big.Int) func(*txmgr.TxRequest) {
}
}
+func EvmTxRequestWithIdempotencyKey(idempotencyKey string) func(*txmgr.TxRequest) {
+ return func(tx *txmgr.TxRequest) {
+ tx.IdempotencyKey = &idempotencyKey
+ }
+}
+
func MustCreateUnstartedTx(t testing.TB, txStore txmgr.EvmTxStore, fromAddress common.Address, toAddress common.Address, encodedPayload []byte, gasLimit uint32, value big.Int, chainID *big.Int, opts ...interface{}) (tx txmgr.Tx) {
txRequest := txmgr.TxRequest{
FromAddress: fromAddress,
@@ -437,7 +443,7 @@ func MustInsertRevertedEthReceipt(t *testing.T, txStore txmgr.TestEvmTxStore, bl
return r
}
-// Inserts into eth_receipts but does not update eth_txes or eth_tx_attempts
+// Inserts into evm.receipts but does not update evm.txes or evm.tx_attempts
func MustInsertConfirmedEthTxWithReceipt(t *testing.T, txStore txmgr.TestEvmTxStore, fromAddress common.Address, nonce, blockNum int64) (etx txmgr.Tx) {
etx = MustInsertConfirmedEthTxWithLegacyAttempt(t, txStore, nonce, blockNum, fromAddress)
MustInsertEthReceipt(t, txStore, blockNum, utils.NewHash(), etx.TxAttempts[0].Hash)
@@ -475,6 +481,14 @@ func MustAddRandomKeyToKeystore(t testing.TB, ethKeyStore keystore.Eth) (ethkey.
return k, k.Address
}
+func MustAddRandomKeyToKeystoreWithChainID(t testing.TB, chainID *big.Int, ethKeyStore keystore.Eth) (ethkey.KeyV2, common.Address) {
+ t.Helper()
+ k := MustGenerateRandomKey(t)
+ MustAddKeyToKeystore(t, k, chainID, ethKeyStore)
+
+ return k, k.Address
+}
+
func MustAddKeyToKeystore(t testing.TB, key ethkey.KeyV2, chainID *big.Int, ethKeyStore keystore.Eth) {
t.Helper()
ethKeyStore.XXXTestingOnlyAdd(key)
@@ -610,15 +624,15 @@ func MustInsertOffchainreportingOracleSpec(t *testing.T, db *sqlx.DB, transmitte
ocrKeyID := models.MustSha256HashFromHex(DefaultOCRKeyBundleID)
spec := job.OCROracleSpec{}
- require.NoError(t, db.Get(&spec, `INSERT INTO ocr_oracle_specs (created_at, updated_at, contract_address, p2p_bootstrap_peers, is_bootstrap_peer, encrypted_ocr_key_bundle_id, transmitter_address, observation_timeout, blockchain_timeout, contract_config_tracker_subscribe_interval, contract_config_tracker_poll_interval, contract_config_confirmations, database_timeout, observation_grace_period, contract_transmitter_transmit_timeout) VALUES (
-NOW(),NOW(),$1,'{}',false,$2,$3,0,0,0,0,0,0,0,0
+ require.NoError(t, db.Get(&spec, `INSERT INTO ocr_oracle_specs (created_at, updated_at, contract_address, p2p_bootstrap_peers, is_bootstrap_peer, encrypted_ocr_key_bundle_id, transmitter_address, observation_timeout, blockchain_timeout, contract_config_tracker_subscribe_interval, contract_config_tracker_poll_interval, contract_config_confirmations, database_timeout, observation_grace_period, contract_transmitter_transmit_timeout, evm_chain_id) VALUES (
+NOW(),NOW(),$1,'{}',false,$2,$3,0,0,0,0,0,0,0,0,0
) RETURNING *`, NewEIP55Address(), &ocrKeyID, &transmitterAddress))
return spec
}
func MakeDirectRequestJobSpec(t *testing.T) *job.Job {
t.Helper()
- drs := &job.DirectRequestSpec{}
+ drs := &job.DirectRequestSpec{EVMChainID: (*utils.Big)(testutils.FixtureChainID)}
spec := &job.Job{
Type: job.DirectRequest,
SchemaVersion: 1,
@@ -634,7 +648,7 @@ func MustInsertKeeperJob(t *testing.T, db *sqlx.DB, korm keeper.ORM, from ethkey
t.Helper()
var keeperSpec job.KeeperSpec
- err := korm.Q().Get(&keeperSpec, `INSERT INTO keeper_specs (contract_address, from_address, created_at, updated_at) VALUES ($1, $2, NOW(), NOW()) RETURNING *`, contract, from)
+ err := korm.Q().Get(&keeperSpec, `INSERT INTO keeper_specs (contract_address, from_address, created_at, updated_at,evm_chain_id) VALUES ($1, $2, NOW(), NOW(), $3) RETURNING *`, contract, from, testutils.SimulatedChainID.Int64())
require.NoError(t, err)
var pipelineSpec pipeline.Spec
@@ -662,7 +676,7 @@ func MustInsertKeeperJob(t *testing.T, db *sqlx.DB, korm keeper.ORM, from ethkey
}
func MustInsertKeeperRegistry(t *testing.T, db *sqlx.DB, korm keeper.ORM, ethKeyStore keystore.Eth, keeperIndex, numKeepers, blockCountPerTurn int32) (keeper.Registry, job.Job) {
- key, _ := MustAddRandomKeyToKeystore(t, ethKeyStore)
+ key, _ := MustAddRandomKeyToKeystoreWithChainID(t, testutils.SimulatedChainID, ethKeyStore)
from := key.EIP55Address
t.Helper()
contractAddress := NewEIP55Address()
diff --git a/core/internal/cltest/job_factories.go b/core/internal/cltest/job_factories.go
index fd496c5f972..910ffe79e38 100644
--- a/core/internal/cltest/job_factories.go
+++ b/core/internal/cltest/job_factories.go
@@ -6,7 +6,6 @@ import (
"github.com/google/uuid"
"github.com/smartcontractkit/sqlx"
- "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/smartcontractkit/chainlink/v2/core/bridges"
@@ -25,6 +24,7 @@ const (
type = "offchainreporting"
schemaVersion = 1
contractAddress = "%s"
+ evmChainID = "0"
p2pPeerID = "%s"
p2pBootstrapPeers = ["/dns4/chain.link/tcp/1234/p2p/16Uiu2HAm58SP7UL8zsnpeuwHfytLocaqgnyaYKP8wu7qRdrixLju"]
isBootstrapPeer = false
@@ -66,8 +66,7 @@ func getORMs(t *testing.T, db *sqlx.DB) (jobORM job.ORM, pipelineORM pipeline.OR
pipelineORM = pipeline.NewORM(db, lggr, config.Database(), config.JobPipeline().MaxSuccessfulRuns())
bridgeORM := bridges.NewORM(db, lggr, config.Database())
cc := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()})
- legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(cc)
- assert.NoError(t, err)
+ legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(cc)
jobORM = job.NewORM(db, legacyChains, pipelineORM, bridgeORM, keyStore, lggr, config.Database())
t.Cleanup(func() { jobORM.Close() })
return
diff --git a/core/internal/cltest/mocks.go b/core/internal/cltest/mocks.go
index 4984b8157f1..439ca2b721d 100644
--- a/core/internal/cltest/mocks.go
+++ b/core/internal/cltest/mocks.go
@@ -27,7 +27,6 @@ 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
@@ -424,14 +423,11 @@ func NewLegacyChainsWithMockChain(t testing.TB, ethClient evmclient.Client, cfg
ch.On("ID").Return(scopedCfg.EVM().ChainID())
ch.On("Config").Return(scopedCfg)
- return NewLegacyChainsWithChain(t, ch, cfg)
+ return NewLegacyChainsWithChain(ch, cfg)
}
-func NewLegacyChainsWithChain(t testing.TB, ch evm.Chain, cfg evm.AppConfig) evm.LegacyChainContainer {
+func NewLegacyChainsWithChain(ch evm.Chain, cfg evm.AppConfig) evm.LegacyChainContainer {
m := map[string]evm.Chain{ch.ID().String(): ch}
- legacyChains, err := evm.NewLegacyChains(cfg, m)
- require.NoError(t, err)
- legacyChains.SetDefault(ch)
- return legacyChains
+ return evm.NewLegacyChains(m, cfg.EVMConfigs())
}
diff --git a/core/internal/cltest/simulated_backend.go b/core/internal/cltest/simulated_backend.go
index 9a3dcfd5184..010478837da 100644
--- a/core/internal/cltest/simulated_backend.go
+++ b/core/internal/cltest/simulated_backend.go
@@ -12,6 +12,7 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/client"
"github.com/smartcontractkit/chainlink/v2/core/internal/testutils"
+ "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/evmtest"
"github.com/smartcontractkit/chainlink/v2/core/logger"
"github.com/smartcontractkit/chainlink/v2/core/services/chainlink"
"github.com/smartcontractkit/chainlink/v2/core/services/pg"
@@ -36,8 +37,8 @@ func NewApplicationWithConfigV2OnSimulatedBlockchain(
if bid := backend.Blockchain().Config().ChainID; bid.Cmp(testutils.SimulatedChainID) != 0 {
t.Fatalf("expected backend chain ID to be %s but it was %s", testutils.SimulatedChainID.String(), bid.String())
}
- defID := cfg.DefaultChainID()
- require.Zero(t, defID.Cmp(testutils.SimulatedChainID))
+
+ require.Zero(t, evmtest.MustGetDefaultChainID(t, cfg.EVMConfigs()).Cmp(testutils.SimulatedChainID))
chainID := utils.NewBig(testutils.SimulatedChainID)
client := client.NewSimulatedBackendClient(t, backend, testutils.SimulatedChainID)
eventBroadcaster := pg.NewEventBroadcaster(cfg.Database().URL(), 0, 0, logger.TestLogger(t), uuid.New())
@@ -61,8 +62,8 @@ func NewApplicationWithConfigV2AndKeyOnSimulatedBlockchain(
if bid := backend.Blockchain().Config().ChainID; bid.Cmp(testutils.SimulatedChainID) != 0 {
t.Fatalf("expected backend chain ID to be %s but it was %s", testutils.SimulatedChainID.String(), bid.String())
}
- defID := cfg.DefaultChainID()
- require.Zero(t, defID.Cmp(testutils.SimulatedChainID))
+
+ require.Zero(t, evmtest.MustGetDefaultChainID(t, cfg.EVMConfigs()).Cmp(testutils.SimulatedChainID))
chainID := utils.NewBig(testutils.SimulatedChainID)
client := client.NewSimulatedBackendClient(t, backend, testutils.SimulatedChainID)
eventBroadcaster := pg.NewEventBroadcaster(cfg.Database().URL(), 0, 0, logger.TestLogger(t), uuid.New())
diff --git a/core/internal/features/features_test.go b/core/internal/features/features_test.go
index e730ec5f3a0..39eee3f7b43 100644
--- a/core/internal/features/features_test.go
+++ b/core/internal/features/features_test.go
@@ -505,13 +505,14 @@ observationSource = """
data="%s"
minConfirmations="2"
failOnRevert=false
+ evmChainID="%s"
from="[\\"%s\\"]"
]
"""
`
// This succeeds for whatever reason
revertingData := "0xdeadbeef"
- tomlSpec = fmt.Sprintf(tomlSpec, operatorContracts.linkTokenAddress.String(), revertingData, sendingAddr)
+ tomlSpec = fmt.Sprintf(tomlSpec, operatorContracts.linkTokenAddress.String(), revertingData, testutils.SimulatedChainID.String(), sendingAddr)
j := cltest.CreateJobViaWeb(t, app, []byte(cltest.MustJSONMarshal(t, web.CreateJobRequest{TOML: tomlSpec})))
cltest.AwaitJobActive(t, app.JobSpawner(), j.ID, testutils.WaitTimeout(t))
@@ -550,13 +551,14 @@ observationSource = """
data="%s"
minConfirmations="2"
failOnRevert=true
+ evmChainID="%s"
from="[\\"%s\\"]"
]
"""
`
// This data is a call to link token's `transfer` function and will revert due to insufficient LINK on the sender address
revertingData := "0xa9059cbb000000000000000000000000526485b5abdd8ae9c6a63548e0215a83e7135e6100000000000000000000000000000000000000000000000db069932ea4fe1400"
- tomlSpec = fmt.Sprintf(tomlSpec, operatorContracts.linkTokenAddress.String(), revertingData, sendingAddr)
+ tomlSpec = fmt.Sprintf(tomlSpec, operatorContracts.linkTokenAddress.String(), revertingData, testutils.SimulatedChainID.String(), sendingAddr)
j := cltest.CreateJobViaWeb(t, app, []byte(cltest.MustJSONMarshal(t, web.CreateJobRequest{TOML: tomlSpec})))
cltest.AwaitJobActive(t, app.JobSpawner(), j.ID, testutils.WaitTimeout(t))
@@ -587,13 +589,14 @@ observationSource = """
data="%s"
minConfirmations="2"
failOnRevert=false
+ evmChainID="%s"
from="[\\"%s\\"]"
]
"""
`
// This data is a call to link token's `transfer` function and will revert due to insufficient LINK on the sender address
revertingData := "0xa9059cbb000000000000000000000000526485b5abdd8ae9c6a63548e0215a83e7135e6100000000000000000000000000000000000000000000000db069932ea4fe1400"
- tomlSpec = fmt.Sprintf(tomlSpec, operatorContracts.linkTokenAddress.String(), revertingData, sendingAddr)
+ tomlSpec = fmt.Sprintf(tomlSpec, operatorContracts.linkTokenAddress.String(), revertingData, testutils.SimulatedChainID.String(), sendingAddr)
j := cltest.CreateJobViaWeb(t, app, []byte(cltest.MustJSONMarshal(t, web.CreateJobRequest{TOML: tomlSpec})))
cltest.AwaitJobActive(t, app.JobSpawner(), j.ID, testutils.WaitTimeout(t))
@@ -929,8 +932,9 @@ type = "offchainreporting"
schemaVersion = 1
name = "boot"
contractAddress = "%s"
+evmChainID = "%s"
isBootstrapPeer = true
-`, ocrContractAddress))
+`, ocrContractAddress, testutils.SimulatedChainID.String()))
require.NoError(t, err)
jb.Name = null.NewString("boot", true)
err = appBootstrap.AddJobV2(testutils.Context(t), &jb)
@@ -997,6 +1001,7 @@ type = "offchainreporting"
schemaVersion = 1
name = "web oracle spec"
contractAddress = "%s"
+evmChainID = "%s"
isBootstrapPeer = false
p2pBootstrapPeers = [
"/ip4/127.0.0.1/tcp/%d/p2p/%s"
@@ -1022,7 +1027,7 @@ observationSource = """
answer1 [type=median index=0];
"""
-`, ocrContractAddress, bootstrapNodePortV1, bootstrapPeerID, keys[i].ID(), transmitters[i], fmt.Sprintf("bridge%d", i), i, slowServers[i].URL, i))
+`, ocrContractAddress, testutils.SimulatedChainID.String(), bootstrapNodePortV1, bootstrapPeerID, keys[i].ID(), transmitters[i], fmt.Sprintf("bridge%d", i), i, slowServers[i].URL, i))
require.NoError(t, err)
jb.Name = null.NewString("testocr", true)
err = apps[i].AddJobV2(testutils.Context(t), &jb)
@@ -1157,9 +1162,10 @@ type = "offchainreporting"
schemaVersion = 1
name = "boot"
contractAddress = "%s"
+evmChainID = "%s"
forwardingAllowed = true
isBootstrapPeer = true
-`, ocrContractAddress))
+`, ocrContractAddress, testutils.SimulatedChainID.String()))
require.NoError(t, err)
jb.Name = null.NewString("boot", true)
err = appBootstrap.AddJobV2(testutils.Context(t), &jb)
@@ -1227,6 +1233,7 @@ type = "offchainreporting"
schemaVersion = 1
name = "web oracle spec"
contractAddress = "%s"
+evmChainID = "%s"
forwardingAllowed = true
isBootstrapPeer = false
p2pBootstrapPeers = [
@@ -1253,7 +1260,7 @@ observationSource = """
answer1 [type=median index=0];
"""
-`, ocrContractAddress, bootstrapNodePortV1, bootstrapPeerID, keys[i].ID(), transmitters[i], fmt.Sprintf("bridge%d", i), i, slowServers[i].URL, i))
+`, ocrContractAddress, testutils.SimulatedChainID.String(), bootstrapNodePortV1, bootstrapPeerID, keys[i].ID(), transmitters[i], fmt.Sprintf("bridge%d", i), i, slowServers[i].URL, i))
require.NoError(t, err)
jb.Name = null.NewString("testocr", true)
err = apps[i].AddJobV2(testutils.Context(t), &jb)
@@ -1342,7 +1349,7 @@ func TestIntegration_BlockHistoryEstimator(t *testing.T) {
Transactions: cltest.LegacyTransactionsFromGasPrices(48_000_000_000, 49_000_000_000, 31_000_000_000),
}
- evmChainID := utils.NewBig(cfg.DefaultChainID())
+ evmChainID := utils.NewBig(evmtest.MustGetDefaultChainID(t, cfg.EVMConfigs()))
h40 := evmtypes.Head{Hash: utils.NewHash(), Number: 40, EVMChainID: evmChainID}
h41 := evmtypes.Head{Hash: b41.Hash, ParentHash: h40.Hash, Number: 41, EVMChainID: evmChainID}
h42 := evmtypes.Head{Hash: b42.Hash, ParentHash: h41.Hash, Number: 42, EVMChainID: evmChainID}
@@ -1373,15 +1380,14 @@ func TestIntegration_BlockHistoryEstimator(t *testing.T) {
})
ethClient.On("Dial", mock.Anything).Return(nil)
- ethClient.On("ConfiguredChainID", mock.Anything).Return(cfg.DefaultChainID(), nil)
+ ethClient.On("ConfiguredChainID", mock.Anything).Return(*evmtest.MustGetDefaultChainID(t, cfg.EVMConfigs()), nil)
ethClient.On("BalanceAt", mock.Anything, mock.Anything, mock.Anything).Maybe().Return(oneETH.ToInt(), nil)
// HeadTracker backfill
ethClient.On("HeadByHash", mock.Anything, h40.Hash).Return(&h40, nil).Maybe()
ethClient.On("HeadByHash", mock.Anything, h41.Hash).Return(&h41, nil).Maybe()
ethClient.On("HeadByHash", mock.Anything, h42.Hash).Return(&h42, nil).Maybe()
- legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(cc)
- require.NoError(t, err)
+ legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(cc)
for _, re := range cc.Slice() {
require.NoError(t, re.Start(testutils.Context(t)))
}
diff --git a/core/internal/features/ocr2/features_ocr2_test.go b/core/internal/features/ocr2/features_ocr2_test.go
index 10317597ebc..3883e0319ed 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,
@@ -266,8 +276,8 @@ func TestIntegration_OCR2(t *testing.T) {
err = bootstrapNode.app.Start(testutils.Context(t))
require.NoError(t, err)
- chainSet := bootstrapNode.app.GetRelayers().LegacyEVMChains()
- require.NotNil(t, chainSet)
+ emvChains := bootstrapNode.app.GetRelayers().LegacyEVMChains()
+ require.NotNil(t, emvChains)
ocrJob, err := ocrbootstrap.ValidatedBootstrapSpecToml(fmt.Sprintf(`
type = "bootstrap"
name = "bootstrap"
@@ -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/configtest/v2/general_config.go b/core/internal/testutils/configtest/v2/general_config.go
index 34843c740d6..febbb367bd5 100644
--- a/core/internal/testutils/configtest/v2/general_config.go
+++ b/core/internal/testutils/configtest/v2/general_config.go
@@ -50,6 +50,7 @@ func overrides(c *chainlink.Config, s *chainlink.Secrets) {
c.Database.MaxIdleConns = ptr[int64](20)
c.Database.MaxOpenConns = ptr[int64](20)
c.Database.MigrateOnStartup = ptr(false)
+ c.Database.DefaultLockTimeout = models.MustNewDuration(1 * time.Minute)
c.JobPipeline.ReaperInterval = models.MustNewDuration(0)
diff --git a/core/internal/testutils/evmtest/evmtest.go b/core/internal/testutils/evmtest/evmtest.go
index 0fd391c3a23..2a86101d0d8 100644
--- a/core/internal/testutils/evmtest/evmtest.go
+++ b/core/internal/testutils/evmtest/evmtest.go
@@ -34,6 +34,7 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/logger"
"github.com/smartcontractkit/chainlink/v2/core/services/keystore"
"github.com/smartcontractkit/chainlink/v2/core/services/pg"
+ "github.com/smartcontractkit/chainlink/v2/core/services/relay"
evmrelay "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm"
"github.com/smartcontractkit/chainlink/v2/core/services/srvctest"
"github.com/smartcontractkit/chainlink/v2/core/utils"
@@ -44,7 +45,7 @@ func NewChainScopedConfig(t testing.TB, cfg evm.AppConfig) evmconfig.ChainScoped
if len(cfg.EVMConfigs()) > 0 {
evmCfg = cfg.EVMConfigs()[0]
} else {
- chainID := utils.NewBigI(0)
+ var chainID = (*utils.Big)(testutils.FixtureChainID)
evmCfg = &evmtoml.EVMConfig{
ChainID: chainID,
Chain: evmtoml.Defaults(chainID),
@@ -81,20 +82,20 @@ 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 {
if testopts.Client != nil {
return testopts.Client
}
- return evmclient.NewNullClient(testopts.GeneralConfig.DefaultChainID(), logger.TestLogger(t))
+ return evmclient.NewNullClient(MustGetDefaultChainID(t, testopts.GeneralConfig.EVMConfigs()), logger.TestLogger(t))
}
if testopts.LogBroadcaster != nil {
opts.GenLogBroadcaster = func(*big.Int) log.Broadcaster {
@@ -128,10 +129,21 @@ func NewChainRelayExtOpts(t testing.TB, testopts TestChainOpts) evm.ChainRelayEx
return opts
}
+// Deprecated, this is a replacement function for tests for now removed default evmChainID logic
+func MustGetDefaultChainID(t testing.TB, evmCfgs evmtoml.EVMConfigs) *big.Int {
+ if len(evmCfgs) == 0 {
+ t.Fatalf("at least one evm chain config must be defined")
+ }
+ return evmCfgs[0].ChainID.ToInt()
+}
+
+// Deprecated, this is a replacement function for tests for now removed default chain logic
func MustGetDefaultChain(t testing.TB, cc evm.LegacyChainContainer) evm.Chain {
- chain, err := cc.Default()
- require.NoError(t, err)
- return chain
+ if len(cc.Slice()) == 0 {
+ t.Fatalf("at least one evm chain container must be defined")
+ }
+
+ return cc.Slice()[0]
}
type TestConfigs struct {
@@ -150,9 +162,9 @@ func (mo *TestConfigs) PutChains(cs ...evmtoml.EVMConfig) {
defer mo.mu.Unlock()
chains:
for i := range cs {
- id := cs[i].ChainID.String()
+ id := cs[i].ChainID
for j, c2 := range mo.EVMConfigs {
- if c2.ChainID.String() == id {
+ if c2.ChainID == id {
mo.EVMConfigs[j] = &cs[i] // replace
continue chains
}
@@ -161,7 +173,7 @@ chains:
}
}
-func (mo *TestConfigs) Chains(offset int, limit int, ids ...string) (cs []types.ChainStatus, count int, err error) {
+func (mo *TestConfigs) Chains(ids ...relay.ChainID) (cs []types.ChainStatus, count int, err error) {
mo.mu.RLock()
defer mo.mu.RUnlock()
if len(ids) == 0 {
@@ -200,19 +212,19 @@ func (mo *TestConfigs) Chains(offset int, limit int, ids ...string) (cs []types.
}
// Nodes implements evmtypes.Configs
-func (mo *TestConfigs) Nodes(chainID utils.Big) (nodes []evmtypes.Node, err error) {
+func (mo *TestConfigs) Nodes(id relay.ChainID) (nodes []evmtypes.Node, err error) {
mo.mu.RLock()
defer mo.mu.RUnlock()
for i := range mo.EVMConfigs {
c := mo.EVMConfigs[i]
- if chainID.Cmp(c.ChainID) == 0 {
+ if id == c.ChainID.String() {
for _, n := range c.Nodes {
nodes = append(nodes, legacyNode(n, c.ChainID))
}
}
}
- err = fmt.Errorf("no nodes: chain %s: %w", chainID.String(), chains.ErrNotFound)
+ err = fmt.Errorf("no nodes: chain %s: %w", id, chains.ErrNotFound)
return
}
diff --git a/core/internal/testutils/testutils.go b/core/internal/testutils/testutils.go
index 447475251c4..d50efcc799a 100644
--- a/core/internal/testutils/testutils.go
+++ b/core/internal/testutils/testutils.go
@@ -427,7 +427,7 @@ func AssertCount(t *testing.T, db *sqlx.DB, tableName string, expected int64) {
func AssertCountPerSubject(t *testing.T, db *sqlx.DB, expected int64, subject uuid.UUID) {
t.Helper()
var count int64
- err := db.Get(&count, `SELECT COUNT(*) FROM eth_txes
+ err := db.Get(&count, `SELECT COUNT(*) FROM evm.txes
WHERE state = 'unstarted' AND subject = $1;`, subject)
require.NoError(t, err)
require.Equal(t, expected, count)
diff --git a/core/logger/logger.go b/core/logger/logger.go
index 1d8feb139f7..8e847a99ac0 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.
@@ -78,8 +79,9 @@ type Logger interface {
With(args ...interface{}) Logger
// Named creates a new Logger sub-scoped with name.
// Names are inherited and dot-separated.
- // a := l.Named("a") // logger=a
- // b := a.Named("b") // logger=a.b
+ // a := l.Named("A") // logger=A
+ // b := a.Named("A") // logger=A.B
+ // Names are generally `MixedCaps`, without spaces, like Go names.
Named(name string) Logger
// SetLogLevel changes the log level for this and all connected Loggers.
diff --git a/core/logger/mocks/logger.go b/core/logger/mocks/logger.go
new file mode 100644
index 00000000000..24752c2b6b6
--- /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/logger/pyroscope.go b/core/logger/pyroscope.go
index 3303fe51dee..226c241d36d 100644
--- a/core/logger/pyroscope.go
+++ b/core/logger/pyroscope.go
@@ -3,7 +3,7 @@ package logger
import (
"runtime"
- "github.com/pyroscope-io/client/pyroscope"
+ "github.com/grafana/pyroscope-go"
"github.com/smartcontractkit/chainlink/v2/core/config"
"github.com/smartcontractkit/chainlink/v2/core/static"
diff --git a/core/scripts/chaincli/command/keeper/launch.go b/core/scripts/chaincli/command/keeper/launch.go
index 7e4c79f70d2..e918095edb4 100644
--- a/core/scripts/chaincli/command/keeper/launch.go
+++ b/core/scripts/chaincli/command/keeper/launch.go
@@ -47,7 +47,7 @@ var launchAndTestCmd = &cobra.Command{
func init() {
launchAndTestCmd.Flags().BoolP("withdraw", "w", true, "Specify if funds should be withdrawn and upkeeps should be canceled")
- launchAndTestCmd.Flags().BoolP("bootstrap", "b", true, "Specify if launching bootstrap node is required. Default listen ports(5688, 8000) are used, if you need to use custom ports, please use bootstrap command")
+ launchAndTestCmd.Flags().BoolP("bootstrap", "b", false, "Specify if launching bootstrap node is required. Default listen ports(5688, 8000) are used, if you need to use custom ports, please use bootstrap command")
launchAndTestCmd.Flags().BoolP("export-logs", "l", false, "Specify if container logs should be exported to ./")
launchAndTestCmd.Flags().BoolP("force", "f", false, "Specify if existing containers should be forcefully removed ./")
}
diff --git a/core/scripts/chaincli/handler/keeper.go b/core/scripts/chaincli/handler/keeper.go
index 0cbc1525577..ba8276efb56 100644
--- a/core/scripts/chaincli/handler/keeper.go
+++ b/core/scripts/chaincli/handler/keeper.go
@@ -27,10 +27,10 @@ import (
registry20 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_registry_wrapper2_0"
registry21 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_registry_wrapper_2_1"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/log_upkeep_counter_wrapper"
- "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/mercury_upkeep_wrapper"
+ "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/streams_lookup_upkeep_wrapper"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/upkeep_counter_wrapper"
upkeep "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/upkeep_perform_counter_restrictive_wrapper"
- "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/verifiable_load_mercury_upkeep_wrapper"
+ "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/verifiable_load_streams_lookup_upkeep_wrapper"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/verifiable_load_upkeep_wrapper"
"github.com/smartcontractkit/chainlink/v2/core/logger"
"github.com/smartcontractkit/chainlink/v2/core/services/keeper"
@@ -577,19 +577,21 @@ func (k *Keeper) deployUpkeeps(ctx context.Context, registryAddr common.Address,
log.Fatal(err)
}
if k.cfg.VerifiableLoadTest {
- upkeepAddr, deployUpkeepTx, _, err = verifiable_load_mercury_upkeep_wrapper.DeployVerifiableLoadMercuryUpkeep(
+ upkeepAddr, deployUpkeepTx, _, err = verifiable_load_streams_lookup_upkeep_wrapper.DeployVerifiableLoadStreamsLookupUpkeep(
k.buildTxOpts(ctx),
k.client,
common.HexToAddress(k.cfg.Registrar),
k.cfg.UseArbBlockNumber,
)
} else {
- upkeepAddr, deployUpkeepTx, _, err = mercury_upkeep_wrapper.DeployMercuryUpkeep(
+ upkeepAddr, deployUpkeepTx, _, err = streams_lookup_upkeep_wrapper.DeployStreamsLookupUpkeep(
k.buildTxOpts(ctx),
k.client,
big.NewInt(k.cfg.UpkeepTestRange),
big.NewInt(k.cfg.UpkeepInterval),
- false,
+ true, /* useArbBlock */
+ true, /* staging */
+ false, /* verify mercury response */
)
}
if err != nil {
@@ -717,7 +719,7 @@ func (k *Keeper) deployUpkeeps(ctx context.Context, registryAddr common.Address,
log.Printf("registry version is %s", v)
log.Printf("active upkeep ids: %v", activeUpkeepIds)
- adminBytes, err := json.Marshal(evm.AdminOffchainConfig{
+ adminBytes, err := json.Marshal(evm.UpkeepPrivilegeConfig{
MercuryEnabled: true,
})
if err != nil {
diff --git a/core/scripts/chaincli/handler/keeper_deployer.go b/core/scripts/chaincli/handler/keeper_deployer.go
index 089b176695c..eae8c68d332 100644
--- a/core/scripts/chaincli/handler/keeper_deployer.go
+++ b/core/scripts/chaincli/handler/keeper_deployer.go
@@ -14,6 +14,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
ocr2config "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper"
+ ocr3confighelper "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3confighelper"
ocr2types "github.com/smartcontractkit/libocr/offchainreporting2plus/types"
"github.com/umbracle/ethgo/abi"
@@ -297,11 +298,13 @@ func (d *v21KeeperDeployer) SetKeepers(opts *bind.TransactOpts, cls []cmd.HTTPCl
panic(err)
}
- signerOnchainPublicKeys, transmitterAccounts, f, _, offchainConfigVersion, offchainConfig, err := ocr2config.ContractSetConfigArgsForTests(
+ signerOnchainPublicKeys, transmitterAccounts, f, _, offchainConfigVersion, offchainConfig, err := ocr3confighelper.ContractSetConfigArgsForTests(
5*time.Second, // deltaProgress time.Duration,
10*time.Second, // deltaResend time.Duration,
+ 400*time.Millisecond, // deltaInitial time.Duration,
2500*time.Millisecond, // deltaRound time.Duration,
40*time.Millisecond, // deltaGrace time.Duration,
+ 300*time.Millisecond, // deltaCertifiedCommitRequest time.Duration,
30*time.Second, // deltaStage time.Duration,
50, // rMax uint8,
S, // s []int,
@@ -309,7 +312,6 @@ func (d *v21KeeperDeployer) SetKeepers(opts *bind.TransactOpts, cls []cmd.HTTPCl
offC, // reportingPluginConfig []byte,
20*time.Millisecond, // maxDurationQuery time.Duration,
1600*time.Millisecond, // maxDurationObservation time.Duration,
- 800*time.Millisecond, // maxDurationReport time.Duration,
20*time.Millisecond, // maxDurationShouldAcceptFinalizedReport time.Duration,
20*time.Millisecond, // maxDurationShouldTransmitAcceptedReport time.Duration,
1, // f int,
diff --git a/core/scripts/chaincli/handler/keeper_launch.go b/core/scripts/chaincli/handler/keeper_launch.go
index fb975b48369..83ee6a77129 100644
--- a/core/scripts/chaincli/handler/keeper_launch.go
+++ b/core/scripts/chaincli/handler/keeper_launch.go
@@ -347,6 +347,7 @@ name = "ocr2-automation"
forwardingAllowed = false
schemaVersion = 1
contractID = "%s"
+contractConfigTrackerPollInterval = "15s"
ocrKeyBundleID = "%s"
transmitterID = "%s"
p2pv2Bootstrappers = [
@@ -358,6 +359,8 @@ chainID = %d
[pluginConfig]
maxServiceWorkers = 100
+cacheEvictionInterval = "1s"
+contractVersion = "%s"
mercuryCredentialName = "%s"`
// createOCR2KeeperJob creates an ocr2keeper job in the chainlink node by the given address
@@ -367,6 +370,12 @@ func (k *Keeper) createOCR2KeeperJob(client cmd.HTTPClient, contractAddr, nodeAd
return fmt.Errorf("failed to get node OCR2 key bundle ID: %s", err)
}
+ // Correctly assign contract version in OCR job spec.
+ var contractVersion string = "v2.0"
+ if k.cfg.RegistryVersion == keeper.RegistryVersion_2_1 {
+ contractVersion = "v2.1"
+ }
+
request, err := json.Marshal(web.CreateJobRequest{
TOML: fmt.Sprintf(ocr2keeperJobTemplate,
contractAddr, // contractID
@@ -374,6 +383,7 @@ func (k *Keeper) createOCR2KeeperJob(client cmd.HTTPClient, contractAddr, nodeAd
nodeAddr, // transmitterID - node wallet address
k.cfg.BootstrapNodeAddr, // bootstrap node key and address
k.cfg.ChainID, // chainID
+ contractVersion, // contractVersion
k.cfg.MercuryCredName, // mercury credential name
),
})
diff --git a/core/scripts/chaincli/handler/keeper_verifiable_load.go b/core/scripts/chaincli/handler/keeper_verifiable_load.go
index ad704393877..429a7620079 100644
--- a/core/scripts/chaincli/handler/keeper_verifiable_load.go
+++ b/core/scripts/chaincli/handler/keeper_verifiable_load.go
@@ -37,7 +37,7 @@ type upkeepInfo struct {
}
type verifiableLoad interface {
- GetActiveUpkeepIDs(opts *bind.CallOpts, startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error)
+ GetAllActiveUpkeepIDsOnRegistry(opts *bind.CallOpts, startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error)
Counters(opts *bind.CallOpts, upkeepId *big.Int) (*big.Int, error)
GetBucketedDelays(opts *bind.CallOpts, upkeepId *big.Int, bucket uint16) ([]*big.Int, error)
Buckets(opts *bind.CallOpts, arg0 *big.Int) (uint16, error)
@@ -79,7 +79,7 @@ func (k *Keeper) GetVerifiableLoadStats(ctx context.Context) {
}
// get all active upkeep IDs on this verifiable load contract
- upkeepIds, err := v.GetActiveUpkeepIDs(opts, big.NewInt(0), big.NewInt(0))
+ upkeepIds, err := v.GetAllActiveUpkeepIDsOnRegistry(opts, big.NewInt(0), big.NewInt(0))
if err != nil {
log.Fatalf("failed to get active upkeep IDs from %s: %v", k.cfg.VerifiableLoadContractAddress, err)
}
diff --git a/core/scripts/common/helpers.go b/core/scripts/common/helpers.go
index c5d6499b2fd..ed8155d1779 100644
--- a/core/scripts/common/helpers.go
+++ b/core/scripts/common/helpers.go
@@ -214,6 +214,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 = ""
}
@@ -410,7 +415,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/src/fetching.go b/core/scripts/functions/src/fetching.go
index 429f4619be8..0b22a93252d 100644
--- a/core/scripts/functions/src/fetching.go
+++ b/core/scripts/functions/src/fetching.go
@@ -69,6 +69,17 @@ func mustFetchNodesKeys(chainID int64, nodes []*node) (nca []NodeKeys) {
helpers.PanicErr(errors.New("node must have EVM OCR2 bundle"))
}
ocr2Bundle := ocr2Bundles[ocr2BundleIndex]
+ output.Reset()
+
+ err = client.ListCSAKeys(&cli.Context{
+ App: app,
+ })
+ helpers.PanicErr(err)
+ var csaKeys []presenters.CSAKeyResource
+ helpers.PanicErr(json.Unmarshal(output.Bytes(), &csaKeys))
+ csaPubKey, err := findFirstCSAPublicKey(csaKeys)
+ helpers.PanicErr(err)
+ output.Reset()
nc := NodeKeys{
EthAddress: ethAddress,
@@ -77,6 +88,7 @@ func mustFetchNodesKeys(chainID int64, nodes []*node) (nca []NodeKeys) {
OCR2ConfigPublicKey: strings.TrimPrefix(ocr2Bundle.ConfigPublicKey, "ocr2cfg_evm_"),
OCR2OnchainPublicKey: strings.TrimPrefix(ocr2Bundle.OnchainPublicKey, "ocr2on_evm_"),
OCR2OffchainPublicKey: strings.TrimPrefix(ocr2Bundle.OffchainPublicKey, "ocr2off_evm_"),
+ CSAPublicKey: csaPubKey,
}
nca = append(nca, nc)
@@ -84,6 +96,13 @@ func mustFetchNodesKeys(chainID int64, nodes []*node) (nca []NodeKeys) {
return
}
+func findFirstCSAPublicKey(csaKeyResources []presenters.CSAKeyResource) (string, error) {
+ for _, r := range csaKeyResources {
+ return r.PubKey, nil
+ }
+ return "", errors.New("did not find any CSA Key Resources")
+}
+
func findEvmOCR2Bundle(ocr2Bundles []ocr2Bundle) int {
for i, b := range ocr2Bundles {
if b.ChainType == "evm" {
diff --git a/core/scripts/functions/src/generate_jobspecs_cmd.go b/core/scripts/functions/src/generate_jobspecs_cmd.go
index 332e2bdc0cb..4f35dac51bd 100644
--- a/core/scripts/functions/src/generate_jobspecs_cmd.go
+++ b/core/scripts/functions/src/generate_jobspecs_cmd.go
@@ -31,6 +31,8 @@ func (g *generateJobSpecs) Run(args []string) {
donID := fs.String("donid", "", "don id string")
routerAddress := fs.String("contract", "", "router contract address")
truncateHostname := fs.Bool("truncateboothostname", false, "truncate host name to first segment (needed for staging DONs)")
+ gatewayID := fs.String("gatewayid", "", "gateway id string")
+ gatewayURL := fs.String("gatewayurl", "", "gateway url string")
err := fs.Parse(args)
if err != nil || nodesFile == nil || *nodesFile == "" || routerAddress == nil || *routerAddress == "" {
fs.Usage()
@@ -45,7 +47,7 @@ func (g *generateJobSpecs) Run(args []string) {
helpers.PanicErr(err)
bootHost := nodes[0].url.Host
- lines = replacePlaceholders(lines, *donID, *chainID, *p2pPort, *routerAddress, bootHost, &bootstrapNode, &bootstrapNode, *truncateHostname)
+ lines = replacePlaceholders(lines, *donID, *chainID, *p2pPort, *routerAddress, bootHost, &bootstrapNode, &bootstrapNode, *truncateHostname, *gatewayID, *gatewayURL)
outputPath := filepath.Join(artefactsDir, bootHost+".toml")
err = writeLines(lines, outputPath)
helpers.PanicErr(err)
@@ -54,7 +56,7 @@ func (g *generateJobSpecs) Run(args []string) {
lines, err = readLines(filepath.Join(templatesDir, oracleSpecTemplate))
helpers.PanicErr(err)
for i := 1; i < len(nodes); i++ {
- oracleLines := replacePlaceholders(lines, *donID, *chainID, *p2pPort, *routerAddress, bootHost, &bootstrapNode, &nca[i], *truncateHostname)
+ oracleLines := replacePlaceholders(lines, *donID, *chainID, *p2pPort, *routerAddress, bootHost, &bootstrapNode, &nca[i], *truncateHostname, *gatewayID, *gatewayURL)
outputPath := filepath.Join(artefactsDir, nodes[i].url.Host+".toml")
err = writeLines(oracleLines, outputPath)
helpers.PanicErr(err)
@@ -62,7 +64,7 @@ func (g *generateJobSpecs) Run(args []string) {
}
}
-func replacePlaceholders(lines []string, donID string, chainID, p2pPort int64, routerAddress, bootHost string, boot *NodeKeys, node *NodeKeys, truncateHostname bool) (output []string) {
+func replacePlaceholders(lines []string, donID string, chainID, p2pPort int64, routerAddress, bootHost string, boot *NodeKeys, node *NodeKeys, truncateHostname bool, gatewayID string, gatewayURL string) (output []string) {
chainIDStr := strconv.FormatInt(chainID, 10)
if truncateHostname {
bootHost = bootHost[:strings.IndexByte(bootHost, '.')]
@@ -77,6 +79,8 @@ func replacePlaceholders(lines []string, donID string, chainID, p2pPort int64, r
l = strings.Replace(l, "{{p2p_bootstrapper}}", bootstrapper, 1)
l = strings.Replace(l, "{{timestamp}}", ts, 1)
l = strings.Replace(l, "{{don_id}}", donID, 1)
+ l = strings.Replace(l, "{{gateway_id}}", gatewayID, 1)
+ l = strings.Replace(l, "{{gateway_url}}", gatewayURL, 1)
output = append(output, l)
}
return
diff --git a/core/scripts/functions/src/generate_ocr2_config_cmd.go b/core/scripts/functions/src/generate_ocr2_config_cmd.go
index cbb6a7f3bbc..1cfddf4413c 100644
--- a/core/scripts/functions/src/generate_ocr2_config_cmd.go
+++ b/core/scripts/functions/src/generate_ocr2_config_cmd.go
@@ -80,6 +80,7 @@ type NodeKeys struct {
OCR2OnchainPublicKey string // ocr2on_evm_
OCR2OffchainPublicKey string // ocr2off_evm_
OCR2ConfigPublicKey string // ocr2cfg_evm_
+ CSAPublicKey string
}
type orc2drOracleConfig struct {
diff --git a/core/scripts/functions/src/sample_keys.json b/core/scripts/functions/src/sample_keys.json
index b832d50a680..ea6bd1f7030 100644
--- a/core/scripts/functions/src/sample_keys.json
+++ b/core/scripts/functions/src/sample_keys.json
@@ -5,7 +5,8 @@
"OCR2BundleID": "0000000000000000000000000000000000000000000000000000000000000000",
"OCR2OnchainPublicKey": "0000000000000000000000000000000000000000",
"OCR2OffchainPublicKey": "0000000000000000000000000000000000000000000000000000000000000000",
- "OCR2ConfigPublicKey": "0000000000000000000000000000000000000000000000000000000000000000"
+ "OCR2ConfigPublicKey": "0000000000000000000000000000000000000000000000000000000000000000",
+ "CSAPublicKey": "0000000000000000000000000000000000000000000000000000000000000000"
},
{
"EthAddress": "0x0000000000000000000000000000000000000000",
@@ -13,7 +14,8 @@
"OCR2BundleID": "0000000000000000000000000000000000000000000000000000000000000000",
"OCR2OnchainPublicKey": "0000000000000000000000000000000000000000",
"OCR2OffchainPublicKey": "0000000000000000000000000000000000000000000000000000000000000000",
- "OCR2ConfigPublicKey": "0000000000000000000000000000000000000000000000000000000000000000"
+ "OCR2ConfigPublicKey": "0000000000000000000000000000000000000000000000000000000000000000",
+ "CSAPublicKey": "0000000000000000000000000000000000000000000000000000000000000000"
},
{
"EthAddress": "0x0000000000000000000000000000000000000000",
@@ -21,7 +23,8 @@
"OCR2BundleID": "0000000000000000000000000000000000000000000000000000000000000000",
"OCR2OnchainPublicKey": "0000000000000000000000000000000000000000",
"OCR2OffchainPublicKey": "0000000000000000000000000000000000000000000000000000000000000000",
- "OCR2ConfigPublicKey": "0000000000000000000000000000000000000000000000000000000000000000"
+ "OCR2ConfigPublicKey": "0000000000000000000000000000000000000000000000000000000000000000",
+ "CSAPublicKey": "0000000000000000000000000000000000000000000000000000000000000000"
},
{
"EthAddress": "0x0000000000000000000000000000000000000000",
@@ -29,6 +32,7 @@
"OCR2BundleID": "0000000000000000000000000000000000000000000000000000000000000000",
"OCR2OnchainPublicKey": "0000000000000000000000000000000000000000",
"OCR2OffchainPublicKey": "0000000000000000000000000000000000000000000000000000000000000000",
- "OCR2ConfigPublicKey": "0000000000000000000000000000000000000000000000000000000000000000"
+ "OCR2ConfigPublicKey": "0000000000000000000000000000000000000000000000000000000000000000",
+ "CSAPublicKey": "0000000000000000000000000000000000000000000000000000000000000000"
}
-]
\ No newline at end of file
+]
diff --git a/core/scripts/functions/templates/oracle.toml b/core/scripts/functions/templates/oracle.toml
index 10e2164a047..4739252d68e 100644
--- a/core/scripts/functions/templates/oracle.toml
+++ b/core/scripts/functions/templates/oracle.toml
@@ -23,13 +23,62 @@ 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 = "2 link"
+
+
+ [pluginConfig.OnchainAllowlist]
+ blockConfirmations = 1
+ contractAddress = "{{router_contract_address}}"
+ contractVersion = 1
+ updateFrequencySec = 30
+ updateTimeoutSec = 10
+
+ [pluginConfig.OnchainSubscriptions]
+ blockConfirmations = 1
+ contractAddress = "{{router_contract_address}}"
+ updateFrequencySec = 30
+ updateTimeoutSec = 10
+ updateRangeSize = 2000
+
+ [pluginConfig.RateLimiter]
+ globalBurst = 30
+ globalRPS = 20
+ perSenderBurst = 5
+ perSenderRPS = 1
+
+ [pluginConfig.S4Constraints]
+ maxPayloadSizeBytes = 20_000
+ maxSlotsPerUser = 5
+ maxExpirationLengthSec = 259_200
+
+ [pluginConfig.decryptionQueueConfig]
+ completedCacheTimeoutSec = 300
+ decryptRequestTimeoutSec = 180
+ maxCiphertextBytes = 20_000
+ maxCiphertextIdLength = 100
+ maxQueueLength = 5_000
+
+ [pluginConfig.gatewayConnectorConfig]
+ AuthMinChallengeLen = 20
+ AuthTimestampToleranceSec = 20
+ DonID = "{{don_id}}"
+ NodeAddress = "{{node_eth_address}}"
+
+ [pluginConfig.gatewayConnectorConfig.WsClientConfig]
+ HandshakeTimeoutMillis = 1_000
+
+ [[pluginConfig.gatewayConnectorConfig.Gateways]]
+ Id = "{{gateway_id}}"
+ URL = "{{gateway_url}}"
\ No newline at end of file
diff --git a/core/scripts/gateway/client/send_request.go b/core/scripts/gateway/client/send_request.go
index ad3ea1cc27c..94ff6fb17da 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 50da3a9cc76..bb4b33eb521 100644
--- a/core/scripts/go.mod
+++ b/core/scripts/go.mod
@@ -1,25 +1,26 @@
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 => ../../
require (
github.com/ava-labs/coreth v0.12.1
- github.com/docker/docker v24.0.2+incompatible
+ github.com/docker/docker v24.0.4+incompatible
github.com/docker/go-connections v0.4.0
github.com/ethereum/go-ethereum v1.12.0
github.com/google/go-cmp v0.5.9
- github.com/google/uuid v1.3.0
+ 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/shopspring/decimal v1.3.1
github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000
- github.com/smartcontractkit/libocr v0.0.0-20230816220705-665e93233ae5
- github.com/smartcontractkit/ocr2keepers v0.7.17
+ 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.6.1
@@ -52,7 +53,7 @@ require (
github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129 // indirect
github.com/armon/go-metrics v0.4.1 // indirect
github.com/ava-labs/avalanchego v1.10.1 // indirect
- github.com/avast/retry-go/v4 v4.3.4 // indirect
+ github.com/avast/retry-go/v4 v4.5.0 // indirect
github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59 // indirect
github.com/benbjohnson/clock v1.3.4 // indirect
github.com/beorn7/perks v1.0.1 // indirect
@@ -85,7 +86,7 @@ require (
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/danieljoos/wincred v1.1.2 // indirect
github.com/danielkov/gin-helmet v0.0.0-20171108135313-1387e224435e // indirect
- github.com/davecgh/go-spew v1.1.1 // indirect
+ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect
github.com/deckarep/golang-set v1.8.0 // indirect
github.com/deckarep/golang-set/v2 v2.3.0 // indirect
@@ -98,6 +99,7 @@ require (
github.com/docker/go-units v0.5.0 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/dvsekhvalnov/jose2go v1.5.0 // indirect
+ github.com/esote/minmaxheap v1.0.0 // indirect
github.com/fatih/color v1.15.0 // indirect
github.com/flynn/noise v0.0.0-20180327030543-2492fe189ae6 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
@@ -142,11 +144,13 @@ require (
github.com/google/go-tpm v0.3.3 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/gopacket v1.1.19 // indirect
- github.com/google/pprof v0.0.0-20230602150820-91b7bce49751 // indirect
+ github.com/google/pprof v0.0.0-20230705174524-200ffdc848b8 // indirect
github.com/gorilla/context v1.1.1 // indirect
github.com/gorilla/securecookie v1.1.1 // indirect
github.com/gorilla/sessions v1.2.1 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
+ github.com/grafana/pyroscope-go v1.0.2 // indirect
+ github.com/grafana/pyroscope-go/godeltaprof v0.1.3 // indirect
github.com/graph-gophers/dataloader v5.0.0+incompatible // indirect
github.com/graph-gophers/graphql-go v1.3.0 // indirect
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect
@@ -157,7 +161,7 @@ require (
github.com/gtank/merlin v0.1.1 // indirect
github.com/gtank/ristretto255 v0.1.2 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
- github.com/hashicorp/go-hclog v1.4.0 // indirect
+ github.com/hashicorp/go-hclog v1.5.0 // indirect
github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hashicorp/go-plugin v1.4.10 // indirect
@@ -178,7 +182,7 @@ require (
github.com/ipfs/go-log v1.0.4 // indirect
github.com/ipfs/go-log/v2 v2.1.1 // indirect
github.com/jackc/chunkreader/v2 v2.0.1 // indirect
- github.com/jackc/pgconn v1.14.0 // indirect
+ github.com/jackc/pgconn v1.14.1 // indirect
github.com/jackc/pgio v1.0.0 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgproto3/v2 v2.3.2 // indirect
@@ -282,27 +286,25 @@ require (
github.com/prometheus/client_model v0.4.0 // indirect
github.com/prometheus/common v0.44.0 // indirect
github.com/prometheus/procfs v0.11.0 // indirect
- github.com/prometheus/prometheus v0.45.0 // indirect
- github.com/pyroscope-io/client v0.7.1 // indirect
- github.com/pyroscope-io/godeltaprof v0.1.0 // indirect
+ github.com/prometheus/prometheus v0.46.0 // indirect
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect
github.com/rivo/uniseg v0.4.4 // indirect
github.com/rjeczalik/notify v0.9.3 // indirect
github.com/robfig/cron/v3 v3.0.1 // indirect
- github.com/rogpeppe/go-internal v1.10.0 // indirect
+ github.com/rogpeppe/go-internal v1.11.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/sasha-s/go-deadlock v0.3.1 // indirect
github.com/scylladb/go-reflectx v1.0.1 // indirect
github.com/shirou/gopsutil v3.21.11+incompatible // indirect
- github.com/shirou/gopsutil/v3 v3.22.12 // indirect
+ github.com/shirou/gopsutil/v3 v3.23.8 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704 // indirect
- github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20230824124058-9b063c470048 // indirect
- github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230824125819-215fd09979a2 // indirect
- github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230802143301-165000751a85 // indirect
- github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20230802150127-d2c95679d61a // indirect
- github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230823081604-f2a0e6b108bb // indirect
- github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230823081604-f2a0e6b108bb // indirect
+ github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20230913032705-f924d753cc47 // 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/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 // indirect
+ github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 // indirect
github.com/smartcontractkit/wsrpc v0.7.2 // indirect
github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 // indirect
github.com/spaolacci/murmur3 v1.1.0 // indirect
@@ -318,10 +320,10 @@ require (
github.com/teris-io/shortid v0.0.0-20201117134242-e59966efd125 // indirect
github.com/theodesp/go-heaps v0.0.0-20190520121037-88e35354fe0a // indirect
github.com/tidwall/btree v1.6.0 // indirect
- github.com/tidwall/gjson v1.14.4 // indirect
+ github.com/tidwall/gjson v1.16.0 // indirect
github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.0 // indirect
- github.com/tklauser/go-sysconf v0.3.11 // indirect
+ github.com/tklauser/go-sysconf v0.3.12 // indirect
github.com/tklauser/numcpus v0.6.1 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/tyler-smith/go-bip39 v1.1.0 // indirect
@@ -349,19 +351,19 @@ require (
go.uber.org/zap v1.24.0 // indirect
golang.org/x/arch v0.4.0 // indirect
golang.org/x/crypto v0.11.0 // indirect
- golang.org/x/exp v0.0.0-20230711153332-06a737ee72cb // indirect
+ golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 // indirect
golang.org/x/mod v0.12.0 // indirect
golang.org/x/net v0.12.0 // indirect
golang.org/x/sync v0.3.0 // indirect
- golang.org/x/sys v0.10.0 // indirect
+ golang.org/x/sys v0.11.0 // indirect
golang.org/x/term v0.10.0 // indirect
golang.org/x/text v0.11.0 // indirect
golang.org/x/time v0.3.0 // indirect
golang.org/x/tools v0.11.0 // indirect
gonum.org/v1/gonum v0.13.0 // indirect
- google.golang.org/genproto v0.0.0-20230706204954-ccb25ca9f130 // indirect
- google.golang.org/genproto/googleapis/api v0.0.0-20230629202037-9506855d4529 // indirect
- google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 // indirect
+ google.golang.org/genproto v0.0.0-20230717213848-3f92550aa753 // indirect
+ google.golang.org/genproto/googleapis/api v0.0.0-20230717213848-3f92550aa753 // indirect
+ google.golang.org/genproto/googleapis/rpc v0.0.0-20230717213848-3f92550aa753 // indirect
google.golang.org/grpc v1.56.2 // indirect
google.golang.org/protobuf v1.31.0 // indirect
gopkg.in/guregu/null.v2 v2.1.2 // indirect
diff --git a/core/scripts/go.sum b/core/scripts/go.sum
index 7da9f19e2be..571b9b0e8ef 100644
--- a/core/scripts/go.sum
+++ b/core/scripts/go.sum
@@ -19,18 +19,22 @@ 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=
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
-cloud.google.com/go/compute v1.20.1 h1:6aKEtlUiwEpJzM001l0yFkpXmUVXaN8W+fbkb2AZNbg=
+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.0 h1:67gSqaPukx7O8WLLHMa0PNs3EBGd2eE4d+psbO/CO94=
+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=
@@ -98,26 +106,32 @@ 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/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/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=
@@ -128,11 +142,12 @@ github.com/ava-labs/avalanchego v1.10.1 h1:lBeamJ1iNq+p2oKg2nAs+A65m8vhSDjkiTDbw
github.com/ava-labs/avalanchego v1.10.1/go.mod h1:ZvSXWlbkUKlbk3BsWx29a+8eVHe/WBsOxh55BSGoeRk=
github.com/ava-labs/coreth v0.12.1 h1:EWSkFGHGVUxmu1pnSK/2pdcxaAVHbGspHqO3Ag+i7sA=
github.com/ava-labs/coreth v0.12.1/go.mod h1:/5x54QlIKjlPebkdzTA5ic9wXdejbWOnQosztkv9jxo=
-github.com/avast/retry-go/v4 v4.3.4 h1:pHLkL7jvCvP317I8Ge+Km2Yhntv3SdkJm7uekkqbKhM=
-github.com/avast/retry-go/v4 v4.3.4/go.mod h1:rv+Nla6Vk3/ilU0H51VHddWHiwimzX66yZ0JT6T+UvE=
+github.com/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.276 h1:ywPlx9C5Yc482dUgAZ9bHpQ6onVvJvYE9FJWsNDCEy0=
+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/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=
@@ -144,6 +159,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=
@@ -155,6 +171,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=
@@ -165,6 +182,7 @@ 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.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s=
@@ -172,8 +190,10 @@ github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZX
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=
@@ -186,6 +206,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=
@@ -194,10 +215,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=
@@ -211,6 +235,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.7.0 h1:uBjbrBx4QzU0zOEnU8KxoDl18dMNgDh+zZRUE0ucsbo=
@@ -218,6 +243,7 @@ github.com/cometbft/cometbft-db v0.7.0/go.mod h1:yiKJIm2WKrt6x8Cyxtq9YTEcIMPcEe4
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=
@@ -238,6 +264,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=
@@ -249,23 +276,28 @@ github.com/cosmos/ics23/go v0.9.1-0.20221207100636-b1abd8678aab/go.mod h1:2Cwqas
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=
github.com/danielkov/gin-helmet v0.0.0-20171108135313-1387e224435e h1:5jVSh2l/ho6ajWhSPNN84eHEdq3dp0T7+f6r3Tc6hsk=
github.com/danielkov/gin-helmet v0.0.0-20171108135313-1387e224435e/go.mod h1:IJgIiGUARc4aOr4bOQ85klmjsShkEEfiRc6q/yBSfo8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
+github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davidlazar/go-crypto v0.0.0-20170701192655-dcfb0a7ac018/go.mod h1:rQYf4tfk5sSwFsnDg3qYaBxSjsD9S8+59vW0dKUgme4=
github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c h1:pFUpOrbxDR6AkioZ1ySsx5yxlDQZ8stG2b88gTPxgJU=
github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c/go.mod h1:6UhI8N9EjYm1c2odKpFpAYeR8dsBeM7PtzQhRgxRr9U=
@@ -274,10 +306,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=
@@ -299,8 +333,8 @@ github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUn
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
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.2+incompatible h1:eATx+oLz9WdNVkQrr0qjQ8HvRJ4bOOxfzEo8R+dA3cg=
-github.com/docker/docker v24.0.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
+github.com/docker/docker v24.0.4+incompatible h1:s/LVDftw9hjblvqIeTiGYXBCD95nOEEl7qRsRrIOuQI=
+github.com/docker/docker v24.0.4+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
@@ -318,13 +352,19 @@ github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5y
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
-github.com/envoyproxy/protoc-gen-validate v1.0.1 h1:kt9FtLiooDc0vbwTLhdg3dyNX1K9Qwa1EK9LcD4jVUQ=
+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/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c h1:8ISkoahWXwZR41ois5lSJBSVw4D0OV19Ht/JSTzvSv0=
+github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c/go.mod h1:Yg+htXGokKKdzcwhuNDwVvN+uBxDGXJ7G/VN1d8fa64=
github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 h1:JWuenKqqX8nojtoVVWjGfOF9635RETekkoH6Cc9SX0A=
+github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg=
github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4 h1:7HZCaLC5+BZpmbhCOZJ293Lz68O7PYrF2EzeiFMwCLk=
+github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4/go.mod h1:5tD+neXqOorC30/tWg0LCSkrqj/AR6gu8yY8/fpw1q0=
github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8=
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=
@@ -333,11 +373,15 @@ 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=
@@ -383,6 +427,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=
@@ -408,6 +453,7 @@ 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-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=
@@ -419,6 +465,7 @@ github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg
github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
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=
@@ -439,6 +486,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=
@@ -529,6 +577,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=
@@ -540,25 +589,30 @@ github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLe
github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
-github.com/google/pprof v0.0.0-20230602150820-91b7bce49751 h1:hR7/MlvK23p6+lIw9SN1TigNLn9ZnF3W4SYRKq2gAHs=
-github.com/google/pprof v0.0.0-20230602150820-91b7bce49751/go.mod h1:Jh3hGz2jkYak8qXPD19ryItVnUgpgeqzdkY/D0EaeuA=
+github.com/google/pprof v0.0.0-20230705174524-200ffdc848b8 h1:n6vlPhxsA+BW/XsS5+uqi7GyzaLa5MH7qlSLBZtRdiA=
+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/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.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
-github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-github.com/googleapis/enterprise-certificate-proxy v0.2.3 h1:yk9/cqRKtT9wXZSsRH9aurXEpJX+U6FLtpYTdC3R06k=
+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.11.0 h1:9V9PWXEsWnPpQhu/PeQIkS4eGzMlTLGgt80cUUI8Ki4=
+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=
@@ -569,6 +623,10 @@ github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/ad
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
+github.com/grafana/pyroscope-go v1.0.2 h1:dEFgO9VbhYTwuwpCC5coTpuW0JjISEWDZtvRAW9v5Tw=
+github.com/grafana/pyroscope-go v1.0.2/go.mod h1:bShDKsVZdzxq+Ol6no0JKigU9y5FTWUcFditMXaH09o=
+github.com/grafana/pyroscope-go/godeltaprof v0.1.3 h1:eunWpv1B3Z7ZK9o4499EmQGlY+CsDmSZ4FbxjRx37uk=
+github.com/grafana/pyroscope-go/godeltaprof v0.1.3/go.mod h1:1HSPtjU8vLG0jE9JrTdzjgFqdJ/VgN7fvxBNq3luJko=
github.com/graph-gophers/dataloader v5.0.0+incompatible h1:R+yjsbrNq1Mo3aPG+Z/EKYrXrXXUNJHOgbRt+U6jOug=
github.com/graph-gophers/dataloader v5.0.0+incompatible/go.mod h1:jk4jk0c5ZISbKaMe8WsVopGB5/15GvGHMdMdPtwlRp4=
github.com/graph-gophers/graphql-go v1.3.0 h1:Eb9x/q6MFpCLz7jBCiP/WTxjSDrYLR1QY41SORZyNJ0=
@@ -599,12 +657,15 @@ 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-hclog v1.4.0 h1:ctuWFGrhFha8BnnzxqeRGidlEcQkDyL5u8J8t5eA11I=
-github.com/hashicorp/go-hclog v1.4.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
+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=
github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc=
github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
@@ -616,13 +677,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=
@@ -660,6 +724,7 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
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.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
@@ -722,8 +787,9 @@ github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsU
github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o=
github.com/jackc/pgconn v1.9.0/go.mod h1:YctiPyvzfU11JFxoXokUOOKQXQmDMoJL9vJzHH8/2JY=
github.com/jackc/pgconn v1.9.1-0.20210724152538-d89c8390a530/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI=
-github.com/jackc/pgconn v1.14.0 h1:vrbA9Ud87g6JdFWkHTJXppVce58qPIdP7N8y0Ml/A7Q=
github.com/jackc/pgconn v1.14.0/go.mod h1:9mBNlny0UvkgJdCDvdVHYSjI+8tD2rnKK69Wz8ti++E=
+github.com/jackc/pgconn v1.14.1 h1:smbxIaZA08n6YuxEX1sDyjV/qkbtUtkH20qLkR9MUR4=
+github.com/jackc/pgconn v1.14.1/go.mod h1:9mBNlny0UvkgJdCDvdVHYSjI+8tD2rnKK69Wz8ti++E=
github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE=
github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8=
github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE=
@@ -776,13 +842,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/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA=
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
@@ -803,6 +872,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/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=
@@ -1064,6 +1134,7 @@ 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/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=
@@ -1094,6 +1165,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=
@@ -1111,6 +1183,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=
@@ -1131,7 +1204,9 @@ 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/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=
@@ -1142,6 +1217,7 @@ github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjY
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=
@@ -1213,6 +1289,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=
@@ -1240,16 +1317,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=
@@ -1259,8 +1339,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/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=
@@ -1304,20 +1384,19 @@ github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsT
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
github.com/prometheus/procfs v0.11.0 h1:5EAgkfkMl659uZPbe9AS2N68a7Cc1TJbPEuGzFuRbyk=
github.com/prometheus/procfs v0.11.0/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM=
-github.com/prometheus/prometheus v0.45.0 h1:O/uG+Nw4kNxx/jDPxmjsSDd+9Ohql6E7ZSY1x5x/0KI=
-github.com/prometheus/prometheus v0.45.0/go.mod h1:jC5hyO8ItJBnDWGecbEucMyXjzxGv9cxsxsjS9u5s1w=
+github.com/prometheus/prometheus v0.46.0 h1:9JSdXnsuT6YsbODEhSQMwxNkGwPExfmzqG73vCMk/Kw=
+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/pyroscope-io/client v0.7.1 h1:yFRhj3vbgjBxehvxQmedmUWJQ4CAfCHhn+itPsuWsHw=
-github.com/pyroscope-io/client v0.7.1/go.mod h1:4h21iOU4pUOq0prKyDlvYRL+SCKsBc5wKiEtV+rJGqU=
-github.com/pyroscope-io/godeltaprof v0.1.0 h1:UBqtjt0yZi4jTxqZmLAs34XG6ycS3vUTlhEUSq4NHLE=
-github.com/pyroscope-io/godeltaprof v0.1.0/go.mod h1:psMITXp90+8pFenXkKIpNhrfmI9saQnPbba27VIaiQE=
github.com/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=
@@ -1332,13 +1411,15 @@ github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTE
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
-github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
-github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
+github.com/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.29.1 h1:cO+d60CHkknCbvzEWxP0S9K6KqyTjrCNUy1LdQLCGPc=
+github.com/rs/zerolog v1.29.1/go.mod h1:Le6ESbR7hc+DP6Lt1THiV8CQSdkkNrd3R0XbEgp3ZBU=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
@@ -1355,8 +1436,10 @@ github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI=
github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
-github.com/shirou/gopsutil/v3 v3.22.12 h1:oG0ns6poeUSxf78JtOsfygNWuEHYYz8hnnNg7P04TJs=
-github.com/shirou/gopsutil/v3 v3.22.12/go.mod h1:Xd7P1kwZcp5VW52+9XsirIKd/BROzbb2wdX3Kqlz9uI=
+github.com/shirou/gopsutil/v3 v3.23.8 h1:xnATPiybo6GgdRoC4YoGnxXZFRc3dqQTGi73oLvvBrE=
+github.com/shirou/gopsutil/v3 v3.23.8/go.mod h1:7hmCaBn+2ZwaZOr6jmPBZDfawwMGuo1id3C6aM8EDqQ=
+github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ=
+github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k=
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8=
@@ -1369,30 +1452,30 @@ github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704 h1:T3lFWumvbfM1u/etVq42Afwq/jtNSBSOA8n5jntnNPo=
github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704/go.mod h1:2QuJdEouTWjh5BDy5o/vgGXQtR4Gz8yH1IYB5eT7u4M=
-github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20230824124058-9b063c470048 h1:OHj8qzXajBAIT9TBnHN5LVGoCxvso/4JgCeg/l76Tgk=
-github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20230824124058-9b063c470048/go.mod h1:xMwqRdj5vqYhCJXgKVqvyAwdcqM6ZAEhnwEQ4Khsop8=
-github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230824125819-215fd09979a2 h1:z9PIgm0klhunwPy+KZYR4E9vCpjgJaMOyQRLCYgfoLk=
-github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230824125819-215fd09979a2/go.mod h1:gWclxGW7rLkbjXn7FGizYlyKhp/boekto4MEYGyiMG4=
-github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230802143301-165000751a85 h1:/fm02hYSUdhbSh7xPn7os9yHj7dnl8aLs2+nFXPiB4g=
-github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230802143301-165000751a85/go.mod h1:H3/j2l84FsxYevCLNERdVasI7FVr+t2mkpv+BCJLSVw=
-github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20230802150127-d2c95679d61a h1:b3rjvZLpTV45TmCV+ALX+EDDslf91pnDUugP54Lu9FA=
-github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20230802150127-d2c95679d61a/go.mod h1:LL+FLf10gOUHrF3aUsRGEZlT/w8DaW5T/eEo/54W68c=
+github.com/smartcontractkit/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-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/go-plugin v0.0.0-20230605132010-0f4d515d1472 h1:x3kNwgFlDmbE/n0gTSRMt9GBDfsfGrs4X9b9arPZtFI=
github.com/smartcontractkit/go-plugin v0.0.0-20230605132010-0f4d515d1472/go.mod h1:6/1TEzT0eQznvI/gV2CM29DLSkAK/e58mUWKVsPaph0=
github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f h1:hgJif132UCdjo8u43i7iPN1/MFnu49hv7lFGFftCHKU=
github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f/go.mod h1:MvMXoufZAtqExNexqi4cjrNYE9MefKddKylxjS+//n0=
-github.com/smartcontractkit/libocr v0.0.0-20230816220705-665e93233ae5 h1:rzbqGoScs9VHGnyCKF7AoQEuUfwJnzcKmGIfaczeanA=
-github.com/smartcontractkit/libocr v0.0.0-20230816220705-665e93233ae5/go.mod h1:2lyRkw/qLQgUWlrWWmq5nj0y90rWeO6Y+v+fCakRgb0=
-github.com/smartcontractkit/ocr2keepers v0.7.17 h1:847GG2SHyHIPc3yu+dhB+1HfeLRhSjyiKnhw3umpoJw=
-github.com/smartcontractkit/ocr2keepers v0.7.17/go.mod h1:AjcIEKeNnU7NRlvnuMCTjBIQ1kpW0YHhlFdeDa/3hs0=
+github.com/smartcontractkit/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=
github.com/smartcontractkit/sqlx v1.3.5-0.20210805004948-4be295aacbeb/go.mod h1:HNUu4cJekUdsJbwRBCiOybtkPJEfGRELQPe2tkoDEyk=
-github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230823081604-f2a0e6b108bb h1:xNLGJcARfz9HCUKla6wH0gmwsG1/FTAWWeOplW2J72A=
-github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230823081604-f2a0e6b108bb/go.mod h1:q6f4fe39oZPdsh1i57WznEZgxd8siidMaSFq3wdPmVg=
-github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230823081604-f2a0e6b108bb h1:jyhgdafuZsex+kEHDIgq8o8wuVoPTr9wsGmuBtcFbEk=
-github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230823081604-f2a0e6b108bb/go.mod h1:G5Sd/yzHWf26rQ+X0nG9E0buKPqRGPMJAfk2gwCzOOw=
+github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 h1:yiKnypAqP8l0OX0P3klzZ7SCcBUxy5KqTAKZmQOvSQE=
+github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1/go.mod h1:q6f4fe39oZPdsh1i57WznEZgxd8siidMaSFq3wdPmVg=
+github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 h1:Dai1bn+Q5cpeGMQwRdjOdVjG8mmFFROVkSKuUgBErRQ=
+github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1/go.mod h1:G5Sd/yzHWf26rQ+X0nG9E0buKPqRGPMJAfk2gwCzOOw=
github.com/smartcontractkit/wsrpc v0.7.2 h1:iBXzMeg7vc5YoezIQBq896y25BARw7OKbhrb6vPbtRQ=
github.com/smartcontractkit/wsrpc v0.7.2/go.mod h1:sj7QX2NQibhkhxTfs3KOhAj/5xwgqMipTvJVSssT9i0=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
@@ -1470,15 +1553,14 @@ github.com/theodesp/go-heaps v0.0.0-20190520121037-88e35354fe0a/go.mod h1:/sfW47
github.com/tidwall/btree v1.6.0 h1:LDZfKfQIBHGHWSwckhXI0RPSXzlo+KYdjK7FWSqOzzg=
github.com/tidwall/btree v1.6.0/go.mod h1:twD9XRA5jj9VUQGELzDO4HPQTNJsoWWfYEL+EUQ2cKY=
github.com/tidwall/gjson v1.9.3/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
-github.com/tidwall/gjson v1.14.4 h1:uo0p8EbA09J7RQaflQ1aBRffTR7xedD2bcIVSYxLnkM=
-github.com/tidwall/gjson v1.14.4/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
+github.com/tidwall/gjson v1.16.0 h1:SyXa+dsSPpUlcwEDuKuEBJEz5vzTvOea+9rjyYodQFg=
+github.com/tidwall/gjson v1.16.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
-github.com/tklauser/go-sysconf v0.3.11 h1:89WgdJhk5SNwJfu+GKyYveZ4IaJ7xAkecBo+KdJV0CM=
-github.com/tklauser/go-sysconf v0.3.11/go.mod h1:GqXfhXY3kiPa0nAXPDIQIWzJbMCB7AmcWpGR8lSZfqI=
-github.com/tklauser/numcpus v0.6.0/go.mod h1:FEZLMke0lhOUG6w2JadTzp0a+Nl8PF/GFkQ5UVIcaL4=
+github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU=
+github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk=
github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
@@ -1496,6 +1578,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=
@@ -1507,6 +1590,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=
@@ -1532,6 +1616,7 @@ github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQ
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
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=
@@ -1542,7 +1627,6 @@ github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
-github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw=
github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
@@ -1592,6 +1676,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=
@@ -1661,8 +1746,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
-golang.org/x/exp v0.0.0-20230711153332-06a737ee72cb h1:xIApU0ow1zwMa2uL1VDNeQlNVFTWMQxZUZCMDy0Q4Us=
-golang.org/x/exp v0.0.0-20230711153332-06a737ee72cb/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc=
+golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 h1:MGwJjxBy0HJshjDNfLsYO8xppfqWlA5ZT9OhtUUhTNw=
+golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@@ -1762,7 +1847,8 @@ golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210413134643-5e61552d6c78/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.8.0 h1:6dkIjl3j3LtZ/O3sTgZTMsLKSftL/B8Zgq4huOIIUu8=
+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=
@@ -1866,13 +1952,11 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
-golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=
+golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
@@ -1976,6 +2060,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=
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=
@@ -1998,7 +2083,8 @@ google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz513
google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=
google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
-google.golang.org/api v0.126.0 h1:q4GJq+cAdMAC7XP7njvQ4tvohGLiSlytuL4BQxbIZ+o=
+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=
@@ -2053,12 +2139,12 @@ google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6D
google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210401141331-865547bb08e2/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=
google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24=
-google.golang.org/genproto v0.0.0-20230706204954-ccb25ca9f130 h1:Au6te5hbKUV8pIYWHqOUZ1pva5qK/rwbIhoXEUB9Lu8=
-google.golang.org/genproto v0.0.0-20230706204954-ccb25ca9f130/go.mod h1:O9kGHb51iE/nOGvQaDUuadVYqovW56s5emA88lQnj6Y=
-google.golang.org/genproto/googleapis/api v0.0.0-20230629202037-9506855d4529 h1:s5YSX+ZH5b5vS9rnpGymvIyMpLRJizowqDlOuyjXnTk=
-google.golang.org/genproto/googleapis/api v0.0.0-20230629202037-9506855d4529/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 h1:bVf09lpb+OJbByTj913DRJioFFAjf/ZGxEz7MajTp2U=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM=
+google.golang.org/genproto v0.0.0-20230717213848-3f92550aa753 h1:+VoAg+OKmWaommL56xmZSE2sUK8A7m6SUO7X89F2tbw=
+google.golang.org/genproto v0.0.0-20230717213848-3f92550aa753/go.mod h1:iqkVr8IRpZ53gx1dEnWlCUIEwDWqWARWrbzpasaTNYM=
+google.golang.org/genproto/googleapis/api v0.0.0-20230717213848-3f92550aa753 h1:lCbbUxUDD+DiXx9Q6F/ttL0aAu7N2pz8XnmMm8ZW4NE=
+google.golang.org/genproto/googleapis/api v0.0.0-20230717213848-3f92550aa753/go.mod h1:rsr7RhLuwsDKL7RmgDDCUc6yaGr1iqceVb5Wv6f6YvQ=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20230717213848-3f92550aa753 h1:XUODHrpzJEUeWmVo/jfNTLj0YyVveOo28oE6vkFbkO4=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20230717213848-3f92550aa753/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM=
google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
@@ -2133,6 +2219,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=
@@ -2150,6 +2237,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=
@@ -2159,16 +2247,27 @@ 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=
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.6 h1:s+C3xAMLwGmlI31Nyn/eAehUlZPwfYZu2JXM621Q5/k=
+nhooyr.io/websocket v1.8.6/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/core/scripts/vrfv2/testnet/setup-envs/README.md b/core/scripts/vrfv2/testnet/setup-envs/README.md
index ed045003fba..a36e3829c43 100644
--- a/core/scripts/vrfv2/testnet/setup-envs/README.md
+++ b/core/scripts/vrfv2/testnet/setup-envs/README.md
@@ -27,6 +27,7 @@ go run . \
--bhs-bk-creds-file \
--bhf-node-url=http://localhost:6614 \
--bhf-creds-file \
+--deploy-contracts true \
--batch-fulfillment-enabled true \
--min-confs 1 \
--num-eth-keys 5 \
diff --git a/core/scripts/vrfv2/testnet/setup-envs/main.go b/core/scripts/vrfv2/testnet/setup-envs/main.go
index 1196108b32f..9e6edf725e5 100644
--- a/core/scripts/vrfv2/testnet/setup-envs/main.go
+++ b/core/scripts/vrfv2/testnet/setup-envs/main.go
@@ -66,6 +66,8 @@ func main() {
maxGasPriceGwei := flag.Int("max-gas-price-gwei", -1, "Max gas price gwei of the eth keys")
numVRFKeys := flag.Int("num-vrf-keys", 1, "Number of vrf keys to create")
+ deployContracts := flag.Bool("deploy-contracts", true, "whether to deploy contracts and create jobs")
+
batchFulfillmentEnabled := flag.Bool("batch-fulfillment-enabled", constants.BatchFulfillmentEnabled, "whether to enable batch fulfillment on Cl node")
minConfs := flag.Int("min-confs", constants.MinConfs, "minimum confirmations")
@@ -141,70 +143,74 @@ func main() {
}
importVRFKeyToNodeIfSet(vrfBackupNodeURL, nodesMap, output, nodesMap[scripts.VRFBackupNodeName].CredsFile)
fmt.Println()
- feeConfig := vrf_coordinator_v2.VRFCoordinatorV2FeeConfig{
- FulfillmentFlatFeeLinkPPMTier1: uint32(constants.FlatFeeTier1),
- FulfillmentFlatFeeLinkPPMTier2: uint32(constants.FlatFeeTier2),
- FulfillmentFlatFeeLinkPPMTier3: uint32(constants.FlatFeeTier3),
- FulfillmentFlatFeeLinkPPMTier4: uint32(constants.FlatFeeTier4),
- FulfillmentFlatFeeLinkPPMTier5: uint32(constants.FlatFeeTier5),
- ReqsForTier2: big.NewInt(constants.ReqsForTier2),
- ReqsForTier3: big.NewInt(constants.ReqsForTier3),
- ReqsForTier4: big.NewInt(constants.ReqsForTier4),
- ReqsForTier5: big.NewInt(constants.ReqsForTier5),
- }
-
- contractAddresses := scripts.ContractAddresses{
- LinkAddress: *linkAddress,
- LinkEthAddress: *linkEthAddress,
- BhsContractAddress: common.HexToAddress(*bhsContractAddressString),
- BatchBHSAddress: common.HexToAddress(*batchBHSAddressString),
- CoordinatorAddress: common.HexToAddress(*coordinatorAddressString),
- BatchCoordinatorAddress: common.HexToAddress(*batchCoordinatorAddressString),
- }
- coordinatorConfig := scripts.CoordinatorConfig{
- MinConfs: minConfs,
- MaxGasLimit: &constants.MaxGasLimit,
- StalenessSeconds: &constants.StalenessSeconds,
- GasAfterPayment: &constants.GasAfterPayment,
- FallbackWeiPerUnitLink: constants.FallbackWeiPerUnitLink,
- FeeConfig: feeConfig,
- }
-
- jobSpecs := scripts.VRFV2DeployUniverse(
- e,
- constants.SubscriptionBalanceJuels,
- &nodesMap[scripts.VRFPrimaryNodeName].VrfKeys[0],
- contractAddresses,
- coordinatorConfig,
- *batchFulfillmentEnabled,
- nodesMap,
- )
-
- for key, node := range nodesMap {
- client, app := connectToNode(&node.URL, output, node.CredsFile)
+ if *deployContracts {
+ feeConfig := vrf_coordinator_v2.VRFCoordinatorV2FeeConfig{
+ FulfillmentFlatFeeLinkPPMTier1: uint32(constants.FlatFeeTier1),
+ FulfillmentFlatFeeLinkPPMTier2: uint32(constants.FlatFeeTier2),
+ FulfillmentFlatFeeLinkPPMTier3: uint32(constants.FlatFeeTier3),
+ FulfillmentFlatFeeLinkPPMTier4: uint32(constants.FlatFeeTier4),
+ FulfillmentFlatFeeLinkPPMTier5: uint32(constants.FlatFeeTier5),
+ ReqsForTier2: big.NewInt(constants.ReqsForTier2),
+ ReqsForTier3: big.NewInt(constants.ReqsForTier3),
+ ReqsForTier4: big.NewInt(constants.ReqsForTier4),
+ ReqsForTier5: big.NewInt(constants.ReqsForTier5),
+ }
- //GET ALL JOBS
- jobIDs := getAllJobIDs(client, app, output)
+ contractAddresses := scripts.ContractAddresses{
+ LinkAddress: *linkAddress,
+ LinkEthAddress: *linkEthAddress,
+ BhsContractAddress: common.HexToAddress(*bhsContractAddressString),
+ BatchBHSAddress: common.HexToAddress(*batchBHSAddressString),
+ CoordinatorAddress: common.HexToAddress(*coordinatorAddressString),
+ BatchCoordinatorAddress: common.HexToAddress(*batchCoordinatorAddressString),
+ }
- //DELETE ALL EXISTING JOBS
- for _, jobID := range jobIDs {
- deleteJob(jobID, client, app, output)
+ coordinatorConfig := scripts.CoordinatorConfig{
+ MinConfs: minConfs,
+ MaxGasLimit: &constants.MaxGasLimit,
+ StalenessSeconds: &constants.StalenessSeconds,
+ GasAfterPayment: &constants.GasAfterPayment,
+ FallbackWeiPerUnitLink: constants.FallbackWeiPerUnitLink,
+ FeeConfig: feeConfig,
}
- //CREATE JOBS
- switch key {
- case scripts.VRFPrimaryNodeName:
- createJob(jobSpecs.VRFPrimaryNode, client, app, output)
- case scripts.VRFBackupNodeName:
- createJob(jobSpecs.VRFBackupyNode, client, app, output)
- case scripts.BHSNodeName:
- createJob(jobSpecs.BHSNode, client, app, output)
- case scripts.BHSBackupNodeName:
- createJob(jobSpecs.BHSBackupNode, client, app, output)
- case scripts.BHFNodeName:
- createJob(jobSpecs.BHFNode, client, app, output)
+
+ jobSpecs := scripts.VRFV2DeployUniverse(
+ e,
+ constants.SubscriptionBalanceJuels,
+ &nodesMap[scripts.VRFPrimaryNodeName].VrfKeys[0],
+ contractAddresses,
+ coordinatorConfig,
+ *batchFulfillmentEnabled,
+ nodesMap,
+ )
+
+ for key, node := range nodesMap {
+ client, app := connectToNode(&node.URL, output, node.CredsFile)
+
+ //GET ALL JOBS
+ jobIDs := getAllJobIDs(client, app, output)
+
+ //DELETE ALL EXISTING JOBS
+ for _, jobID := range jobIDs {
+ deleteJob(jobID, client, app, output)
+ }
+ //CREATE JOBS
+ switch key {
+ case scripts.VRFPrimaryNodeName:
+ createJob(jobSpecs.VRFPrimaryNode, client, app, output)
+ case scripts.VRFBackupNodeName:
+ createJob(jobSpecs.VRFBackupyNode, client, app, output)
+ case scripts.BHSNodeName:
+ createJob(jobSpecs.BHSNode, client, app, output)
+ case scripts.BHSBackupNodeName:
+ createJob(jobSpecs.BHSBackupNode, client, app, output)
+ case scripts.BHFNodeName:
+ createJob(jobSpecs.BHFNode, client, app, output)
+ }
}
}
+
}
func fundNodesIfNeeded(node scripts.Node, key string, e helpers.Environment) {
diff --git a/core/scripts/vrfv2plus/testnet/main.go b/core/scripts/vrfv2plus/testnet/main.go
index 20e7ea92714..7bc64108669 100644
--- a/core/scripts/vrfv2plus/testnet/main.go
+++ b/core/scripts/vrfv2plus/testnet/main.go
@@ -11,6 +11,10 @@ import (
"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"
@@ -28,9 +32,7 @@ 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_load_test_with_metrics"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_v2plus_single_consumer"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_v2plus_sub_owner"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrfv2plus_wrapper"
@@ -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)
@@ -677,7 +684,7 @@ func main() {
loadTestConsumerDeployCmd := flag.NewFlagSet("eoa-load-test-consumer-with-metrics-deploy", flag.ExitOnError)
consumerCoordinator := loadTestConsumerDeployCmd.String("coordinator-address", "", "coordinator address")
helpers.ParseArgs(loadTestConsumerDeployCmd, os.Args[2:], "coordinator-address")
- _, tx, _, err := vrf_load_test_with_metrics.DeployVRFV2LoadTestWithMetrics(
+ _, tx, _, err := vrf_v2plus_load_test_with_metrics.DeployVRFV2PlusLoadTestWithMetrics(
e.Owner,
e.Ec,
common.HexToAddress(*consumerCoordinator),
@@ -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()
@@ -806,16 +813,17 @@ func main() {
case "eoa-load-test-request-with-metrics":
request := flag.NewFlagSet("eoa-load-test-request-with-metrics", flag.ExitOnError)
consumerAddress := request.String("consumer-address", "", "consumer address")
- subID := request.Uint64("sub-id", 0, "subscription ID")
+ subID := request.String("sub-id", "", "subscription ID")
requestConfirmations := request.Uint("request-confirmations", 3, "minimum request confirmations")
keyHash := request.String("key-hash", "", "key hash")
cbGasLimit := request.Uint("cb-gas-limit", 100_000, "request callback gas limit")
+ nativePaymentEnabled := request.Bool("native-payment-enabled", false, "native payment enabled")
numWords := request.Uint("num-words", 1, "num words to request")
requests := request.Uint("requests", 10, "number of randomness requests to make per run")
runs := request.Uint("runs", 1, "number of runs to do. total randomness requests will be (requests * runs).")
helpers.ParseArgs(request, os.Args[2:], "consumer-address", "sub-id", "key-hash")
keyHashBytes := common.HexToHash(*keyHash)
- consumer, err := vrf_load_test_with_metrics.NewVRFV2LoadTestWithMetrics(
+ consumer, err := vrf_v2plus_load_test_with_metrics.NewVRFV2PlusLoadTestWithMetrics(
common.HexToAddress(*consumerAddress),
e.Ec)
helpers.PanicErr(err)
@@ -823,10 +831,11 @@ func main() {
for i := 0; i < int(*runs); i++ {
tx, err := consumer.RequestRandomWords(
e.Owner,
- *subID,
+ decimal.RequireFromString(*subID).BigInt(),
uint16(*requestConfirmations),
keyHashBytes,
uint32(*cbGasLimit),
+ *nativePaymentEnabled,
uint32(*numWords),
uint16(*requests),
)
@@ -843,7 +852,7 @@ func main() {
request := flag.NewFlagSet("eoa-load-test-read-metrics", flag.ExitOnError)
consumerAddress := request.String("consumer-address", "", "consumer address")
helpers.ParseArgs(request, os.Args[2:], "consumer-address")
- consumer, err := vrf_load_test_with_metrics.NewVRFV2LoadTestWithMetrics(
+ consumer, err := vrf_v2plus_load_test_with_metrics.NewVRFV2PlusLoadTestWithMetrics(
common.HexToAddress(*consumerAddress),
e.Ec)
helpers.PanicErr(err)
@@ -866,7 +875,7 @@ func main() {
request := flag.NewFlagSet("eoa-load-test-reset-metrics", flag.ExitOnError)
consumerAddress := request.String("consumer-address", "", "consumer address")
helpers.ParseArgs(request, os.Args[2:], "consumer-address")
- consumer, err := vrf_load_test_with_metrics.NewVRFV2LoadTestWithMetrics(
+ consumer, err := vrf_v2plus_load_test_with_metrics.NewVRFV2PlusLoadTestWithMetrics(
common.HexToAddress(*consumerAddress),
e.Ec)
helpers.PanicErr(err)
@@ -879,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)
@@ -889,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)
@@ -899,11 +908,27 @@ 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)
helpers.ConfirmTXMined(context.Background(), e.Ec, tx, e.ChainID)
+ case "eoa-fund-sub-with-native-token":
+ fund := flag.NewFlagSet("eoa-fund-sub-with-native-token", flag.ExitOnError)
+ coordinatorAddress := fund.String("coordinator-address", "", "coordinator address")
+ amountStr := fund.String("amount", "", "amount to fund in wei")
+ subID := fund.String("sub-id", "", "sub-id")
+ helpers.ParseArgs(fund, os.Args[2:], "coordinator-address", "amount", "sub-id")
+ amount, s := big.NewInt(0).SetString(*amountStr, 10)
+ if !s {
+ panic(fmt.Sprintf("failed to parse top up amount '%s'", *amountStr))
+ }
+ coordinator, err := vrf_coordinator_v2_5.NewVRFCoordinatorV25(common.HexToAddress(*coordinatorAddress), e.Ec)
+ helpers.PanicErr(err)
+ e.Owner.Value = amount
+ tx, err := coordinator.FundSubscriptionWithNative(e.Owner, parseSubID(*subID))
+ helpers.PanicErr(err)
+ helpers.ConfirmTXMined(context.Background(), e.Ec, tx, e.ChainID)
case "eoa-fund-sub":
fund := flag.NewFlagSet("eoa-fund-sub", flag.ExitOnError)
coordinatorAddress := fund.String("coordinator-address", "", "coordinator address")
@@ -915,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))
@@ -937,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)
@@ -947,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)
@@ -961,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 {
@@ -991,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))
@@ -1006,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 a617733cb19..f9efde8f148 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 d002b8c03b4..904a3f6ba4f 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/bhs_test.go b/core/services/blockhashstore/bhs_test.go
index d0e5ac71a7b..79494ea41f6 100644
--- a/core/services/blockhashstore/bhs_test.go
+++ b/core/services/blockhashstore/bhs_test.go
@@ -30,8 +30,7 @@ func TestStoreRotatesFromAddresses(t *testing.T) {
kst := cltest.NewKeyStore(t, db, cfg.Database())
require.NoError(t, kst.Unlock(cltest.Password))
relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, KeyStore: kst.Eth(), GeneralConfig: cfg, Client: ethClient})
- legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
- require.NoError(t, err)
+ legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
chain, err := legacyChains.Get(cltest.FixtureChainID.String())
require.NoError(t, err)
lggr := logger.TestLogger(t)
diff --git a/core/services/blockhashstore/common.go b/core/services/blockhashstore/common.go
index 61aaf989298..677016253fb 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 1a8588dbbb6..ff5aff1f5e5 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 3c2c241a0b7..ccd4d3463f5 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"
@@ -65,12 +66,6 @@ func (d *Delegate) ServicesForSpec(jb job.Job, qopts ...pg.QOpt) ([]job.ServiceC
return nil, errors.New("log poller must be enabled to run blockhashstore")
}
- if jb.BlockhashStoreSpec.WaitBlocks < int32(chain.Config().EVM().FinalityDepth()) {
- return nil, fmt.Errorf(
- "waitBlocks must be greater than or equal to chain's finality depth (%d), currently %d",
- chain.Config().EVM().FinalityDepth(), jb.BlockhashStoreSpec.WaitBlocks)
- }
-
keys, err := d.ks.EnabledKeysForChain(chain.ID())
if err != nil {
return nil, errors.Wrap(err, "getting sending keys")
@@ -133,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")
@@ -162,7 +157,7 @@ func (d *Delegate) ServicesForSpec(jb job.Job, qopts ...pg.QOpt) ([]job.ServiceC
return nil, errors.Wrap(err, "building bulletproof bhs")
}
- log := d.logger.Named("BHS Feeder").With("jobID", jb.ID, "externalJobID", jb.ExternalJobID)
+ log := d.logger.Named("BHSFeeder").With("jobID", jb.ID, "externalJobID", jb.ExternalJobID)
feeder := NewFeeder(
log,
NewMultiCoordinator(coordinators...),
@@ -171,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 {
@@ -184,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
}
@@ -204,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
@@ -218,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 s.wg.Done()
+ s.feeder.StartHeartbeats(s.parentCtx, &realTimer{})
+ }()
go func() {
- defer close(s.done)
+ defer s.wg.Done()
defer ticker.Stop()
for {
select {
@@ -239,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/delegate_test.go b/core/services/blockhashstore/delegate_test.go
index b0456206861..3060f617876 100644
--- a/core/services/blockhashstore/delegate_test.go
+++ b/core/services/blockhashstore/delegate_test.go
@@ -70,8 +70,7 @@ func createTestDelegate(t *testing.T) (*blockhashstore.Delegate, *testData) {
LogPoller: lp,
},
)
- legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
- require.NoError(t, err)
+ legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
return blockhashstore.NewDelegate(lggr, legacyChains, kst), &testData{
ethClient: ethClient,
ethKeyStore: kst,
@@ -90,7 +89,7 @@ func TestDelegate_ServicesForSpec(t *testing.T) {
defaultWaitBlocks := (int32)(testData.legacyChains.Slice()[0].Config().EVM().FinalityDepth())
t.Run("happy", func(t *testing.T) {
- spec := job.Job{BlockhashStoreSpec: &job.BlockhashStoreSpec{WaitBlocks: defaultWaitBlocks}}
+ spec := job.Job{BlockhashStoreSpec: &job.BlockhashStoreSpec{WaitBlocks: defaultWaitBlocks, EVMChainID: (*utils.Big)(testutils.FixtureChainID)}}
services, err := delegate.ServicesForSpec(spec)
require.NoError(t, err)
@@ -107,6 +106,7 @@ func TestDelegate_ServicesForSpec(t *testing.T) {
CoordinatorV1Address: &coordinatorV1,
CoordinatorV2Address: &coordinatorV2,
CoordinatorV2PlusAddress: &coordinatorV2Plus,
+ EVMChainID: (*utils.Big)(testutils.FixtureChainID),
}}
services, err := delegate.ServicesForSpec(spec)
@@ -128,14 +128,6 @@ func TestDelegate_ServicesForSpec(t *testing.T) {
assert.Error(t, err)
})
- t.Run("WaitBlocks less than EvmFinalityDepth", func(t *testing.T) {
- spec := job.Job{BlockhashStoreSpec: &job.BlockhashStoreSpec{
- WaitBlocks: defaultWaitBlocks - 1,
- }}
- _, err := delegate.ServicesForSpec(spec)
- assert.Error(t, err)
- })
-
t.Run("missing EnabledKeysForChain", func(t *testing.T) {
_, err := testData.ethKeyStore.Delete(testData.sendingKey.ID())
require.NoError(t, err)
@@ -159,6 +151,7 @@ func TestDelegate_StartStop(t *testing.T) {
WaitBlocks: defaultWaitBlocks,
PollPeriod: time.Second,
RunTimeout: testutils.WaitTimeout(t),
+ EVMChainID: (*utils.Big)(testutils.FixtureChainID),
}}
services, err := delegate.ServicesForSpec(spec)
diff --git a/core/services/blockhashstore/feeder.go b/core/services/blockhashstore/feeder.go
index 22bbf7f163d..8cc607db9b3 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{
@@ -37,8 +39,10 @@ func NewFeeder(
lookbackBlocks: lookbackBlocks,
latestBlock: latestBlock,
stored: make(map[uint64]struct{}),
+ storedTrusted: make(map[uint64]common.Hash),
lastRunBlock: 0,
wgStored: sync.WaitGroup{},
+ heartbeatPeriod: heartbeatPeriod,
}
}
@@ -54,12 +58,52 @@ type Feeder struct {
lookbackBlocks int
latestBlock func(ctx context.Context) (uint64, error)
- stored map[uint64]struct{}
- lastRunBlock uint64
- wgStored sync.WaitGroup
- batchLock sync.Mutex
- storedLock sync.RWMutex
- errsLock sync.Mutex
+ // 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
+ wgStored sync.WaitGroup
+ batchLock sync.Mutex
+ 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.
@@ -103,10 +147,10 @@ func (f *Feeder) Run(ctx context.Context) error {
"block", block)
errs = multierr.Append(errs, errors.Wrap(err, "checking if stored"))
} else if stored {
+ // IsStored() can be based on unfinalized blocks. Therefore, f.stored mapping is not updated
f.lggr.Infow("Blockhash already stored",
"block", block, "latestBlock", latestBlock,
"unfulfilledReqIDs", LimitReqIDs(unfulfilledReqs, 50))
- f.stored[block] = struct{}{}
continue
}
@@ -161,13 +205,6 @@ func (f *Feeder) runTrusted(
if len(unfulfilled) == 0 {
return
}
- f.storedLock.RLock()
- if _, ok := f.stored[block]; ok {
- // Already stored
- f.storedLock.RUnlock()
- return
- }
- f.storedLock.RUnlock()
// Do not store a block if it has been marked as stored; otherwise, store it even
// if the RPC call errors, as to be conservative.
@@ -185,9 +222,6 @@ func (f *Feeder) runTrusted(
f.lggr.Infow("Blockhash already stored",
"block", block, "latestBlock", latestBlock,
"unfulfilledReqIDs", LimitReqIDs(unfulfilled, 50))
- f.storedLock.Lock()
- f.stored[block] = struct{}{}
- f.storedLock.Unlock()
return
}
@@ -224,15 +258,23 @@ func (f *Feeder) runTrusted(
// append its blockhash to our blockhashes we want to store.
// If it is the log poller block pertaining to our recent block number, assig it.
for _, b := range lpBlocks {
+ if b.BlockNumber == int64(latestBlock) {
+ latestBlockhash = b.BlockHash
+ }
+ if f.storedTrusted[uint64(b.BlockNumber)] == b.BlockHash {
+ // blockhash is already stored. skip to save gas
+ continue
+ }
if _, ok := batch[uint64(b.BlockNumber)]; ok {
blocksToStore = append(blocksToStore, uint64(b.BlockNumber))
blockhashesToStore = append(blockhashesToStore, b.BlockHash)
}
- if b.BlockNumber == int64(latestBlock) {
- latestBlockhash = b.BlockHash
- }
}
+ if len(blocksToStore) == 0 {
+ f.lggr.Debugw("no blocks to store", "latestBlock", latestBlock)
+ return errs
+ }
// Store the batch of blocks and their blockhashes.
err = f.bhs.StoreTrusted(ctx, blocksToStore, blockhashesToStore, latestBlock, latestBlockhash)
if err != nil {
@@ -246,12 +288,15 @@ func (f *Feeder) runTrusted(
errs = multierr.Append(errs, errors.Wrap(err, "checking if stored"))
return errs
}
+ for i, block := range blocksToStore {
+ f.storedTrusted[block] = blockhashesToStore[i]
+ }
}
- // Prune stored, anything older than fromBlock can be discarded.
- for b := range f.stored {
+ // Prune storedTrusted, anything older than fromBlock can be discarded.
+ for b := range f.storedTrusted {
if b < fromBlock {
- delete(f.stored, b)
+ delete(f.storedTrusted, b)
}
}
diff --git a/core/services/blockhashstore/feeder_test.go b/core/services/blockhashstore/feeder_test.go
index 7efb7052985..3145a9fd76d 100644
--- a/core/services/blockhashstore/feeder_test.go
+++ b/core/services/blockhashstore/feeder_test.go
@@ -2,105 +2,101 @@ package blockhashstore
import (
"context"
+ "fmt"
"math/big"
"testing"
+ "time"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
+ "golang.org/x/exp/maps"
mocklp "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller/mocks"
evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types"
"github.com/smartcontractkit/chainlink/v2/core/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
- expectedErrMsg string
- }{
+ tests = []testCase{
{
- name: "single unfulfilled request",
- requests: []Event{{Block: 150, ID: "1000"}},
- wait: 25,
- lookback: 100,
- latest: 200,
- expectedStored: []uint64{150},
+ name: "single unfulfilled request",
+ requests: []Event{{Block: 150, ID: "1000"}},
+ wait: 25,
+ lookback: 100,
+ latest: 200,
+ expectedStored: []uint64{150},
+ expectedStoredMapBlocks: []uint64{150},
},
{
- name: "single fulfilled request",
- requests: []Event{{Block: 150, ID: "1000"}},
- fulfillments: []Event{{Block: 155, ID: "1000"}},
- wait: 25,
- lookback: 100,
- latest: 200,
- expectedStored: []uint64{},
+ name: "single fulfilled request",
+ requests: []Event{{Block: 150, ID: "1000"}},
+ fulfillments: []Event{{Block: 155, ID: "1000"}},
+ wait: 25,
+ lookback: 100,
+ latest: 200,
+ expectedStored: []uint64{},
+ expectedStoredMapBlocks: []uint64{},
},
{
- name: "single already fulfilled",
- requests: []Event{{Block: 150, ID: "1000"}},
- wait: 25,
- lookback: 100,
- latest: 200,
- bhs: TestBHS{Stored: []uint64{150}},
- expectedStored: []uint64{150},
+ name: "single already fulfilled",
+ requests: []Event{{Block: 150, ID: "1000"}},
+ wait: 25,
+ lookback: 100,
+ latest: 200,
+ bhs: TestBHS{Stored: []uint64{150}},
+ expectedStored: []uint64{150},
+ expectedStoredMapBlocks: []uint64{},
},
{
- name: "error checking if stored, store anyway",
- requests: []Event{{Block: 150, ID: "1000"}},
- wait: 25,
- lookback: 100,
- latest: 200,
- bhs: TestBHS{ErrorsIsStored: []uint64{150}},
- expectedStored: []uint64{150},
- expectedErrMsg: "checking if stored: error checking if stored",
+ name: "error checking if stored, store anyway",
+ requests: []Event{{Block: 150, ID: "1000"}},
+ wait: 25,
+ lookback: 100,
+ latest: 200,
+ bhs: TestBHS{ErrorsIsStored: []uint64{150}},
+ expectedStored: []uint64{150},
+ expectedStoredMapBlocks: []uint64{150},
+ expectedErrMsg: "checking if stored: error checking if stored",
},
{
- name: "error storing, continue to next block anyway",
- requests: []Event{{Block: 150, ID: "1000"}, {Block: 151, ID: "1000"}},
- wait: 25,
- lookback: 100,
- latest: 200,
- bhs: TestBHS{ErrorsStore: []uint64{150}},
- expectedStored: []uint64{151},
- expectedErrMsg: "storing block: error storing",
+ name: "error storing, continue to next block anyway",
+ requests: []Event{{Block: 150, ID: "1000"}, {Block: 151, ID: "1000"}},
+ wait: 25,
+ lookback: 100,
+ latest: 200,
+ bhs: TestBHS{ErrorsStore: []uint64{150}},
+ expectedStored: []uint64{151},
+ expectedStoredMapBlocks: []uint64{151},
+ expectedErrMsg: "storing block: error storing",
},
{
name: "multiple requests same block, some fulfilled",
@@ -111,10 +107,11 @@ var (
fulfillments: []Event{
{Block: 150, ID: "10001"},
{Block: 150, ID: "10003"}},
- wait: 25,
- lookback: 100,
- latest: 200,
- expectedStored: []uint64{150},
+ wait: 25,
+ lookback: 100,
+ latest: 200,
+ expectedStored: []uint64{150},
+ expectedStoredMapBlocks: []uint64{150},
},
{
name: "multiple requests same block, all fulfilled",
@@ -126,52 +123,58 @@ var (
{Block: 150, ID: "10001"},
{Block: 150, ID: "10002"},
{Block: 150, ID: "10003"}},
- wait: 25,
- lookback: 100,
- latest: 200,
- expectedStored: []uint64{},
+ wait: 25,
+ lookback: 100,
+ latest: 200,
+ expectedStored: []uint64{},
+ expectedStoredMapBlocks: []uint64{},
},
{
- name: "fulfillment no matching request no error",
- requests: []Event{{Block: 150, ID: "1000"}},
- fulfillments: []Event{{Block: 199, ID: "10002"}},
- wait: 25,
- lookback: 100,
- latest: 200,
- expectedStored: []uint64{150},
+ name: "fulfillment no matching request no error",
+ requests: []Event{{Block: 150, ID: "1000"}},
+ fulfillments: []Event{{Block: 199, ID: "10002"}},
+ wait: 25,
+ lookback: 100,
+ latest: 200,
+ expectedStored: []uint64{150},
+ expectedStoredMapBlocks: []uint64{150},
},
{
- name: "multiple unfulfilled requests",
- requests: []Event{{Block: 150, ID: "10001"}, {Block: 151, ID: "10002"}},
- wait: 25,
- lookback: 100,
- latest: 200,
- expectedStored: []uint64{150, 151},
+ name: "multiple unfulfilled requests",
+ requests: []Event{{Block: 150, ID: "10001"}, {Block: 151, ID: "10002"}},
+ wait: 25,
+ lookback: 100,
+ latest: 200,
+ expectedStored: []uint64{150, 151},
+ expectedStoredMapBlocks: []uint64{150, 151},
},
{
- name: "multiple fulfilled requests",
- requests: []Event{{Block: 150, ID: "10001"}, {Block: 151, ID: "10002"}},
- fulfillments: []Event{{Block: 150, ID: "10001"}, {Block: 151, ID: "10002"}},
- wait: 25,
- lookback: 100,
- latest: 200,
- expectedStored: []uint64{},
+ name: "multiple fulfilled requests",
+ requests: []Event{{Block: 150, ID: "10001"}, {Block: 151, ID: "10002"}},
+ fulfillments: []Event{{Block: 150, ID: "10001"}, {Block: 151, ID: "10002"}},
+ wait: 25,
+ lookback: 100,
+ latest: 200,
+ expectedStored: []uint64{},
+ expectedStoredMapBlocks: []uint64{},
},
{
- name: "recent unfulfilled request do not store",
- requests: []Event{{Block: 185, ID: "1000"}},
- wait: 25,
- lookback: 100,
- latest: 200,
- expectedStored: []uint64{},
+ name: "recent unfulfilled request do not store",
+ requests: []Event{{Block: 185, ID: "1000"}},
+ wait: 25,
+ lookback: 100,
+ latest: 200,
+ expectedStored: []uint64{},
+ expectedStoredMapBlocks: []uint64{},
},
{
- name: "old unfulfilled request do not store",
- requests: []Event{{Block: 99, ID: "1000"}, {Block: 57, ID: "1000"}},
- wait: 25,
- lookback: 100,
- latest: 200,
- expectedStored: []uint64{},
+ name: "old unfulfilled request do not store",
+ requests: []Event{{Block: 99, ID: "1000"}, {Block: 57, ID: "1000"}},
+ wait: 25,
+ lookback: 100,
+ latest: 200,
+ expectedStored: []uint64{},
+ expectedStoredMapBlocks: []uint64{},
},
{
name: "mixed",
@@ -204,335 +207,485 @@ var (
// Block 154
{Block: 154, ID: "10007"}},
- wait: 25,
- lookback: 100,
- latest: 200,
- expectedStored: []uint64{150, 153},
+ wait: 25,
+ lookback: 100,
+ latest: 200,
+ expectedStored: []uint64{150, 153},
+ expectedStoredMapBlocks: []uint64{150, 153},
},
{
- name: "lookback before 0th block",
- requests: []Event{{Block: 20, ID: "1000"}},
- wait: 25,
- lookback: 100,
- latest: 50,
- expectedStored: []uint64{20},
+ name: "lookback before 0th block",
+ requests: []Event{{Block: 20, ID: "1000"}},
+ wait: 25,
+ lookback: 100,
+ latest: 50,
+ expectedStored: []uint64{20},
+ expectedStoredMapBlocks: []uint64{20},
},
}
)
-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)
+ 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)
+ // 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)
+ // 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)
+ // 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) {
@@ -551,6 +704,7 @@ func TestFeeder_CachesStoredBlocks(t *testing.T) {
0,
100,
200,
+ 600*time.Second,
func(ctx context.Context) (uint64, error) {
return 250, nil
})
@@ -813,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,
@@ -901,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),
@@ -909,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 {
@@ -942,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 00000000000..bf01e80ffdd
--- /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 00000000000..722cd35f271
--- /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 157f6f2ec03..82b813a37f4 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 10eaae10d34..0b7110a7528 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 0e52ee9447d..6c1ec0946e7 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 938df59bb76..2f37991f741 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")
@@ -156,7 +156,7 @@ func (d *Delegate) ServicesForSpec(jb job.Job, qopts ...pg.QOpt) ([]job.ServiceC
return nil, errors.Wrap(err, "building batchBHS")
}
- log := d.logger.Named("Block Header Feeder").With(
+ log := d.logger.Named("BlockHeaderFeeder").With(
"jobID", jb.ID,
"externalJobID", jb.ExternalJobID,
"bhsAddress", bhs.Address(),
diff --git a/core/services/chainlink/application.go b/core/services/chainlink/application.go
index e031973e561..814c8a1c10b 100644
--- a/core/services/chainlink/application.go
+++ b/core/services/chainlink/application.go
@@ -11,8 +11,8 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/google/uuid"
+ "github.com/grafana/pyroscope-go"
"github.com/pkg/errors"
- "github.com/pyroscope-io/client/pyroscope"
"go.uber.org/multierr"
"go.uber.org/zap/zapcore"
@@ -125,7 +125,6 @@ type ChainlinkApplication struct {
ExternalInitiatorManager webhook.ExternalInitiatorManager
SessionReaper utils.SleeperTask
shutdownOnce sync.Once
- explorerClient synchronization.ExplorerClient
srvcs []services.ServiceCtx
HealthChecker services.Checker
Nurse *services.Nurse
@@ -179,13 +178,13 @@ func NewApplication(opts ApplicationOpts) (Application, error) {
restrictedHTTPClient := opts.RestrictedHTTPClient
unrestrictedHTTPClient := opts.UnrestrictedHTTPClient
- // LOOPs can be be created as options, in the case of LOOP relayers, or
+ // LOOPs can be created as options, in the case of LOOP relayers, or
// as OCR2 job implementations, in the case of Median today.
// We will have a non-nil registry here in LOOP relayers are being used, otherwise
// we need to initialize in case we serve OCR2 LOOPs
loopRegistry := opts.LoopRegistry
if loopRegistry == nil {
- loopRegistry = plugins.NewLoopRegistry(globalLogger.Named("LoopRegistry"))
+ loopRegistry = plugins.NewLoopRegistry(globalLogger)
}
// If the audit logger is enabled
@@ -218,25 +217,12 @@ func NewApplication(opts ApplicationOpts) (Application, error) {
globalLogger.Info("Nurse service (automatic pprof profiling) is disabled")
}
- healthChecker := services.NewChecker()
-
telemetryIngressClient := synchronization.TelemetryIngressClient(&synchronization.NoopTelemetryIngressClient{})
telemetryIngressBatchClient := synchronization.TelemetryIngressBatchClient(&synchronization.NoopTelemetryIngressBatchClient{})
- explorerClient := synchronization.ExplorerClient(&synchronization.NoopExplorerClient{})
monitoringEndpointGen := telemetry.MonitoringEndpointGenerator(&telemetry.NoopAgent{})
- if cfg.Explorer().URL() != nil && cfg.TelemetryIngress().URL() != nil {
- globalLogger.Warn("Both ExplorerUrl and TelemetryIngress.Url are set, defaulting to Explorer")
- }
-
- if cfg.Explorer().URL() != nil {
- explorerClient = synchronization.NewExplorerClient(cfg.Explorer().URL(), cfg.Explorer().AccessKey(), cfg.Explorer().Secret(), globalLogger)
- monitoringEndpointGen = telemetry.NewExplorerAgent(explorerClient)
- }
-
ticfg := cfg.TelemetryIngress()
- // Use Explorer over TelemetryIngress if both URLs are set
- if cfg.Explorer().URL() == nil && ticfg.URL() != nil {
+ if ticfg.URL() != nil {
if ticfg.UseBatchSend() {
telemetryIngressBatchClient = synchronization.NewTelemetryIngressBatchClient(ticfg.URL(),
ticfg.ServerPubKey(), keyStore.CSA(), ticfg.Logging(), globalLogger, ticfg.BufferSize(), ticfg.MaxBatchSize(), ticfg.SendInterval(), ticfg.SendTimeout(), ticfg.UniConn())
@@ -248,7 +234,7 @@ func NewApplication(opts ApplicationOpts) (Application, error) {
monitoringEndpointGen = telemetry.NewIngressAgentWrapper(telemetryIngressClient)
}
}
- srvcs = append(srvcs, explorerClient, telemetryIngressClient, telemetryIngressBatchClient)
+ srvcs = append(srvcs, telemetryIngressClient, telemetryIngressBatchClient)
backupCfg := cfg.Database().Backup()
if backupCfg.Mode() != config.DatabaseBackupModeNone && backupCfg.Frequency() > 0 {
@@ -418,11 +404,13 @@ func NewApplication(opts ApplicationOpts) (Application, error) {
globalLogger.Debug("Off-chain reporting v2 disabled")
}
+ healthChecker := services.NewChecker()
+
var lbs []utils.DependentAwaiter
for _, c := range legacyEVMChains.Slice() {
lbs = append(lbs, c.LogBroadcaster())
}
- jobSpawner := job.NewSpawner(jobORM, cfg.Database(), delegates, db, globalLogger, lbs)
+ jobSpawner := job.NewSpawner(jobORM, cfg.Database(), healthChecker, delegates, db, globalLogger, lbs)
srvcs = append(srvcs, jobSpawner, pipelineRunner)
// We start the log poller after the job spawner
@@ -455,7 +443,13 @@ func NewApplication(opts ApplicationOpts) (Application, error) {
feedsService = &feeds.NullService{}
}
- app := &ChainlinkApplication{
+ for _, s := range srvcs {
+ if err := healthChecker.Register(s); err != nil {
+ return nil, err
+ }
+ }
+
+ return &ChainlinkApplication{
relayers: opts.RelayerChainInteroperators,
EventBroadcaster: eventBroadcaster,
jobORM: jobORM,
@@ -471,7 +465,6 @@ func NewApplication(opts ApplicationOpts) (Application, error) {
KeyStore: keyStore,
SessionReaper: sessions.NewSessionReaper(db.DB, cfg.WebServer(), globalLogger),
ExternalInitiatorManager: externalInitiatorManager,
- explorerClient: explorerClient,
HealthChecker: healthChecker,
Nurse: nurse,
logger: globalLogger,
@@ -485,27 +478,7 @@ func NewApplication(opts ApplicationOpts) (Application, error) {
// NOTE: Can keep things clean by putting more things in srvcs instead of manually start/closing
srvcs: srvcs,
- }
-
- for _, service := range app.srvcs {
- checkable := service.(services.Checkable)
- if err := app.HealthChecker.Register(service.Name(), checkable); err != nil {
- return nil, err
- }
- }
-
- // To avoid subscribing chain services twice, we only subscribe them if OCR2 is not enabled.
- // If it's enabled, they are going to be registered with relayers by default.
- if !cfg.OCR2().Enabled() {
- for _, service := range app.relayers.Services() {
- checkable := service.(services.Checkable)
- if err := app.HealthChecker.Register(service.Name(), checkable); err != nil {
- return nil, err
- }
- }
- }
-
- return app, nil
+ }, nil
}
func (app *ChainlinkApplication) SetLogLevel(lvl zapcore.Level) error {
@@ -750,6 +723,7 @@ func (app *ChainlinkApplication) RunJobV2(
"externalJobID": jb.ExternalJobID,
"name": jb.Name.ValueOrZero(),
"publicKey": jb.VRFSpec.PublicKey[:],
+ "evmChainID": jb.VRFSpec.EVMChainID.String(),
},
"jobRun": map[string]interface{}{
"meta": meta,
diff --git a/core/services/chainlink/config.go b/core/services/chainlink/config.go
index 73bfeb3d973..5578f8c0453 100644
--- a/core/services/chainlink/config.go
+++ b/core/services/chainlink/config.go
@@ -129,28 +129,24 @@ func (s *Secrets) SetFrom(f *Secrets) (err error) {
err = multierr.Append(err, config.NamedMultiErrorList(err1, "Database"))
}
- if err2 := s.Explorer.SetFrom(&f.Explorer); err2 != nil {
- err = multierr.Append(err, config.NamedMultiErrorList(err2, "Explorer"))
+ if err2 := s.Password.SetFrom(&f.Password); err2 != nil {
+ err = multierr.Append(err, config.NamedMultiErrorList(err2, "Password"))
}
- if err3 := s.Password.SetFrom(&f.Password); err3 != nil {
- err = multierr.Append(err, config.NamedMultiErrorList(err3, "Password"))
+ if err3 := s.Pyroscope.SetFrom(&f.Pyroscope); err3 != nil {
+ err = multierr.Append(err, config.NamedMultiErrorList(err3, "Pyroscope"))
}
- if err4 := s.Pyroscope.SetFrom(&f.Pyroscope); err4 != nil {
- err = multierr.Append(err, config.NamedMultiErrorList(err4, "Pyroscope"))
+ if err4 := s.Prometheus.SetFrom(&f.Prometheus); err4 != nil {
+ err = multierr.Append(err, config.NamedMultiErrorList(err4, "Prometheus"))
}
- if err5 := s.Prometheus.SetFrom(&f.Prometheus); err5 != nil {
- err = multierr.Append(err, config.NamedMultiErrorList(err5, "Prometheus"))
+ if err5 := s.Mercury.SetFrom(&f.Mercury); err5 != nil {
+ err = multierr.Append(err, config.NamedMultiErrorList(err5, "Mercury"))
}
- if err6 := s.Mercury.SetFrom(&f.Mercury); err6 != nil {
- err = multierr.Append(err, config.NamedMultiErrorList(err6, "Mercury"))
- }
-
- if err7 := s.Threshold.SetFrom(&f.Threshold); err7 != nil {
- err = multierr.Append(err, config.NamedMultiErrorList(err7, "Threshold"))
+ if err6 := s.Threshold.SetFrom(&f.Threshold); err6 != nil {
+ err = multierr.Append(err, config.NamedMultiErrorList(err6, "Threshold"))
}
_, err = utils.MultiErrorList(err)
@@ -223,12 +219,6 @@ func (s *Secrets) setEnv() error {
s.Database.AllowSimplePasswords = new(bool)
*s.Database.AllowSimplePasswords = true
}
- if explorerKey := env.ExplorerAccessKey.Get(); explorerKey != "" {
- s.Explorer.AccessKey = &explorerKey
- }
- if explorerSecret := env.ExplorerSecret.Get(); explorerSecret != "" {
- s.Explorer.Secret = &explorerSecret
- }
if keystorePassword := env.PasswordKeystore.Get(); keystorePassword != "" {
s.Password.Keystore = &keystorePassword
}
diff --git a/core/services/chainlink/config_explorer.go b/core/services/chainlink/config_explorer.go
deleted file mode 100644
index ce6001de195..00000000000
--- a/core/services/chainlink/config_explorer.go
+++ /dev/null
@@ -1,35 +0,0 @@
-package chainlink
-
-import (
- "net/url"
-
- "github.com/smartcontractkit/chainlink/v2/core/config/toml"
- "github.com/smartcontractkit/chainlink/v2/core/store/models"
-)
-
-type explorerConfig struct {
- explorerURL *models.URL
- s toml.ExplorerSecrets
-}
-
-func (e *explorerConfig) URL() *url.URL {
- u := (*url.URL)(e.explorerURL)
- if *u == zeroURL {
- u = nil
- }
- return u
-}
-
-func (e *explorerConfig) AccessKey() string {
- if e.s.AccessKey == nil {
- return ""
- }
- return string(*e.s.AccessKey)
-}
-
-func (e *explorerConfig) Secret() string {
- if e.s.Secret == nil {
- return ""
- }
- return string(*e.s.Secret)
-}
diff --git a/core/services/chainlink/config_explorer_test.go b/core/services/chainlink/config_explorer_test.go
deleted file mode 100644
index d68f671690b..00000000000
--- a/core/services/chainlink/config_explorer_test.go
+++ /dev/null
@@ -1,20 +0,0 @@
-package chainlink
-
-import (
- "testing"
-
- "github.com/stretchr/testify/assert"
- "github.com/stretchr/testify/require"
-)
-
-func TestExplorerConfig(t *testing.T) {
- opts := GeneralConfigOpts{
- ConfigStrings: []string{fullTOML},
- }
- cfg, err := opts.New()
- require.NoError(t, err)
-
- e := cfg.Explorer()
- assert.Equal(t, "http://explorer.url", e.URL().String())
-
-}
diff --git a/core/services/chainlink/config_general.go b/core/services/chainlink/config_general.go
index c25539684de..688215c6978 100644
--- a/core/services/chainlink/config_general.go
+++ b/core/services/chainlink/config_general.go
@@ -3,7 +3,6 @@ package chainlink
import (
_ "embed"
"fmt"
- "math/big"
"net/url"
"os"
"path/filepath"
@@ -313,15 +312,6 @@ func (g *generalConfig) EVMRPCEnabled() bool {
return false
}
-func (g *generalConfig) DefaultChainID() *big.Int {
- for _, c := range g.c.EVM {
- if c.IsEnabled() {
- return (*big.Int)(c.ChainID)
- }
- }
- return nil
-}
-
func (g *generalConfig) SolanaEnabled() bool {
for _, c := range g.c.Solana {
if c.IsEnabled() {
@@ -409,18 +399,6 @@ func (g *generalConfig) ShutdownGracePeriod() time.Duration {
return g.c.ShutdownGracePeriod.Duration()
}
-func (g *generalConfig) Explorer() config.Explorer {
- return &explorerConfig{s: g.secrets.Explorer, explorerURL: g.c.ExplorerURL}
-}
-
-func (g *generalConfig) ExplorerURL() *url.URL {
- u := (*url.URL)(g.c.ExplorerURL)
- if *u == zeroURL {
- u = nil
- }
- return u
-}
-
func (g *generalConfig) FluxMonitor() config.FluxMonitor {
return &fluxMonitorConfig{c: g.c.FluxMonitor}
}
diff --git a/core/services/chainlink/config_general_secrets.go b/core/services/chainlink/config_general_secrets.go
index 6138eab58a3..25dc62d4d01 100644
--- a/core/services/chainlink/config_general_secrets.go
+++ b/core/services/chainlink/config_general_secrets.go
@@ -14,17 +14,3 @@ func (g *generalConfig) DatabaseURL() url.URL {
func (g *generalConfig) DatabaseBackupURL() *url.URL {
return g.secrets.Database.BackupURL.URL()
}
-
-func (g *generalConfig) ExplorerAccessKey() string {
- if g.secrets.Explorer.AccessKey == nil {
- return ""
- }
- return string(*g.secrets.Explorer.AccessKey)
-}
-
-func (g *generalConfig) ExplorerSecret() string {
- if g.secrets.Explorer.Secret == nil {
- return ""
- }
- return string(*g.secrets.Explorer.Secret)
-}
diff --git a/core/services/chainlink/config_general_test.go b/core/services/chainlink/config_general_test.go
index c640e54beb0..8e95e389ffc 100644
--- a/core/services/chainlink/config_general_test.go
+++ b/core/services/chainlink/config_general_test.go
@@ -24,7 +24,6 @@ func TestTOMLGeneralConfig_Defaults(t *testing.T) {
config, err := GeneralConfigOpts{}.New()
require.NoError(t, err)
assert.Equal(t, (*url.URL)(nil), config.WebServer().BridgeResponseURL())
- assert.Nil(t, config.DefaultChainID())
assert.False(t, config.EVMRPCEnabled())
assert.False(t, config.EVMEnabled())
assert.False(t, config.CosmosEnabled())
@@ -133,9 +132,6 @@ func TestConfig_LogSQL(t *testing.T) {
//go:embed testdata/mergingsecretsdata/secrets-database.toml
var databaseSecretsTOML string
-//go:embed testdata/mergingsecretsdata/secrets-explorer.toml
-var explorerSecretsTOML string
-
//go:embed testdata/mergingsecretsdata/secrets-password.toml
var passwordSecretsTOML string
@@ -158,8 +154,6 @@ func TestConfig_SecretsMerging(t *testing.T) {
t.Run("verify secrets merging in GeneralConfigOpts.New()", func(t *testing.T) {
databaseSecrets, err := parseSecrets(databaseSecretsTOML)
require.NoErrorf(t, err, "error: %s", err)
- explorerSecrets, err1 := parseSecrets(explorerSecretsTOML)
- require.NoErrorf(t, err1, "error: %s", err1)
passwordSecrets, err2 := parseSecrets(passwordSecretsTOML)
require.NoErrorf(t, err2, "error: %s", err2)
pyroscopeSecrets, err3 := parseSecrets(pyroscopeSecretsTOML)
@@ -179,7 +173,6 @@ func TestConfig_SecretsMerging(t *testing.T) {
}
secretsFiles := []string{
"testdata/mergingsecretsdata/secrets-database.toml",
- "testdata/mergingsecretsdata/secrets-explorer.toml",
"testdata/mergingsecretsdata/secrets-password.toml",
"testdata/mergingsecretsdata/secrets-pyroscope.toml",
"testdata/mergingsecretsdata/secrets-prometheus.toml",
@@ -196,8 +189,6 @@ func TestConfig_SecretsMerging(t *testing.T) {
assert.Equal(t, databaseSecrets.Database.URL.URL().String(), opts.Secrets.Database.URL.URL().String())
assert.Equal(t, databaseSecrets.Database.BackupURL.URL().String(), opts.Secrets.Database.BackupURL.URL().String())
- assert.Equal(t, (string)(*explorerSecrets.Explorer.AccessKey), (string)(*opts.Secrets.Explorer.AccessKey))
- assert.Equal(t, (string)(*explorerSecrets.Explorer.Secret), (string)(*opts.Secrets.Explorer.Secret))
assert.Equal(t, (string)(*passwordSecrets.Password.Keystore), (string)(*opts.Secrets.Password.Keystore))
assert.Equal(t, (string)(*passwordSecrets.Password.VRF), (string)(*opts.Secrets.Password.VRF))
assert.Equal(t, (string)(*pyroscopeSecrets.Pyroscope.AuthToken), (string)(*opts.Secrets.Pyroscope.AuthToken))
diff --git a/core/services/chainlink/config_mercury.go b/core/services/chainlink/config_mercury.go
index 93d88c689b8..1a20dd069d8 100644
--- a/core/services/chainlink/config_mercury.go
+++ b/core/services/chainlink/config_mercury.go
@@ -11,11 +11,15 @@ type mercuryConfig struct {
func (m *mercuryConfig) Credentials(credName string) *models.MercuryCredentials {
if mc, ok := m.s.Credentials[credName]; ok {
- return &models.MercuryCredentials{
+ c := &models.MercuryCredentials{
URL: mc.URL.URL().String(),
- Username: string(*mc.Username),
Password: string(*mc.Password),
+ Username: string(*mc.Username),
+ }
+ if mc.LegacyURL != nil && mc.LegacyURL.URL() != nil {
+ c.LegacyURL = mc.LegacyURL.URL().String()
}
+ return c
}
return nil
}
diff --git a/core/services/chainlink/config_test.go b/core/services/chainlink/config_test.go
index e2e12545613..480d06b5806 100644
--- a/core/services/chainlink/config_test.go
+++ b/core/services/chainlink/config_test.go
@@ -213,7 +213,6 @@ func TestConfig_Marshal(t *testing.T) {
global := Config{
Core: toml.Core{
- ExplorerURL: mustURL("http://explorer.url"),
InsecureFastScrypt: ptr(true),
RootDir: ptr("test/root/dir"),
ShutdownGracePeriod: models.MustNewDuration(10 * time.Second),
@@ -614,7 +613,7 @@ func TestConfig_Marshal(t *testing.T) {
BlocksUntilTxTimeout: ptr[int64](12),
ConfirmPollPeriod: relayutils.MustNewDuration(time.Second),
FallbackGasPrice: mustDecimal("0.001"),
- FeeToken: ptr("ucosm"),
+ GasToken: ptr("ucosm"),
GasLimitMultiplier: mustDecimal("1.2"),
MaxMsgsPerBatch: ptr[int64](17),
OCR2CachePollPeriod: relayutils.MustNewDuration(time.Minute),
@@ -635,8 +634,7 @@ func TestConfig_Marshal(t *testing.T) {
exp string
}{
{"empty", Config{}, ``},
- {"global", global, `ExplorerURL = 'http://explorer.url'
-InsecureFastScrypt = true
+ {"global", global, `InsecureFastScrypt = true
RootDir = 'test/root/dir'
ShutdownGracePeriod = '10s'
@@ -962,7 +960,7 @@ BlockRate = '1m0s'
BlocksUntilTxTimeout = 12
ConfirmPollPeriod = '1s'
FallbackGasPrice = '0.001'
-FeeToken = 'ucosm'
+GasToken = 'ucosm'
GasLimitMultiplier = '1.2'
MaxMsgsPerBatch = 17
OCR2CachePollPeriod = '1m0s'
@@ -1303,9 +1301,7 @@ func TestSecrets_Validate(t *testing.T) {
}{
{name: "partial",
toml: `
-Database.AllowSimplePasswords = true
-Explorer.AccessKey = "access_key"
-Explorer.Secret = "secret"`,
+Database.AllowSimplePasswords = true`,
exp: `invalid secrets: 2 errors:
- Database.URL: empty: must be provided and non-empty
- Password.Keystore: empty: must be provided and non-empty`},
diff --git a/core/services/chainlink/legacy.env b/core/services/chainlink/legacy.env
index 142b4e3b872..01469736e0f 100644
--- a/core/services/chainlink/legacy.env
+++ b/core/services/chainlink/legacy.env
@@ -7,9 +7,6 @@ AUDIT_LOGGER_JSON_WRAPPER_KEY=
CHAIN_TYPE=
CHAINLINK_DEV=
-EXPLORER_ACCESS_KEY=
-EXPLORER_SECRET=
-EXPLORER_URL=
FLAGS_CONTRACT_ADDRESS=
INSECURE_FAST_SCRYPT=
REAPER_EXPIRATION=
diff --git a/core/services/chainlink/mocks/general_config.go b/core/services/chainlink/mocks/general_config.go
index 289c23b26b2..416fbd33756 100644
--- a/core/services/chainlink/mocks/general_config.go
+++ b/core/services/chainlink/mocks/general_config.go
@@ -3,11 +3,8 @@
package mocks
import (
- big "math/big"
-
- config "github.com/smartcontractkit/chainlink/v2/core/config"
-
cosmos "github.com/smartcontractkit/chainlink/v2/core/chains/cosmos"
+ config "github.com/smartcontractkit/chainlink/v2/core/config"
mock "github.com/stretchr/testify/mock"
@@ -147,22 +144,6 @@ func (_m *GeneralConfig) Database() config.Database {
return r0
}
-// DefaultChainID provides a mock function with given fields:
-func (_m *GeneralConfig) DefaultChainID() *big.Int {
- ret := _m.Called()
-
- var r0 *big.Int
- if rf, ok := ret.Get(0).(func() *big.Int); ok {
- r0 = rf()
- } else {
- if ret.Get(0) != nil {
- r0 = ret.Get(0).(*big.Int)
- }
- }
-
- return r0
-}
-
// EVMConfigs provides a mock function with given fields:
func (_m *GeneralConfig) EVMConfigs() toml.EVMConfigs {
ret := _m.Called()
@@ -207,22 +188,6 @@ func (_m *GeneralConfig) EVMRPCEnabled() bool {
return r0
}
-// Explorer provides a mock function with given fields:
-func (_m *GeneralConfig) Explorer() config.Explorer {
- ret := _m.Called()
-
- var r0 config.Explorer
- if rf, ok := ret.Get(0).(func() config.Explorer); ok {
- r0 = rf()
- } else {
- if ret.Get(0) != nil {
- r0 = ret.Get(0).(config.Explorer)
- }
- }
-
- return r0
-}
-
// Feature provides a mock function with given fields:
func (_m *GeneralConfig) Feature() config.Feature {
ret := _m.Called()
diff --git a/core/services/chainlink/mocks/relayer_chain_interoperators.go b/core/services/chainlink/mocks/relayer_chain_interoperators.go
index f25ced6c3ca..c0eb699a492 100644
--- a/core/services/chainlink/mocks/relayer_chain_interoperators.go
+++ b/core/services/chainlink/mocks/relayer_chain_interoperators.go
@@ -10,7 +10,7 @@ import (
cosmos "github.com/smartcontractkit/chainlink/v2/core/chains/cosmos"
evm "github.com/smartcontractkit/chainlink/v2/core/chains/evm"
-
+
// Manually edited. mockery generates the wrong dependency. edited to use `loop` rather than `loop/internal`
// seems to caused by incorrect alias resolution of the relayer dep
internal "github.com/smartcontractkit/chainlink-relay/pkg/loop"
@@ -160,11 +160,11 @@ func (_m *RelayerChainInteroperators) List(filter chainlink.FilterFn) chainlink.
return r0
}
-// NodeStatuses provides a mock function with given fields: ctx, offset, limit, chainIDs
-func (_m *RelayerChainInteroperators) NodeStatuses(ctx context.Context, offset int, limit int, chainIDs ...string) ([]types.NodeStatus, int, error) {
- _va := make([]interface{}, len(chainIDs))
- for _i := range chainIDs {
- _va[_i] = chainIDs[_i]
+// NodeStatuses provides a mock function with given fields: ctx, offset, limit, relayIDs
+func (_m *RelayerChainInteroperators) NodeStatuses(ctx context.Context, offset int, limit int, relayIDs ...relay.ID) ([]types.NodeStatus, int, error) {
+ _va := make([]interface{}, len(relayIDs))
+ for _i := range relayIDs {
+ _va[_i] = relayIDs[_i]
}
var _ca []interface{}
_ca = append(_ca, ctx, offset, limit)
@@ -174,25 +174,25 @@ func (_m *RelayerChainInteroperators) NodeStatuses(ctx context.Context, offset i
var r0 []types.NodeStatus
var r1 int
var r2 error
- if rf, ok := ret.Get(0).(func(context.Context, int, int, ...string) ([]types.NodeStatus, int, error)); ok {
- return rf(ctx, offset, limit, chainIDs...)
+ if rf, ok := ret.Get(0).(func(context.Context, int, int, ...relay.ID) ([]types.NodeStatus, int, error)); ok {
+ return rf(ctx, offset, limit, relayIDs...)
}
- if rf, ok := ret.Get(0).(func(context.Context, int, int, ...string) []types.NodeStatus); ok {
- r0 = rf(ctx, offset, limit, chainIDs...)
+ if rf, ok := ret.Get(0).(func(context.Context, int, int, ...relay.ID) []types.NodeStatus); ok {
+ r0 = rf(ctx, offset, limit, relayIDs...)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]types.NodeStatus)
}
}
- if rf, ok := ret.Get(1).(func(context.Context, int, int, ...string) int); ok {
- r1 = rf(ctx, offset, limit, chainIDs...)
+ if rf, ok := ret.Get(1).(func(context.Context, int, int, ...relay.ID) int); ok {
+ r1 = rf(ctx, offset, limit, relayIDs...)
} else {
r1 = ret.Get(1).(int)
}
- if rf, ok := ret.Get(2).(func(context.Context, int, int, ...string) error); ok {
- r2 = rf(ctx, offset, limit, chainIDs...)
+ if rf, ok := ret.Get(2).(func(context.Context, int, int, ...relay.ID) error); ok {
+ r2 = rf(ctx, offset, limit, relayIDs...)
} else {
r2 = ret.Error(2)
}
diff --git a/core/services/chainlink/relayer_chain_interoperators.go b/core/services/chainlink/relayer_chain_interoperators.go
index e4de1352925..6513184d9ec 100644
--- a/core/services/chainlink/relayer_chain_interoperators.go
+++ b/core/services/chainlink/relayer_chain_interoperators.go
@@ -9,6 +9,7 @@ import (
"github.com/smartcontractkit/chainlink-relay/pkg/loop"
"github.com/smartcontractkit/chainlink-relay/pkg/types"
+
"github.com/smartcontractkit/chainlink/v2/core/chains"
"github.com/smartcontractkit/chainlink/v2/core/chains/cosmos"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm"
@@ -52,17 +53,21 @@ type LegacyChainer interface {
LegacyCosmosChains() cosmos.LegacyChainContainer
}
-// Similar to [chains.ChainStatuser] but keyed by relay identifier instead of string
-// TODO BCF-2441 remove this comment when chains.ChainStatus is no longer keyed.
type ChainStatuser interface {
ChainStatus(ctx context.Context, id relay.ID) (types.ChainStatus, error)
ChainStatuses(ctx context.Context, offset, limit int) ([]types.ChainStatus, int, error)
}
+// NodesStatuser is an interface for node configuration and state.
+// TODO BCF-2440, BCF-2511 may need Node(ctx,name) to get a node status by name
+type NodesStatuser interface {
+ NodeStatuses(ctx context.Context, offset, limit int, relayIDs ...relay.ID) (nodes []types.NodeStatus, count int, err error)
+}
+
// ChainsNodesStatuser report statuses about chains and nodes
type ChainsNodesStatuser interface {
ChainStatuser
- chains.NodesStatuser
+ NodesStatuser
}
var _ RelayerChainInteroperators = &CoreRelayerChainInteroperators{}
@@ -85,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
@@ -105,26 +110,13 @@ func InitEVM(ctx context.Context, factory RelayerFactory, config EVMFactoryConfi
}
legacyMap := make(map[string]evm.Chain)
- var defaultChain evm.Chain
for id, a := range adapters {
// adapter is a service
op.srvs = append(op.srvs, a)
op.loopRelayers[id] = a
- legacyMap[id.ChainID.String()] = a.Chain()
- if a.Default() {
- defaultChain = a.Chain()
- }
-
- }
- legacy, err := evm.NewLegacyChains(config.AppConfig, legacyMap)
- if err != nil {
- return err
- }
- op.legacyChains.EVMChains = legacy
- // TODO BCF-2510 this may not be necessary if EVM is not enabled by default
- if defaultChain != nil {
- op.legacyChains.EVMChains.SetDefault(defaultChain)
+ legacyMap[id.ChainID] = a.Chain()
}
+ op.legacyChains.EVMChains = evm.NewLegacyChains(legacyMap, config.AppConfig.EVMConfigs())
return nil
}
}
@@ -137,10 +129,11 @@ func InitCosmos(ctx context.Context, factory RelayerFactory, config CosmosFactor
return fmt.Errorf("failed to setup Cosmos relayer: %w", err2)
}
legacyMap := make(map[string]cosmos.Chain)
+
for id, a := range adapters {
op.srvs = append(op.srvs, a)
op.loopRelayers[id] = a
- legacyMap[id.ChainID.String()] = a.Chain()
+ legacyMap[id.ChainID] = a.Chain()
}
op.legacyChains.CosmosChains = cosmos.NewLegacyChains(legacyMap)
@@ -155,6 +148,7 @@ func InitSolana(ctx context.Context, factory RelayerFactory, config SolanaFactor
if err2 != nil {
return fmt.Errorf("failed to setup Solana relayer: %w", err2)
}
+
for id, relayer := range solRelayers {
op.srvs = append(op.srvs, relayer)
op.loopRelayers[id] = relayer
@@ -171,10 +165,12 @@ func InitStarknet(ctx context.Context, factory RelayerFactory, config StarkNetFa
if err2 != nil {
return fmt.Errorf("failed to setup StarkNet relayer: %w", err2)
}
+
for id, relayer := range starkRelayers {
op.srvs = append(op.srvs, relayer)
op.loopRelayers[id] = relayer
}
+
return nil
}
}
@@ -211,16 +207,13 @@ func (rs *CoreRelayerChainInteroperators) ChainStatus(ctx context.Context, id re
lr, err := rs.Get(id)
if err != nil {
- return types.ChainStatus{}, fmt.Errorf("%w: error getting chainstatus: %w", chains.ErrNotFound, err)
+ return types.ChainStatus{}, fmt.Errorf("%w: error getting chain status: %w", chains.ErrNotFound, err)
}
- // this call is weird because the [loop.Relayer] interface still requires id
- // but in this context the `relayer` should only have only id
- // moreover, the `relayer` here is pinned to one chain we need to pass the chain id
- return lr.ChainStatus(ctx, id.ChainID.String())
+
+ return lr.GetChainStatus(ctx)
}
func (rs *CoreRelayerChainInteroperators) ChainStatuses(ctx context.Context, offset, limit int) ([]types.ChainStatus, int, error) {
- // chain statuses are not dynamic; the call would be better named as ChainConfig or such.
var (
stats []types.ChainStatus
@@ -238,8 +231,7 @@ func (rs *CoreRelayerChainInteroperators) ChainStatuses(ctx context.Context, off
})
for _, rid := range relayerIds {
lr := rs.loopRelayers[rid]
- // the relayer is chain specific; use the chain id and not the relayer id
- stat, err := lr.ChainStatus(ctx, rid.ChainID.String())
+ stat, err := lr.GetChainStatus(ctx)
if err != nil {
totalErr = errors.Join(totalErr, err)
continue
@@ -273,51 +265,46 @@ func (rs *CoreRelayerChainInteroperators) Node(ctx context.Context, name string)
}
// ids must be a string representation of relay.Identifier
-// ids are a filter; if none are specificied, all are returned.
-// TODO: BCF-2440/1 this signature can be changed to id relay.Identifier which is a much better API
-func (rs *CoreRelayerChainInteroperators) NodeStatuses(ctx context.Context, offset, limit int, relayerIDs ...string) (nodes []types.NodeStatus, count int, err error) {
+// ids are a filter; if none are specified, all are returned.
+func (rs *CoreRelayerChainInteroperators) NodeStatuses(ctx context.Context, offset, limit int, relayerIDs ...relay.ID) (nodes []types.NodeStatus, count int, err error) {
var (
totalErr error
result []types.NodeStatus
)
if len(relayerIDs) == 0 {
- for rid, lr := range rs.loopRelayers {
- stats, _, err := lr.NodeStatuses(ctx, offset, limit, rid.ChainID.String())
+ for _, lr := range rs.loopRelayers {
+ stats, _, total, err := lr.ListNodeStatuses(ctx, int32(limit), "")
if err != nil {
totalErr = errors.Join(totalErr, err)
continue
}
result = append(result, stats...)
+ count += total
}
} else {
- for _, idStr := range relayerIDs {
- rid := new(relay.ID)
- err := rid.UnmarshalString(idStr)
- if err != nil {
- totalErr = errors.Join(totalErr, err)
- continue
- }
- lr, exist := rs.loopRelayers[*rid]
+ for _, rid := range relayerIDs {
+ lr, exist := rs.loopRelayers[rid]
if !exist {
totalErr = errors.Join(totalErr, fmt.Errorf("relayer %s does not exist", rid.Name()))
continue
}
- nodeStats, _, err := lr.NodeStatuses(ctx, offset, limit, rid.ChainID.String())
+ nodeStats, _, total, err := lr.ListNodeStatuses(ctx, int32(limit), "")
if err != nil {
totalErr = errors.Join(totalErr, err)
continue
}
result = append(result, nodeStats...)
+ count += total
}
}
if totalErr != nil {
return nil, 0, totalErr
}
if len(result) > limit && limit > 0 {
- return result[offset : offset+limit], limit, nil
+ return result[offset : offset+limit], count, nil
}
- return result[offset:], len(result[offset:]), nil
+ return result[offset:], count, nil
}
type FilterFn func(id relay.ID) bool
diff --git a/core/services/chainlink/relayer_chain_interoperators_test.go b/core/services/chainlink/relayer_chain_interoperators_test.go
index e86900ea0ee..527dacd56d8 100644
--- a/core/services/chainlink/relayer_chain_interoperators_test.go
+++ b/core/services/chainlink/relayer_chain_interoperators_test.go
@@ -140,7 +140,7 @@ func TestCoreRelayerChainInteroperators(t *testing.T) {
Chain: coscfg.Chain{
GasLimitMultiplier: ptr(decimal.RequireFromString("1.55555")),
Bech32Prefix: ptr("wasm"),
- FeeToken: ptr("cosm"),
+ GasToken: ptr("cosm"),
},
Nodes: cosmos.CosmosNodes{
&coscfg.Node{
@@ -155,7 +155,7 @@ func TestCoreRelayerChainInteroperators(t *testing.T) {
Chain: coscfg.Chain{
GasLimitMultiplier: ptr(decimal.RequireFromString("0.777")),
Bech32Prefix: ptr("wasm"),
- FeeToken: ptr("cosm"),
+ GasToken: ptr("cosm"),
},
Nodes: cosmos.CosmosNodes{
&coscfg.Node{
@@ -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{},
}
@@ -183,8 +181,9 @@ func TestCoreRelayerChainInteroperators(t *testing.T) {
testctx := testutils.Context(t)
tests := []struct {
- name string
- initFuncs []chainlink.CoreRelayerChainInitFunc
+ name string
+ initFuncs []chainlink.CoreRelayerChainInitFunc
+ expectedRelayerNetworks map[relay.Network]struct{}
expectedEVMChainCnt int
expectedEVMNodeCnt int
@@ -206,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,
}),
@@ -220,8 +220,11 @@ func TestCoreRelayerChainInteroperators(t *testing.T) {
{Network: relay.EVM, ChainID: relay.ChainID(evmChainID1.String())},
{Network: relay.EVM, ChainID: relay.ChainID(evmChainID2.String())},
},
+ expectedRelayerNetworks: map[relay.Network]struct{}{relay.EVM: {}},
},
+
{name: "2 solana chain with 2 node",
+
initFuncs: []chainlink.CoreRelayerChainInitFunc{
chainlink.InitSolana(testctx, factory, chainlink.SolanaFactoryConfig{
Keystore: keyStore.Solana(),
@@ -233,8 +236,11 @@ func TestCoreRelayerChainInteroperators(t *testing.T) {
{Network: relay.Solana, ChainID: relay.ChainID(solanaChainID1)},
{Network: relay.Solana, ChainID: relay.ChainID(solanaChainID2)},
},
+ expectedRelayerNetworks: map[relay.Network]struct{}{relay.Solana: {}},
},
+
{name: "2 starknet chain with 4 nodes",
+
initFuncs: []chainlink.CoreRelayerChainInitFunc{
chainlink.InitStarknet(testctx, factory, chainlink.StarkNetFactoryConfig{
Keystore: keyStore.StarkNet(),
@@ -246,14 +252,18 @@ func TestCoreRelayerChainInteroperators(t *testing.T) {
{Network: relay.StarkNet, ChainID: relay.ChainID(starknetChainID1)},
{Network: relay.StarkNet, ChainID: relay.ChainID(starknetChainID2)},
},
+ expectedRelayerNetworks: map[relay.Network]struct{}{relay.StarkNet: {}},
},
+
{
name: "2 cosmos chains with 2 nodes",
initFuncs: []chainlink.CoreRelayerChainInitFunc{
chainlink.InitCosmos(testctx, factory, chainlink.CosmosFactoryConfig{
Keystore: keyStore.Cosmos(),
CosmosConfigs: cfg.CosmosConfigs(),
- EventBroadcaster: pg.NewNullEventBroadcaster()}),
+ EventBroadcaster: pg.NewNullEventBroadcaster(),
+ DB: db,
+ QConfig: cfg.Database()}),
},
expectedCosmosChainCnt: 2,
expectedCosmosNodeCnt: 2,
@@ -261,17 +271,20 @@ func TestCoreRelayerChainInteroperators(t *testing.T) {
{Network: relay.Cosmos, ChainID: relay.ChainID(cosmosChainID1)},
{Network: relay.Cosmos, ChainID: relay.ChainID(cosmosChainID2)},
},
+ expectedRelayerNetworks: map[relay.Network]struct{}{relay.Cosmos: {}},
},
{name: "all chains",
+
initFuncs: []chainlink.CoreRelayerChainInitFunc{chainlink.InitSolana(testctx, factory, chainlink.SolanaFactoryConfig{
Keystore: keyStore.Solana(),
SolanaConfigs: cfg.SolanaConfigs()}),
chainlink.InitEVM(testctx, factory, chainlink.EVMFactoryConfig{
- RelayerConfig: evm.RelayerConfig{
+ ChainOpts: evm.ChainOpts{
AppConfig: cfg,
EventBroadcaster: pg.NewNullEventBroadcaster(),
MailMon: &utils.MailboxMonitor{},
+ DB: db,
},
CSAETHKeystore: keyStore,
}),
@@ -282,6 +295,8 @@ func TestCoreRelayerChainInteroperators(t *testing.T) {
Keystore: keyStore.Cosmos(),
CosmosConfigs: cfg.CosmosConfigs(),
EventBroadcaster: pg.NewNullEventBroadcaster(),
+ DB: db,
+ QConfig: cfg.Database(),
}),
},
expectedEVMChainCnt: 2,
@@ -311,9 +326,12 @@ func TestCoreRelayerChainInteroperators(t *testing.T) {
{Network: relay.Cosmos, ChainID: relay.ChainID(cosmosChainID1)},
{Network: relay.Cosmos, ChainID: relay.ChainID(cosmosChainID2)},
},
+
+ expectedRelayerNetworks: map[relay.Network]struct{}{relay.EVM: {}, relay.Cosmos: {}, relay.Solana: {}, relay.StarkNet: {}},
},
}
for _, tt := range tests {
+ tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
cr, err := chainlink.NewCoreRelayerChainInteroperators(tt.initFuncs...)
@@ -336,6 +354,7 @@ func TestCoreRelayerChainInteroperators(t *testing.T) {
assert.Len(t, allNodeStats, expectedNodeCnt)
assert.Equal(t, cnt, len(allNodeStats))
+ gotRelayerNetworks := make(map[relay.Network]struct{})
for relayNetwork := range relay.SupportedRelays {
var expectedChainCnt, expectedNodeCnt int
switch relayNetwork {
@@ -353,11 +372,26 @@ func TestCoreRelayerChainInteroperators(t *testing.T) {
interops := cr.List(chainlink.FilterRelayersByType(relayNetwork))
assert.Len(t, cr.List(chainlink.FilterRelayersByType(relayNetwork)).Slice(), expectedChainCnt)
+ if len(interops.Slice()) > 0 {
+ gotRelayerNetworks[relayNetwork] = struct{}{}
+ }
+
+ // check legacy chains for those that haven't migrated fully to the loop relayer interface
if relayNetwork == relay.EVM {
- assert.Len(t, cr.LegacyEVMChains().Slice(), expectedChainCnt)
+ _, wantEVM := tt.expectedRelayerNetworks[relay.EVM]
+ if wantEVM {
+ assert.Len(t, cr.LegacyEVMChains().Slice(), expectedChainCnt)
+ } else {
+ assert.Nil(t, cr.LegacyEVMChains())
+ }
}
if relayNetwork == relay.Cosmos {
- assert.Len(t, cr.LegacyCosmosChains().Slice(), expectedChainCnt)
+ _, wantCosmos := tt.expectedRelayerNetworks[relay.Cosmos]
+ if wantCosmos {
+ assert.Len(t, cr.LegacyCosmosChains().Slice(), expectedChainCnt)
+ } else {
+ assert.Nil(t, cr.LegacyCosmosChains())
+ }
}
nodesStats, cnt, err := interops.NodeStatuses(testctx, 0, 0)
@@ -366,6 +400,7 @@ func TestCoreRelayerChainInteroperators(t *testing.T) {
assert.Equal(t, cnt, len(nodesStats))
}
+ assert.EqualValues(t, gotRelayerNetworks, tt.expectedRelayerNetworks)
allRelayerIds := [][]relay.ID{
tt.expectedEVMRelayerIds,
@@ -381,19 +416,19 @@ func TestCoreRelayerChainInteroperators(t *testing.T) {
assert.NoError(t, err)
stat, err := cr.ChainStatus(testctx, wantId)
assert.NoError(t, err)
- assert.Equal(t, wantId.ChainID.String(), stat.ID)
+ assert.Equal(t, wantId.ChainID, stat.ID)
// check legacy chains for evm and cosmos
if wantId.Network == relay.EVM {
- c, err := cr.LegacyEVMChains().Get(wantId.ChainID.String())
+ c, err := cr.LegacyEVMChains().Get(wantId.ChainID)
assert.NoError(t, err)
assert.NotNil(t, c)
- assert.Equal(t, wantId.ChainID.String(), c.ID().String())
+ assert.Equal(t, wantId.ChainID, c.ID().String())
}
if wantId.Network == relay.Cosmos {
- c, err := cr.LegacyCosmosChains().Get(wantId.ChainID.String())
+ c, err := cr.LegacyCosmosChains().Get(wantId.ChainID)
assert.NoError(t, err)
assert.NotNil(t, c)
- assert.Equal(t, wantId.ChainID.String(), c.ID())
+ assert.Equal(t, wantId.ChainID, c.ID())
}
}
}
@@ -404,6 +439,7 @@ func TestCoreRelayerChainInteroperators(t *testing.T) {
assert.ErrorIs(t, err, chainlink.ErrNoSuchRelayer)
})
+
}
t.Run("bad init func", func(t *testing.T) {
diff --git a/core/services/chainlink/relayer_factory.go b/core/services/chainlink/relayer_factory.go
index 51f18b7e61b..c0541f4384d 100644
--- a/core/services/chainlink/relayer_factory.go
+++ b/core/services/chainlink/relayer_factory.go
@@ -2,15 +2,18 @@ package chainlink
import (
"context"
+ "errors"
"fmt"
"github.com/pelletier/go-toml/v2"
+
"github.com/smartcontractkit/sqlx"
pkgcosmos "github.com/smartcontractkit/chainlink-cosmos/pkg/cosmos"
"github.com/smartcontractkit/chainlink-relay/pkg/loop"
pkgsolana "github.com/smartcontractkit/chainlink-solana/pkg/solana"
pkgstarknet "github.com/smartcontractkit/chainlink-starknet/relayer/pkg/chainlink"
+
"github.com/smartcontractkit/chainlink/v2/core/chains/cosmos"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm"
"github.com/smartcontractkit/chainlink/v2/core/chains/solana"
@@ -26,50 +29,56 @@ import (
type RelayerFactory struct {
logger.Logger
- *sqlx.DB
- pg.QConfig
*plugins.LoopRegistry
loop.GRPCOpts
}
type EVMFactoryConfig struct {
- evm.RelayerConfig
+ evm.ChainOpts
evmrelay.CSAETHKeystore
}
func (r *RelayerFactory) NewEVM(ctx context.Context, config EVMFactoryConfig) (map[relay.ID]evmrelay.LoopRelayAdapter, error) {
- // TODO impl EVM loop. For now always 'fallback' to an adapter and embedded chainset
+ // TODO impl EVM loop. For now always 'fallback' to an adapter and embedded chain
relayers := make(map[relay.ID]evmrelay.LoopRelayAdapter)
// override some common opts with the factory values. this seems weird... maybe other signatures should change, or this should take a different type...
ccOpts := evm.ChainRelayExtenderConfig{
-
- Logger: r.Logger,
- DB: r.DB,
- KeyStore: config.CSAETHKeystore.Eth(),
- RelayerConfig: config.RelayerConfig,
+ Logger: r.Logger.Named("EVM"),
+ KeyStore: config.CSAETHKeystore.Eth(),
+ ChainOpts: config.ChainOpts,
}
evmRelayExtenders, err := evmrelay.NewChainRelayerExtenders(ctx, ccOpts)
if err != nil {
return nil, err
}
- legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(evmRelayExtenders)
- if err != nil {
- return nil, err
- }
+ 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.String())
- 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.NewLoopRelayAdapter(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 {
@@ -84,43 +93,56 @@ func (r *RelayerFactory) NewSolana(ks keystore.Solana, chainCfgs solana.SolanaCo
signer = &keystore.SolanaSigner{Solana: ks}
)
+ unique := make(map[string]struct{})
// create one relayer per chain id
for _, chainCfg := range chainCfgs {
+
relayId := relay.ID{Network: relay.Solana, ChainID: relay.ChainID(*chainCfg.ChainID)}
- // all the lower level APIs expect chainsets. create a single valued set per id
- singleChainCfg := solana.SolanaConfigs{chainCfg}
+ _, alreadyExists := unique[relayId.Name()]
+ if alreadyExists {
+ return nil, fmt.Errorf("duplicate chain definitions for %s", relayId.Name())
+ }
+ unique[relayId.Name()] = struct{}{}
+
+ // skip disabled chains from further processing
+ if !chainCfg.IsEnabled() {
+ solLggr.Warnw("Skipping disabled chain", "id", chainCfg.ChainID)
+ continue
+ }
if cmdName := env.SolanaPluginCmd.Get(); cmdName != "" {
// setup the solana relayer to be a LOOP
- tomls, err := toml.Marshal(struct {
- Solana solana.SolanaConfigs
- }{Solana: singleChainCfg})
+ cfgTOML, err := toml.Marshal(struct {
+ Solana solana.SolanaConfig
+ }{Solana: *chainCfg})
+
if err != nil {
return nil, fmt.Errorf("failed to marshal Solana configs: %w", err)
}
solCmdFn, err := plugins.NewCmdFactory(r.Register, plugins.CmdConfig{
- ID: solLggr.Name(),
+ ID: relayId.Name(),
Cmd: cmdName,
})
if err != nil {
return nil, fmt.Errorf("failed to create Solana LOOP command: %w", err)
}
- solanaRelayers[relayId] = loop.NewRelayerService(solLggr, r.GRPCOpts, solCmdFn, string(tomls), signer)
+
+ solanaRelayers[relayId] = loop.NewRelayerService(solLggr, r.GRPCOpts, solCmdFn, string(cfgTOML), signer)
} else {
- // fallback to embedded chainset
- opts := solana.ChainSetOpts{
+ // fallback to embedded chain
+ opts := solana.ChainOpts{
Logger: solLggr,
KeyStore: signer,
- Configs: solana.NewConfigs(singleChainCfg),
}
- chainSet, err := solana.NewChainSet(opts, singleChainCfg)
+
+ chain, err := solana.NewChain(chainCfg, opts)
if err != nil {
- return nil, fmt.Errorf("failed to load Solana chainset: %w", err)
+ return nil, err
}
- solanaRelayers[relayId] = relay.NewRelayerAdapter(pkgsolana.NewRelayer(solLggr, chainSet), chainSet)
+ solanaRelayers[relayId] = relay.NewRelayerServerAdapter(pkgsolana.NewRelayer(solLggr, chain), chain)
}
}
return solanaRelayers, nil
@@ -131,6 +153,8 @@ type StarkNetFactoryConfig struct {
starknet.StarknetConfigs
}
+// TODO BCF-2606 consider consolidating the driving logic with that of NewSolana above via generics
+// perhaps when we implement a Cosmos LOOP
func (r *RelayerFactory) NewStarkNet(ks keystore.StarkNet, chainCfgs starknet.StarknetConfigs) (map[relay.ID]loop.Relayer, error) {
starknetRelayers := make(map[relay.ID]loop.Relayer)
@@ -139,23 +163,33 @@ func (r *RelayerFactory) NewStarkNet(ks keystore.StarkNet, chainCfgs starknet.St
loopKs = &keystore.StarknetLooppSigner{StarkNet: ks}
)
+ unique := make(map[string]struct{})
// create one relayer per chain id
for _, chainCfg := range chainCfgs {
relayId := relay.ID{Network: relay.StarkNet, ChainID: relay.ChainID(*chainCfg.ChainID)}
- // all the lower level APIs expect chainsets. create a single valued set per id
- singleChainCfg := starknet.StarknetConfigs{chainCfg}
+ _, alreadyExists := unique[relayId.Name()]
+ if alreadyExists {
+ return nil, fmt.Errorf("duplicate chain definitions for %s", relayId.Name())
+ }
+ unique[relayId.Name()] = struct{}{}
+
+ // skip disabled chains from further processing
+ if !chainCfg.IsEnabled() {
+ starkLggr.Warnw("Skipping disabled chain", "id", chainCfg.ChainID)
+ continue
+ }
if cmdName := env.StarknetPluginCmd.Get(); cmdName != "" {
// setup the starknet relayer to be a LOOP
- tomls, err := toml.Marshal(struct {
- Starknet starknet.StarknetConfigs
- }{Starknet: singleChainCfg})
+ cfgTOML, err := toml.Marshal(struct {
+ Starknet starknet.StarknetConfig
+ }{Starknet: *chainCfg})
if err != nil {
return nil, fmt.Errorf("failed to marshal StarkNet configs: %w", err)
}
starknetCmdFn, err := plugins.NewCmdFactory(r.Register, plugins.CmdConfig{
- ID: starkLggr.Name(),
+ ID: relayId.Name(),
Cmd: cmdName,
})
if err != nil {
@@ -163,19 +197,20 @@ func (r *RelayerFactory) NewStarkNet(ks keystore.StarkNet, chainCfgs starknet.St
}
// the starknet relayer service has a delicate keystore dependency. the value that is passed to NewRelayerService must
// be compatible with instantiating a starknet transaction manager KeystoreAdapter within the LOOPp executable.
- starknetRelayers[relayId] = loop.NewRelayerService(starkLggr, r.GRPCOpts, starknetCmdFn, string(tomls), loopKs)
+ starknetRelayers[relayId] = loop.NewRelayerService(starkLggr, r.GRPCOpts, starknetCmdFn, string(cfgTOML), loopKs)
} else {
- // fallback to embedded chainset
- opts := starknet.ChainSetOpts{
+ // fallback to embedded chain
+ opts := starknet.ChainOpts{
Logger: starkLggr,
KeyStore: loopKs,
- Configs: starknet.NewConfigs(singleChainCfg),
}
- chainSet, err := starknet.NewChainSet(opts, singleChainCfg)
+
+ chain, err := starknet.NewChain(chainCfg, opts)
if err != nil {
- return nil, fmt.Errorf("failed to load StarkNet chainset: %w", err)
+ return nil, err
}
- starknetRelayers[relayId] = relay.NewRelayerAdapter(pkgstarknet.NewRelayer(starkLggr, chainSet), chainSet)
+
+ starknetRelayers[relayId] = relay.NewRelayerServerAdapter(pkgstarknet.NewRelayer(starkLggr, chain), chain)
}
}
return starknetRelayers, nil
@@ -186,33 +221,64 @@ 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 lggr = r.Logger.Named("Cosmos")
+ var (
+ lggr = r.Logger.Named("Cosmos")
+ loopKs = &keystore.CosmosLoopKeystore{Cosmos: config.Keystore}
+ )
// create one relayer per chain id
for _, chainCfg := range config.CosmosConfigs {
relayId := relay.ID{Network: relay.Cosmos, ChainID: relay.ChainID(*chainCfg.ChainID)}
- // all the lower level APIs expect chainsets. create a single valued set per id
- // TODO: Cosmos LOOPp impl. For now, use relayer adapter
-
- opts := cosmos.ChainSetOpts{
- QueryConfig: r.QConfig,
- Logger: lggr.Named(relayId.ChainID.String()),
- DB: r.DB,
- KeyStore: config.Keystore,
+
+ opts := cosmos.ChainOpts{
+ QueryConfig: config.QConfig,
+ Logger: lggr.Named(relayId.ChainID),
+ DB: config.DB,
+ KeyStore: loopKs,
EventBroadcaster: config.EventBroadcaster,
}
- opts.Configs = cosmos.NewConfigs(cosmos.CosmosConfigs{chainCfg})
- singleChainChainSet, err := cosmos.NewSingleChainSet(opts, chainCfg)
+
+ chain, err := cosmos.NewChain(chainCfg, opts)
if err != nil {
return nil, fmt.Errorf("failed to load Cosmos chain %q: %w", relayId, err)
}
- relayers[relayId] = cosmos.NewLoopRelayerSingleChain(pkgcosmos.NewRelayer(lggr, singleChainChainSet), singleChainChainSet)
+ relayers[relayId] = cosmos.NewLoopRelayerChain(pkgcosmos.NewRelayer(lggr, chain), chain)
}
return relayers, nil
diff --git a/core/services/chainlink/testdata/config-empty-effective.toml b/core/services/chainlink/testdata/config-empty-effective.toml
index 8c3eef53f6a..45e92a147d3 100644
--- a/core/services/chainlink/testdata/config-empty-effective.toml
+++ b/core/services/chainlink/testdata/config-empty-effective.toml
@@ -1,4 +1,3 @@
-ExplorerURL = ''
InsecureFastScrypt = false
RootDir = '~/.chainlink'
ShutdownGracePeriod = '5s'
diff --git a/core/services/chainlink/testdata/config-full.toml b/core/services/chainlink/testdata/config-full.toml
index 4279cc729f9..92d0b553d6e 100644
--- a/core/services/chainlink/testdata/config-full.toml
+++ b/core/services/chainlink/testdata/config-full.toml
@@ -1,4 +1,3 @@
-ExplorerURL = 'http://explorer.url'
InsecureFastScrypt = true
RootDir = 'test/root/dir'
ShutdownGracePeriod = '10s'
@@ -325,7 +324,7 @@ BlockRate = '1m0s'
BlocksUntilTxTimeout = 12
ConfirmPollPeriod = '1s'
FallbackGasPrice = '0.001'
-FeeToken = 'ucosm'
+GasToken = 'ucosm'
GasLimitMultiplier = '1.2'
MaxMsgsPerBatch = 17
OCR2CachePollPeriod = '1m0s'
diff --git a/core/services/chainlink/testdata/config-multi-chain-effective.toml b/core/services/chainlink/testdata/config-multi-chain-effective.toml
index d6b38349b83..665de9be8cb 100644
--- a/core/services/chainlink/testdata/config-multi-chain-effective.toml
+++ b/core/services/chainlink/testdata/config-multi-chain-effective.toml
@@ -1,4 +1,3 @@
-ExplorerURL = ''
InsecureFastScrypt = false
RootDir = 'my/root/dir'
ShutdownGracePeriod = '5s'
@@ -456,7 +455,7 @@ BlockRate = '6s'
BlocksUntilTxTimeout = 30
ConfirmPollPeriod = '1s'
FallbackGasPrice = '0.015'
-FeeToken = 'ucosm'
+GasToken = 'ucosm'
GasLimitMultiplier = '1.5'
MaxMsgsPerBatch = 13
OCR2CachePollPeriod = '4s'
@@ -474,7 +473,7 @@ BlockRate = '6s'
BlocksUntilTxTimeout = 20
ConfirmPollPeriod = '1s'
FallbackGasPrice = '0.015'
-FeeToken = 'ucosm'
+GasToken = 'ucosm'
GasLimitMultiplier = '1.5'
MaxMsgsPerBatch = 100
OCR2CachePollPeriod = '4s'
diff --git a/core/services/chainlink/testdata/mergingsecretsdata/secrets-explorer.toml b/core/services/chainlink/testdata/mergingsecretsdata/secrets-explorer.toml
deleted file mode 100644
index 6f0682240a8..00000000000
--- a/core/services/chainlink/testdata/mergingsecretsdata/secrets-explorer.toml
+++ /dev/null
@@ -1,3 +0,0 @@
-[Explorer]
-AccessKey = "EXPLORER_ACCESS_KEY"
-Secret = "EXPLORER_TOKEN"
\ No newline at end of file
diff --git a/core/services/chainlink/testdata/secrets-full-redacted.toml b/core/services/chainlink/testdata/secrets-full-redacted.toml
index c0c97b76e57..740c3250edb 100644
--- a/core/services/chainlink/testdata/secrets-full-redacted.toml
+++ b/core/services/chainlink/testdata/secrets-full-redacted.toml
@@ -3,10 +3,6 @@ URL = 'xxxxx'
BackupURL = 'xxxxx'
AllowSimplePasswords = false
-[Explorer]
-AccessKey = 'xxxxx'
-Secret = 'xxxxx'
-
[Password]
Keystore = 'xxxxx'
VRF = 'xxxxx'
@@ -28,3 +24,9 @@ Password = 'xxxxx'
URL = 'xxxxx'
Username = 'xxxxx'
Password = 'xxxxx'
+
+[Mercury.Credentials.cred3]
+LegacyURL = 'xxxxx'
+URL = 'xxxxx'
+Username = 'xxxxx'
+Password = 'xxxxx'
diff --git a/core/services/chainlink/testdata/secrets-full.toml b/core/services/chainlink/testdata/secrets-full.toml
index 3773a798f7e..37e5dafc7d7 100644
--- a/core/services/chainlink/testdata/secrets-full.toml
+++ b/core/services/chainlink/testdata/secrets-full.toml
@@ -2,10 +2,6 @@
URL = "postgresql://user:pass@localhost:5432/dbname?sslmode=disable"
BackupURL = "postgresql://user:pass@localhost:5432/backupdbname?sslmode=disable"
-[Explorer]
-AccessKey = "access_key"
-Secret = "secret"
-
[Password]
Keystore = "keystore_pass"
VRF = "VRF_pass"
@@ -25,3 +21,9 @@ Password = "password1"
URL = "https://chain2.link"
Username = "username2"
Password = "password2"
+
+[Mercury.Credentials.cred3]
+LegacyURL = "https://chain2.old.link"
+URL = "https://chain2.link"
+Username = "username2"
+Password = "password2"
diff --git a/core/services/chainlink/testdata/secrets-multi-redacted.toml b/core/services/chainlink/testdata/secrets-multi-redacted.toml
index 32e4b6fca34..27a1eb9fb6c 100644
--- a/core/services/chainlink/testdata/secrets-multi-redacted.toml
+++ b/core/services/chainlink/testdata/secrets-multi-redacted.toml
@@ -2,9 +2,5 @@
URL = 'xxxxx'
AllowSimplePasswords = false
-[Explorer]
-AccessKey = 'xxxxx'
-Secret = 'xxxxx'
-
[Password]
Keystore = 'xxxxx'
diff --git a/core/services/chainlink/testdata/secrets-multi.toml b/core/services/chainlink/testdata/secrets-multi.toml
index f497d20f307..23438f9e4ab 100644
--- a/core/services/chainlink/testdata/secrets-multi.toml
+++ b/core/services/chainlink/testdata/secrets-multi.toml
@@ -1,9 +1,5 @@
[Database]
URL = "postgresql://user:pass@localhost:5432/dbname?sslmode=disable"
-[Explorer]
-AccessKey = "access_key"
-Secret = "secret"
-
[Password]
Keystore = "keystore_pass"
diff --git a/core/services/checkable.go b/core/services/checkable.go
index 298e3dda471..a702f9f979d 100644
--- a/core/services/checkable.go
+++ b/core/services/checkable.go
@@ -10,4 +10,6 @@ type Checkable interface {
// HealthReport returns a full health report of the callee including it's dependencies.
// key is the dep name, value is nil if healthy, or error message otherwise.
HealthReport() map[string]error
+ // Name returns the fully qualified name of the component. Usually the logger name.
+ Name() string
}
diff --git a/core/services/cron/cron.go b/core/services/cron/cron.go
index 56c67096e50..e89dd1ceabd 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/cron/cron_test.go b/core/services/cron/cron_test.go
index 1d89248d4a5..174f80586ae 100644
--- a/core/services/cron/cron_test.go
+++ b/core/services/cron/cron_test.go
@@ -32,8 +32,7 @@ func TestCronV2Pipeline(t *testing.T) {
lggr := logger.TestLogger(t)
orm := pipeline.NewORM(db, lggr, cfg.Database(), cfg.JobPipeline().MaxSuccessfulRuns())
btORM := bridges.NewORM(db, lggr, cfg.Database())
- legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayerExtenders)
- require.NoError(t, err)
+ legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayerExtenders)
jobORM := job.NewORM(db, legacyChains, orm, btORM, keyStore, lggr, cfg.Database())
jb := &job.Job{
@@ -45,8 +44,7 @@ func TestCronV2Pipeline(t *testing.T) {
}
delegate := cron.NewDelegate(runner, lggr)
- err = jobORM.CreateJob(jb)
- require.NoError(t, err)
+ require.NoError(t, jobORM.CreateJob(jb))
serviceArray, err := delegate.ServicesForSpec(*jb)
require.NoError(t, err)
assert.Len(t, serviceArray, 1)
diff --git a/core/services/directrequest/delegate.go b/core/services/directrequest/delegate.go
index 4e2ca1e1899..39564b8c8bd 100644
--- a/core/services/directrequest/delegate.go
+++ b/core/services/directrequest/delegate.go
@@ -138,6 +138,12 @@ type listener struct {
utils.StartStopOnce
}
+func (l *listener) HealthReport() map[string]error {
+ return map[string]error{l.Name(): l.Healthy()}
+}
+
+func (l *listener) Name() string { return l.logger.Name() }
+
// Start complies with job.Service
func (l *listener) Start(context.Context) error {
return l.StartOnce("DirectRequestListener", func() error {
@@ -339,6 +345,7 @@ func (l *listener) handleOracleRequest(request *operator_wrapper.OperatorOracleR
ctx, cancel := runCloserChannel.NewCtx()
defer cancel()
+ evmChainID := lb.EVMChainID()
vars := pipeline.NewVarsFrom(map[string]interface{}{
"jobSpec": map[string]interface{}{
"databaseID": l.job.ID,
@@ -347,6 +354,7 @@ func (l *listener) handleOracleRequest(request *operator_wrapper.OperatorOracleR
"pipelineSpec": &pipeline.Spec{
ForwardingAllowed: l.job.ForwardingAllowed,
},
+ "evmChainID": evmChainID.String(),
},
"jobRun": map[string]interface{}{
"meta": meta,
@@ -362,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/directrequest/delegate_test.go b/core/services/directrequest/delegate_test.go
index 8a453dbe9db..ffd78443cc2 100644
--- a/core/services/directrequest/delegate_test.go
+++ b/core/services/directrequest/delegate_test.go
@@ -47,8 +47,7 @@ func TestDelegate_ServicesForSpec(t *testing.T) {
relayerExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: cfg, Client: ethClient, MailMon: mailMon, KeyStore: keyStore.Eth()})
lggr := logger.TestLogger(t)
- legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayerExtenders)
- require.NoError(t, err)
+ legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayerExtenders)
delegate := directrequest.NewDelegate(lggr, runner, nil, legacyChains, mailMon)
t.Run("Spec without DirectRequestSpec", func(t *testing.T) {
@@ -58,7 +57,7 @@ func TestDelegate_ServicesForSpec(t *testing.T) {
})
t.Run("Spec with DirectRequestSpec", func(t *testing.T) {
- spec := job.Job{DirectRequestSpec: &job.DirectRequestSpec{}, PipelineSpec: &pipeline.Spec{}}
+ spec := job.Job{DirectRequestSpec: &job.DirectRequestSpec{EVMChainID: (*utils.Big)(testutils.FixtureChainID)}, PipelineSpec: &pipeline.Spec{}}
services, err := delegate.ServicesForSpec(spec)
require.NoError(t, err)
assert.Len(t, services, 1)
@@ -89,8 +88,7 @@ func NewDirectRequestUniverseWithConfig(t *testing.T, cfg chainlink.GeneralConfi
lggr := logger.TestLogger(t)
orm := pipeline.NewORM(db, lggr, cfg.Database(), cfg.JobPipeline().MaxSuccessfulRuns())
btORM := bridges.NewORM(db, lggr, cfg.Database())
- legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
- require.NoError(t, err)
+ legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
jobORM := job.NewORM(db, legacyChains, orm, btORM, keyStore, lggr, cfg.Database())
delegate := directrequest.NewDelegate(lggr, runner, orm, legacyChains, mailMon)
@@ -99,8 +97,7 @@ func NewDirectRequestUniverseWithConfig(t *testing.T, cfg chainlink.GeneralConfi
if specF != nil {
specF(jb)
}
- err = jobORM.CreateJob(jb)
- require.NoError(t, err)
+ require.NoError(t, jobORM.CreateJob(jb))
serviceArray, err := delegate.ServicesForSpec(*jb)
require.NoError(t, err)
assert.Len(t, serviceArray, 1)
@@ -146,6 +143,7 @@ func TestDelegate_ServicesListenerHandleLog(t *testing.T) {
log.On("ReceiptsRoot").Return(common.Hash{})
log.On("TransactionsRoot").Return(common.Hash{})
log.On("StateRoot").Return(common.Hash{})
+ log.On("EVMChainID").Return(*big.NewInt(0))
uni.logBroadcaster.On("WasAlreadyConsumed", mock.Anything, mock.Anything).Return(false, nil)
logOracleRequest := operator_wrapper.OperatorOracleRequest{
@@ -206,6 +204,7 @@ func TestDelegate_ServicesListenerHandleLog(t *testing.T) {
}).Maybe()
log.On("DecodedLog").Return(&logOracleRequest).Maybe()
log.On("String").Return("")
+ log.On("EVMChainID").Return(*big.NewInt(0))
uni.logBroadcaster.On("MarkConsumed", mock.Anything, mock.Anything).Return(nil).Maybe()
err := uni.service.Start(testutils.Context(t))
@@ -298,6 +297,7 @@ func TestDelegate_ServicesListenerHandleLog(t *testing.T) {
runLog.On("ReceiptsRoot").Return(common.Hash{})
runLog.On("TransactionsRoot").Return(common.Hash{})
runLog.On("StateRoot").Return(common.Hash{})
+ runLog.On("EVMChainID").Return(*big.NewInt(0))
uni.logBroadcaster.On("WasAlreadyConsumed", mock.Anything, mock.Anything).Return(false, nil)
logOracleRequest := operator_wrapper.OperatorOracleRequest{
@@ -367,6 +367,7 @@ func TestDelegate_ServicesListenerHandleLog(t *testing.T) {
log.On("ReceiptsRoot").Return(common.Hash{})
log.On("TransactionsRoot").Return(common.Hash{})
log.On("StateRoot").Return(common.Hash{})
+ log.On("EVMChainID").Return(*big.NewInt(0))
uni.logBroadcaster.On("WasAlreadyConsumed", mock.Anything, mock.Anything).Return(false, nil)
logOracleRequest := operator_wrapper.OperatorOracleRequest{
@@ -459,6 +460,7 @@ func TestDelegate_ServicesListenerHandleLog(t *testing.T) {
log.On("ReceiptsRoot").Return(common.Hash{})
log.On("TransactionsRoot").Return(common.Hash{})
log.On("StateRoot").Return(common.Hash{})
+ log.On("EVMChainID").Return(*big.NewInt(0))
uni.logBroadcaster.On("WasAlreadyConsumed", mock.Anything, mock.Anything).Return(false, nil)
logOracleRequest := operator_wrapper.OperatorOracleRequest{
diff --git a/core/services/feeds/models.go b/core/services/feeds/models.go
index 345919d4ad8..8e30ca74b25 100644
--- a/core/services/feeds/models.go
+++ b/core/services/feeds/models.go
@@ -154,12 +154,13 @@ func (c *OCR1Config) Scan(value interface{}) error {
// OCR2ConfigModel defines configuration for OCR2 Jobs.
type OCR2ConfigModel struct {
- Enabled bool `json:"enabled"`
- IsBootstrap bool `json:"is_bootstrap"`
- Multiaddr null.String `json:"multiaddr"`
- P2PPeerID null.String `json:"p2p_peer_id"`
- KeyBundleID null.String `json:"key_bundle_id"`
- Plugins Plugins `json:"plugins"`
+ Enabled bool `json:"enabled"`
+ IsBootstrap bool `json:"is_bootstrap"`
+ Multiaddr null.String `json:"multiaddr"`
+ ForwarderAddress null.String `json:"forwarder_address"`
+ P2PPeerID null.String `json:"p2p_peer_id"`
+ KeyBundleID null.String `json:"key_bundle_id"`
+ Plugins Plugins `json:"plugins"`
}
func (c OCR2ConfigModel) Value() (driver.Value, error) {
@@ -250,6 +251,8 @@ type JobProposalCounts struct {
Cancelled int64
Approved int64
Rejected int64
+ Deleted int64
+ Revoked int64
}
// toMetrics transforms JobProposalCounts into a map with float64 values for setting metrics
diff --git a/core/services/feeds/models_test.go b/core/services/feeds/models_test.go
index eb025699525..67d669b85f4 100644
--- a/core/services/feeds/models_test.go
+++ b/core/services/feeds/models_test.go
@@ -283,11 +283,12 @@ func Test_OCR2Config_Value(t *testing.T) {
var (
give = OCR2ConfigModel{
- Enabled: true,
- IsBootstrap: false,
- Multiaddr: null.StringFrom("multiaddr"),
- P2PPeerID: null.StringFrom("peerid"),
- KeyBundleID: null.StringFrom("ocrkeyid"),
+ Enabled: true,
+ IsBootstrap: false,
+ Multiaddr: null.StringFrom("multiaddr"),
+ ForwarderAddress: null.StringFrom("forwarderaddress"),
+ P2PPeerID: null.StringFrom("peerid"),
+ KeyBundleID: null.StringFrom("ocrkeyid"),
Plugins: Plugins{
Commit: true,
Execute: true,
@@ -295,7 +296,7 @@ func Test_OCR2Config_Value(t *testing.T) {
Mercury: true,
},
}
- want = `{"enabled":true,"is_bootstrap":false,"multiaddr":"multiaddr","p2p_peer_id":"peerid","key_bundle_id":"ocrkeyid","plugins":{"commit":true,"execute":true,"median":false,"mercury":true}}`
+ want = `{"enabled":true,"is_bootstrap":false,"multiaddr":"multiaddr","forwarder_address":"forwarderaddress","p2p_peer_id":"peerid","key_bundle_id":"ocrkeyid","plugins":{"commit":true,"execute":true,"median":false,"mercury":true}}`
)
val, err := give.Value()
@@ -311,13 +312,14 @@ func Test_OCR2Config_Scan(t *testing.T) {
t.Parallel()
var (
- give = `{"enabled":true,"is_bootstrap":false,"multiaddr":"multiaddr","p2p_peer_id":"peerid","key_bundle_id":"ocrkeyid","plugins":{"commit":true,"execute":true,"median":false,"mercury":true}}`
+ give = `{"enabled":true,"is_bootstrap":false,"multiaddr":"multiaddr","forwarder_address":"forwarderaddress","p2p_peer_id":"peerid","key_bundle_id":"ocrkeyid","plugins":{"commit":true,"execute":true,"median":false,"mercury":true}}`
want = OCR2ConfigModel{
- Enabled: true,
- IsBootstrap: false,
- Multiaddr: null.StringFrom("multiaddr"),
- P2PPeerID: null.StringFrom("peerid"),
- KeyBundleID: null.StringFrom("ocrkeyid"),
+ Enabled: true,
+ IsBootstrap: false,
+ Multiaddr: null.StringFrom("multiaddr"),
+ ForwarderAddress: null.StringFrom("forwarderaddress"),
+ P2PPeerID: null.StringFrom("peerid"),
+ KeyBundleID: null.StringFrom("ocrkeyid"),
Plugins: Plugins{
Commit: true,
Execute: true,
diff --git a/core/services/feeds/orm.go b/core/services/feeds/orm.go
index dd04446bce9..b0b0bb38b55 100644
--- a/core/services/feeds/orm.go
+++ b/core/services/feeds/orm.go
@@ -325,6 +325,8 @@ SELECT
COUNT(*) filter (where job_proposals.status = 'pending' OR job_proposals.pending_update = TRUE) as pending,
COUNT(*) filter (where job_proposals.status = 'approved' AND job_proposals.pending_update = FALSE) as approved,
COUNT(*) filter (where job_proposals.status = 'rejected' AND job_proposals.pending_update = FALSE) as rejected,
+ COUNT(*) filter (where job_proposals.status = 'revoked' AND job_proposals.pending_update = FALSE) as revoked,
+ COUNT(*) filter (where job_proposals.status = 'deleted' AND job_proposals.pending_update = FALSE) as deleted,
COUNT(*) filter (where job_proposals.status = 'cancelled' AND job_proposals.pending_update = FALSE) as cancelled
FROM job_proposals;
`
diff --git a/core/services/feeds/orm_test.go b/core/services/feeds/orm_test.go
index 0ff60188008..f2dacc4f02f 100644
--- a/core/services/feeds/orm_test.go
+++ b/core/services/feeds/orm_test.go
@@ -575,8 +575,8 @@ func Test_ORM_CountJobProposalsByStatus(t *testing.T) {
fmID = createFeedsManager(t, orm)
// Set initial values for job proposal counts
- wantApproved, wantRejected int64
- wantPending, wantCancelled = int64(1), int64(1)
+ wantApproved, wantRejected, wantDeleted, wantRevoked int64
+ wantPending, wantCancelled = int64(1), int64(1)
)
// Create a pending job proposal.
@@ -604,6 +604,8 @@ func Test_ORM_CountJobProposalsByStatus(t *testing.T) {
assert.Equal(t, wantApproved, counts.Approved)
assert.Equal(t, wantRejected, counts.Rejected)
assert.Equal(t, wantCancelled, counts.Cancelled)
+ assert.Equal(t, wantDeleted, counts.Deleted)
+ assert.Equal(t, wantRevoked, counts.Revoked)
// Upsert the cancelled job proposal to rejected
// which changes pending_update to TRUE, but leaves status as
@@ -630,6 +632,8 @@ func Test_ORM_CountJobProposalsByStatus(t *testing.T) {
assert.Equal(t, wantApproved, counts.Approved)
assert.Equal(t, wantRejected, counts.Rejected)
assert.Equal(t, wantCancelled, counts.Cancelled)
+ assert.Equal(t, wantDeleted, counts.Deleted)
+ assert.Equal(t, wantRevoked, counts.Revoked)
}
func Test_ORM_ListJobProposalByManagersIDs(t *testing.T) {
@@ -1475,8 +1479,7 @@ func createJob(t *testing.T, db *sqlx.DB, externalJobID uuid.UUID) *job.Job {
bridgeORM = bridges.NewORM(db, lggr, config.Database())
relayExtenders = evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()})
)
- legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
- require.NoError(t, err)
+ legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
orm := job.NewORM(db, legacyChains, pipelineORM, bridgeORM, keyStore, lggr, config.Database())
require.NoError(t, keyStore.OCR().Add(cltest.DefaultOCRKey))
require.NoError(t, keyStore.P2P().Add(cltest.DefaultP2PKey))
diff --git a/core/services/feeds/proto/feeds_manager.pb.go b/core/services/feeds/proto/feeds_manager.pb.go
index b02c2b77601..77ab4289e42 100644
--- a/core/services/feeds/proto/feeds_manager.pb.go
+++ b/core/services/feeds/proto/feeds_manager.pb.go
@@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.29.0
+// protoc-gen-go v1.31.0
// protoc v3.21.7
// source: pkg/noderpc/proto/feeds_manager.proto
@@ -375,12 +375,13 @@ type OCR2Config struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
- Enabled bool `protobuf:"varint,1,opt,name=enabled,proto3" json:"enabled,omitempty"`
- IsBootstrap bool `protobuf:"varint,2,opt,name=is_bootstrap,json=isBootstrap,proto3" json:"is_bootstrap,omitempty"`
- P2PKeyBundle *OCR2Config_P2PKeyBundle `protobuf:"bytes,3,opt,name=p2p_key_bundle,json=p2pKeyBundle,proto3" json:"p2p_key_bundle,omitempty"`
- OcrKeyBundle *OCR2Config_OCRKeyBundle `protobuf:"bytes,4,opt,name=ocr_key_bundle,json=ocrKeyBundle,proto3" json:"ocr_key_bundle,omitempty"`
- Multiaddr string `protobuf:"bytes,5,opt,name=multiaddr,proto3" json:"multiaddr,omitempty"`
- Plugins *OCR2Config_Plugins `protobuf:"bytes,6,opt,name=plugins,proto3" json:"plugins,omitempty"`
+ Enabled bool `protobuf:"varint,1,opt,name=enabled,proto3" json:"enabled,omitempty"`
+ IsBootstrap bool `protobuf:"varint,2,opt,name=is_bootstrap,json=isBootstrap,proto3" json:"is_bootstrap,omitempty"`
+ P2PKeyBundle *OCR2Config_P2PKeyBundle `protobuf:"bytes,3,opt,name=p2p_key_bundle,json=p2pKeyBundle,proto3" json:"p2p_key_bundle,omitempty"`
+ OcrKeyBundle *OCR2Config_OCRKeyBundle `protobuf:"bytes,4,opt,name=ocr_key_bundle,json=ocrKeyBundle,proto3" json:"ocr_key_bundle,omitempty"`
+ Multiaddr string `protobuf:"bytes,5,opt,name=multiaddr,proto3" json:"multiaddr,omitempty"`
+ Plugins *OCR2Config_Plugins `protobuf:"bytes,6,opt,name=plugins,proto3" json:"plugins,omitempty"`
+ ForwarderAddress *string `protobuf:"bytes,7,opt,name=forwarder_address,json=forwarderAddress,proto3,oneof" json:"forwarder_address,omitempty"`
}
func (x *OCR2Config) Reset() {
@@ -457,6 +458,13 @@ func (x *OCR2Config) GetPlugins() *OCR2Config_Plugins {
return nil
}
+func (x *OCR2Config) GetForwarderAddress() string {
+ if x != nil && x.ForwarderAddress != nil {
+ return *x.ForwarderAddress
+ }
+ return ""
+}
+
type ChainConfig struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@@ -1736,7 +1744,7 @@ var file_pkg_noderpc_proto_feeds_manager_proto_rawDesc = []byte{
0x6e, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x5f, 0x61,
0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x15, 0x6f, 0x6e,
0x63, 0x68, 0x61, 0x69, 0x6e, 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x41, 0x64, 0x64, 0x72,
- 0x65, 0x73, 0x73, 0x22, 0x9b, 0x05, 0x0a, 0x0a, 0x4f, 0x43, 0x52, 0x32, 0x43, 0x6f, 0x6e, 0x66,
+ 0x65, 0x73, 0x73, 0x22, 0xe3, 0x05, 0x0a, 0x0a, 0x4f, 0x43, 0x52, 0x32, 0x43, 0x6f, 0x6e, 0x66,
0x69, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20,
0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x21, 0x0a, 0x0c,
0x69, 0x73, 0x5f, 0x62, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x18, 0x02, 0x20, 0x01,
@@ -1754,166 +1762,170 @@ var file_pkg_noderpc_proto_feeds_manager_proto_rawDesc = []byte{
0x69, 0x61, 0x64, 0x64, 0x72, 0x12, 0x31, 0x0a, 0x07, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x73,
0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x66, 0x6d, 0x2e, 0x4f, 0x43, 0x52,
0x32, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x73, 0x52,
- 0x07, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x73, 0x1a, 0x46, 0x0a, 0x0c, 0x50, 0x32, 0x50, 0x4b,
- 0x65, 0x79, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x70, 0x65, 0x65, 0x72,
- 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x65, 0x65, 0x72, 0x49,
- 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18,
- 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79,
- 0x1a, 0xbf, 0x01, 0x0a, 0x0c, 0x4f, 0x43, 0x52, 0x4b, 0x65, 0x79, 0x42, 0x75, 0x6e, 0x64, 0x6c,
- 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01,
- 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x49, 0x64, 0x12, 0x2a,
- 0x0a, 0x11, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f,
- 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x63, 0x6f, 0x6e, 0x66, 0x69,
- 0x67, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x2e, 0x0a, 0x13, 0x6f, 0x66,
- 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65,
- 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x6f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69,
- 0x6e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x36, 0x0a, 0x17, 0x6f, 0x6e,
- 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x5f, 0x61, 0x64,
- 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x15, 0x6f, 0x6e, 0x63,
- 0x68, 0x61, 0x69, 0x6e, 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x41, 0x64, 0x64, 0x72, 0x65,
- 0x73, 0x73, 0x1a, 0x6d, 0x0a, 0x07, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x73, 0x12, 0x16, 0x0a,
- 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x63,
- 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65,
- 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x12,
- 0x16, 0x0a, 0x06, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52,
- 0x06, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x72, 0x63, 0x75,
- 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x6d, 0x65, 0x72, 0x63, 0x75, 0x72,
- 0x79, 0x22, 0xa9, 0x02, 0x0a, 0x0b, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69,
- 0x67, 0x12, 0x20, 0x0a, 0x05, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
- 0x32, 0x0a, 0x2e, 0x63, 0x66, 0x6d, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x52, 0x05, 0x63, 0x68,
- 0x61, 0x69, 0x6e, 0x12, 0x27, 0x0a, 0x0f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x61,
- 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x61, 0x63,
- 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x23, 0x0a, 0x0d,
- 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20,
- 0x01, 0x28, 0x09, 0x52, 0x0c, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73,
- 0x73, 0x12, 0x46, 0x0a, 0x13, 0x66, 0x6c, 0x75, 0x78, 0x5f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f,
- 0x72, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16,
- 0x2e, 0x63, 0x66, 0x6d, 0x2e, 0x46, 0x6c, 0x75, 0x78, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72,
- 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x11, 0x66, 0x6c, 0x75, 0x78, 0x4d, 0x6f, 0x6e, 0x69,
- 0x74, 0x6f, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x30, 0x0a, 0x0b, 0x6f, 0x63, 0x72,
- 0x31, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f,
- 0x2e, 0x63, 0x66, 0x6d, 0x2e, 0x4f, 0x43, 0x52, 0x31, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52,
- 0x0a, 0x6f, 0x63, 0x72, 0x31, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x30, 0x0a, 0x0b, 0x6f,
- 0x63, 0x72, 0x32, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b,
- 0x32, 0x0f, 0x2e, 0x63, 0x66, 0x6d, 0x2e, 0x4f, 0x43, 0x52, 0x32, 0x43, 0x6f, 0x6e, 0x66, 0x69,
- 0x67, 0x52, 0x0a, 0x6f, 0x63, 0x72, 0x32, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x9f, 0x03,
- 0x0a, 0x11, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75,
- 0x65, 0x73, 0x74, 0x12, 0x29, 0x0a, 0x09, 0x6a, 0x6f, 0x62, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73,
- 0x18, 0x01, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x0c, 0x2e, 0x63, 0x66, 0x6d, 0x2e, 0x4a, 0x6f, 0x62,
- 0x54, 0x79, 0x70, 0x65, 0x52, 0x08, 0x6a, 0x6f, 0x62, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x19,
- 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03,
- 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x2b, 0x0a, 0x11, 0x61, 0x63, 0x63,
- 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x03,
- 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x64, 0x64,
- 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x69, 0x73, 0x5f, 0x62, 0x6f, 0x6f,
- 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x5f, 0x70, 0x65, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28,
- 0x08, 0x52, 0x0f, 0x69, 0x73, 0x42, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x50, 0x65,
- 0x65, 0x72, 0x12, 0x2f, 0x0a, 0x13, 0x62, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x5f,
- 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x61, 0x64, 0x64, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52,
- 0x12, 0x62, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x61,
- 0x64, 0x64, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x06,
- 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1b, 0x0a,
- 0x09, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x03,
- 0x52, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x73, 0x12, 0x28, 0x0a, 0x08, 0x61, 0x63,
- 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x63,
- 0x66, 0x6d, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x08, 0x61, 0x63, 0x63, 0x6f,
- 0x75, 0x6e, 0x74, 0x73, 0x12, 0x22, 0x0a, 0x06, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x73, 0x18, 0x09,
- 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x63, 0x66, 0x6d, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e,
- 0x52, 0x06, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x73, 0x12, 0x35, 0x0a, 0x0d, 0x63, 0x68, 0x61, 0x69,
- 0x6e, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0b, 0x32,
- 0x10, 0x2e, 0x63, 0x66, 0x6d, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69,
- 0x67, 0x52, 0x0c, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x22,
- 0x14, 0x0a, 0x12, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73,
- 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x42, 0x0a, 0x12, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65,
- 0x64, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x75,
- 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x12,
- 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03,
- 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x15, 0x0a, 0x13, 0x41, 0x70, 0x70,
- 0x72, 0x6f, 0x76, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
- 0x22, 0x14, 0x0a, 0x12, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x52,
- 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x15, 0x0a, 0x13, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68,
- 0x63, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x42, 0x0a,
- 0x12, 0x52, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75,
+ 0x07, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x73, 0x12, 0x30, 0x0a, 0x11, 0x66, 0x6f, 0x72, 0x77,
+ 0x61, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x07, 0x20,
+ 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x10, 0x66, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x65, 0x72,
+ 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x88, 0x01, 0x01, 0x1a, 0x46, 0x0a, 0x0c, 0x50, 0x32,
+ 0x50, 0x4b, 0x65, 0x79, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x70, 0x65,
+ 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x65, 0x65,
+ 0x72, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65,
+ 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b,
+ 0x65, 0x79, 0x1a, 0xbf, 0x01, 0x0a, 0x0c, 0x4f, 0x43, 0x52, 0x4b, 0x65, 0x79, 0x42, 0x75, 0x6e,
+ 0x64, 0x6c, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x5f, 0x69, 0x64,
+ 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x49, 0x64,
+ 0x12, 0x2a, 0x0a, 0x11, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69,
+ 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x63, 0x6f, 0x6e,
+ 0x66, 0x69, 0x67, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x2e, 0x0a, 0x13,
+ 0x6f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f,
+ 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x6f, 0x66, 0x66, 0x63, 0x68,
+ 0x61, 0x69, 0x6e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x36, 0x0a, 0x17,
+ 0x6f, 0x6e, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x5f,
+ 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x15, 0x6f,
+ 0x6e, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x41, 0x64, 0x64,
+ 0x72, 0x65, 0x73, 0x73, 0x1a, 0x6d, 0x0a, 0x07, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x73, 0x12,
+ 0x16, 0x0a, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52,
+ 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x78, 0x65, 0x63, 0x75,
+ 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74,
+ 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28,
+ 0x08, 0x52, 0x06, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x72,
+ 0x63, 0x75, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x6d, 0x65, 0x72, 0x63,
+ 0x75, 0x72, 0x79, 0x42, 0x14, 0x0a, 0x12, 0x5f, 0x66, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x65,
+ 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0xa9, 0x02, 0x0a, 0x0b, 0x43, 0x68,
+ 0x61, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x20, 0x0a, 0x05, 0x63, 0x68, 0x61,
+ 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x63, 0x66, 0x6d, 0x2e, 0x43,
+ 0x68, 0x61, 0x69, 0x6e, 0x52, 0x05, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x12, 0x27, 0x0a, 0x0f, 0x61,
+ 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02,
+ 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x64, 0x64,
+ 0x72, 0x65, 0x73, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x5f, 0x61, 0x64,
+ 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x61, 0x64, 0x6d,
+ 0x69, 0x6e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x46, 0x0a, 0x13, 0x66, 0x6c, 0x75,
+ 0x78, 0x5f, 0x6d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
+ 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x63, 0x66, 0x6d, 0x2e, 0x46, 0x6c, 0x75,
+ 0x78, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x11,
+ 0x66, 0x6c, 0x75, 0x78, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69,
+ 0x67, 0x12, 0x30, 0x0a, 0x0b, 0x6f, 0x63, 0x72, 0x31, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
+ 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x63, 0x66, 0x6d, 0x2e, 0x4f, 0x43, 0x52,
+ 0x31, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0a, 0x6f, 0x63, 0x72, 0x31, 0x43, 0x6f, 0x6e,
+ 0x66, 0x69, 0x67, 0x12, 0x30, 0x0a, 0x0b, 0x6f, 0x63, 0x72, 0x32, 0x5f, 0x63, 0x6f, 0x6e, 0x66,
+ 0x69, 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x63, 0x66, 0x6d, 0x2e, 0x4f,
+ 0x43, 0x52, 0x32, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0a, 0x6f, 0x63, 0x72, 0x32, 0x43,
+ 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x9f, 0x03, 0x0a, 0x11, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65,
+ 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x29, 0x0a, 0x09, 0x6a,
+ 0x6f, 0x62, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x0c,
+ 0x2e, 0x63, 0x66, 0x6d, 0x2e, 0x4a, 0x6f, 0x62, 0x54, 0x79, 0x70, 0x65, 0x52, 0x08, 0x6a, 0x6f,
+ 0x62, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f,
+ 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49,
+ 0x64, 0x12, 0x2b, 0x0a, 0x11, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x61, 0x64, 0x64,
+ 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x61, 0x63,
+ 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x12, 0x2a,
+ 0x0a, 0x11, 0x69, 0x73, 0x5f, 0x62, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x5f, 0x70,
+ 0x65, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x69, 0x73, 0x42, 0x6f, 0x6f,
+ 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x50, 0x65, 0x65, 0x72, 0x12, 0x2f, 0x0a, 0x13, 0x62, 0x6f,
+ 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x5f, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x61, 0x64, 0x64,
+ 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x62, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72,
+ 0x61, 0x70, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x61, 0x64, 0x64, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x76,
+ 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65,
+ 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69,
+ 0x64, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x03, 0x52, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49,
+ 0x64, 0x73, 0x12, 0x28, 0x0a, 0x08, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x18, 0x08,
+ 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x63, 0x66, 0x6d, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75,
+ 0x6e, 0x74, 0x52, 0x08, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x12, 0x22, 0x0a, 0x06,
+ 0x63, 0x68, 0x61, 0x69, 0x6e, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x63,
+ 0x66, 0x6d, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x52, 0x06, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x73,
+ 0x12, 0x35, 0x0a, 0x0d, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
+ 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x63, 0x66, 0x6d, 0x2e, 0x43, 0x68,
+ 0x61, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0c, 0x63, 0x68, 0x61, 0x69, 0x6e,
+ 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x22, 0x14, 0x0a, 0x12, 0x55, 0x70, 0x64, 0x61, 0x74,
+ 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x42, 0x0a,
+ 0x12, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75,
0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69,
0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f,
- 0x6e, 0x22, 0x15, 0x0a, 0x13, 0x52, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x65, 0x64, 0x4a, 0x6f, 0x62,
- 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x43, 0x0a, 0x13, 0x43, 0x61, 0x6e, 0x63,
- 0x65, 0x6c, 0x6c, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
- 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75,
- 0x75, 0x69, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02,
- 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x16, 0x0a,
- 0x14, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x6c, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73,
- 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x71, 0x0a, 0x11, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65,
- 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64,
- 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x70,
- 0x65, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x73, 0x70, 0x65, 0x63, 0x12, 0x1e,
- 0x0a, 0x0a, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x61, 0x64, 0x64, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03,
- 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x61, 0x64, 0x64, 0x72, 0x73, 0x12, 0x18,
- 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52,
- 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x24, 0x0a, 0x12, 0x50, 0x72, 0x6f, 0x70,
- 0x6f, 0x73, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e,
- 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x22,
- 0x0a, 0x10, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65,
+ 0x6e, 0x22, 0x15, 0x0a, 0x13, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x64, 0x4a, 0x6f, 0x62,
+ 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x14, 0x0a, 0x12, 0x48, 0x65, 0x61, 0x6c,
+ 0x74, 0x68, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x15,
+ 0x0a, 0x13, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73,
+ 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x42, 0x0a, 0x12, 0x52, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x65,
+ 0x64, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x75,
+ 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x12,
+ 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03,
+ 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x15, 0x0a, 0x13, 0x52, 0x65, 0x6a,
+ 0x65, 0x63, 0x74, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
+ 0x22, 0x43, 0x0a, 0x13, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x6c, 0x65, 0x64, 0x4a, 0x6f, 0x62,
+ 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18,
+ 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x76,
+ 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x76, 0x65,
+ 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x16, 0x0a, 0x14, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x6c,
+ 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x71, 0x0a,
+ 0x11, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02,
- 0x69, 0x64, 0x22, 0x23, 0x0a, 0x11, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4a, 0x6f, 0x62, 0x52,
- 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20,
- 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x22, 0x0a, 0x10, 0x52, 0x65, 0x76, 0x6f, 0x6b,
- 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69,
- 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x23, 0x0a, 0x11, 0x52,
- 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
- 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64,
- 0x2a, 0x63, 0x0a, 0x07, 0x4a, 0x6f, 0x62, 0x54, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x14, 0x4a,
- 0x4f, 0x42, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46,
- 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x19, 0x0a, 0x15, 0x4a, 0x4f, 0x42, 0x5f, 0x54, 0x59, 0x50,
- 0x45, 0x5f, 0x46, 0x4c, 0x55, 0x58, 0x5f, 0x4d, 0x4f, 0x4e, 0x49, 0x54, 0x4f, 0x52, 0x10, 0x01,
- 0x12, 0x10, 0x0a, 0x0c, 0x4a, 0x4f, 0x42, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4f, 0x43, 0x52,
- 0x10, 0x02, 0x12, 0x11, 0x0a, 0x0d, 0x4a, 0x4f, 0x42, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4f,
- 0x43, 0x52, 0x32, 0x10, 0x03, 0x2a, 0x52, 0x0a, 0x09, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x54, 0x79,
- 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x16, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45,
- 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x12,
- 0x0a, 0x0e, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x45, 0x56, 0x4d,
- 0x10, 0x01, 0x12, 0x15, 0x0a, 0x11, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45,
- 0x5f, 0x53, 0x4f, 0x4c, 0x41, 0x4e, 0x41, 0x10, 0x02, 0x32, 0xd8, 0x02, 0x0a, 0x0c, 0x46, 0x65,
- 0x65, 0x64, 0x73, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x12, 0x40, 0x0a, 0x0b, 0x41, 0x70,
- 0x70, 0x72, 0x6f, 0x76, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x12, 0x17, 0x2e, 0x63, 0x66, 0x6d, 0x2e,
- 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65,
- 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x63, 0x66, 0x6d, 0x2e, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65,
- 0x64, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, 0x0b,
- 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x12, 0x17, 0x2e, 0x63, 0x66,
- 0x6d, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x71,
- 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x63, 0x66, 0x6d, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74,
- 0x68, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3d,
- 0x0a, 0x0a, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x16, 0x2e, 0x63,
- 0x66, 0x6d, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71,
- 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x63, 0x66, 0x6d, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74,
- 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a,
- 0x0b, 0x52, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x12, 0x17, 0x2e, 0x63,
- 0x66, 0x6d, 0x2e, 0x52, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x52, 0x65,
- 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x63, 0x66, 0x6d, 0x2e, 0x52, 0x65, 0x6a, 0x65,
- 0x63, 0x74, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
- 0x43, 0x0a, 0x0c, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x6c, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x12,
- 0x18, 0x2e, 0x63, 0x66, 0x6d, 0x2e, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x6c, 0x65, 0x64, 0x4a,
- 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x63, 0x66, 0x6d, 0x2e,
- 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x6c, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70,
- 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xc4, 0x01, 0x0a, 0x0b, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x65, 0x72,
- 0x76, 0x69, 0x63, 0x65, 0x12, 0x3d, 0x0a, 0x0a, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x4a,
- 0x6f, 0x62, 0x12, 0x16, 0x2e, 0x63, 0x66, 0x6d, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65,
- 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x63, 0x66, 0x6d,
- 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f,
- 0x6e, 0x73, 0x65, 0x12, 0x3a, 0x0a, 0x09, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4a, 0x6f, 0x62,
- 0x12, 0x15, 0x2e, 0x63, 0x66, 0x6d, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4a, 0x6f, 0x62,
- 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x63, 0x66, 0x6d, 0x2e, 0x44, 0x65,
+ 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
+ 0x52, 0x04, 0x73, 0x70, 0x65, 0x63, 0x12, 0x1e, 0x0a, 0x0a, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x61,
+ 0x64, 0x64, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x75, 0x6c, 0x74,
+ 0x69, 0x61, 0x64, 0x64, 0x72, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f,
+ 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
+ 0x22, 0x24, 0x0a, 0x12, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65,
+ 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01,
+ 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x22, 0x0a, 0x10, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65,
+ 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64,
+ 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x23, 0x0a, 0x11, 0x44, 0x65,
0x6c, 0x65, 0x74, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
- 0x3a, 0x0a, 0x09, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x4a, 0x6f, 0x62, 0x12, 0x15, 0x2e, 0x63,
- 0x66, 0x6d, 0x2e, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75,
- 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x63, 0x66, 0x6d, 0x2e, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65,
- 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x3d, 0x5a, 0x3b, 0x67,
- 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x6d, 0x61, 0x72, 0x74, 0x63,
- 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x6b, 0x69, 0x74, 0x2f, 0x66, 0x65, 0x65, 0x64, 0x73,
- 0x2d, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x6e, 0x6f, 0x64,
- 0x65, 0x72, 0x70, 0x63, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
- 0x6f, 0x33,
+ 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22,
+ 0x22, 0x0a, 0x10, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75,
+ 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
+ 0x02, 0x69, 0x64, 0x22, 0x23, 0x0a, 0x11, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x4a, 0x6f, 0x62,
+ 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01,
+ 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x2a, 0x63, 0x0a, 0x07, 0x4a, 0x6f, 0x62, 0x54,
+ 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x14, 0x4a, 0x4f, 0x42, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f,
+ 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x19, 0x0a,
+ 0x15, 0x4a, 0x4f, 0x42, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x46, 0x4c, 0x55, 0x58, 0x5f, 0x4d,
+ 0x4f, 0x4e, 0x49, 0x54, 0x4f, 0x52, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x4a, 0x4f, 0x42, 0x5f,
+ 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4f, 0x43, 0x52, 0x10, 0x02, 0x12, 0x11, 0x0a, 0x0d, 0x4a, 0x4f,
+ 0x42, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4f, 0x43, 0x52, 0x32, 0x10, 0x03, 0x2a, 0x52, 0x0a,
+ 0x09, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x16, 0x43, 0x48,
+ 0x41, 0x49, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49,
+ 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f,
+ 0x54, 0x59, 0x50, 0x45, 0x5f, 0x45, 0x56, 0x4d, 0x10, 0x01, 0x12, 0x15, 0x0a, 0x11, 0x43, 0x48,
+ 0x41, 0x49, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x4f, 0x4c, 0x41, 0x4e, 0x41, 0x10,
+ 0x02, 0x32, 0xd8, 0x02, 0x0a, 0x0c, 0x46, 0x65, 0x65, 0x64, 0x73, 0x4d, 0x61, 0x6e, 0x61, 0x67,
+ 0x65, 0x72, 0x12, 0x40, 0x0a, 0x0b, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x64, 0x4a, 0x6f,
+ 0x62, 0x12, 0x17, 0x2e, 0x63, 0x66, 0x6d, 0x2e, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x64,
+ 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x63, 0x66, 0x6d,
+ 0x2e, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70,
+ 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, 0x0b, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x63, 0x68,
+ 0x65, 0x63, 0x6b, 0x12, 0x17, 0x2e, 0x63, 0x66, 0x6d, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68,
+ 0x63, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x63,
+ 0x66, 0x6d, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65,
+ 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3d, 0x0a, 0x0a, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65,
+ 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x16, 0x2e, 0x63, 0x66, 0x6d, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74,
+ 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x63,
+ 0x66, 0x6d, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73,
+ 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, 0x0b, 0x52, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x65,
+ 0x64, 0x4a, 0x6f, 0x62, 0x12, 0x17, 0x2e, 0x63, 0x66, 0x6d, 0x2e, 0x52, 0x65, 0x6a, 0x65, 0x63,
+ 0x74, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e,
+ 0x63, 0x66, 0x6d, 0x2e, 0x52, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x52,
+ 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x43, 0x0a, 0x0c, 0x43, 0x61, 0x6e, 0x63, 0x65,
+ 0x6c, 0x6c, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x12, 0x18, 0x2e, 0x63, 0x66, 0x6d, 0x2e, 0x43, 0x61,
+ 0x6e, 0x63, 0x65, 0x6c, 0x6c, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
+ 0x74, 0x1a, 0x19, 0x2e, 0x63, 0x66, 0x6d, 0x2e, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x6c, 0x65,
+ 0x64, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xc4, 0x01, 0x0a,
+ 0x0b, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x3d, 0x0a, 0x0a,
+ 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x4a, 0x6f, 0x62, 0x12, 0x16, 0x2e, 0x63, 0x66, 0x6d,
+ 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65,
+ 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x63, 0x66, 0x6d, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65,
+ 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3a, 0x0a, 0x09, 0x44,
+ 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4a, 0x6f, 0x62, 0x12, 0x15, 0x2e, 0x63, 0x66, 0x6d, 0x2e, 0x44,
+ 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
+ 0x16, 0x2e, 0x63, 0x66, 0x6d, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4a, 0x6f, 0x62, 0x52,
+ 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3a, 0x0a, 0x09, 0x52, 0x65, 0x76, 0x6f, 0x6b,
+ 0x65, 0x4a, 0x6f, 0x62, 0x12, 0x15, 0x2e, 0x63, 0x66, 0x6d, 0x2e, 0x52, 0x65, 0x76, 0x6f, 0x6b,
+ 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x63, 0x66,
+ 0x6d, 0x2e, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f,
+ 0x6e, 0x73, 0x65, 0x42, 0x3d, 0x5a, 0x3b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f,
+ 0x6d, 0x2f, 0x73, 0x6d, 0x61, 0x72, 0x74, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x6b,
+ 0x69, 0x74, 0x2f, 0x66, 0x65, 0x65, 0x64, 0x73, 0x2d, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72,
+ 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x6e, 0x6f, 0x64, 0x65, 0x72, 0x70, 0x63, 0x2f, 0x70, 0x72, 0x6f,
+ 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@@ -2331,6 +2343,7 @@ func file_pkg_noderpc_proto_feeds_manager_proto_init() {
}
}
}
+ file_pkg_noderpc_proto_feeds_manager_proto_msgTypes[4].OneofWrappers = []interface{}{}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
diff --git a/core/services/feeds/service.go b/core/services/feeds/service.go
index ca0dcbb06cc..890cb586910 100644
--- a/core/services/feeds/service.go
+++ b/core/services/feeds/service.go
@@ -450,6 +450,10 @@ func (s *service) DeleteJob(ctx context.Context, args *DeleteJobArgs) (int64, er
return 0, errors.Wrap(err, "DeleteProposal failed")
}
+ if err = s.observeJobProposalCounts(); err != nil {
+ return 0, err
+ }
+
return proposal.ID, nil
}
@@ -494,6 +498,10 @@ func (s *service) RevokeJob(ctx context.Context, args *RevokeJobArgs) (int64, er
return 0, errors.Wrap(err, "RevokeSpec failed")
}
+ if err = s.observeJobProposalCounts(); err != nil {
+ return 0, err
+ }
+
return proposal.ID, nil
}
@@ -1207,9 +1215,10 @@ func (s *service) newOCR2ConfigMsg(cfg OCR2ConfigModel) (*pb.OCR2Config, error)
}
msg := &pb.OCR2Config{
- Enabled: true,
- IsBootstrap: cfg.IsBootstrap,
- Multiaddr: cfg.Multiaddr.ValueOrZero(),
+ Enabled: true,
+ IsBootstrap: cfg.IsBootstrap,
+ Multiaddr: cfg.Multiaddr.ValueOrZero(),
+ ForwarderAddress: cfg.ForwarderAddress.Ptr(),
Plugins: &pb.OCR2Config_Plugins{
Commit: cfg.Plugins.Commit,
Execute: cfg.Plugins.Execute,
diff --git a/core/services/feeds/service_test.go b/core/services/feeds/service_test.go
index 48fefd35daf..85f14e407f8 100644
--- a/core/services/feeds/service_test.go
+++ b/core/services/feeds/service_test.go
@@ -73,6 +73,7 @@ type = "offchainreporting"
schemaVersion = 1
name = "example OCR1 spec"
externalJobID = "0EEC7E1D-D0D2-476C-A1A8-72DFB6633F46"
+evmChainID = 0
contractAddress = "0x613a38AC1659769640aaE063C651F48E0250454C"
p2pBootstrapPeers = [
"/dns4/chain.link/tcp/1234/p2p/16Uiu2HAm58SP7UL8zsnpeuwHfytLocaqgnyaYKP8wu7qRdrixLju",
@@ -179,10 +180,9 @@ 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, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
- require.NoError(t, err)
+ legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
keyStore.On("Eth").Return(ethKeyStore)
keyStore.On("CSA").Return(csaKeystore)
keyStore.On("P2P").Return(p2pKeystore)
@@ -816,6 +816,7 @@ func Test_Service_DeleteJob(t *testing.T) {
before: func(svc *TestService) {
svc.orm.On("GetJobProposalByRemoteUUID", approved.RemoteUUID).Return(&approved, nil)
svc.orm.On("DeleteProposal", approved.ID, mock.Anything).Return(nil)
+ svc.orm.On("CountJobProposalsByStatus").Return(&feeds.JobProposalCounts{}, nil)
},
args: args,
wantID: approved.ID,
@@ -956,6 +957,7 @@ answer1 [type=median index=0];
svc.orm.On("GetJobProposalByRemoteUUID", pendingProposal.RemoteUUID).Return(pendingProposal, nil)
svc.orm.On("GetLatestSpec", pendingSpec.JobProposalID).Return(pendingSpec, nil)
svc.orm.On("RevokeSpec", pendingSpec.ID, mock.Anything).Return(nil)
+ svc.orm.On("CountJobProposalsByStatus").Return(&feeds.JobProposalCounts{}, nil)
},
args: args,
wantID: pendingProposal.ID,
@@ -972,6 +974,7 @@ answer1 [type=median index=0];
Definition: defn,
}, nil)
svc.orm.On("RevokeSpec", pendingSpec.ID, mock.Anything).Return(nil)
+ svc.orm.On("CountJobProposalsByStatus").Return(&feeds.JobProposalCounts{}, nil)
},
args: args,
wantID: pendingProposal.ID,
@@ -1120,9 +1123,10 @@ func Test_Service_SyncNodeInfo(t *testing.T) {
require.NoError(t, err)
var (
- multiaddr = "/dns4/chain.link/tcp/1234/p2p/16Uiu2HAm58SP7UL8zsnpeuwHfytLocaqgnyaYKP8wu7qRdrixLju"
- mgr = &feeds.FeedsManager{ID: 1}
- ccfg = feeds.ChainConfig{
+ multiaddr = "/dns4/chain.link/tcp/1234/p2p/16Uiu2HAm58SP7UL8zsnpeuwHfytLocaqgnyaYKP8wu7qRdrixLju"
+ mgr = &feeds.FeedsManager{ID: 1}
+ forwarderAddr = "0x0002"
+ ccfg = feeds.ChainConfig{
ID: 100,
FeedsManagerID: mgr.ID,
ChainID: "42",
@@ -1139,9 +1143,10 @@ func Test_Service_SyncNodeInfo(t *testing.T) {
KeyBundleID: null.StringFrom(ocrKey.GetID()),
},
OCR2Config: feeds.OCR2ConfigModel{
- Enabled: true,
- IsBootstrap: true,
- Multiaddr: null.StringFrom(multiaddr),
+ Enabled: true,
+ IsBootstrap: true,
+ Multiaddr: null.StringFrom(multiaddr),
+ ForwarderAddress: null.StringFrom(forwarderAddr),
Plugins: feeds.Plugins{
Commit: true,
Execute: true,
@@ -1189,9 +1194,10 @@ func Test_Service_SyncNodeInfo(t *testing.T) {
},
},
Ocr2Config: &proto.OCR2Config{
- Enabled: true,
- IsBootstrap: ccfg.OCR2Config.IsBootstrap,
- Multiaddr: multiaddr,
+ Enabled: true,
+ IsBootstrap: ccfg.OCR2Config.IsBootstrap,
+ Multiaddr: multiaddr,
+ ForwarderAddress: &forwarderAddr,
Plugins: &proto.OCR2Config_Plugins{
Commit: ccfg.OCR2Config.Plugins.Commit,
Execute: ccfg.OCR2Config.Plugins.Execute,
diff --git a/core/services/fluxmonitorv2/contract_submitter.go b/core/services/fluxmonitorv2/contract_submitter.go
index fe1db281393..d60f5b70e01 100644
--- a/core/services/fluxmonitorv2/contract_submitter.go
+++ b/core/services/fluxmonitorv2/contract_submitter.go
@@ -7,7 +7,6 @@ import (
evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/flux_aggregator_wrapper"
- "github.com/smartcontractkit/chainlink/v2/core/services/pg"
)
//go:generate mockery --quiet --name ContractSubmitter --output ./mocks/ --case=underscore
@@ -17,7 +16,7 @@ var FluxAggregatorABI = evmtypes.MustGetABI(flux_aggregator_wrapper.FluxAggregat
// ContractSubmitter defines an interface to submit an eth tx.
type ContractSubmitter interface {
- Submit(roundID *big.Int, submission *big.Int, qopts ...pg.QOpt) error
+ Submit(roundID *big.Int, submission *big.Int, idempotencyKey *string) error
}
// FluxAggregatorContractSubmitter submits the polled answer in an eth tx.
@@ -51,7 +50,7 @@ func NewFluxAggregatorContractSubmitter(
// Submit submits the answer by writing a EthTx for the txmgr to
// pick up
-func (c *FluxAggregatorContractSubmitter) Submit(roundID *big.Int, submission *big.Int, qopts ...pg.QOpt) error {
+func (c *FluxAggregatorContractSubmitter) Submit(roundID *big.Int, submission *big.Int, idempotencyKey *string) error {
fromAddress, err := c.keyStore.GetRoundRobinAddress(c.chainID)
if err != nil {
return err
@@ -63,7 +62,7 @@ func (c *FluxAggregatorContractSubmitter) Submit(roundID *big.Int, submission *b
}
return errors.Wrap(
- c.orm.CreateEthTransaction(fromAddress, c.Address(), payload, c.gasLimit, qopts...),
+ c.orm.CreateEthTransaction(fromAddress, c.Address(), payload, c.gasLimit, idempotencyKey),
"failed to send Eth transaction",
)
}
diff --git a/core/services/fluxmonitorv2/contract_submitter_test.go b/core/services/fluxmonitorv2/contract_submitter_test.go
index 1585810ab8e..7c282e3190c 100644
--- a/core/services/fluxmonitorv2/contract_submitter_test.go
+++ b/core/services/fluxmonitorv2/contract_submitter_test.go
@@ -4,6 +4,7 @@ import (
"math/big"
"testing"
+ "github.com/google/uuid"
"github.com/stretchr/testify/assert"
"github.com/smartcontractkit/chainlink/v2/core/internal/mocks"
@@ -32,8 +33,10 @@ func TestFluxAggregatorContractSubmitter_Submit(t *testing.T) {
keyStore.On("GetRoundRobinAddress", testutils.FixtureChainID).Return(fromAddress, nil)
fluxAggregator.On("Address").Return(toAddress)
- orm.On("CreateEthTransaction", fromAddress, toAddress, payload, gasLimit).Return(nil)
- err = submitter.Submit(roundID, submission)
+ idempotencyKey := uuid.New().String()
+ orm.On("CreateEthTransaction", fromAddress, toAddress, payload, gasLimit, &idempotencyKey).Return(nil)
+
+ err = submitter.Submit(roundID, submission, &idempotencyKey)
assert.NoError(t, err)
}
diff --git a/core/services/fluxmonitorv2/flux_monitor.go b/core/services/fluxmonitorv2/flux_monitor.go
index ad34c84b1d8..0b09655707d 100644
--- a/core/services/fluxmonitorv2/flux_monitor.go
+++ b/core/services/fluxmonitorv2/flux_monitor.go
@@ -735,6 +735,7 @@ func (fm *FluxMonitor) respondToNewRoundLog(log flux_aggregator_wrapper.FluxAggr
"databaseID": fm.jobSpec.ID,
"externalJobID": fm.jobSpec.ExternalJobID,
"name": fm.jobSpec.Name.ValueOrZero(),
+ "evmChainID": fm.chainID.String(),
},
"jobRun": map[string]interface{}{
"meta": metaDataForBridge,
@@ -768,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 {
@@ -938,6 +939,7 @@ func (fm *FluxMonitor) pollIfEligible(pollReq PollRequestType, deviationChecker
"databaseID": fm.jobSpec.ID,
"externalJobID": fm.jobSpec.ExternalJobID,
"name": fm.jobSpec.Name.ValueOrZero(),
+ "evmChainID": fm.chainID.String(),
},
"jobRun": map[string]interface{}{
"meta": metaDataForBridge,
@@ -991,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 {
@@ -1071,13 +1073,16 @@ func (fm *FluxMonitor) initialRoundState() flux_aggregator_wrapper.OracleRoundSt
}
func (fm *FluxMonitor) queueTransactionForTxm(tx pg.Queryer, runID int64, answer decimal.Decimal, roundID uint32, log *flux_aggregator_wrapper.FluxAggregatorNewRound) error {
+ // Use pipeline run ID to generate globally unique key that can correlate this run to a Tx
+ idempotencyKey := fmt.Sprintf("fluxmonitor-%d", runID)
// Submit the Eth Tx
err := fm.contractSubmitter.Submit(
new(big.Int).SetInt64(int64(roundID)),
answer.BigInt(),
- pg.WithQueryer(tx),
+ &idempotencyKey,
)
if err != nil {
+ fm.logger.Errorw("failed to submit Tx to TXM", "err", err)
return err
}
diff --git a/core/services/fluxmonitorv2/flux_monitor_test.go b/core/services/fluxmonitorv2/flux_monitor_test.go
index 923658fef09..27d40cd69c7 100644
--- a/core/services/fluxmonitorv2/flux_monitor_test.go
+++ b/core/services/fluxmonitorv2/flux_monitor_test.go
@@ -1,6 +1,7 @@
package fluxmonitorv2_test
import (
+ "fmt"
"math/big"
"strings"
"testing"
@@ -130,6 +131,11 @@ func setupMocks(t *testing.T) *testMocks {
return tm
}
+func buildIdempotencyKey(ID int64) *string {
+ key := fmt.Sprintf("fluxmonitor-%d", ID)
+ return &key
+}
+
type setupOptions struct {
pollTickerDisabled bool
idleTimerDisabled bool
@@ -445,10 +451,11 @@ func TestFluxMonitor_PollIfEligible(t *testing.T) {
"databaseID": int32(0),
"externalJobID": uuid.UUID{},
"name": "",
+ "evmChainID": testutils.FixtureChainID.String(),
},
},
), mock.Anything).
- Return(pipeline.Run{}, pipeline.TaskRunResults{
+ Return(&run, pipeline.TaskRunResults{
{
Result: pipeline.Result{
Value: decimal.NewFromInt(answers.polledAnswer),
@@ -467,7 +474,7 @@ func TestFluxMonitor_PollIfEligible(t *testing.T) {
}).
Once()
tm.contractSubmitter.
- On("Submit", big.NewInt(reportableRoundID), big.NewInt(answers.polledAnswer), mock.Anything).
+ On("Submit", big.NewInt(reportableRoundID), big.NewInt(answers.polledAnswer), buildIdempotencyKey(run.ID)).
Return(nil).
Once()
@@ -577,6 +584,7 @@ func TestPollingDeviationChecker_BuffersLogs(t *testing.T) {
tm.orm.On("MostRecentFluxMonitorRoundID", contractAddress).Return(uint32(4), nil)
// Round 1
+ run := &pipeline.Run{ID: 1}
tm.orm.
On("FindOrCreateFluxMonitorRoundStats", contractAddress, uint32(1), mock.Anything).
Return(fluxmonitorv2.FluxMonitorRoundStatsV2{
@@ -585,7 +593,7 @@ func TestPollingDeviationChecker_BuffersLogs(t *testing.T) {
}, nil)
tm.pipelineRunner.
On("ExecuteRun", mock.Anything, pipelineSpec, mock.Anything, mock.Anything).
- Return(pipeline.Run{}, pipeline.TaskRunResults{
+ Return(run, pipeline.TaskRunResults{
{
Result: pipeline.Result{
Value: decimal.NewFromInt(fetchedValue),
@@ -593,15 +601,15 @@ func TestPollingDeviationChecker_BuffersLogs(t *testing.T) {
},
Task: &pipeline.HTTPTask{},
},
- }, nil)
+ }, nil).Once()
tm.pipelineRunner.
On("InsertFinishedRun", mock.Anything, mock.Anything, mock.Anything, mock.Anything).
Return(nil).
Run(func(args mock.Arguments) {
args.Get(0).(*pipeline.Run).ID = 1
- })
+ }).Once()
tm.contractSubmitter.
- On("Submit", big.NewInt(1), big.NewInt(fetchedValue), mock.Anything).
+ On("Submit", big.NewInt(1), big.NewInt(fetchedValue), buildIdempotencyKey(run.ID)).
Return(nil).
Once()
@@ -616,6 +624,7 @@ func TestPollingDeviationChecker_BuffersLogs(t *testing.T) {
Return(nil).Once()
// Round 3
+ run = &pipeline.Run{ID: 2}
tm.orm.
On("FindOrCreateFluxMonitorRoundStats", contractAddress, uint32(3), mock.Anything).
Return(fluxmonitorv2.FluxMonitorRoundStatsV2{
@@ -624,7 +633,7 @@ func TestPollingDeviationChecker_BuffersLogs(t *testing.T) {
}, nil)
tm.pipelineRunner.
On("ExecuteRun", mock.Anything, pipelineSpec, mock.Anything, mock.Anything).
- Return(pipeline.Run{}, pipeline.TaskRunResults{
+ Return(run, pipeline.TaskRunResults{
{
Result: pipeline.Result{
Value: decimal.NewFromInt(fetchedValue),
@@ -632,15 +641,15 @@ func TestPollingDeviationChecker_BuffersLogs(t *testing.T) {
},
Task: &pipeline.HTTPTask{},
},
- }, nil)
+ }, nil).Once()
tm.pipelineRunner.
On("InsertFinishedRun", mock.Anything, mock.Anything, mock.Anything, mock.Anything).
Return(nil).
Run(func(args mock.Arguments) {
args.Get(0).(*pipeline.Run).ID = 2
- })
+ }).Once()
tm.contractSubmitter.
- On("Submit", big.NewInt(3), big.NewInt(fetchedValue), mock.Anything).
+ On("Submit", big.NewInt(3), big.NewInt(fetchedValue), buildIdempotencyKey(run.ID)).
Return(nil).
Once()
tm.orm.
@@ -654,6 +663,7 @@ func TestPollingDeviationChecker_BuffersLogs(t *testing.T) {
Return(nil).Once()
// Round 4
+ run = &pipeline.Run{ID: 3}
tm.orm.
On("FindOrCreateFluxMonitorRoundStats", contractAddress, uint32(4), mock.Anything).
Return(fluxmonitorv2.FluxMonitorRoundStatsV2{
@@ -662,7 +672,7 @@ func TestPollingDeviationChecker_BuffersLogs(t *testing.T) {
}, nil)
tm.pipelineRunner.
On("ExecuteRun", mock.Anything, pipelineSpec, mock.Anything, mock.Anything).
- Return(pipeline.Run{}, pipeline.TaskRunResults{
+ Return(run, pipeline.TaskRunResults{
{
Result: pipeline.Result{
Value: decimal.NewFromInt(fetchedValue),
@@ -670,15 +680,15 @@ func TestPollingDeviationChecker_BuffersLogs(t *testing.T) {
},
Task: &pipeline.HTTPTask{},
},
- }, nil)
+ }, nil).Once()
tm.pipelineRunner.
On("InsertFinishedRun", mock.Anything, mock.Anything, mock.Anything, mock.Anything).
Return(nil).
Run(func(args mock.Arguments) {
args.Get(0).(*pipeline.Run).ID = 3
- })
+ }).Once()
tm.contractSubmitter.
- On("Submit", big.NewInt(4), big.NewInt(fetchedValue), mock.Anything).
+ On("Submit", big.NewInt(4), big.NewInt(fetchedValue), buildIdempotencyKey(run.ID)).
Return(nil).
Once()
tm.orm.
@@ -1474,6 +1484,8 @@ func TestFluxMonitor_DoesNotDoubleSubmit(t *testing.T) {
answer = 100
)
+ 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()
@@ -1487,7 +1499,7 @@ func TestFluxMonitor_DoesNotDoubleSubmit(t *testing.T) {
}, nil).Once()
tm.pipelineRunner.
On("ExecuteRun", mock.Anything, pipelineSpec, mock.Anything, mock.Anything).
- Return(pipeline.Run{}, pipeline.TaskRunResults{
+ Return(run, pipeline.TaskRunResults{
{
Result: pipeline.Result{
Value: decimal.NewFromInt(answer),
@@ -1503,7 +1515,7 @@ func TestFluxMonitor_DoesNotDoubleSubmit(t *testing.T) {
args.Get(0).(*pipeline.Run).ID = 1
})
tm.logBroadcaster.On("MarkConsumed", mock.Anything, mock.Anything).Return(nil).Once()
- tm.contractSubmitter.On("Submit", big.NewInt(roundID), big.NewInt(answer), mock.Anything).Return(nil).Once()
+ tm.contractSubmitter.On("Submit", big.NewInt(roundID), big.NewInt(answer), buildIdempotencyKey(run.ID)).Return(nil).Once()
tm.orm.
On("UpdateFluxMonitorRoundStats",
contractAddress,
@@ -1587,6 +1599,8 @@ func TestFluxMonitor_DoesNotDoubleSubmit(t *testing.T) {
roundID = 3
answer = 100
)
+
+ 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()
@@ -1613,7 +1627,7 @@ func TestFluxMonitor_DoesNotDoubleSubmit(t *testing.T) {
}, nil).Once()
tm.pipelineRunner.
On("ExecuteRun", mock.Anything, pipelineSpec, mock.Anything, mock.Anything).
- Return(pipeline.Run{}, pipeline.TaskRunResults{
+ Return(run, pipeline.TaskRunResults{
{
Result: pipeline.Result{
Value: decimal.NewFromInt(answer),
@@ -1628,7 +1642,7 @@ func TestFluxMonitor_DoesNotDoubleSubmit(t *testing.T) {
Run(func(args mock.Arguments) {
args.Get(0).(*pipeline.Run).ID = 1
})
- tm.contractSubmitter.On("Submit", big.NewInt(roundID), big.NewInt(answer), mock.Anything).Return(nil).Once()
+ tm.contractSubmitter.On("Submit", big.NewInt(roundID), big.NewInt(answer), buildIdempotencyKey(run.ID)).Return(nil).Once()
tm.orm.
On("UpdateFluxMonitorRoundStats",
contractAddress,
@@ -1682,6 +1696,7 @@ func TestFluxMonitor_DoesNotDoubleSubmit(t *testing.T) {
roundID = 3
answer = 100
)
+ 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()
@@ -1708,7 +1723,7 @@ func TestFluxMonitor_DoesNotDoubleSubmit(t *testing.T) {
}, nil).Once()
tm.pipelineRunner.
On("ExecuteRun", mock.Anything, pipelineSpec, mock.Anything, mock.Anything).
- Return(pipeline.Run{}, pipeline.TaskRunResults{
+ Return(run, pipeline.TaskRunResults{
{
Result: pipeline.Result{
Value: decimal.NewFromInt(answer),
@@ -1723,7 +1738,7 @@ func TestFluxMonitor_DoesNotDoubleSubmit(t *testing.T) {
Run(func(args mock.Arguments) {
args.Get(0).(*pipeline.Run).ID = 1
})
- tm.contractSubmitter.On("Submit", big.NewInt(roundID), big.NewInt(answer), mock.Anything).Return(nil).Once()
+ tm.contractSubmitter.On("Submit", big.NewInt(roundID), big.NewInt(answer), buildIdempotencyKey(run.ID)).Return(nil).Once()
tm.orm.
On("UpdateFluxMonitorRoundStats",
contractAddress,
@@ -1796,7 +1811,7 @@ func TestFluxMonitor_DoesNotDoubleSubmit(t *testing.T) {
Once()
// and that should result in a new submission
- tm.contractSubmitter.On("Submit", big.NewInt(olderRoundID), big.NewInt(answer), mock.Anything).Return(nil).Once()
+ tm.contractSubmitter.On("Submit", big.NewInt(olderRoundID), big.NewInt(answer), buildIdempotencyKey(run.ID)).Return(nil).Once()
tm.orm.
On("UpdateFluxMonitorRoundStats",
@@ -1882,10 +1897,11 @@ func TestFluxMonitor_DrumbeatTicker(t *testing.T) {
"databaseID": int32(0),
"externalJobID": uuid.UUID{},
"name": "",
+ "evmChainID": testutils.FixtureChainID.String(),
},
},
), mock.Anything).
- Return(pipeline.Run{}, pipeline.TaskRunResults{
+ Return(&pipeline.Run{ID: runID}, pipeline.TaskRunResults{
{
Result: pipeline.Result{
Value: decimal.NewFromInt(fetchedAnswer),
@@ -1903,7 +1919,7 @@ func TestFluxMonitor_DrumbeatTicker(t *testing.T) {
}).
Once()
tm.contractSubmitter.
- On("Submit", big.NewInt(int64(roundID)), answerBigInt, mock.Anything).
+ On("Submit", big.NewInt(int64(roundID)), answerBigInt, buildIdempotencyKey(runID)).
Return(nil).
Once()
diff --git a/core/services/fluxmonitorv2/integrations_test.go b/core/services/fluxmonitorv2/integrations_test.go
index e76d859e81b..5b6a94cac58 100644
--- a/core/services/fluxmonitorv2/integrations_test.go
+++ b/core/services/fluxmonitorv2/integrations_test.go
@@ -644,6 +644,7 @@ type = "fluxmonitor"
schemaVersion = 1
name = "example flux monitor spec"
contractAddress = "%s"
+evmChainID = "%s"
threshold = 0.5
absoluteThreshold = 0.0
@@ -661,7 +662,7 @@ ds1 -> ds1_parse
"""
`
- s = fmt.Sprintf(s, fa.aggregatorContractAddress, pollTimerPeriod, mockServer.URL)
+ s = fmt.Sprintf(s, fa.aggregatorContractAddress, testutils.SimulatedChainID.String(), pollTimerPeriod, mockServer.URL)
// raise flags to disable polling
_, err = fa.flagsContract.RaiseFlag(fa.sergey, utils.ZeroAddress) // global kill switch
@@ -752,6 +753,7 @@ type = "fluxmonitor"
schemaVersion = 1
name = "example flux monitor spec"
contractAddress = "%s"
+evmChainID = "%s"
threshold = 0.5
absoluteThreshold = 0.0
@@ -769,7 +771,7 @@ ds1 -> ds1_parse
"""
`
- s = fmt.Sprintf(s, fa.aggregatorContractAddress, "1000ms", mockServer.URL)
+ s = fmt.Sprintf(s, fa.aggregatorContractAddress, testutils.SimulatedChainID.String(), "1000ms", mockServer.URL)
// raise flags
_, err = fa.flagsContract.RaiseFlag(fa.sergey, utils.ZeroAddress) // global kill switch
@@ -862,6 +864,7 @@ type = "fluxmonitor"
schemaVersion = 1
name = "example flux monitor spec"
contractAddress = "%s"
+evmChainID = "%s"
threshold = 0.5
absoluteThreshold = 0.01
@@ -879,7 +882,7 @@ ds1 -> ds1_parse
"""
`
- s := fmt.Sprintf(toml, fa.aggregatorContractAddress, "100ms", mockServer.URL)
+ s := fmt.Sprintf(toml, fa.aggregatorContractAddress, testutils.SimulatedChainID.String(), "100ms", mockServer.URL)
// raise flags
_, err = fa.flagsContract.RaiseFlag(fa.sergey, utils.ZeroAddress) // global kill switch
@@ -963,6 +966,7 @@ type = "fluxmonitor"
schemaVersion = 1
name = "example flux monitor spec"
contractAddress = "%s"
+evmChainID = "%s"
threshold = 0.5
absoluteThreshold = 0.0
@@ -981,7 +985,7 @@ ds1 -> ds1_parse -> ds1_multiply
"""
`
- s = fmt.Sprintf(s, fa.aggregatorContractAddress, "200ms", mockServer.URL)
+ s = fmt.Sprintf(s, fa.aggregatorContractAddress, testutils.SimulatedChainID.String(), "200ms", mockServer.URL)
requestBody, err := json.Marshal(web.CreateJobRequest{
TOML: string(s),
})
diff --git a/core/services/fluxmonitorv2/mocks/contract_submitter.go b/core/services/fluxmonitorv2/mocks/contract_submitter.go
index fd1469c1b9b..6214255ff66 100644
--- a/core/services/fluxmonitorv2/mocks/contract_submitter.go
+++ b/core/services/fluxmonitorv2/mocks/contract_submitter.go
@@ -6,8 +6,6 @@ import (
big "math/big"
mock "github.com/stretchr/testify/mock"
-
- pg "github.com/smartcontractkit/chainlink/v2/core/services/pg"
)
// ContractSubmitter is an autogenerated mock type for the ContractSubmitter type
@@ -15,20 +13,13 @@ type ContractSubmitter struct {
mock.Mock
}
-// Submit provides a mock function with given fields: roundID, submission, qopts
-func (_m *ContractSubmitter) Submit(roundID *big.Int, submission *big.Int, qopts ...pg.QOpt) error {
- _va := make([]interface{}, len(qopts))
- for _i := range qopts {
- _va[_i] = qopts[_i]
- }
- var _ca []interface{}
- _ca = append(_ca, roundID, submission)
- _ca = append(_ca, _va...)
- ret := _m.Called(_ca...)
+// Submit provides a mock function with given fields: roundID, submission, idempotencyKey
+func (_m *ContractSubmitter) Submit(roundID *big.Int, submission *big.Int, idempotencyKey *string) error {
+ ret := _m.Called(roundID, submission, idempotencyKey)
var r0 error
- if rf, ok := ret.Get(0).(func(*big.Int, *big.Int, ...pg.QOpt) error); ok {
- r0 = rf(roundID, submission, qopts...)
+ if rf, ok := ret.Get(0).(func(*big.Int, *big.Int, *string) error); ok {
+ r0 = rf(roundID, submission, idempotencyKey)
} else {
r0 = ret.Error(0)
}
diff --git a/core/services/fluxmonitorv2/mocks/orm.go b/core/services/fluxmonitorv2/mocks/orm.go
index 705c2e8b2bb..1f2303fbf1a 100644
--- a/core/services/fluxmonitorv2/mocks/orm.go
+++ b/core/services/fluxmonitorv2/mocks/orm.go
@@ -39,20 +39,13 @@ func (_m *ORM) CountFluxMonitorRoundStats() (int, error) {
return r0, r1
}
-// CreateEthTransaction provides a mock function with given fields: fromAddress, toAddress, payload, gasLimit, qopts
-func (_m *ORM) CreateEthTransaction(fromAddress common.Address, toAddress common.Address, payload []byte, gasLimit uint32, qopts ...pg.QOpt) error {
- _va := make([]interface{}, len(qopts))
- for _i := range qopts {
- _va[_i] = qopts[_i]
- }
- var _ca []interface{}
- _ca = append(_ca, fromAddress, toAddress, payload, gasLimit)
- _ca = append(_ca, _va...)
- ret := _m.Called(_ca...)
+// CreateEthTransaction provides a mock function with given fields: fromAddress, toAddress, payload, gasLimit, idempotencyKey
+func (_m *ORM) CreateEthTransaction(fromAddress common.Address, toAddress common.Address, payload []byte, gasLimit uint32, idempotencyKey *string) error {
+ ret := _m.Called(fromAddress, toAddress, payload, gasLimit, idempotencyKey)
var r0 error
- if rf, ok := ret.Get(0).(func(common.Address, common.Address, []byte, uint32, ...pg.QOpt) error); ok {
- r0 = rf(fromAddress, toAddress, payload, gasLimit, qopts...)
+ if rf, ok := ret.Get(0).(func(common.Address, common.Address, []byte, uint32, *string) error); ok {
+ r0 = rf(fromAddress, toAddress, payload, gasLimit, idempotencyKey)
} else {
r0 = ret.Error(0)
}
diff --git a/core/services/fluxmonitorv2/orm.go b/core/services/fluxmonitorv2/orm.go
index c2f99c8345e..70ebd2e7020 100644
--- a/core/services/fluxmonitorv2/orm.go
+++ b/core/services/fluxmonitorv2/orm.go
@@ -26,7 +26,7 @@ type ORM interface {
DeleteFluxMonitorRoundsBackThrough(aggregator common.Address, roundID uint32) error
FindOrCreateFluxMonitorRoundStats(aggregator common.Address, roundID uint32, newRoundLogs uint) (FluxMonitorRoundStatsV2, error)
UpdateFluxMonitorRoundStats(aggregator common.Address, roundID uint32, runID int64, newRoundLogsAddition uint, qopts ...pg.QOpt) error
- CreateEthTransaction(fromAddress, toAddress common.Address, payload []byte, gasLimit uint32, qopts ...pg.QOpt) error
+ CreateEthTransaction(fromAddress, toAddress common.Address, payload []byte, gasLimit uint32, idempotencyKey *string) error
CountFluxMonitorRoundStats() (count int, err error)
}
@@ -118,16 +118,17 @@ func (o *orm) CreateEthTransaction(
toAddress common.Address,
payload []byte,
gasLimit uint32,
- qopts ...pg.QOpt,
+ idempotencyKey *string,
) (err error) {
_, err = o.txm.CreateTransaction(txmgr.TxRequest{
+ IdempotencyKey: idempotencyKey,
FromAddress: fromAddress,
ToAddress: toAddress,
EncodedPayload: payload,
FeeLimit: gasLimit,
Strategy: o.strategy,
Checker: o.checker,
- }, qopts...)
+ })
return errors.Wrap(err, "Skipped Flux Monitor submission")
}
diff --git a/core/services/fluxmonitorv2/orm_test.go b/core/services/fluxmonitorv2/orm_test.go
index e7185efa7bd..a24f516c7f0 100644
--- a/core/services/fluxmonitorv2/orm_test.go
+++ b/core/services/fluxmonitorv2/orm_test.go
@@ -23,6 +23,7 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/services/job"
"github.com/smartcontractkit/chainlink/v2/core/services/pipeline"
evmrelay "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm"
+ "github.com/smartcontractkit/chainlink/v2/core/utils"
)
func TestORM_MostRecentFluxMonitorRoundID(t *testing.T) {
@@ -95,8 +96,7 @@ func TestORM_UpdateFluxMonitorRoundStats(t *testing.T) {
bridgeORM := bridges.NewORM(db, lggr, cfg.Database())
relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{GeneralConfig: cfg, DB: db, KeyStore: keyStore.Eth()})
- legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
- require.NoError(t, err)
+ legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
// Instantiate a real job ORM because we need to create a job to satisfy
// a check in pipeline.CreateRun
jobORM := job.NewORM(db, legacyChains, pipelineORM, bridgeORM, keyStore, lggr, cfg.Database())
@@ -106,8 +106,7 @@ func TestORM_UpdateFluxMonitorRoundStats(t *testing.T) {
var roundID uint32 = 1
jb := makeJob(t)
- err = jobORM.CreateJob(jb)
- require.NoError(t, err)
+ require.NoError(t, jobORM.CreateJob(jb))
for expectedCount := uint64(1); expectedCount < 4; expectedCount++ {
f := time.Now()
@@ -163,6 +162,7 @@ func makeJob(t *testing.T) *job.Job {
IdleTimerDisabled: false,
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
+ EVMChainID: (*utils.Big)(testutils.FixtureChainID),
},
}
}
@@ -185,8 +185,9 @@ func TestORM_CreateEthTransaction(t *testing.T) {
payload = []byte{1, 0, 0}
gasLimit = uint32(21000)
)
-
+ idempotencyKey := uuid.New().String()
txm.On("CreateTransaction", txmgr.TxRequest{
+ IdempotencyKey: &idempotencyKey,
FromAddress: from,
ToAddress: to,
EncodedPayload: payload,
@@ -195,5 +196,5 @@ func TestORM_CreateEthTransaction(t *testing.T) {
Strategy: strategy,
}).Return(txmgr.Tx{}, nil).Once()
- require.NoError(t, orm.CreateEthTransaction(from, to, payload, gasLimit))
+ require.NoError(t, orm.CreateEthTransaction(from, to, payload, gasLimit, &idempotencyKey))
}
diff --git a/core/services/functions/connector_handler.go b/core/services/functions/connector_handler.go
index b03c4604258..c32bf56f0cd 100644
--- a/core/services/functions/connector_handler.go
+++ b/core/services/functions/connector_handler.go
@@ -6,6 +6,9 @@ import (
"encoding/json"
"fmt"
+ "go.uber.org/multierr"
+
+ "github.com/smartcontractkit/chainlink/v2/core/assets"
"github.com/smartcontractkit/chainlink/v2/core/logger"
"github.com/smartcontractkit/chainlink/v2/core/services/gateway/api"
"github.com/smartcontractkit/chainlink/v2/core/services/gateway/common"
@@ -21,13 +24,15 @@ import (
type functionsConnectorHandler struct {
utils.StartStopOnce
- connector connector.GatewayConnector
- signerKey *ecdsa.PrivateKey
- nodeAddress string
- storage s4.Storage
- allowlist functions.OnchainAllowlist
- rateLimiter *hc.RateLimiter
- lggr logger.Logger
+ connector connector.GatewayConnector
+ signerKey *ecdsa.PrivateKey
+ nodeAddress string
+ storage s4.Storage
+ allowlist functions.OnchainAllowlist
+ rateLimiter *hc.RateLimiter
+ subscriptions functions.OnchainSubscriptions
+ minimumBalance assets.Link
+ lggr logger.Logger
}
var (
@@ -35,17 +40,19 @@ var (
_ connector.GatewayConnectorHandler = &functionsConnectorHandler{}
)
-func NewFunctionsConnectorHandler(nodeAddress string, signerKey *ecdsa.PrivateKey, storage s4.Storage, allowlist functions.OnchainAllowlist, rateLimiter *hc.RateLimiter, lggr logger.Logger) (*functionsConnectorHandler, error) {
- if signerKey == nil || storage == nil || allowlist == nil || rateLimiter == nil {
- return nil, fmt.Errorf("signerKey, storage, allowlist and rateLimiter must be non-nil")
+func NewFunctionsConnectorHandler(nodeAddress string, signerKey *ecdsa.PrivateKey, storage s4.Storage, allowlist functions.OnchainAllowlist, rateLimiter *hc.RateLimiter, subscriptions functions.OnchainSubscriptions, minimumBalance assets.Link, lggr logger.Logger) (*functionsConnectorHandler, error) {
+ if signerKey == nil || storage == nil || allowlist == nil || rateLimiter == nil || subscriptions == nil {
+ return nil, fmt.Errorf("signerKey, storage, allowlist, rateLimiter and subscriptions must be non-nil")
}
return &functionsConnectorHandler{
- nodeAddress: nodeAddress,
- signerKey: signerKey,
- storage: storage,
- allowlist: allowlist,
- rateLimiter: rateLimiter,
- lggr: lggr.Named("functionsConnectorHandler"),
+ nodeAddress: nodeAddress,
+ signerKey: signerKey,
+ storage: storage,
+ allowlist: allowlist,
+ rateLimiter: rateLimiter,
+ subscriptions: subscriptions,
+ minimumBalance: minimumBalance,
+ lggr: lggr.Named("FunctionsConnectorHandler"),
}, nil
}
@@ -68,6 +75,10 @@ func (h *functionsConnectorHandler) HandleGatewayMessage(ctx context.Context, ga
h.lggr.Errorw("request rate-limited", "id", gatewayId, "address", fromAddr)
return
}
+ if balance, err := h.subscriptions.GetMaxUserBalance(fromAddr); err != nil || balance.Cmp(h.minimumBalance.ToInt()) < 0 {
+ h.lggr.Errorw("user subscription has insufficient balance", "id", gatewayId, "address", fromAddr, "balance", balance, "minBalance", h.minimumBalance)
+ return
+ }
h.lggr.Debugw("handling gateway request", "id", gatewayId, "method", body.Method)
@@ -83,13 +94,18 @@ func (h *functionsConnectorHandler) HandleGatewayMessage(ctx context.Context, ga
func (h *functionsConnectorHandler) Start(ctx context.Context) error {
return h.StartOnce("FunctionsConnectorHandler", func() error {
- return h.allowlist.Start(ctx)
+ if err := h.allowlist.Start(ctx); err != nil {
+ return err
+ }
+ return h.subscriptions.Start(ctx)
})
}
func (h *functionsConnectorHandler) Close() error {
- return h.StopOnce("FunctionsConnectorHandler", func() error {
- return h.allowlist.Close()
+ return h.StopOnce("FunctionsConnectorHandler", func() (err error) {
+ err = multierr.Combine(err, h.allowlist.Close())
+ err = multierr.Combine(err, h.subscriptions.Close())
+ return
})
}
diff --git a/core/services/functions/connector_handler_test.go b/core/services/functions/connector_handler_test.go
index 99b0cba0a28..bb3e2acbabd 100644
--- a/core/services/functions/connector_handler_test.go
+++ b/core/services/functions/connector_handler_test.go
@@ -4,8 +4,10 @@ import (
"encoding/base64"
"encoding/json"
"errors"
+ "math/big"
"testing"
+ "github.com/smartcontractkit/chainlink/v2/core/assets"
"github.com/smartcontractkit/chainlink/v2/core/internal/testutils"
"github.com/smartcontractkit/chainlink/v2/core/logger"
"github.com/smartcontractkit/chainlink/v2/core/services/functions"
@@ -31,10 +33,13 @@ func TestFunctionsConnectorHandler(t *testing.T) {
connector := gcmocks.NewGatewayConnector(t)
allowlist := gfmocks.NewOnchainAllowlist(t)
rateLimiter, err := hc.NewRateLimiter(hc.RateLimiterConfig{GlobalRPS: 100.0, GlobalBurst: 100, PerSenderRPS: 100.0, PerSenderBurst: 100})
+ subscriptions := gfmocks.NewOnchainSubscriptions(t)
require.NoError(t, err)
allowlist.On("Start", mock.Anything).Return(nil)
allowlist.On("Close", mock.Anything).Return(nil)
- handler, err := functions.NewFunctionsConnectorHandler(addr.Hex(), privateKey, storage, allowlist, rateLimiter, logger)
+ subscriptions.On("Start", mock.Anything).Return(nil)
+ subscriptions.On("Close", mock.Anything).Return(nil)
+ handler, err := functions.NewFunctionsConnectorHandler(addr.Hex(), privateKey, storage, allowlist, rateLimiter, subscriptions, *assets.NewLinkFromJuels(0), logger)
require.NoError(t, err)
handler.SetConnector(connector)
@@ -73,6 +78,7 @@ func TestFunctionsConnectorHandler(t *testing.T) {
}
storage.On("List", ctx, addr).Return(snapshot, nil).Once()
allowlist.On("Allow", addr).Return(true).Once()
+ subscriptions.On("GetMaxUserBalance", mock.Anything).Return(big.NewInt(100), nil)
connector.On("SendToGateway", ctx, "gw1", mock.Anything).Run(func(args mock.Arguments) {
msg, ok := args[2].(*api.Message)
require.True(t, ok)
@@ -129,6 +135,7 @@ func TestFunctionsConnectorHandler(t *testing.T) {
storage.On("Put", ctx, &key, &record, signature).Return(nil).Once()
allowlist.On("Allow", addr).Return(true).Once()
+ subscriptions.On("GetMaxUserBalance", mock.Anything).Return(big.NewInt(100), nil)
connector.On("SendToGateway", ctx, "gw1", mock.Anything).Run(func(args mock.Arguments) {
msg, ok := args[2].(*api.Message)
require.True(t, ok)
diff --git a/core/services/functions/listener.go b/core/services/functions/listener.go
index f7c94437654..084d1530a76 100644
--- a/core/services/functions/listener.go
+++ b/core/services/functions/listener.go
@@ -142,6 +142,12 @@ type FunctionsListener struct {
logPollerWrapper evmrelayTypes.LogPollerWrapper
}
+func (l *FunctionsListener) HealthReport() map[string]error {
+ return map[string]error{l.Name(): l.Healthy()}
+}
+
+func (l *FunctionsListener) Name() string { return l.logger.Name() }
+
func formatRequestId(requestId [32]byte) string {
return fmt.Sprintf("0x%x", requestId)
}
@@ -689,7 +695,11 @@ func (l *FunctionsListener) getSecrets(ctx context.Context, eaClient ExternalAda
switch requestData.SecretsLocation {
case LocationInline:
- l.logger.Warnw("request used Inline secrets location, processing with no secrets", "requestID", requestIDStr)
+ if len(requestData.Secrets) > 0 {
+ l.logger.Warnw("request used Inline secrets location, processing with no secrets", "requestID", requestIDStr)
+ } else {
+ l.logger.Debugw("request does not use any secrets", "requestID", requestIDStr)
+ }
return "", nil, nil
case LocationRemote:
thresholdEncSecrets, userError, err := eaClient.FetchEncryptedSecrets(ctx, requestData.Secrets, requestIDStr, l.job.Name.ValueOrZero())
@@ -714,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
}
@@ -728,6 +738,7 @@ func (l *FunctionsListener) getSecrets(ctx context.Context, eaClient ExternalAda
decryptedSecretsBytes, err := l.decryptor.Decrypt(decryptCtx, requestID[:], secrets)
if err != nil {
+ l.logger.Debugw("threshold decryption of secrets failed", "requestID", requestIDStr, "err", err)
return "", errors.New("threshold decryption of secrets failed"), nil
}
return string(decryptedSecretsBytes), nil, nil
diff --git a/core/services/functions/listener_test.go b/core/services/functions/listener_test.go
index 0c74b0563f4..a06fcf3e3b2 100644
--- a/core/services/functions/listener_test.go
+++ b/core/services/functions/listener_test.go
@@ -90,8 +90,7 @@ func NewFunctionsListenerUniverse(t *testing.T, timeoutSec int, pruneFrequencySe
db := pgtest.NewSqlxDB(t)
kst := cltest.NewKeyStore(t, db, cfg.Database())
relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: cfg, Client: ethClient, KeyStore: kst.Eth(), LogBroadcaster: broadcaster, MailMon: mailMon})
- legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
- require.NoError(t, err)
+ legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
chain := legacyChains.Slice()[0]
lggr := logger.TestLogger(t)
@@ -127,8 +126,7 @@ func NewFunctionsListenerUniverse(t *testing.T, timeoutSec int, pruneFrequencySe
decryptor := threshold_mocks.NewDecryptor(t)
var pluginConfig config.PluginConfig
- err = json.Unmarshal(jsonConfig.Bytes(), &pluginConfig)
- require.NoError(t, err)
+ require.NoError(t, json.Unmarshal(jsonConfig.Bytes(), &pluginConfig))
contractAddress := "0xa"
diff --git a/core/services/functions/models.go b/core/services/functions/models.go
index 88bebce1e29..2dadf3daf5a 100644
--- a/core/services/functions/models.go
+++ b/core/services/functions/models.go
@@ -109,7 +109,7 @@ func CheckStateTransition(prev RequestState, next RequestState) error {
},
FINALIZED: {
IN_PROGRESS: errors.New("cannot go back from FINALIZED to IN_PROGRESS"),
- RESULT_READY: errors.New("cannot go back from FINALIZED to RESULT_READY"),
+ RESULT_READY: errors.New("cannot go back from FINALIZED to RESULT_READY, result was already finalized by DON before this request was picked up"),
TIMED_OUT: nil, // timed out while in transmission - no reason to attempt sending it any more
FINALIZED: sameStateError,
CONFIRMED: nil, // received an on-chain result confirmation
diff --git a/core/services/gateway/api/constants.go b/core/services/gateway/api/constants.go
index 9ab7e0c4495..c028e259e22 100644
--- a/core/services/gateway/api/constants.go
+++ b/core/services/gateway/api/constants.go
@@ -6,19 +6,40 @@ const (
NoError ErrorCode = iota
UserMessageParseError
UnsupportedDONIdError
- InternalHandlerError
+ HandlerError
RequestTimeoutError
NodeReponseEncodingError
FatalError
)
+func (e ErrorCode) String() string {
+ switch e {
+ case NoError:
+ return "NoError"
+ case UserMessageParseError:
+ return "UserMessageParseError"
+ case UnsupportedDONIdError:
+ return "UnsupportedDONIdError"
+ case HandlerError:
+ return "HandlerError"
+ case RequestTimeoutError:
+ return "RequestTimeoutError"
+ case NodeReponseEncodingError:
+ return "NodeReponseEncodingError"
+ case FatalError:
+ return "FatalError"
+ default:
+ return "UnknownError"
+ }
+}
+
// See https://www.jsonrpc.org/specification#error_object
func ToJsonRPCErrorCode(errorCode ErrorCode) int {
gatewayErrorToJsonRPCError := map[ErrorCode]int{
NoError: 0,
UserMessageParseError: -32700, // Parse Error
UnsupportedDONIdError: -32602, // Invalid Params
- InternalHandlerError: -32000, // Server Error
+ HandlerError: -32600, // Invalid Request
RequestTimeoutError: -32000, // Server Error
NodeReponseEncodingError: -32603, // Internal Error
FatalError: -32000, // Server Error
@@ -37,7 +58,7 @@ func ToHttpErrorCode(errorCode ErrorCode) int {
NoError: 200, // OK
UserMessageParseError: 400, // Bad Request
UnsupportedDONIdError: 400, // Bad Request
- InternalHandlerError: 500, // Internal Server Error
+ HandlerError: 400, // Bad Request
RequestTimeoutError: 504, // Gateway Timeout
NodeReponseEncodingError: 500, // Internal Server Error
FatalError: 500, // Internal Server Error
diff --git a/core/services/gateway/common/utils.go b/core/services/gateway/common/utils.go
index 7501504f87b..2e5033432bb 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 e223ba1e9fc..f3ed6a0dfbb 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/config/config.go b/core/services/gateway/config/config.go
index a5536a381a6..a4d94155c8f 100644
--- a/core/services/gateway/config/config.go
+++ b/core/services/gateway/config/config.go
@@ -17,6 +17,7 @@ type ConnectionManagerConfig struct {
AuthGatewayId string
AuthTimestampToleranceSec uint32
AuthChallengeLen uint32
+ HeartbeatIntervalSec uint32
}
type DONConfig struct {
diff --git a/core/services/gateway/connectionmanager.go b/core/services/gateway/connectionmanager.go
index 840ee8689ab..f225b66fe18 100644
--- a/core/services/gateway/connectionmanager.go
+++ b/core/services/gateway/connectionmanager.go
@@ -8,9 +8,13 @@ import (
"fmt"
"strings"
"sync"
+ "time"
"github.com/gorilla/websocket"
+ "github.com/prometheus/client_golang/prometheus"
+ "github.com/prometheus/client_golang/prometheus/promauto"
"go.uber.org/multierr"
+ "golang.org/x/exp/maps"
"github.com/smartcontractkit/chainlink/v2/core/logger"
"github.com/smartcontractkit/chainlink/v2/core/services/gateway/api"
@@ -22,6 +26,11 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/utils"
)
+var promHeartbeatsSent = promauto.NewGaugeVec(prometheus.GaugeOpts{
+ Name: "gateway_heartbeats_sent",
+ Help: "Metric to track the number of successful node heartbeates per DON",
+}, []string{"don_id"})
+
// ConnectionManager holds all connections between Gateway and Nodes.
type ConnectionManager interface {
job.ServiceCtx
@@ -44,6 +53,18 @@ type connectionManager struct {
lggr logger.Logger
}
+func (m *connectionManager) HealthReport() map[string]error {
+ hr := map[string]error{m.Name(): m.Healthy()}
+ for _, d := range m.dons {
+ for _, n := range d.nodes {
+ maps.Copy(hr, n.conn.HealthReport())
+ }
+ }
+ return hr
+}
+
+func (m *connectionManager) Name() string { return m.lggr.Name() }
+
type donConnectionManager struct {
donConfig *config.DONConfig
nodes map[string]*nodeState
@@ -85,14 +106,17 @@ func NewConnectionManager(gwConfig *config.GatewayConfig, clock utils.Clock, lgg
if ok {
return nil, fmt.Errorf("duplicate node address %s in DON %s", nodeAddress, donConfig.DonId)
}
- nodes[nodeAddress] = &nodeState{conn: network.NewWSConnectionWrapper()}
+ nodes[nodeAddress] = &nodeState{conn: network.NewWSConnectionWrapper(lggr)}
+ if nodes[nodeAddress].conn == nil {
+ return nil, fmt.Errorf("error creating WSConnectionWrapper for node %s", nodeAddress)
+ }
}
dons[donConfig.DonId] = &donConnectionManager{
donConfig: &donConfig,
codec: codec,
nodes: nodes,
shutdownCh: make(chan struct{}),
- lggr: lggr,
+ lggr: lggr.Named("DONConnectionManager." + donConfig.DonId),
}
}
connMgr := &connectionManager{
@@ -117,11 +141,13 @@ func (m *connectionManager) Start(ctx context.Context) error {
for _, donConnMgr := range m.dons {
donConnMgr.closeWait.Add(len(donConnMgr.nodes))
for nodeAddress, nodeState := range donConnMgr.nodes {
- if err := nodeState.conn.Start(); err != nil {
+ if err := nodeState.conn.Start(ctx); err != nil {
return err
}
go donConnMgr.readLoop(nodeAddress, nodeState)
}
+ donConnMgr.closeWait.Add(1)
+ go donConnMgr.heartbeatLoop(m.config.HeartbeatIntervalSec)
}
return m.wsServer.Start(ctx)
})
@@ -202,6 +228,12 @@ func (m *connectionManager) FinalizeHandshake(attemptId string, response []byte,
if err != nil || attempt.nodeAddress != "0x"+hex.EncodeToString(signer) {
return network.ErrChallengeInvalidSignature
}
+ if conn != nil {
+ conn.SetPongHandler(func(data string) error {
+ m.lggr.Debugw("received heartbeat pong from node", "nodeAddress", attempt.nodeAddress)
+ return nil
+ })
+ }
attempt.nodeState.conn.Reset(conn)
m.lggr.Infof("node %s connected", attempt.nodeAddress)
return nil
@@ -223,11 +255,18 @@ func (m *donConnectionManager) SetHandler(handler handlers.Handler) {
}
func (m *donConnectionManager) SendToNode(ctx context.Context, nodeAddress string, msg *api.Message) error {
+ if msg == nil {
+ return errors.New("nil message")
+ }
data, err := m.codec.EncodeRequest(msg)
if err != nil {
return fmt.Errorf("error encoding request for node %s: %v", nodeAddress, err)
}
- return m.nodes[nodeAddress].conn.Write(ctx, websocket.BinaryMessage, data)
+ nodeState := m.nodes[nodeAddress]
+ if nodeState == nil {
+ return fmt.Errorf("node %s not found", nodeAddress)
+ }
+ return nodeState.conn.Write(ctx, websocket.BinaryMessage, data)
}
func (m *donConnectionManager) readLoop(nodeAddress string, nodeState *nodeState) {
@@ -254,3 +293,35 @@ func (m *donConnectionManager) readLoop(nodeAddress string, nodeState *nodeState
}
}
}
+
+func (m *donConnectionManager) heartbeatLoop(intervalSec uint32) {
+ ctx, _ := utils.StopChan(m.shutdownCh).NewCtx()
+ defer m.closeWait.Done()
+
+ if intervalSec == 0 {
+ m.lggr.Error("heartbeat interval is 0, heartbeat disabled")
+ return
+ }
+ m.lggr.Info("starting heartbeat loop")
+
+ ticker := time.NewTicker(time.Duration(intervalSec) * time.Second)
+ defer ticker.Stop()
+
+ for {
+ select {
+ case <-m.shutdownCh:
+ return
+ case <-ticker.C:
+ errorCount := 0
+ for nodeAddress, nodeState := range m.nodes {
+ err := nodeState.conn.Write(ctx, websocket.PingMessage, []byte{})
+ if err != nil {
+ m.lggr.Debugw("unable to send heartbeat to node", "nodeAddress", nodeAddress, "err", err)
+ errorCount++
+ }
+ }
+ promHeartbeatsSent.WithLabelValues(m.donConfig.DonId).Set(float64(len(m.nodes) - errorCount))
+ m.lggr.Infow("sent heartbeat to nodes", "donID", m.donConfig.DonId, "errCount", errorCount)
+ }
+ }
+}
diff --git a/core/services/gateway/connectionmanager_test.go b/core/services/gateway/connectionmanager_test.go
index f924761439a..d198ef67295 100644
--- a/core/services/gateway/connectionmanager_test.go
+++ b/core/services/gateway/connectionmanager_test.go
@@ -8,8 +8,10 @@ import (
"github.com/stretchr/testify/require"
+ "github.com/smartcontractkit/chainlink/v2/core/internal/testutils"
"github.com/smartcontractkit/chainlink/v2/core/logger"
"github.com/smartcontractkit/chainlink/v2/core/services/gateway"
+ "github.com/smartcontractkit/chainlink/v2/core/services/gateway/api"
gc "github.com/smartcontractkit/chainlink/v2/core/services/gateway/common"
"github.com/smartcontractkit/chainlink/v2/core/services/gateway/config"
"github.com/smartcontractkit/chainlink/v2/core/services/gateway/network"
@@ -208,3 +210,20 @@ func TestConnectionManager_FinalizeHandshake(t *testing.T) {
err = mgr.FinalizeHandshake(attemptId, response, nil)
require.ErrorIs(t, err, network.ErrChallengeInvalidSignature)
}
+
+func TestConnectionManager_SendToNode_Failures(t *testing.T) {
+ t.Parallel()
+
+ config, nodes := newTestConfig(t, 2)
+ clock := utils.NewFixedClock(time.Now())
+ mgr, err := gateway.NewConnectionManager(config, clock, logger.TestLogger(t))
+ require.NoError(t, err)
+
+ donMgr := mgr.DONConnectionManager("my_don_1")
+ err = donMgr.SendToNode(testutils.Context(t), nodes[0].Address, nil)
+ require.Error(t, err)
+
+ message := &api.Message{}
+ err = donMgr.SendToNode(testutils.Context(t), "some_other_node", message)
+ require.Error(t, err)
+}
diff --git a/core/services/gateway/connector/connector.go b/core/services/gateway/connector/connector.go
index 1cd1995e3a4..4cc84d37490 100644
--- a/core/services/gateway/connector/connector.go
+++ b/core/services/gateway/connector/connector.go
@@ -8,6 +8,8 @@ import (
"sync"
"time"
+ "golang.org/x/exp/maps"
+
"github.com/gorilla/websocket"
"github.com/smartcontractkit/chainlink/v2/core/logger"
@@ -59,6 +61,16 @@ type gatewayConnector struct {
lggr logger.Logger
}
+func (c *gatewayConnector) HealthReport() map[string]error {
+ m := map[string]error{c.Name(): c.Healthy()}
+ for _, g := range c.gateways {
+ maps.Copy(m, g.conn.HealthReport())
+ }
+ return m
+}
+
+func (c *gatewayConnector) Name() string { return c.lggr.Name() }
+
type gatewayState struct {
conn network.WSConnectionWrapper
config ConnectorGatewayConfig
@@ -67,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) {
@@ -85,7 +97,7 @@ func NewGatewayConnector(config *ConnectorConfig, signer Signer, handler Gateway
signer: signer,
handler: handler,
shutdownCh: make(chan struct{}),
- lggr: lggr,
+ lggr: lggr.Named("GatewayConnector"),
}
gateways := make(map[string]*gatewayState)
urlToId := make(map[string]string)
@@ -102,7 +114,7 @@ func NewGatewayConnector(config *ConnectorConfig, signer Signer, handler Gateway
return nil, err
}
gateway := &gatewayState{
- conn: network.NewWSConnectionWrapper(),
+ conn: network.NewWSConnectionWrapper(lggr),
config: gw,
url: parsedURL,
wsClient: network.NewWebSocketClient(config.WsClientConfig, connector, lggr),
@@ -189,7 +201,7 @@ func (c *gatewayConnector) Start(ctx context.Context) error {
}
for _, gatewayState := range c.gateways {
gatewayState := gatewayState
- if err := gatewayState.conn.Start(); err != nil {
+ if err := gatewayState.conn.Start(ctx); err != nil {
return err
}
c.closeWait.Add(2)
diff --git a/core/services/gateway/gateway.go b/core/services/gateway/gateway.go
index 7dbf87f0513..fb38ae10de9 100644
--- a/core/services/gateway/gateway.go
+++ b/core/services/gateway/gateway.go
@@ -4,9 +4,15 @@ import (
"context"
"encoding/json"
"fmt"
+ "strings"
"go.uber.org/multierr"
+ "github.com/ethereum/go-ethereum/common"
+
+ "github.com/prometheus/client_golang/prometheus"
+ "github.com/prometheus/client_golang/prometheus/promauto"
+
"github.com/smartcontractkit/chainlink/v2/core/logger"
"github.com/smartcontractkit/chainlink/v2/core/services/gateway/api"
"github.com/smartcontractkit/chainlink/v2/core/services/gateway/config"
@@ -16,6 +22,11 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/utils"
)
+var promRequest = promauto.NewCounterVec(prometheus.CounterOpts{
+ Name: "gateway_request",
+ Help: "Metric to track received requests and response codes",
+}, []string{"response_code"})
+
type Gateway interface {
job.ServiceCtx
gw_net.HTTPRequestHandler
@@ -59,6 +70,12 @@ func NewGatewayFromConfig(config *config.GatewayConfig, handlerFactory HandlerFa
if donConnMgr == nil {
return nil, fmt.Errorf("connection manager ID %s not found", donConfig.DonId)
}
+ for idx, nodeConfig := range donConfig.Members {
+ donConfig.Members[idx].Address = strings.ToLower(nodeConfig.Address)
+ if !common.IsHexAddress(nodeConfig.Address) {
+ return nil, fmt.Errorf("invalid node address %s", nodeConfig.Address)
+ }
+ }
handler, err := handlerFactory.NewHandler(donConfig.HandlerName, donConfig.HandlerConfig, &donConfig, donConnMgr)
if err != nil {
return nil, err
@@ -75,7 +92,7 @@ func NewGateway(codec api.Codec, httpServer gw_net.HttpServer, handlers map[stri
httpServer: httpServer,
handlers: handlers,
connMgr: connMgr,
- lggr: lggr.Named("gateway"),
+ lggr: lggr.Named("Gateway"),
}
httpServer.SetHTTPRequestHandler(gw)
return gw
@@ -115,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())
}
@@ -127,7 +147,7 @@ func (g *gateway) ProcessRequest(ctx context.Context, rawRequest []byte) (rawRes
responseCh := make(chan handlers.UserCallbackPayload, 1)
err = handler.HandleUserMessage(ctx, msg, responseCh)
if err != nil {
- return newError(g.codec, msg.Body.MessageId, api.InternalHandlerError, err.Error())
+ return newError(g.codec, msg.Body.MessageId, api.HandlerError, err.Error())
}
// await response
var response handlers.UserCallbackPayload
@@ -145,6 +165,7 @@ func (g *gateway) ProcessRequest(ctx context.Context, rawRequest []byte) (rawRes
if err != nil {
return newError(g.codec, msg.Body.MessageId, api.NodeReponseEncodingError, "")
}
+ promRequest.WithLabelValues(api.NoError.String()).Inc()
return rawResponse, api.ToHttpErrorCode(api.NoError)
}
@@ -152,8 +173,10 @@ func newError(codec api.Codec, id string, errCode api.ErrorCode, errMsg string)
rawResponse, err := codec.EncodeNewErrorResponse(id, api.ToJsonRPCErrorCode(errCode), errMsg, nil)
if err != nil {
// we're not even able to encode a valid JSON response
+ promRequest.WithLabelValues(api.FatalError.String()).Inc()
return []byte("fatal error"), api.ToHttpErrorCode(api.FatalError)
}
+ promRequest.WithLabelValues(errCode.String()).Inc()
return rawResponse, api.ToHttpErrorCode(errCode)
}
diff --git a/core/services/gateway/gateway_test.go b/core/services/gateway/gateway_test.go
index a6662505db0..5fad6315a31 100644
--- a/core/services/gateway/gateway_test.go
+++ b/core/services/gateway/gateway_test.go
@@ -49,6 +49,10 @@ HandlerName = "dummy"
[[dons]]
DonId = "my_don_2"
HandlerName = "dummy"
+
+[[dons.Members]]
+Name = "node one"
+Address = "0x0001020304050607080900010203040506070809"
`)
lggr := logger.TestLogger(t)
@@ -102,6 +106,24 @@ SomeOtherField = "abcd"
require.Error(t, err)
}
+func TestGateway_NewGatewayFromConfig_InvalidNodeAddress(t *testing.T) {
+ t.Parallel()
+
+ tomlConfig := buildConfig(`
+[[dons]]
+HandlerName = "dummy"
+DonId = "my_don"
+
+[[dons.Members]]
+Name = "node one"
+Address = "0xnot_an_address"
+`)
+
+ lggr := logger.TestLogger(t)
+ _, err := gateway.NewGatewayFromConfig(parseTOMLConfig(t, tomlConfig), gateway.NewHandlerFactory(nil, lggr), lggr)
+ require.Error(t, err)
+}
+
func TestGateway_CleanStartAndClose(t *testing.T) {
t.Parallel()
@@ -220,6 +242,6 @@ func TestGateway_ProcessRequest_HandlerError(t *testing.T) {
req := newSignedRequest(t, "abcd", "request", "testDON", []byte{})
response, statusCode := gw.ProcessRequest(testutils.Context(t), req)
- requireJsonRPCError(t, response, "abcd", -32000, "failure")
- require.Equal(t, 500, statusCode)
+ requireJsonRPCError(t, response, "abcd", -32600, "failure")
+ require.Equal(t, 400, statusCode)
}
diff --git a/core/services/gateway/handlers/functions/allowlist.go b/core/services/gateway/handlers/functions/allowlist.go
index f05738ade40..0ee9b5bcfb9 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"
@@ -14,6 +15,7 @@ import (
evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/functions/generated/functions_allow_list"
+ "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/functions/generated/functions_router"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/functions/generated/ocr2dr_oracle"
"github.com/smartcontractkit/chainlink/v2/core/logger"
"github.com/smartcontractkit/chainlink/v2/core/services/job"
@@ -50,7 +52,7 @@ type onchainAllowlist struct {
allowlist atomic.Pointer[map[common.Address]struct{}]
client evmclient.Client
contractV0 *ocr2dr_oracle.OCR2DROracle
- contractV1 *functions_allow_list.TermsOfServiceAllowList
+ contractV1 *functions_router.FunctionsRouter
blockConfirmations *big.Int
lggr logger.Logger
closeWait sync.WaitGroup
@@ -68,7 +70,7 @@ func NewOnchainAllowlist(client evmclient.Client, config OnchainAllowlistConfig,
if err != nil {
return nil, fmt.Errorf("unexpected error during NewOCR2DROracle: %s", err)
}
- contractV1, err := functions_allow_list.NewTermsOfServiceAllowList(config.ContractAddress, client)
+ contractV1, err := functions_router.NewFunctionsRouter(config.ContractAddress, client)
if err != nil {
return nil, fmt.Errorf("unexpected error during functions_router.NewFunctionsRouter: %s", err)
}
@@ -169,13 +171,36 @@ func (a *onchainAllowlist) updateFromContractV0(ctx context.Context, blockNum *b
}
func (a *onchainAllowlist) updateFromContractV1(ctx context.Context, blockNum *big.Int) error {
- addrList, err := a.contractV1.GetAllAllowedSenders(&bind.CallOpts{
+ tosID, err := a.contractV1.GetAllowListId(&bind.CallOpts{
+ Pending: false,
+ Context: ctx,
+ })
+ if err != nil {
+ return errors.Wrap(err, "unexpected error during functions_router.GetAllowListId")
+ }
+ 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")
+ }
+ tosAddress, err := a.contractV1.GetContractById(&bind.CallOpts{
+ Pending: false,
+ Context: ctx,
+ }, tosID)
+ if err != nil {
+ return errors.Wrap(err, "unexpected error during functions_router.GetContractById")
+ }
+ a.lggr.Debugw("successfully fetched allowlist contract address", "address", tosAddress)
+ tosContract, err := functions_allow_list.NewTermsOfServiceAllowList(tosAddress, a.client)
+ if err != nil {
+ return errors.Wrap(err, "unexpected error during functions_allow_list.NewTermsOfServiceAllowList")
+ }
+ addrList, err := tosContract.GetAllAllowedSenders(&bind.CallOpts{
Pending: false,
BlockNumber: blockNum,
Context: ctx,
})
if err != nil {
- return errors.Wrap(err, "error calling GetAuthorizedSenders")
+ return errors.Wrap(err, "error calling GetAllAllowedSenders")
}
a.update(addrList)
return nil
diff --git a/core/services/gateway/handlers/functions/handler.functions.go b/core/services/gateway/handlers/functions/handler.functions.go
index aee099e6cee..7eb15ef6ffd 100644
--- a/core/services/gateway/handlers/functions/handler.functions.go
+++ b/core/services/gateway/handlers/functions/handler.functions.go
@@ -4,10 +4,15 @@ import (
"context"
"encoding/json"
"errors"
+ "fmt"
"time"
"github.com/ethereum/go-ethereum/common"
+ "github.com/prometheus/client_golang/prometheus"
+ "github.com/prometheus/client_golang/prometheus/promauto"
+ "go.uber.org/multierr"
+ "github.com/smartcontractkit/chainlink/v2/core/assets"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm"
"github.com/smartcontractkit/chainlink/v2/core/logger"
"github.com/smartcontractkit/chainlink/v2/core/services/gateway/api"
@@ -17,10 +22,44 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/utils"
)
+var (
+ ErrNotAllowlisted = errors.New("sender not allowlisted")
+ ErrRateLimited = errors.New("rate-limited")
+ ErrUnsupportedMethod = errors.New("unsupported method")
+
+ promHandlerError = promauto.NewCounterVec(prometheus.CounterOpts{
+ Name: "gateway_functions_handler_error",
+ Help: "Metric to track functions handler errors",
+ }, []string{"don_id", "error"})
+
+ promSecretsSetSuccess = promauto.NewCounterVec(prometheus.CounterOpts{
+ Name: "gateway_functions_secrets_set_success",
+ Help: "Metric to track successful secrets_set calls",
+ }, []string{"don_id"})
+
+ promSecretsSetFailure = promauto.NewCounterVec(prometheus.CounterOpts{
+ Name: "gateway_functions_secrets_set_failure",
+ Help: "Metric to track failed secrets_set calls",
+ }, []string{"don_id"})
+
+ promSecretsListSuccess = promauto.NewCounterVec(prometheus.CounterOpts{
+ Name: "gateway_functions_secrets_list_success",
+ Help: "Metric to track successful secrets_list calls",
+ }, []string{"don_id"})
+
+ promSecretsListFailure = promauto.NewCounterVec(prometheus.CounterOpts{
+ Name: "gateway_functions_secrets_list_failure",
+ Help: "Metric to track failed secrets_list calls",
+ }, []string{"don_id"})
+)
+
type FunctionsHandlerConfig struct {
- OnchainAllowlistChainID string `json:"onchainAllowlistChainId"`
+ ChainID string `json:"chainId"`
// Not specifying OnchainAllowlist config disables allowlist checks
OnchainAllowlist *OnchainAllowlistConfig `json:"onchainAllowlist"`
+ // Not specifying OnchainSubscriptions config disables minimum balance checks
+ OnchainSubscriptions *OnchainSubscriptionsConfig `json:"onchainSubscriptions"`
+ MinimumSubscriptionBalance *assets.Link `json:"minimumSubscriptionBalance"`
// Not specifying RateLimiter config disables rate limiting
UserRateLimiter *hc.RateLimiterConfig `json:"userRateLimiter"`
NodeRateLimiter *hc.RateLimiterConfig `json:"nodeRateLimiter"`
@@ -36,6 +75,8 @@ type functionsHandler struct {
don handlers.DON
pendingRequests hc.RequestCache[PendingSecretsRequest]
allowlist OnchainAllowlist
+ subscriptions OnchainSubscriptions
+ minimumBalance *assets.Link
userRateLimiter *hc.RateLimiter
nodeRateLimiter *hc.RateLimiter
chStop utils.StopChan
@@ -57,15 +98,16 @@ func NewFunctionsHandlerFromConfig(handlerConfig json.RawMessage, donConfig *con
if err != nil {
return nil, err
}
+ lggr = lggr.Named("FunctionsHandler:" + donConfig.DonId)
var allowlist OnchainAllowlist
if cfg.OnchainAllowlist != nil {
- chain, err2 := legacyChains.Get(cfg.OnchainAllowlistChainID)
+ chain, err2 := legacyChains.Get(cfg.ChainID)
if err2 != nil {
- return nil, err
+ return nil, err2
}
allowlist, err2 = NewOnchainAllowlist(chain.Client(), *cfg.OnchainAllowlist, lggr)
if err2 != nil {
- return nil, err
+ return nil, err2
}
}
var userRateLimiter, nodeRateLimiter *hc.RateLimiter
@@ -81,8 +123,19 @@ func NewFunctionsHandlerFromConfig(handlerConfig json.RawMessage, donConfig *con
return nil, err
}
}
+ var subscriptions OnchainSubscriptions
+ if cfg.OnchainSubscriptions != nil {
+ chain, err2 := legacyChains.Get(cfg.ChainID)
+ if err2 != nil {
+ return nil, err2
+ }
+ subscriptions, err2 = NewOnchainSubscriptions(chain.Client(), *cfg.OnchainSubscriptions, lggr)
+ if err2 != nil {
+ return nil, err2
+ }
+ }
pendingRequestsCache := hc.NewRequestCache[PendingSecretsRequest](time.Millisecond*time.Duration(cfg.RequestTimeoutMillis), cfg.MaxPendingRequests)
- return NewFunctionsHandler(cfg, donConfig, don, pendingRequestsCache, allowlist, userRateLimiter, nodeRateLimiter, lggr), nil
+ return NewFunctionsHandler(cfg, donConfig, don, pendingRequestsCache, allowlist, subscriptions, cfg.MinimumSubscriptionBalance, userRateLimiter, nodeRateLimiter, lggr), nil
}
func NewFunctionsHandler(
@@ -91,6 +144,8 @@ func NewFunctionsHandler(
don handlers.DON,
pendingRequestsCache hc.RequestCache[PendingSecretsRequest],
allowlist OnchainAllowlist,
+ subscriptions OnchainSubscriptions,
+ minimumBalance *assets.Link,
userRateLimiter *hc.RateLimiter,
nodeRateLimiter *hc.RateLimiter,
lggr logger.Logger) handlers.Handler {
@@ -100,6 +155,8 @@ func NewFunctionsHandler(
don: don,
pendingRequests: pendingRequestsCache,
allowlist: allowlist,
+ subscriptions: subscriptions,
+ minimumBalance: minimumBalance,
userRateLimiter: userRateLimiter,
nodeRateLimiter: nodeRateLimiter,
chStop: make(utils.StopChan),
@@ -111,18 +168,27 @@ func (h *functionsHandler) HandleUserMessage(ctx context.Context, msg *api.Messa
sender := common.HexToAddress(msg.Body.Sender)
if h.allowlist != nil && !h.allowlist.Allow(sender) {
h.lggr.Debugw("received a message from a non-allowlisted address", "sender", msg.Body.Sender)
- return errors.New("sender not allowlisted")
+ promHandlerError.WithLabelValues(h.donConfig.DonId, ErrNotAllowlisted.Error()).Inc()
+ return ErrNotAllowlisted
}
if h.userRateLimiter != nil && !h.userRateLimiter.Allow(msg.Body.Sender) {
- h.lggr.Debug("rate-limited", "sender", msg.Body.Sender)
- return errors.New("rate-limited")
+ h.lggr.Debugw("rate-limited", "sender", msg.Body.Sender)
+ promHandlerError.WithLabelValues(h.donConfig.DonId, ErrRateLimited.Error()).Inc()
+ return ErrRateLimited
+ }
+ if h.subscriptions != nil && h.minimumBalance != nil {
+ if balance, err := h.subscriptions.GetMaxUserBalance(sender); err != nil || balance.Cmp(h.minimumBalance.ToInt()) < 0 {
+ h.lggr.Debug("received a message from a user having insufficient balance", "sender", msg.Body.Sender, "balance", balance.String())
+ return fmt.Errorf("sender has insufficient balance: %v juels", balance.String())
+ }
}
switch msg.Body.Method {
case MethodSecretsSet, MethodSecretsList:
return h.handleSecretsRequest(ctx, msg, callbackCh)
default:
- h.lggr.Debug("unsupported method", "method", msg.Body.Method)
- return errors.New("unsupported method")
+ h.lggr.Debugw("unsupported method", "method", msg.Body.Method)
+ promHandlerError.WithLabelValues(h.donConfig.DonId, ErrUnsupportedMethod.Error()).Inc()
+ return ErrUnsupportedMethod
}
}
@@ -131,6 +197,7 @@ func (h *functionsHandler) handleSecretsRequest(ctx context.Context, msg *api.Me
err := h.pendingRequests.NewRequest(msg, callbackCh, &PendingSecretsRequest{request: msg, responses: make(map[string]*api.Message)})
if err != nil {
h.lggr.Warnw("handleSecretsRequest: error adding new request", "sender", msg.Body.Sender, "err", err)
+ promHandlerError.WithLabelValues(h.donConfig.DonId, err.Error()).Inc()
return err
}
// Send to all nodes.
@@ -146,15 +213,15 @@ func (h *functionsHandler) handleSecretsRequest(ctx context.Context, msg *api.Me
func (h *functionsHandler) HandleNodeMessage(ctx context.Context, msg *api.Message, nodeAddr string) error {
h.lggr.Debugw("HandleNodeMessage: processing message", "nodeAddr", nodeAddr, "receiver", msg.Body.Receiver, "id", msg.Body.MessageId)
if h.nodeRateLimiter != nil && !h.nodeRateLimiter.Allow(nodeAddr) {
- h.lggr.Debug("rate-limited", "sender", nodeAddr)
+ h.lggr.Debugw("rate-limited", "sender", nodeAddr)
return errors.New("rate-limited")
}
switch msg.Body.Method {
case MethodSecretsSet, MethodSecretsList:
return h.pendingRequests.ProcessResponse(msg, h.processSecretsResponse)
default:
- h.lggr.Debug("unsupported method", "method", msg.Body.Method)
- return errors.New("unsupported method")
+ h.lggr.Debugw("unsupported method", "method", msg.Body.Method)
+ return ErrUnsupportedMethod
}
}
@@ -163,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 {
@@ -199,6 +266,21 @@ func newSecretsResponse(request *api.Message, success bool, responses []*api.Mes
if err != nil {
return nil, err
}
+
+ if request.Body.Method == MethodSecretsSet {
+ if success {
+ promSecretsSetSuccess.WithLabelValues(request.Body.DonId).Inc()
+ } else {
+ promSecretsSetFailure.WithLabelValues(request.Body.DonId).Inc()
+ }
+ } else if request.Body.Method == MethodSecretsList {
+ if success {
+ promSecretsListSuccess.WithLabelValues(request.Body.DonId).Inc()
+ } else {
+ promSecretsListFailure.WithLabelValues(request.Body.DonId).Inc()
+ }
+ }
+
userResponse := *request
userResponse.Body.Receiver = request.Body.Sender
userResponse.Body.Payload = payloadJson
@@ -209,7 +291,14 @@ func (h *functionsHandler) Start(ctx context.Context) error {
return h.StartOnce("FunctionsHandler", func() error {
h.lggr.Info("starting FunctionsHandler")
if h.allowlist != nil {
- return h.allowlist.Start(ctx)
+ if err := h.allowlist.Start(ctx); err != nil {
+ return err
+ }
+ }
+ if h.subscriptions != nil {
+ if err := h.subscriptions.Start(ctx); err != nil {
+ return err
+ }
}
return nil
})
@@ -219,8 +308,11 @@ func (h *functionsHandler) Close() error {
return h.StopOnce("FunctionsHandler", func() (err error) {
close(h.chStop)
if h.allowlist != nil {
- return h.allowlist.Close()
+ err = multierr.Combine(err, h.allowlist.Close())
}
- return nil
+ if h.subscriptions != nil {
+ err = multierr.Combine(err, h.subscriptions.Close())
+ }
+ return
})
}
diff --git a/core/services/gateway/handlers/functions/handler.functions_test.go b/core/services/gateway/handlers/functions/handler.functions_test.go
index 12fa8b954f5..1446bc84571 100644
--- a/core/services/gateway/handlers/functions/handler.functions_test.go
+++ b/core/services/gateway/handlers/functions/handler.functions_test.go
@@ -4,6 +4,7 @@ import (
"crypto/ecdsa"
"encoding/json"
"fmt"
+ "math/big"
"testing"
"time"
@@ -11,6 +12,7 @@ import (
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
+ "github.com/smartcontractkit/chainlink/v2/core/assets"
"github.com/smartcontractkit/chainlink/v2/core/internal/testutils"
"github.com/smartcontractkit/chainlink/v2/core/logger"
"github.com/smartcontractkit/chainlink/v2/core/services/gateway/api"
@@ -23,7 +25,7 @@ import (
handlers_mocks "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/mocks"
)
-func newFunctionsHandlerForATestDON(t *testing.T, nodes []gc.TestNode, requestTimeout time.Duration) (handlers.Handler, *handlers_mocks.DON, *functions_mocks.OnchainAllowlist) {
+func newFunctionsHandlerForATestDON(t *testing.T, nodes []gc.TestNode, requestTimeout time.Duration) (handlers.Handler, *handlers_mocks.DON, *functions_mocks.OnchainAllowlist, *functions_mocks.OnchainSubscriptions) {
cfg := functions.FunctionsHandlerConfig{}
donConfig := &config.DONConfig{
Members: []config.NodeConfig{},
@@ -39,13 +41,15 @@ func newFunctionsHandlerForATestDON(t *testing.T, nodes []gc.TestNode, requestTi
don := handlers_mocks.NewDON(t)
allowlist := functions_mocks.NewOnchainAllowlist(t)
+ subscriptions := functions_mocks.NewOnchainSubscriptions(t)
+ minBalance := assets.NewLinkFromJuels(100)
userRateLimiter, err := hc.NewRateLimiter(hc.RateLimiterConfig{GlobalRPS: 100.0, GlobalBurst: 100, PerSenderRPS: 100.0, PerSenderBurst: 100})
require.NoError(t, err)
nodeRateLimiter, err := hc.NewRateLimiter(hc.RateLimiterConfig{GlobalRPS: 100.0, GlobalBurst: 100, PerSenderRPS: 100.0, PerSenderBurst: 100})
require.NoError(t, err)
pendingRequestsCache := hc.NewRequestCache[functions.PendingSecretsRequest](requestTimeout, 1000)
- handler := functions.NewFunctionsHandler(cfg, donConfig, don, pendingRequestsCache, allowlist, userRateLimiter, nodeRateLimiter, logger.TestLogger(t))
- return handler, don, allowlist
+ handler := functions.NewFunctionsHandler(cfg, donConfig, don, pendingRequestsCache, allowlist, subscriptions, minBalance, userRateLimiter, nodeRateLimiter, logger.TestLogger(t))
+ return handler, don, allowlist, subscriptions
}
func newSignedMessage(t *testing.T, id string, method string, donId string, privateKey *ecdsa.PrivateKey) api.Message {
@@ -113,7 +117,7 @@ func TestFunctionsHandler_HandleUserMessage_SecretsSet(t *testing.T) {
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
nodes, user := gc.NewTestNodes(t, 4), gc.NewTestNodes(t, 1)[0]
- handler, don, allowlist := newFunctionsHandlerForATestDON(t, nodes, time.Hour*24)
+ handler, don, allowlist, subscriptions := newFunctionsHandlerForATestDON(t, nodes, time.Hour*24)
userRequestMsg := newSignedMessage(t, "1234", "secrets_set", "don_id", user.PrivateKey)
callbachCh := make(chan handlers.UserCallbackPayload)
@@ -131,6 +135,7 @@ func TestFunctionsHandler_HandleUserMessage_SecretsSet(t *testing.T) {
}()
allowlist.On("Allow", common.HexToAddress(user.Address)).Return(true, nil)
+ subscriptions.On("GetMaxUserBalance", common.HexToAddress(user.Address)).Return(big.NewInt(1000), nil)
don.On("SendToNode", mock.Anything, mock.Anything, mock.Anything).Return(nil)
require.NoError(t, handler.HandleUserMessage(testutils.Context(t), &userRequestMsg, callbachCh))
sendNodeReponses(t, handler, userRequestMsg, nodes, test.nodeResults)
@@ -143,10 +148,11 @@ func TestFunctionsHandler_HandleUserMessage_InvalidMethod(t *testing.T) {
t.Parallel()
nodes, user := gc.NewTestNodes(t, 4), gc.NewTestNodes(t, 1)[0]
- handler, _, allowlist := newFunctionsHandlerForATestDON(t, nodes, time.Hour*24)
+ handler, _, allowlist, subscriptions := newFunctionsHandlerForATestDON(t, nodes, time.Hour*24)
userRequestMsg := newSignedMessage(t, "1234", "secrets_reveal_all_please", "don_id", user.PrivateKey)
allowlist.On("Allow", common.HexToAddress(user.Address)).Return(true, nil)
+ subscriptions.On("GetMaxUserBalance", common.HexToAddress(user.Address)).Return(big.NewInt(1000), nil)
err := handler.HandleUserMessage(testutils.Context(t), &userRequestMsg, make(chan handlers.UserCallbackPayload))
require.Error(t, err)
}
@@ -155,7 +161,7 @@ func TestFunctionsHandler_HandleUserMessage_Timeout(t *testing.T) {
t.Parallel()
nodes, user := gc.NewTestNodes(t, 4), gc.NewTestNodes(t, 1)[0]
- handler, don, allowlist := newFunctionsHandlerForATestDON(t, nodes, time.Millisecond*10)
+ handler, don, allowlist, subscriptions := newFunctionsHandlerForATestDON(t, nodes, time.Millisecond*10)
userRequestMsg := newSignedMessage(t, "1234", "secrets_set", "don_id", user.PrivateKey)
callbachCh := make(chan handlers.UserCallbackPayload)
@@ -169,6 +175,7 @@ func TestFunctionsHandler_HandleUserMessage_Timeout(t *testing.T) {
}()
allowlist.On("Allow", common.HexToAddress(user.Address)).Return(true, nil)
+ subscriptions.On("GetMaxUserBalance", common.HexToAddress(user.Address)).Return(big.NewInt(1000), nil)
don.On("SendToNode", mock.Anything, mock.Anything, mock.Anything).Return(nil)
require.NoError(t, handler.HandleUserMessage(testutils.Context(t), &userRequestMsg, callbachCh))
<-done
diff --git a/core/services/gateway/handlers/functions/mocks/onchain_subscriptions.go b/core/services/gateway/handlers/functions/mocks/onchain_subscriptions.go
new file mode 100644
index 00000000000..86397407466
--- /dev/null
+++ b/core/services/gateway/handlers/functions/mocks/onchain_subscriptions.go
@@ -0,0 +1,86 @@
+// Code generated by mockery v2.28.1. DO NOT EDIT.
+
+package mocks
+
+import (
+ context "context"
+ big "math/big"
+
+ common "github.com/ethereum/go-ethereum/common"
+
+ mock "github.com/stretchr/testify/mock"
+)
+
+// OnchainSubscriptions is an autogenerated mock type for the OnchainSubscriptions type
+type OnchainSubscriptions struct {
+ mock.Mock
+}
+
+// Close provides a mock function with given fields:
+func (_m *OnchainSubscriptions) Close() error {
+ ret := _m.Called()
+
+ var r0 error
+ if rf, ok := ret.Get(0).(func() error); ok {
+ r0 = rf()
+ } else {
+ r0 = ret.Error(0)
+ }
+
+ return r0
+}
+
+// GetMaxUserBalance provides a mock function with given fields: _a0
+func (_m *OnchainSubscriptions) GetMaxUserBalance(_a0 common.Address) (*big.Int, error) {
+ ret := _m.Called(_a0)
+
+ var r0 *big.Int
+ var r1 error
+ if rf, ok := ret.Get(0).(func(common.Address) (*big.Int, error)); ok {
+ return rf(_a0)
+ }
+ if rf, ok := ret.Get(0).(func(common.Address) *big.Int); ok {
+ r0 = rf(_a0)
+ } else {
+ if ret.Get(0) != nil {
+ r0 = ret.Get(0).(*big.Int)
+ }
+ }
+
+ if rf, ok := ret.Get(1).(func(common.Address) error); ok {
+ r1 = rf(_a0)
+ } else {
+ r1 = ret.Error(1)
+ }
+
+ return r0, r1
+}
+
+// Start provides a mock function with given fields: _a0
+func (_m *OnchainSubscriptions) Start(_a0 context.Context) error {
+ ret := _m.Called(_a0)
+
+ var r0 error
+ if rf, ok := ret.Get(0).(func(context.Context) error); ok {
+ r0 = rf(_a0)
+ } else {
+ r0 = ret.Error(0)
+ }
+
+ return r0
+}
+
+type mockConstructorTestingTNewOnchainSubscriptions interface {
+ mock.TestingT
+ Cleanup(func())
+}
+
+// NewOnchainSubscriptions creates a new instance of OnchainSubscriptions. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+func NewOnchainSubscriptions(t mockConstructorTestingTNewOnchainSubscriptions) *OnchainSubscriptions {
+ mock := &OnchainSubscriptions{}
+ mock.Mock.Test(t)
+
+ t.Cleanup(func() { mock.AssertExpectations(t) })
+
+ return mock
+}
diff --git a/core/services/gateway/handlers/functions/subscriptions.go b/core/services/gateway/handlers/functions/subscriptions.go
new file mode 100644
index 00000000000..181a98009f1
--- /dev/null
+++ b/core/services/gateway/handlers/functions/subscriptions.go
@@ -0,0 +1,208 @@
+package functions
+
+import (
+ "context"
+ "fmt"
+ "math/big"
+ "sync"
+ "time"
+
+ "github.com/ethereum/go-ethereum/accounts/abi/bind"
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/pkg/errors"
+
+ evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client"
+ "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/functions/generated/functions_router"
+ "github.com/smartcontractkit/chainlink/v2/core/logger"
+ "github.com/smartcontractkit/chainlink/v2/core/services/job"
+ "github.com/smartcontractkit/chainlink/v2/core/utils"
+)
+
+type OnchainSubscriptionsConfig struct {
+ ContractAddress common.Address `json:"contractAddress"`
+ BlockConfirmations uint `json:"blockConfirmations"`
+ UpdateFrequencySec uint `json:"updateFrequencySec"`
+ UpdateTimeoutSec uint `json:"updateTimeoutSec"`
+ UpdateRangeSize uint `json:"updateRangeSize"`
+}
+
+// OnchainSubscriptions maintains a mirror of all subscriptions fetched from the blockchain (EVM-only).
+// All methods are thread-safe.
+//
+//go:generate mockery --quiet --name OnchainSubscriptions --output ./mocks/ --case=underscore
+type OnchainSubscriptions interface {
+ job.ServiceCtx
+
+ // GetMaxUserBalance returns a maximum subscription balance (juels), or error if user has no subscriptions.
+ GetMaxUserBalance(common.Address) (*big.Int, error)
+}
+
+type onchainSubscriptions struct {
+ utils.StartStopOnce
+
+ config OnchainSubscriptionsConfig
+ subscriptions UserSubscriptions
+ client evmclient.Client
+ router *functions_router.FunctionsRouter
+ blockConfirmations *big.Int
+ lggr logger.Logger
+ closeWait sync.WaitGroup
+ rwMutex sync.RWMutex
+ stopCh utils.StopChan
+}
+
+func NewOnchainSubscriptions(client evmclient.Client, config OnchainSubscriptionsConfig, lggr logger.Logger) (OnchainSubscriptions, error) {
+ if client == nil {
+ return nil, errors.New("client is nil")
+ }
+ if lggr == nil {
+ return nil, errors.New("logger is nil")
+ }
+ router, err := functions_router.NewFunctionsRouter(config.ContractAddress, client)
+ if err != nil {
+ return nil, fmt.Errorf("unexpected error during functions_router.NewFunctionsRouter: %s", err)
+ }
+ return &onchainSubscriptions{
+ config: config,
+ subscriptions: NewUserSubscriptions(),
+ client: client,
+ router: router,
+ blockConfirmations: big.NewInt(int64(config.BlockConfirmations)),
+ lggr: lggr.Named("OnchainSubscriptions"),
+ stopCh: make(utils.StopChan),
+ }, nil
+}
+
+func (s *onchainSubscriptions) Start(ctx context.Context) error {
+ return s.StartOnce("OnchainSubscriptions", func() error {
+ s.lggr.Info("starting onchain subscriptions")
+ if s.config.UpdateFrequencySec == 0 {
+ return errors.New("OnchainSubscriptionsConfig.UpdateFrequencySec must be greater than 0")
+ }
+ if s.config.UpdateTimeoutSec == 0 {
+ return errors.New("OnchainSubscriptionsConfig.UpdateTimeoutSec must be greater than 0")
+ }
+ if s.config.UpdateRangeSize == 0 {
+ return errors.New("OnchainSubscriptionsConfig.UpdateRangeSize must be greater than 0")
+ }
+
+ s.closeWait.Add(1)
+ go s.queryLoop()
+
+ return nil
+ })
+}
+
+func (s *onchainSubscriptions) Close() error {
+ return s.StopOnce("OnchainSubscriptions", func() (err error) {
+ s.lggr.Info("closing onchain subscriptions")
+ close(s.stopCh)
+ s.closeWait.Wait()
+ return nil
+ })
+}
+
+func (s *onchainSubscriptions) GetMaxUserBalance(user common.Address) (*big.Int, error) {
+ s.rwMutex.RLock()
+ defer s.rwMutex.RUnlock()
+ return s.subscriptions.GetMaxUserBalance(user)
+}
+
+func (s *onchainSubscriptions) queryLoop() {
+ defer s.closeWait.Done()
+
+ ticker := time.NewTicker(time.Duration(s.config.UpdateFrequencySec) * time.Second)
+ defer ticker.Stop()
+
+ start := uint64(1)
+ lastKnownCount := uint64(0)
+
+ queryFunc := func() {
+ ctx, cancel := utils.ContextFromChanWithTimeout(s.stopCh, time.Duration(s.config.UpdateTimeoutSec)*time.Second)
+ defer cancel()
+
+ latestBlockHeight, err := s.client.LatestBlockHeight(ctx)
+ if err != nil || latestBlockHeight == nil {
+ s.lggr.Errorw("Error calling LatestBlockHeight", "err", err, "latestBlockHeight", latestBlockHeight.Int64())
+ return
+ }
+
+ blockNumber := big.NewInt(0).Sub(latestBlockHeight, s.blockConfirmations)
+
+ updateLastKnownCount := func() {
+ count, err := s.getSubscriptionsCount(ctx, blockNumber)
+ if err != nil {
+ s.lggr.Errorw("Error getting subscriptions count", "err", err)
+ return
+ }
+ s.lggr.Infow("Updated subscriptions count", "err", err, "count", count, "blockNumber", blockNumber.Int64())
+ lastKnownCount = count
+ }
+
+ if lastKnownCount == 0 {
+ updateLastKnownCount()
+ }
+ if lastKnownCount == 0 {
+ s.lggr.Info("Router has no subscriptions yet")
+ return
+ }
+
+ if start > lastKnownCount {
+ start = 1
+ }
+
+ end := start + uint64(s.config.UpdateRangeSize)
+ if end > lastKnownCount {
+ updateLastKnownCount()
+ if end > lastKnownCount {
+ end = lastKnownCount
+ }
+ }
+ if err := s.querySubscriptionsRange(ctx, blockNumber, start, end); err != nil {
+ s.lggr.Errorw("Error querying subscriptions", "err", err, "start", start, "end", end)
+ return
+ }
+
+ start = end + 1
+ }
+
+ queryFunc()
+
+ for {
+ select {
+ case <-s.stopCh:
+ return
+ case <-ticker.C:
+ queryFunc()
+ }
+ }
+}
+
+func (s *onchainSubscriptions) querySubscriptionsRange(ctx context.Context, blockNumber *big.Int, start, end uint64) error {
+ subscriptions, err := s.router.GetSubscriptionsInRange(&bind.CallOpts{
+ Pending: false,
+ BlockNumber: blockNumber,
+ Context: ctx,
+ }, start, end)
+ if err != nil {
+ return errors.Wrap(err, "unexpected error during functions_router.GetSubscriptionsInRange")
+ }
+
+ s.rwMutex.Lock()
+ defer s.rwMutex.Unlock()
+ for i, subscription := range subscriptions {
+ subscriptionId := start + uint64(i)
+ subscription := subscription
+ s.subscriptions.UpdateSubscription(subscriptionId, &subscription)
+ }
+
+ return nil
+}
+
+func (s *onchainSubscriptions) getSubscriptionsCount(ctx context.Context, blockNumber *big.Int) (uint64, error) {
+ return s.router.GetSubscriptionCount(&bind.CallOpts{
+ Pending: false,
+ BlockNumber: blockNumber,
+ Context: ctx,
+ })
+}
diff --git a/core/services/gateway/handlers/functions/subscriptions_test.go b/core/services/gateway/handlers/functions/subscriptions_test.go
new file mode 100644
index 00000000000..1e46bff5c0f
--- /dev/null
+++ b/core/services/gateway/handlers/functions/subscriptions_test.go
@@ -0,0 +1,66 @@
+package functions_test
+
+import (
+ "math/big"
+ "testing"
+ "time"
+
+ "github.com/ethereum/go-ethereum"
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/common/hexutil"
+ "github.com/onsi/gomega"
+ "github.com/stretchr/testify/assert"
+ "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/internal/testutils"
+ "github.com/smartcontractkit/chainlink/v2/core/logger"
+ "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/functions"
+)
+
+const (
+ validUser = "0x9ED925d8206a4f88a2f643b28B3035B315753Cd6"
+ invalidUser = "0x6E2dc0F9DB014aE19888F539E59285D2Ea04244C"
+)
+
+func TestSubscriptions(t *testing.T) {
+ t.Parallel()
+
+ getSubscriptionCount := hexutil.MustDecode("0x0000000000000000000000000000000000000000000000000000000000000003")
+ getSubscriptionsInRange := hexutil.MustDecode("0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000240000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000109e6e1b12098cc8f3a1e9719a817ec53ab9b35c000000000000000000000000000000000000000000000000000034e23f515cb0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000f5340f0968ee8b7dfd97e3327a6139273cc2c4fa000000000000000000000000000000000000000000000001158e460913d000000000000000000000000000009ed925d8206a4f88a2f643b28b3035b315753cd60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001bc14b92364c75e20000000000000000000000009ed925d8206a4f88a2f643b28b3035b315753cd60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000005439e5881a529f3ccbffc0e82d49f9db3950aefe")
+
+ ctx := testutils.Context(t)
+ client := mocks.NewClient(t)
+ client.On("LatestBlockHeight", mock.Anything).Return(big.NewInt(42), nil)
+ client.On("CallContract", mock.Anything, ethereum.CallMsg{ // getSubscriptionCount
+ To: &common.Address{},
+ Data: hexutil.MustDecode("0x66419970"),
+ }, mock.Anything).Return(getSubscriptionCount, nil)
+ client.On("CallContract", mock.Anything, ethereum.CallMsg{ // GetSubscriptionsInRange
+ To: &common.Address{},
+ Data: hexutil.MustDecode("0xec2454e500000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000003"),
+ }, mock.Anything).Return(getSubscriptionsInRange, nil)
+ config := functions.OnchainSubscriptionsConfig{
+ ContractAddress: common.Address{},
+ BlockConfirmations: 1,
+ UpdateFrequencySec: 1,
+ UpdateTimeoutSec: 1,
+ UpdateRangeSize: 10,
+ }
+ subscriptions, err := functions.NewOnchainSubscriptions(client, config, logger.TestLogger(t))
+ require.NoError(t, err)
+
+ err = subscriptions.Start(ctx)
+ require.NoError(t, err)
+ t.Cleanup(func() {
+ assert.NoError(t, subscriptions.Close())
+ })
+
+ gomega.NewGomegaWithT(t).Eventually(func() bool {
+ expectedBalance := big.NewInt(0).SetBytes(hexutil.MustDecode("0x01158e460913d00000"))
+ balance, err1 := subscriptions.GetMaxUserBalance(common.HexToAddress(validUser))
+ _, err2 := subscriptions.GetMaxUserBalance(common.HexToAddress(invalidUser))
+ return err1 == nil && err2 != nil && balance.Cmp(expectedBalance) == 0
+ }, testutils.WaitTimeout(t), time.Second).Should(gomega.BeTrue())
+}
diff --git a/core/services/gateway/handlers/functions/user_subscriptions.go b/core/services/gateway/handlers/functions/user_subscriptions.go
new file mode 100644
index 00000000000..c47ac8a4c90
--- /dev/null
+++ b/core/services/gateway/handlers/functions/user_subscriptions.go
@@ -0,0 +1,64 @@
+package functions
+
+import (
+ "math/big"
+
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/pkg/errors"
+
+ "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/functions/generated/functions_router"
+ "github.com/smartcontractkit/chainlink/v2/core/utils"
+)
+
+// Methods are NOT thread-safe.
+
+type UserSubscriptions interface {
+ UpdateSubscription(subscriptionId uint64, subscription *functions_router.IFunctionsSubscriptionsSubscription)
+ GetMaxUserBalance(user common.Address) (*big.Int, error)
+}
+
+type userSubscriptions struct {
+ userSubscriptionsMap map[common.Address]map[uint64]*functions_router.IFunctionsSubscriptionsSubscription
+ subscriptionIdsMap map[uint64]common.Address
+}
+
+func NewUserSubscriptions() UserSubscriptions {
+ return &userSubscriptions{
+ userSubscriptionsMap: make(map[common.Address]map[uint64]*functions_router.IFunctionsSubscriptionsSubscription),
+ subscriptionIdsMap: make(map[uint64]common.Address),
+ }
+}
+
+func (us *userSubscriptions) UpdateSubscription(subscriptionId uint64, subscription *functions_router.IFunctionsSubscriptionsSubscription) {
+ if subscription == nil || subscription.Owner == utils.ZeroAddress {
+ user, ok := us.subscriptionIdsMap[subscriptionId]
+ if ok {
+ delete(us.userSubscriptionsMap[user], subscriptionId)
+ if len(us.userSubscriptionsMap[user]) == 0 {
+ delete(us.userSubscriptionsMap, user)
+ }
+ }
+ delete(us.subscriptionIdsMap, subscriptionId)
+ } else {
+ us.subscriptionIdsMap[subscriptionId] = subscription.Owner
+ if _, ok := us.userSubscriptionsMap[subscription.Owner]; !ok {
+ us.userSubscriptionsMap[subscription.Owner] = make(map[uint64]*functions_router.IFunctionsSubscriptionsSubscription)
+ }
+ us.userSubscriptionsMap[subscription.Owner][subscriptionId] = subscription
+ }
+}
+
+func (us *userSubscriptions) GetMaxUserBalance(user common.Address) (*big.Int, error) {
+ subs, exists := us.userSubscriptionsMap[user]
+ if !exists {
+ return nil, errors.New("user has no subscriptions")
+ }
+
+ maxBalance := big.NewInt(0)
+ for _, sub := range subs {
+ if sub.Balance.Cmp(maxBalance) > 0 {
+ maxBalance = sub.Balance
+ }
+ }
+ return maxBalance, nil
+}
diff --git a/core/services/gateway/handlers/functions/user_subscriptions_test.go b/core/services/gateway/handlers/functions/user_subscriptions_test.go
new file mode 100644
index 00000000000..9e6a660adad
--- /dev/null
+++ b/core/services/gateway/handlers/functions/user_subscriptions_test.go
@@ -0,0 +1,77 @@
+package functions_test
+
+import (
+ "math/big"
+ "testing"
+
+ "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/functions/generated/functions_router"
+ "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/functions"
+ "github.com/smartcontractkit/chainlink/v2/core/utils"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestUserSubscriptions(t *testing.T) {
+ t.Parallel()
+
+ us := functions.NewUserSubscriptions()
+
+ t.Run("GetMaxUserBalance for unknown user", func(t *testing.T) {
+ _, err := us.GetMaxUserBalance(utils.RandomAddress())
+ assert.Error(t, err)
+ })
+
+ t.Run("UpdateSubscription then GetMaxUserBalance", func(t *testing.T) {
+ user1 := utils.RandomAddress()
+ user1Balance := big.NewInt(10)
+ user2 := utils.RandomAddress()
+ user2Balance1 := big.NewInt(50)
+ user2Balance2 := big.NewInt(70)
+
+ us.UpdateSubscription(5, &functions_router.IFunctionsSubscriptionsSubscription{
+ Owner: user1,
+ Balance: user1Balance,
+ })
+ us.UpdateSubscription(3, &functions_router.IFunctionsSubscriptionsSubscription{
+ Owner: user2,
+ Balance: user2Balance1,
+ })
+ us.UpdateSubscription(10, &functions_router.IFunctionsSubscriptionsSubscription{
+ Owner: user2,
+ Balance: user2Balance2,
+ })
+
+ balance, err := us.GetMaxUserBalance(user1)
+ assert.NoError(t, err)
+ assert.Zero(t, balance.Cmp(user1Balance))
+
+ balance, err = us.GetMaxUserBalance(user2)
+ assert.NoError(t, err)
+ assert.Zero(t, balance.Cmp(user2Balance2))
+ })
+
+ t.Run("UpdateSubscription to remove subscriptions", func(t *testing.T) {
+ user2 := utils.RandomAddress()
+ user2Balance1 := big.NewInt(50)
+ user2Balance2 := big.NewInt(70)
+
+ us.UpdateSubscription(3, &functions_router.IFunctionsSubscriptionsSubscription{
+ Owner: user2,
+ Balance: user2Balance1,
+ })
+ us.UpdateSubscription(10, &functions_router.IFunctionsSubscriptionsSubscription{
+ Owner: user2,
+ Balance: user2Balance2,
+ })
+
+ us.UpdateSubscription(3, &functions_router.IFunctionsSubscriptionsSubscription{
+ Owner: utils.ZeroAddress,
+ })
+ us.UpdateSubscription(10, &functions_router.IFunctionsSubscriptionsSubscription{
+ Owner: utils.ZeroAddress,
+ })
+
+ _, err := us.GetMaxUserBalance(user2)
+ assert.Error(t, err)
+ })
+}
diff --git a/core/services/gateway/handlers/handler.dummy.go b/core/services/gateway/handlers/handler.dummy.go
index 7615c734d8d..9cdd0865606 100644
--- a/core/services/gateway/handlers/handler.dummy.go
+++ b/core/services/gateway/handlers/handler.dummy.go
@@ -32,7 +32,7 @@ func NewDummyHandler(donConfig *config.DONConfig, don DON, lggr logger.Logger) (
donConfig: donConfig,
don: don,
savedCallbacks: make(map[string]*savedCallback),
- lggr: lggr,
+ lggr: lggr.Named("DummyHandler." + donConfig.DonId),
}, nil
}
diff --git a/core/services/gateway/integration_tests/gateway_integration_test.go b/core/services/gateway/integration_tests/gateway_integration_test.go
index 7a0204a3156..310047950e6 100644
--- a/core/services/gateway/integration_tests/gateway_integration_test.go
+++ b/core/services/gateway/integration_tests/gateway_integration_test.go
@@ -6,6 +6,7 @@ import (
"crypto/ecdsa"
"fmt"
"net/http"
+ "strings"
"sync/atomic"
"testing"
@@ -110,6 +111,8 @@ func TestIntegration_Gateway_NoFullNodes_BasicConnectionAndMessage(t *testing.T)
t.Parallel()
nodeKeys := common.NewTestNodes(t, 1)[0]
+ // Verify that addresses in config are case-insensitive
+ nodeKeys.Address = strings.ToUpper(nodeKeys.Address)
// Launch Gateway
lggr := logger.TestLogger(t)
diff --git a/core/services/gateway/network/httpserver.go b/core/services/gateway/network/httpserver.go
index 26b9126da3b..d9d3e5ee7e4 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 2e20957cf34..92215245e20 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 04b6fe3f338..bc248d202ac 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/gateway/network/wsconnection.go b/core/services/gateway/network/wsconnection.go
index 27835c363bc..b2aaf445d20 100644
--- a/core/services/gateway/network/wsconnection.go
+++ b/core/services/gateway/network/wsconnection.go
@@ -5,8 +5,11 @@ import (
"errors"
"sync/atomic"
+ "github.com/smartcontractkit/chainlink/v2/core/services"
+
"github.com/gorilla/websocket"
+ "github.com/smartcontractkit/chainlink/v2/core/logger"
"github.com/smartcontractkit/chainlink/v2/core/services/job"
"github.com/smartcontractkit/chainlink/v2/core/utils"
)
@@ -26,7 +29,8 @@ import (
// The concept of "pumps" is borrowed from https://github.com/smartcontractkit/wsrpc
// All methods are thread-safe.
type WSConnectionWrapper interface {
- job.Service
+ job.ServiceCtx
+ services.Checkable
// Update underlying connection object. Return a channel that gets an error on connection close.
// Cannot be called after Close().
@@ -39,6 +43,7 @@ type WSConnectionWrapper interface {
type wsConnectionWrapper struct {
utils.StartStopOnce
+ lggr logger.Logger
conn atomic.Pointer[websocket.Conn]
@@ -47,6 +52,12 @@ type wsConnectionWrapper struct {
shutdownCh chan struct{}
}
+func (c *wsConnectionWrapper) HealthReport() map[string]error {
+ return map[string]error{c.Name(): c.Healthy()}
+}
+
+func (c *wsConnectionWrapper) Name() string { return c.lggr.Name() }
+
type ReadItem struct {
MsgType int
Data []byte
@@ -65,8 +76,9 @@ var (
ErrWrapperShutdown = errors.New("wrapper shutting down")
)
-func NewWSConnectionWrapper() WSConnectionWrapper {
+func NewWSConnectionWrapper(lggr logger.Logger) WSConnectionWrapper {
cw := &wsConnectionWrapper{
+ lggr: lggr.Named("WSConnectionWrapper"),
writeCh: make(chan writeItem),
readCh: make(chan ReadItem),
shutdownCh: make(chan struct{}),
@@ -74,7 +86,7 @@ func NewWSConnectionWrapper() WSConnectionWrapper {
return cw
}
-func (c *wsConnectionWrapper) Start() error {
+func (c *wsConnectionWrapper) Start(_ context.Context) error {
return c.StartOnce("WSConnectionWrapper", func() error {
// write pump runs until Shutdown() is called
go c.writePump()
diff --git a/core/services/gateway/network/wsconnection_test.go b/core/services/gateway/network/wsconnection_test.go
index 23f7a856cd4..5fd8aa50e33 100644
--- a/core/services/gateway/network/wsconnection_test.go
+++ b/core/services/gateway/network/wsconnection_test.go
@@ -10,6 +10,7 @@ import (
"github.com/stretchr/testify/require"
"github.com/smartcontractkit/chainlink/v2/core/internal/testutils"
+ "github.com/smartcontractkit/chainlink/v2/core/logger"
"github.com/smartcontractkit/chainlink/v2/core/services/gateway/network"
)
@@ -29,16 +30,18 @@ func (ssl *serverSideLogic) wsHandler(w http.ResponseWriter, r *http.Request) {
}
func TestWSConnectionWrapper_ClientReconnect(t *testing.T) {
+ ctx := testutils.Context(t)
+ lggr := logger.TestLogger(t)
// server
- ssl := &serverSideLogic{connWrapper: network.NewWSConnectionWrapper()}
- require.NoError(t, ssl.connWrapper.Start())
+ ssl := &serverSideLogic{connWrapper: network.NewWSConnectionWrapper(lggr)}
+ require.NoError(t, ssl.connWrapper.Start(ctx))
s := httptest.NewServer(http.HandlerFunc(ssl.wsHandler))
serverURL := "ws" + strings.TrimPrefix(s.URL, "http")
defer s.Close()
// client
- clientConnWrapper := network.NewWSConnectionWrapper()
- require.NoError(t, clientConnWrapper.Start())
+ clientConnWrapper := network.NewWSConnectionWrapper(lggr)
+ require.NoError(t, clientConnWrapper.Start(ctx))
// connect, write a message, disconnect
conn, _, err := websocket.DefaultDialer.Dial(serverURL, nil)
diff --git a/core/services/health.go b/core/services/health.go
index b9367429dbf..1912a49b75e 100644
--- a/core/services/health.go
+++ b/core/services/health.go
@@ -21,7 +21,7 @@ type (
// Checker provides a service which can be probed for system health.
Checker interface {
// Register a service for health checks.
- Register(name string, service Checkable) error
+ Register(service Checkable) error
// Unregister a service.
Unregister(name string) error
// IsReady returns the current readiness of the system.
@@ -176,8 +176,9 @@ func (c *checker) update() {
uptimeSeconds.Add(interval.Seconds())
}
-func (c *checker) Register(name string, service Checkable) error {
- if service == nil || name == "" {
+func (c *checker) Register(service Checkable) error {
+ name := service.Name()
+ if name == "" {
return errors.Errorf("misconfigured check %#v for %v", name, service)
}
@@ -252,11 +253,7 @@ func (i *InBackupHealthReport) Stop() {
func (i *InBackupHealthReport) Start() {
go func() {
http.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) {
- w.WriteHeader(http.StatusServiceUnavailable)
- _, err := w.Write([]byte("Database backup in progress..."))
- if err != nil {
- i.lggr.Errorf("Cannot write response to /health")
- }
+ w.WriteHeader(http.StatusNoContent)
})
i.lggr.Info("Starting InBackupHealthReport")
if err := i.server.ListenAndServe(); !errors.Is(err, http.ErrServerClosed) {
diff --git a/core/services/health_test.go b/core/services/health_test.go
index 56c91277e4c..f8e139af157 100644
--- a/core/services/health_test.go
+++ b/core/services/health_test.go
@@ -1,8 +1,6 @@
package services_test
import (
- "fmt"
- "io"
"net/http"
"testing"
"time"
@@ -23,6 +21,8 @@ type boolCheck struct {
healthy bool
}
+func (b boolCheck) Name() string { return b.name }
+
func (b boolCheck) Ready() error {
if b.healthy {
return nil
@@ -58,8 +58,8 @@ func TestCheck(t *testing.T) {
}},
} {
c := services.NewChecker()
- for i, check := range test.checks {
- require.NoError(t, c.Register(fmt.Sprint(i), check))
+ for _, check := range test.checks {
+ require.NoError(t, c.Register(check))
}
require.NoError(t, c.Start())
@@ -81,11 +81,7 @@ func TestNewInBackupHealthReport(t *testing.T) {
res, err := http.Get("http://localhost:1234/health")
require.NoError(t, err)
- require.Equal(t, http.StatusServiceUnavailable, res.StatusCode)
-
- resBody, err := io.ReadAll(res.Body)
- require.NoError(t, err)
- require.Equal(t, "Database backup in progress...", string(resBody))
+ require.Equal(t, http.StatusNoContent, res.StatusCode)
ibhr.Stop()
require.Eventually(t, func() bool { return observed.Len() >= 1 }, time.Second*5, time.Millisecond*100)
diff --git a/core/services/job/helpers_test.go b/core/services/job/helpers_test.go
index 106ba8d27c7..167ed5297cc 100644
--- a/core/services/job/helpers_test.go
+++ b/core/services/job/helpers_test.go
@@ -35,6 +35,7 @@ const (
type = "offchainreporting"
schemaVersion = 1
contractAddress = "%s"
+evmChainID = "0"
p2pBootstrapPeers = [
"/dns4/chain.link/tcp/1234/p2p/16Uiu2HAm58SP7UL8zsnpeuwHfytLocaqgnyaYKP8wu7qRdrixLju",
]
@@ -112,6 +113,7 @@ ds1 -> ds1_parse -> ds1_multiply;
transmitterAddress = "%s"
keyBundleID = "%s"
observationTimeout = "10s"
+ evmChainID = "0"
observationSource = """
ds1 [type=http method=GET url="%s" allowunrestrictednetworkaccess="true" %s];
ds1_parse [type=jsonparse path="USD" lax=true];
@@ -122,6 +124,7 @@ ds1 -> ds1_parse;
type = "offchainreporting"
schemaVersion = 1
contractAddress = "%s"
+ evmChainID = "0"
p2pBootstrapPeers = []
isBootstrapPeer = true
`
@@ -129,6 +132,7 @@ ds1 -> ds1_parse;
type = "offchainreporting"
schemaVersion = 1
contractAddress = "%s"
+evmChainID = "0"
p2pPeerID = "%s"
p2pBootstrapPeers = [
"/dns4/chain.link/tcp/1234/p2p/16Uiu2HAm58SP7UL8zsnpeuwHfytLocaqgnyaYKP8wu7qRdrixLju",
@@ -220,9 +224,8 @@ func makeMinimalHTTPOracleSpec(t *testing.T, db *sqlx.DB, cfg chainlink.GeneralC
s := fmt.Sprintf(minimalNonBootstrapTemplate, contractAddress, transmitterAddress, keyBundle, fetchUrl, timeout)
keyStore := cltest.NewKeyStore(t, db, pgtest.NewQConfig(true))
relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, Client: evmtest.NewEthClientMockWithDefaultChain(t), GeneralConfig: cfg, KeyStore: keyStore.Eth()})
- legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
- require.NoError(t, err)
- _, err = ocr.ValidatedOracleSpecToml(legacyChains, s)
+ legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
+ _, err := ocr.ValidatedOracleSpecToml(legacyChains, s)
require.NoError(t, err)
err = toml.Unmarshal([]byte(s), &os)
require.NoError(t, err)
diff --git a/core/services/job/job_orm_test.go b/core/services/job/job_orm_test.go
index 0f70e74b247..bf81064e6a6 100644
--- a/core/services/job/job_orm_test.go
+++ b/core/services/job/job_orm_test.go
@@ -15,6 +15,8 @@ import (
"github.com/stretchr/testify/require"
"gopkg.in/guregu/null.v4"
+ "github.com/smartcontractkit/chainlink-relay/pkg/types"
+
"github.com/smartcontractkit/chainlink/v2/core/services/relay"
"github.com/smartcontractkit/chainlink/v2/core/assets"
@@ -83,8 +85,7 @@ func TestORM(t *testing.T) {
bridgesORM := bridges.NewORM(db, logger.TestLogger(t), config.Database())
relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: ethKeyStore})
- legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
- require.NoError(t, err)
+ legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
orm := NewTestORM(t, db, legacyChains, pipelineORM, bridgesORM, keyStore, config.Database())
borm := bridges.NewORM(db, logger.TestLogger(t), config.Database())
@@ -259,6 +260,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)
@@ -317,8 +319,7 @@ func TestORM_DeleteJob_DeletesAssociatedRecords(t *testing.T) {
pipelineORM := pipeline.NewORM(db, lggr, config.Database(), config.JobPipeline().MaxSuccessfulRuns())
bridgesORM := bridges.NewORM(db, lggr, config.Database())
relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()})
- legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
- require.NoError(t, err)
+ legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
jobORM := NewTestORM(t, db, legacyChains, pipelineORM, bridgesORM, keyStore, config.Database())
scopedConfig := evmtest.NewChainScopedConfig(t, config)
korm := keeper.NewORM(db, logger.TestLogger(t), scopedConfig.Database())
@@ -418,8 +419,7 @@ func TestORM_CreateJob_VRFV2(t *testing.T) {
pipelineORM := pipeline.NewORM(db, lggr, config.Database(), config.JobPipeline().MaxSuccessfulRuns())
bridgesORM := bridges.NewORM(db, lggr, config.Database())
relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()})
- legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
- require.NoError(t, err)
+ legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
jobORM := NewTestORM(t, db, legacyChains, pipelineORM, bridgesORM, keyStore, config.Database())
@@ -502,8 +502,7 @@ func TestORM_CreateJob_VRFV2Plus(t *testing.T) {
pipelineORM := pipeline.NewORM(db, lggr, config.Database(), config.JobPipeline().MaxSuccessfulRuns())
bridgesORM := bridges.NewORM(db, lggr, config.Database())
cc := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()})
- legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(cc)
- require.NoError(t, err)
+ legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(cc)
jobORM := NewTestORM(t, db, legacyChains, pipelineORM, bridgesORM, keyStore, config.Database())
fromAddresses := []string{cltest.NewEIP55Address().String(), cltest.NewEIP55Address().String()}
@@ -588,8 +587,7 @@ func TestORM_CreateJob_OCRBootstrap(t *testing.T) {
pipelineORM := pipeline.NewORM(db, lggr, config.Database(), config.JobPipeline().MaxSuccessfulRuns())
bridgesORM := bridges.NewORM(db, lggr, config.Database())
relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()})
- legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
- require.NoError(t, err)
+ legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
jobORM := NewTestORM(t, db, legacyChains, pipelineORM, bridgesORM, keyStore, config.Database())
jb, err := ocrbootstrap.ValidatedBootstrapSpecToml(testspecs.OCRBootstrapSpec)
@@ -608,6 +606,92 @@ func TestORM_CreateJob_OCRBootstrap(t *testing.T) {
cltest.AssertCount(t, db, "jobs", 0)
}
+func TestORM_CreateJob_EVMChainID_Validation(t *testing.T) {
+ config := configtest.NewGeneralConfig(t, nil)
+ db := pgtest.NewSqlxDB(t)
+ keyStore := cltest.NewKeyStore(t, db, config.Database())
+
+ lggr := logger.TestLogger(t)
+ pipelineORM := pipeline.NewORM(db, lggr, config.Database(), config.JobPipeline().MaxSuccessfulRuns())
+ bridgesORM := bridges.NewORM(db, lggr, config.Database())
+
+ relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()})
+ legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
+ jobORM := NewTestORM(t, db, legacyChains, pipelineORM, bridgesORM, keyStore, config.Database())
+
+ t.Run("evm chain id validation for ocr works", func(t *testing.T) {
+ jb := job.Job{
+ Type: job.OffchainReporting,
+ OCROracleSpec: &job.OCROracleSpec{},
+ }
+ assert.Equal(t, "CreateJobFailed: evm chain id must be defined", jobORM.CreateJob(&jb).Error())
+ })
+
+ t.Run("evm chain id validation for direct request works", func(t *testing.T) {
+ jb := job.Job{
+ Type: job.DirectRequest,
+ DirectRequestSpec: &job.DirectRequestSpec{},
+ }
+ assert.Equal(t, "CreateJobFailed: evm chain id must be defined", jobORM.CreateJob(&jb).Error())
+ })
+
+ t.Run("evm chain id validation for flux monitor works", func(t *testing.T) {
+ jb := job.Job{
+ Type: job.FluxMonitor,
+ FluxMonitorSpec: &job.FluxMonitorSpec{},
+ }
+ assert.Equal(t, "CreateJobFailed: evm chain id must be defined", jobORM.CreateJob(&jb).Error())
+ })
+
+ t.Run("evm chain id validation for keepers works", func(t *testing.T) {
+ jb := job.Job{
+ Type: job.Keeper,
+ KeeperSpec: &job.KeeperSpec{},
+ }
+ assert.Equal(t, "CreateJobFailed: evm chain id must be defined", jobORM.CreateJob(&jb).Error())
+ })
+
+ t.Run("evm chain id validation for vrf works", func(t *testing.T) {
+ jb := job.Job{
+ Type: job.VRF,
+ VRFSpec: &job.VRFSpec{},
+ }
+ assert.Equal(t, "CreateJobFailed: evm chain id must be defined", jobORM.CreateJob(&jb).Error())
+ })
+
+ t.Run("evm chain id validation for block hash store works", func(t *testing.T) {
+ jb := job.Job{
+ Type: job.BlockhashStore,
+ BlockhashStoreSpec: &job.BlockhashStoreSpec{},
+ }
+ assert.Equal(t, "CreateJobFailed: evm chain id must be defined", jobORM.CreateJob(&jb).Error())
+ })
+
+ t.Run("evm chain id validation for block header feeder works", func(t *testing.T) {
+ jb := job.Job{
+ Type: job.BlockHeaderFeeder,
+ BlockHeaderFeederSpec: &job.BlockHeaderFeederSpec{},
+ }
+ assert.Equal(t, "CreateJobFailed: evm chain id must be defined", jobORM.CreateJob(&jb).Error())
+ })
+
+ t.Run("evm chain id validation for legacy gas station server spec works", func(t *testing.T) {
+ jb := job.Job{
+ Type: job.LegacyGasStationServer,
+ LegacyGasStationServerSpec: &job.LegacyGasStationServerSpec{},
+ }
+ assert.Equal(t, "CreateJobFailed: evm chain id must be defined", jobORM.CreateJob(&jb).Error())
+ })
+
+ t.Run("evm chain id validation for legacy gas station sidecar spec works", func(t *testing.T) {
+ jb := job.Job{
+ Type: job.LegacyGasStationSidecar,
+ LegacyGasStationSidecarSpec: &job.LegacyGasStationSidecarSpec{},
+ }
+ assert.Equal(t, "CreateJobFailed: evm chain id must be defined", jobORM.CreateJob(&jb).Error())
+ })
+}
+
func TestORM_CreateJob_OCR_DuplicatedContractAddress(t *testing.T) {
customChainID := utils.NewBig(testutils.NewRandomEVMChainID())
@@ -629,117 +713,51 @@ func TestORM_CreateJob_OCR_DuplicatedContractAddress(t *testing.T) {
bridgesORM := bridges.NewORM(db, lggr, config.Database())
relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()})
- legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
- require.NoError(t, err)
+ legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
jobORM := NewTestORM(t, db, legacyChains, pipelineORM, bridgesORM, keyStore, config.Database())
- defaultChainID := config.DefaultChainID()
-
+ // defaultChainID is deprecated
+ defaultChainID := customChainID
_, address := cltest.MustInsertRandomKey(t, keyStore.Eth())
_, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}, config.Database())
_, bridge2 := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}, config.Database())
- // EVMChainID will default to 0, but we want to override that
- // with nil later to represent a job spec with no chain id
- spec := testspecs.GenerateOCRSpec(testspecs.OCRSpecParams{
- Name: "job1",
- DS1BridgeName: bridge.Name.String(),
- DS2BridgeName: bridge2.Name.String(),
- TransmitterAddress: address.Hex(),
- })
-
- jb, err := ocr.ValidatedOracleSpecToml(legacyChains, spec.Toml())
- require.NoError(t, err)
-
- // 2nd job with no Chain ID
- spec2 := testspecs.GenerateOCRSpec(testspecs.OCRSpecParams{
- Name: "job2",
- DS1BridgeName: bridge.Name.String(),
- DS2BridgeName: bridge2.Name.String(),
- TransmitterAddress: address.Hex(),
- })
- jb2, err := ocr.ValidatedOracleSpecToml(legacyChains, spec2.Toml())
- require.NoError(t, err)
-
- // Default Chain Job
+ // Custom Chain Job
externalJobID := uuid.NullUUID{UUID: uuid.New(), Valid: true}
- spec3 := testspecs.GenerateOCRSpec(testspecs.OCRSpecParams{
+ spec := testspecs.GenerateOCRSpec(testspecs.OCRSpecParams{
Name: "job3",
- EVMChainID: defaultChainID.String(),
- DS1BridgeName: bridge.Name.String(),
- DS2BridgeName: bridge2.Name.String(),
- TransmitterAddress: address.Hex(),
- JobID: externalJobID.UUID.String(),
- })
- jb3, err := ocr.ValidatedOracleSpecToml(legacyChains, spec3.Toml())
- require.NoError(t, err)
-
- // Custom Chain Job
- externalJobID = uuid.NullUUID{UUID: uuid.New(), Valid: true}
- spec4 := testspecs.GenerateOCRSpec(testspecs.OCRSpecParams{
- Name: "job4",
EVMChainID: customChainID.String(),
DS1BridgeName: bridge.Name.String(),
DS2BridgeName: bridge2.Name.String(),
TransmitterAddress: address.Hex(),
JobID: externalJobID.UUID.String(),
})
- jb4, err := ocr.ValidatedOracleSpecToml(legacyChains, spec4.Toml())
+ jb, err := ocr.ValidatedOracleSpecToml(legacyChains, spec.Toml())
require.NoError(t, err)
- t.Run("with legacy NULL chain id", func(t *testing.T) {
- err = jobORM.CreateJob(&jb)
- require.NoError(t, err)
- _, err := db.ExecContext(testutils.Context(t),
- "UPDATE ocr_oracle_specs o SET evm_chain_id=NULL FROM jobs j WHERE o.id = j.ocr_oracle_spec_id AND j.id=$1", jb.ID)
- require.NoError(t, err)
-
- cltest.AssertCount(t, db, "ocr_oracle_specs", 1)
- cltest.AssertCount(t, db, "jobs", 1)
-
- jb2.OCROracleSpec.EVMChainID = nil
- err = jobORM.CreateJob(&jb2) // try adding job for same contract with no chain id in spec
- require.Error(t, err)
- assert.Equal(t, fmt.Sprintf("CreateJobFailed: a job with contract address %s already exists for chain ID %s", jb2.OCROracleSpec.ContractAddress, defaultChainID.String()), err.Error())
-
- err = jobORM.CreateJob(&jb3) // try adding job for same contract with default chain id
- require.Error(t, err)
- assert.Equal(t, fmt.Sprintf("CreateJobFailed: a job with contract address %s already exists for chain ID %d", jb3.OCROracleSpec.ContractAddress, jb3.OCROracleSpec.EVMChainID.ToInt()), err.Error())
-
- err = jobORM.CreateJob(&jb4) // Try adding job with custom chain id
- require.Error(t, err)
- assert.Equal(t, fmt.Sprintf("CreateJobFailed: a job with contract address %s already exists for chain ID %d", jb4.OCROracleSpec.ContractAddress, jb4.OCROracleSpec.EVMChainID.ToInt()), err.Error())
- })
-
- require.NoError(t, jobORM.DeleteJob(jb.ID))
-
t.Run("with a set chain id", func(t *testing.T) {
- err = jobORM.CreateJob(&jb4) // Add job with custom chain id
+ err = jobORM.CreateJob(&jb) // Add job with custom chain id
require.NoError(t, err)
cltest.AssertCount(t, db, "ocr_oracle_specs", 1)
cltest.AssertCount(t, db, "jobs", 1)
- jb.OCROracleSpec.EVMChainID = nil
- err = jobORM.CreateJob(&jb)
- require.NoError(t, err) // should be able to add same contract address on default chain by omitting chain id
-
externalJobID = uuid.NullUUID{UUID: uuid.New(), Valid: true}
- spec3.JobID = externalJobID.UUID.String()
- jb3a, err := ocr.ValidatedOracleSpecToml(legacyChains, spec3.Toml())
+ spec.JobID = externalJobID.UUID.String()
+ jba, err := ocr.ValidatedOracleSpecToml(legacyChains, spec.Toml())
require.NoError(t, err)
- err = jobORM.CreateJob(&jb3a) // Try to add duplicate job with default id
+ err = jobORM.CreateJob(&jba) // Try to add duplicate job with default id
require.Error(t, err)
- assert.Equal(t, fmt.Sprintf("CreateJobFailed: a job with contract address %s already exists for chain ID %s", jb3.OCROracleSpec.ContractAddress, defaultChainID.String()), err.Error())
+ assert.Equal(t, fmt.Sprintf("CreateJobFailed: a job with contract address %s already exists for chain ID %s", jb.OCROracleSpec.ContractAddress, defaultChainID.String()), err.Error())
externalJobID = uuid.NullUUID{UUID: uuid.New(), Valid: true}
- spec4.JobID = externalJobID.UUID.String()
- jb5, err := ocr.ValidatedOracleSpecToml(legacyChains, spec4.Toml())
+ spec.JobID = externalJobID.UUID.String()
+ jb2, err := ocr.ValidatedOracleSpecToml(legacyChains, spec.Toml())
require.NoError(t, err)
- err = jobORM.CreateJob(&jb5) // Try to add duplicate job with custom id
+ err = jobORM.CreateJob(&jb2) // Try to add duplicate job with custom id
require.Error(t, err)
- assert.Equal(t, fmt.Sprintf("CreateJobFailed: a job with contract address %s already exists for chain ID %s", jb4.OCROracleSpec.ContractAddress, customChainID), err.Error())
+ assert.Equal(t, fmt.Sprintf("CreateJobFailed: a job with contract address %s already exists for chain ID %s", jb2.OCROracleSpec.ContractAddress, customChainID), err.Error())
})
}
@@ -764,8 +782,7 @@ func TestORM_CreateJob_OCR2_DuplicatedContractAddress(t *testing.T) {
bridgesORM := bridges.NewORM(db, lggr, config.Database())
relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()})
- legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
- require.NoError(t, err)
+ legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
jobORM := NewTestORM(t, db, legacyChains, pipelineORM, bridgesORM, keyStore, config.Database())
_, address := cltest.MustInsertRandomKey(t, keyStore.Eth())
@@ -829,8 +846,7 @@ func TestORM_CreateJob_OCR2_Sending_Keys_Transmitter_Keys_Validations(t *testing
relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()})
require.True(t, relayExtenders.Len() > 0)
- legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
- require.NoError(t, err)
+ legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
jobORM := NewTestORM(t, db, legacyChains, pipelineORM, bridgesORM, keyStore, config.Database())
jb, err := ocr2validate.ValidatedOracleSpecToml(config.OCR2(), config.Insecure(), testspecs.OCR2EVMSpecMinimal)
@@ -919,7 +935,7 @@ func TestORM_ValidateKeyStoreMatch(t *testing.T) {
})
t.Run("test Mercury ETH key validation", func(t *testing.T) {
- jb.OCR2OracleSpec.PluginType = job.Mercury
+ jb.OCR2OracleSpec.PluginType = types.Mercury
err = job.ValidateKeyStoreMatch(jb.OCR2OracleSpec, keyStore, "bad key")
require.EqualError(t, err, "no CSA key matching: \"bad key\"")
@@ -942,8 +958,7 @@ func Test_FindJobs(t *testing.T) {
pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.Database(), config.JobPipeline().MaxSuccessfulRuns())
bridgesORM := bridges.NewORM(db, logger.TestLogger(t), config.Database())
relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()})
- legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
- require.NoError(t, err)
+ legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
orm := NewTestORM(t, db, legacyChains, pipelineORM, bridgesORM, keyStore, config.Database())
_, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}, config.Database())
@@ -1001,9 +1016,8 @@ func Test_FindJobs(t *testing.T) {
func Test_FindJob(t *testing.T) {
t.Parallel()
- // Create a config with multiple EVM chains. The test fixtures already load a 1337 and the
- // default EVM chain ID. Additional chains will need additional fixture statements to add
- // a chain to evm_chains.
+ // Create a config with multiple EVM chains. The test fixtures already load 1337
+ // Additional chains will need additional fixture statements to add a chain to evm_chains.
config := configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) {
chainID := utils.NewBigI(1337)
enabled := true
@@ -1024,8 +1038,7 @@ func Test_FindJob(t *testing.T) {
pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.Database(), config.JobPipeline().MaxSuccessfulRuns())
bridgesORM := bridges.NewORM(db, logger.TestLogger(t), config.Database())
relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()})
- legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
- require.NoError(t, err)
+ legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
orm := NewTestORM(t, db, legacyChains, pipelineORM, bridgesORM, keyStore, config.Database())
_, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}, config.Database())
@@ -1088,28 +1101,12 @@ func Test_FindJob(t *testing.T) {
jobOCR2WithFeedID2.Name = null.StringFrom("new name")
require.NoError(t, err)
- // Create a job with the legacy null evm chain id.
- jobWithNullChain, err := ocr.ValidatedOracleSpecToml(legacyChains,
- testspecs.GenerateOCRSpec(testspecs.OCRSpecParams{
- JobID: uuid.New().String(),
- ContractAddress: "0xB47f9a6D281B2A82F8692F8dE058E4249363A6fc",
- TransmitterAddress: address.Hex(),
- Name: "ocr legacy null chain id",
- DS1BridgeName: bridge.Name.String(),
- DS2BridgeName: bridge2.Name.String(),
- }).Toml(),
- )
- require.NoError(t, err)
-
err = orm.CreateJob(&job)
require.NoError(t, err)
err = orm.CreateJob(&jobSameAddress)
require.NoError(t, err)
- err = orm.CreateJob(&jobWithNullChain)
- require.NoError(t, err)
-
err = orm.CreateJob(&jobOCR2)
require.NoError(t, err)
@@ -1120,11 +1117,6 @@ func Test_FindJob(t *testing.T) {
err = orm.CreateJob(&jobOCR2WithFeedID2)
require.NoError(t, err)
- // Set the ChainID to null manually since we can't do this in the test helper
- _, err = db.ExecContext(testutils.Context(t),
- "UPDATE ocr_oracle_specs o SET evm_chain_id=NULL FROM jobs j WHERE o.id = j.ocr_oracle_spec_id AND j.id=$1", jobWithNullChain.ID)
- require.NoError(t, err)
-
t.Run("by id", func(t *testing.T) {
ctx, cancel := context.WithTimeout(testutils.Context(t), 5*time.Second)
defer cancel()
@@ -1164,24 +1156,6 @@ func Test_FindJob(t *testing.T) {
require.ErrorIs(t, err, sql.ErrNoRows)
})
- t.Run("by address with legacy null evm chain id", func(t *testing.T) {
- jbID, err := orm.FindJobIDByAddress(
- jobWithNullChain.OCROracleSpec.ContractAddress,
- jobWithNullChain.OCROracleSpec.EVMChainID,
- )
- require.NoError(t, err)
-
- assert.Equal(t, jobWithNullChain.ID, jbID)
-
- jbID, err = orm.FindJobIDByAddress(
- jobWithNullChain.OCROracleSpec.ContractAddress,
- utils.NewBig(nil),
- )
- require.NoError(t, err)
-
- assert.Equal(t, jobWithNullChain.ID, jbID)
- })
-
t.Run("by address yet chain scoped", func(t *testing.T) {
commonAddr := jobSameAddress.OCROracleSpec.ContractAddress
@@ -1242,12 +1216,12 @@ func Test_FindJobsByPipelineSpecIDs(t *testing.T) {
pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.Database(), config.JobPipeline().MaxSuccessfulRuns())
bridgesORM := bridges.NewORM(db, logger.TestLogger(t), config.Database())
relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()})
- legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
- require.NoError(t, err)
+ legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
orm := NewTestORM(t, db, legacyChains, pipelineORM, bridgesORM, keyStore, config.Database())
jb, err := directrequest.ValidatedDirectRequestSpec(testspecs.DirectRequestSpec)
require.NoError(t, err)
+ jb.DirectRequestSpec.EVMChainID = utils.NewBigI(0)
err = orm.CreateJob(&jb)
require.NoError(t, err)
@@ -1270,6 +1244,27 @@ func Test_FindJobsByPipelineSpecIDs(t *testing.T) {
require.NoError(t, err)
assert.Len(t, jbs, 0)
})
+
+ t.Run("with chainID disabled", func(t *testing.T) {
+ newCfg := configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) {
+ c.EVM[0] = &evmcfg.EVMConfig{
+ ChainID: utils.NewBigI(0),
+ Enabled: ptr(false),
+ }
+ c.EVM = append(c.EVM, &evmcfg.EVMConfig{
+ ChainID: utils.NewBigI(123123123),
+ Enabled: ptr(true),
+ })
+ })
+ relayExtenders2 := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: newCfg, KeyStore: keyStore.Eth()})
+ legacyChains2 := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders2)
+
+ orm2 := NewTestORM(t, db, legacyChains2, pipelineORM, bridgesORM, keyStore, config.Database())
+
+ jbs, err := orm2.FindJobsByPipelineSpecIDs([]int32{jb.PipelineSpecID})
+ require.NoError(t, err)
+ assert.Len(t, jbs, 1)
+ })
}
func Test_FindPipelineRuns(t *testing.T) {
@@ -1284,8 +1279,7 @@ func Test_FindPipelineRuns(t *testing.T) {
pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.Database(), config.JobPipeline().MaxSuccessfulRuns())
bridgesORM := bridges.NewORM(db, logger.TestLogger(t), config.Database())
relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()})
- legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
- require.NoError(t, err)
+ legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
orm := NewTestORM(t, db, legacyChains, pipelineORM, bridgesORM, keyStore, config.Database())
_, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}, config.Database())
@@ -1346,8 +1340,7 @@ func Test_PipelineRunsByJobID(t *testing.T) {
pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.Database(), config.JobPipeline().MaxSuccessfulRuns())
bridgesORM := bridges.NewORM(db, logger.TestLogger(t), config.Database())
relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()})
- legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
- require.NoError(t, err)
+ legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
orm := NewTestORM(t, db, legacyChains, pipelineORM, bridgesORM, keyStore, config.Database())
_, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}, config.Database())
@@ -1408,8 +1401,7 @@ func Test_FindPipelineRunIDsByJobID(t *testing.T) {
pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.Database(), config.JobPipeline().MaxSuccessfulRuns())
bridgesORM := bridges.NewORM(db, lggr, config.Database())
relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()})
- legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
- require.NoError(t, err)
+ legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
orm := NewTestORM(t, db, legacyChains, pipelineORM, bridgesORM, keyStore, config.Database())
_, address := cltest.MustInsertRandomKey(t, keyStore.Eth())
@@ -1517,8 +1509,7 @@ func Test_FindPipelineRunsByIDs(t *testing.T) {
pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.Database(), config.JobPipeline().MaxSuccessfulRuns())
bridgesORM := bridges.NewORM(db, logger.TestLogger(t), config.Database())
relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()})
- legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
- require.NoError(t, err)
+ legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
orm := NewTestORM(t, db, legacyChains, pipelineORM, bridgesORM, keyStore, config.Database())
_, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}, config.Database())
@@ -1576,8 +1567,7 @@ func Test_FindPipelineRunByID(t *testing.T) {
pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.Database(), config.JobPipeline().MaxSuccessfulRuns())
bridgesORM := bridges.NewORM(db, logger.TestLogger(t), config.Database())
relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()})
- legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
- require.NoError(t, err)
+ legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
orm := NewTestORM(t, db, legacyChains, pipelineORM, bridgesORM, keyStore, config.Database())
jb, err := directrequest.ValidatedDirectRequestSpec(testspecs.DirectRequestSpec)
@@ -1622,8 +1612,7 @@ func Test_FindJobWithoutSpecErrors(t *testing.T) {
pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.Database(), config.JobPipeline().MaxSuccessfulRuns())
bridgesORM := bridges.NewORM(db, logger.TestLogger(t), config.Database())
relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()})
- legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
- require.NoError(t, err)
+ legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
orm := NewTestORM(t, db, legacyChains, pipelineORM, bridgesORM, keyStore, config.Database())
jb, err := directrequest.ValidatedDirectRequestSpec(testspecs.DirectRequestSpec)
@@ -1662,8 +1651,7 @@ func Test_FindSpecErrorsByJobIDs(t *testing.T) {
pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.Database(), config.JobPipeline().MaxSuccessfulRuns())
bridgesORM := bridges.NewORM(db, logger.TestLogger(t), config.Database())
relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()})
- legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
- require.NoError(t, err)
+ legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
orm := NewTestORM(t, db, legacyChains, pipelineORM, bridgesORM, keyStore, config.Database())
jb, err := directrequest.ValidatedDirectRequestSpec(testspecs.DirectRequestSpec)
@@ -1699,8 +1687,7 @@ func Test_CountPipelineRunsByJobID(t *testing.T) {
pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.Database(), config.JobPipeline().MaxSuccessfulRuns())
bridgesORM := bridges.NewORM(db, logger.TestLogger(t), config.Database())
relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()})
- legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
- require.NoError(t, err)
+ legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
orm := NewTestORM(t, db, legacyChains, pipelineORM, bridgesORM, keyStore, config.Database())
_, bridge := cltest.MustCreateBridge(t, db, cltest.BridgeOpts{}, config.Database())
diff --git a/core/services/job/job_pipeline_orm_integration_test.go b/core/services/job/job_pipeline_orm_integration_test.go
index ff1cab4f3c6..a5d3ee984da 100644
--- a/core/services/job/job_pipeline_orm_integration_test.go
+++ b/core/services/job/job_pipeline_orm_integration_test.go
@@ -152,8 +152,7 @@ func TestPipelineORM_Integration(t *testing.T) {
orm := pipeline.NewORM(db, logger.TestLogger(t), cfg.Database(), cfg.JobPipeline().MaxSuccessfulRuns())
btORM := bridges.NewORM(db, logger.TestLogger(t), cfg.Database())
relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{Client: evmtest.NewEthClientMockWithDefaultChain(t), DB: db, GeneralConfig: config, KeyStore: ethKeyStore})
- legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
- require.NoError(t, err)
+ legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
runner := pipeline.NewRunner(orm, btORM, config.JobPipeline(), cfg.WebServer(), legacyChains, nil, nil, lggr, nil, nil)
jobORM := NewTestORM(t, db, legacyChains, orm, btORM, keyStore, cfg.Database())
@@ -161,13 +160,11 @@ func TestPipelineORM_Integration(t *testing.T) {
dbSpec := makeVoterTurnoutOCRJobSpec(t, transmitterAddress, bridge.Name.String(), bridge2.Name.String())
// Need a job in order to create a run
- err = jobORM.CreateJob(dbSpec)
- require.NoError(t, err)
+ require.NoError(t, jobORM.CreateJob(dbSpec))
var pipelineSpecs []pipeline.Spec
sql := `SELECT * FROM pipeline_specs;`
- err = db.Select(&pipelineSpecs, sql)
- require.NoError(t, err)
+ require.NoError(t, db.Select(&pipelineSpecs, sql))
require.Len(t, pipelineSpecs, 1)
require.Equal(t, dbSpec.PipelineSpecID, pipelineSpecs[0].ID)
pipelineSpecID := pipelineSpecs[0].ID
diff --git a/core/services/job/models.go b/core/services/job/models.go
index d70afde12c2..5787ce5fb5f 100644
--- a/core/services/job/models.go
+++ b/core/services/job/models.go
@@ -14,8 +14,10 @@ import (
"github.com/pkg/errors"
"gopkg.in/guregu/null.v4"
+ "github.com/smartcontractkit/chainlink-relay/pkg/types"
"github.com/smartcontractkit/chainlink/v2/core/assets"
"github.com/smartcontractkit/chainlink/v2/core/bridges"
+ "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/toml"
clnull "github.com/smartcontractkit/chainlink/v2/core/null"
"github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ethkey"
"github.com/smartcontractkit/chainlink/v2/core/services/pipeline"
@@ -310,28 +312,7 @@ func (r JSONConfig) MercuryCredentialName() (string, error) {
return name, nil
}
-var ForwardersSupportedPlugins = []OCR2PluginType{Median, DKG, OCR2VRF, OCR2Keeper, OCR2Functions}
-
-// OCR2PluginType defines supported OCR2 plugin types.
-type OCR2PluginType string
-
-const (
- // Median refers to the median.Median type
- Median OCR2PluginType = "median"
-
- DKG OCR2PluginType = "dkg"
-
- OCR2VRF OCR2PluginType = "ocr2vrf"
-
- // Keeper was rebranded to automation. For now the plugin type required in job spec points
- // to the new name (automation) but in code we refer it to keepers
- // TODO: sc-55296 to rename ocr2keeper to ocr2automation in code
- OCR2Keeper OCR2PluginType = "ocr2automation"
-
- OCR2Functions OCR2PluginType = "functions"
-
- Mercury OCR2PluginType = "mercury"
-)
+var ForwardersSupportedPlugins = []types.OCR2PluginType{types.Median, types.DKG, types.OCR2VRF, types.OCR2Keeper, types.Functions}
// OCR2OracleSpec defines the job spec for OCR2 jobs.
// Relay config is chain specific config for a relay (chain adapter).
@@ -341,21 +322,32 @@ type OCR2OracleSpec struct {
FeedID *common.Hash `toml:"feedID"`
Relay relay.Network `toml:"relay"`
// TODO BCF-2442 implement ChainID as top level parameter rathe than buried in RelayConfig.
- ChainID string `toml:"chainID"`
- RelayConfig JSONConfig `toml:"relayConfig"`
- P2PV2Bootstrappers pq.StringArray `toml:"p2pv2Bootstrappers"`
- OCRKeyBundleID null.String `toml:"ocrKeyBundleID"`
- MonitoringEndpoint null.String `toml:"monitoringEndpoint"`
- TransmitterID null.String `toml:"transmitterID"`
- BlockchainTimeout models.Interval `toml:"blockchainTimeout"`
- ContractConfigTrackerPollInterval models.Interval `toml:"contractConfigTrackerPollInterval"`
- ContractConfigConfirmations uint16 `toml:"contractConfigConfirmations"`
- PluginConfig JSONConfig `toml:"pluginConfig"`
- PluginType OCR2PluginType `toml:"pluginType"`
- CreatedAt time.Time `toml:"-"`
- UpdatedAt time.Time `toml:"-"`
- CaptureEATelemetry bool `toml:"captureEATelemetry"`
- CaptureAutomationCustomTelemetry bool `toml:"captureAutomationCustomTelemetry"`
+ ChainID string `toml:"chainID"`
+ RelayConfig JSONConfig `toml:"relayConfig"`
+ P2PV2Bootstrappers pq.StringArray `toml:"p2pv2Bootstrappers"`
+ OCRKeyBundleID null.String `toml:"ocrKeyBundleID"`
+ MonitoringEndpoint null.String `toml:"monitoringEndpoint"`
+ TransmitterID null.String `toml:"transmitterID"`
+ BlockchainTimeout models.Interval `toml:"blockchainTimeout"`
+ ContractConfigTrackerPollInterval models.Interval `toml:"contractConfigTrackerPollInterval"`
+ ContractConfigConfirmations uint16 `toml:"contractConfigConfirmations"`
+ PluginConfig JSONConfig `toml:"pluginConfig"`
+ PluginType types.OCR2PluginType `toml:"pluginType"`
+ CreatedAt time.Time `toml:"-"`
+ UpdatedAt time.Time `toml:"-"`
+ CaptureEATelemetry bool `toml:"captureEATelemetry"`
+ CaptureAutomationCustomTelemetry bool `toml:"captureAutomationCustomTelemetry"`
+}
+
+func validateRelayID(id relay.ID) error {
+ // only the EVM has specific requirements
+ if id.Network == relay.EVM {
+ _, err := toml.ChainIDInt64(id.ChainID)
+ if err != nil {
+ return fmt.Errorf("invalid EVM chain id %s: %w", id.ChainID, err)
+ }
+ }
+ return nil
}
func (s *OCR2OracleSpec) RelayID() (relay.ID, error) {
@@ -363,7 +355,12 @@ func (s *OCR2OracleSpec) RelayID() (relay.ID, error) {
if err != nil {
return relay.ID{}, err
}
- return relay.NewID(s.Relay, cid)
+ rid := relay.NewID(s.Relay, cid)
+ err = validateRelayID(rid)
+ if err != nil {
+ return relay.ID{}, err
+ }
+ return rid, nil
}
func (s *OCR2OracleSpec) getChainID() (relay.ChainID, error) {
@@ -576,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 d7cfbd0fc4a..369ce039ad4 100644
--- a/core/services/job/orm.go
+++ b/core/services/job/orm.go
@@ -19,7 +19,10 @@ import (
"github.com/smartcontractkit/sqlx"
+ "github.com/smartcontractkit/chainlink-relay/pkg/types"
+
"github.com/smartcontractkit/chainlink/v2/core/bridges"
+ "github.com/smartcontractkit/chainlink/v2/core/chains"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm"
evmconfig "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config"
"github.com/smartcontractkit/chainlink/v2/core/config"
@@ -164,6 +167,9 @@ func (o *orm) CreateJob(jb *Job, qopts ...pg.QOpt) error {
switch jb.Type {
case DirectRequest:
+ if jb.DirectRequestSpec.EVMChainID == nil {
+ return errors.New("evm chain id must be defined")
+ }
var specID int32
sql := `INSERT INTO direct_request_specs (contract_address, min_incoming_confirmations, requesters, min_contract_payment, evm_chain_id, created_at, updated_at)
VALUES (:contract_address, :min_incoming_confirmations, :requesters, :min_contract_payment, :evm_chain_id, now(), now())
@@ -173,6 +179,9 @@ func (o *orm) CreateJob(jb *Job, qopts ...pg.QOpt) error {
}
jb.DirectRequestSpecID = &specID
case FluxMonitor:
+ if jb.FluxMonitorSpec.EVMChainID == nil {
+ return errors.New("evm chain id must be defined")
+ }
var specID int32
sql := `INSERT INTO flux_monitor_specs (contract_address, threshold, absolute_threshold, poll_timer_period, poll_timer_disabled, idle_timer_period, idle_timer_disabled,
drumbeat_schedule, drumbeat_random_delay, drumbeat_enabled, min_payment, evm_chain_id, created_at, updated_at)
@@ -184,6 +193,10 @@ func (o *orm) CreateJob(jb *Job, qopts ...pg.QOpt) error {
}
jb.FluxMonitorSpecID = &specID
case OffchainReporting:
+ if jb.OCROracleSpec.EVMChainID == nil {
+ return errors.New("evm chain id must be defined")
+ }
+
var specID int32
if jb.OCROracleSpec.EncryptedOCRKeyBundleID != nil {
_, err := o.keyStore.OCR().Get(jb.OCROracleSpec.EncryptedOCRKeyBundleID.String())
@@ -198,16 +211,7 @@ func (o *orm) CreateJob(jb *Job, qopts ...pg.QOpt) error {
}
}
- if jb.OCROracleSpec.EVMChainID == nil {
- // If unspecified, assume we're creating a job intended to run on default chain id
- newChain, err := o.legacyChains.Default()
- if err != nil {
- return err
- }
- jb.OCROracleSpec.EVMChainID = utils.NewBig(newChain.ID())
- }
newChainID := jb.OCROracleSpec.EVMChainID
-
existingSpec := new(OCROracleSpec)
err := tx.Get(existingSpec, `SELECT * FROM ocr_oracle_specs WHERE contract_address = $1 and (evm_chain_id = $2 or evm_chain_id IS NULL) LIMIT 1;`,
jb.OCROracleSpec.ContractAddress, newChainID,
@@ -267,7 +271,7 @@ func (o *orm) CreateJob(jb *Job, qopts ...pg.QOpt) error {
return errors.Errorf("forwarding is not currently supported for %s jobs", jb.OCR2OracleSpec.PluginType)
}
- if jb.OCR2OracleSpec.PluginType == Mercury {
+ if jb.OCR2OracleSpec.PluginType == types.Mercury {
if jb.OCR2OracleSpec.FeedID == nil {
return errors.New("feed ID is required for mercury plugin type")
}
@@ -277,7 +281,7 @@ func (o *orm) CreateJob(jb *Job, qopts ...pg.QOpt) error {
}
}
- if jb.OCR2OracleSpec.PluginType == Median {
+ if jb.OCR2OracleSpec.PluginType == types.Median {
var cfg medianconfig.PluginConfig
err = json.Unmarshal(jb.OCR2OracleSpec.PluginConfig.Bytes(), &cfg)
if err != nil {
@@ -305,6 +309,9 @@ func (o *orm) CreateJob(jb *Job, qopts ...pg.QOpt) error {
}
jb.OCR2OracleSpecID = &specID
case Keeper:
+ if jb.KeeperSpec.EVMChainID == nil {
+ return errors.New("evm chain id must be defined")
+ }
var specID int32
sql := `INSERT INTO keeper_specs (contract_address, from_address, evm_chain_id, created_at, updated_at)
VALUES (:contract_address, :from_address, :evm_chain_id, NOW(), NOW())
@@ -323,6 +330,9 @@ func (o *orm) CreateJob(jb *Job, qopts ...pg.QOpt) error {
}
jb.CronSpecID = &specID
case VRF:
+ if jb.VRFSpec.EVMChainID == nil {
+ return errors.New("evm chain id must be defined")
+ }
var specID int32
sql := `INSERT INTO vrf_specs (
coordinator_address, public_key, min_incoming_confirmations,
@@ -374,15 +384,21 @@ func (o *orm) CreateJob(jb *Job, qopts ...pg.QOpt) error {
}
}
case BlockhashStore:
+ if jb.BlockhashStoreSpec.EVMChainID == nil {
+ 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")
}
jb.BlockhashStoreSpecID = &specID
case BlockHeaderFeeder:
+ if jb.BlockHeaderFeederSpec.EVMChainID == nil {
+ return errors.New("evm chain id must be defined")
+ }
var specID int32
sql := `INSERT INTO block_header_feeder_specs (coordinator_v1_address, coordinator_v2_address, coordinator_v2_plus_address, wait_blocks, lookback_blocks, blockhash_store_address, batch_blockhash_store_address, poll_period, run_timeout, evm_chain_id, from_addresses, get_blockhashes_batch_size, store_blockhashes_batch_size, created_at, updated_at)
VALUES (:coordinator_v1_address, :coordinator_v2_address, :coordinator_v2_plus_address, :wait_blocks, :lookback_blocks, :blockhash_store_address, :batch_blockhash_store_address, :poll_period, :run_timeout, :evm_chain_id, :from_addresses, :get_blockhashes_batch_size, :store_blockhashes_batch_size, NOW(), NOW())
@@ -392,6 +408,9 @@ func (o *orm) CreateJob(jb *Job, qopts ...pg.QOpt) error {
}
jb.BlockHeaderFeederSpecID = &specID
case LegacyGasStationServer:
+ if jb.LegacyGasStationServerSpec.EVMChainID == nil {
+ return errors.New("evm chain id must be defined")
+ }
var specID int32
sql := `INSERT INTO legacy_gas_station_server_specs (forwarder_address, evm_chain_id, ccip_chain_selector, from_addresses, created_at, updated_at)
VALUES (:forwarder_address, :evm_chain_id, :ccip_chain_selector, :from_addresses, NOW(), NOW())
@@ -401,6 +420,9 @@ func (o *orm) CreateJob(jb *Job, qopts ...pg.QOpt) error {
}
jb.LegacyGasStationServerSpecID = &specID
case LegacyGasStationSidecar:
+ if jb.LegacyGasStationSidecarSpec.EVMChainID == nil {
+ return errors.New("evm chain id must be defined")
+ }
var specID int32
sql := `INSERT INTO legacy_gas_station_sidecar_specs (forwarder_address, off_ramp_address, lookback_blocks, poll_period, run_timeout, evm_chain_id, ccip_chain_selector, created_at, updated_at)
VALUES (:forwarder_address, :off_ramp_address, :lookback_blocks, :poll_period, :run_timeout, :evm_chain_id, :ccip_chain_selector, NOW(), NOW())
@@ -455,7 +477,7 @@ func (o *orm) CreateJob(jb *Job, qopts ...pg.QOpt) error {
// ValidateKeyStoreMatch confirms that the key has a valid match in the keystore
func ValidateKeyStoreMatch(spec *OCR2OracleSpec, keyStore keystore.Master, key string) error {
- if spec.PluginType == Mercury {
+ if spec.PluginType == types.Mercury {
_, err := keyStore.CSA().Get(key)
if err != nil {
return errors.Errorf("no CSA key matching: %q", key)
@@ -1185,7 +1207,8 @@ func (o *orm) FindJobsByPipelineSpecIDs(ids []int32) ([]Job, error) {
}
for i := range jbs {
err = o.LoadEnvConfigVars(&jbs[i])
- if err != nil {
+ //We must return the jobs even if the chainID is disabled
+ if err != nil && !errors.Is(err, chains.ErrNoSuchChainID) {
return err
}
}
diff --git a/core/services/job/runner_integration_test.go b/core/services/job/runner_integration_test.go
index 8418ae999bb..a886c52f283 100644
--- a/core/services/job/runner_integration_test.go
+++ b/core/services/job/runner_integration_test.go
@@ -53,19 +53,19 @@ var monitoringEndpoint = telemetry.MonitoringEndpointGenerator(&telemetry.NoopAg
func TestRunner(t *testing.T) {
db := pgtest.NewSqlxDB(t)
keyStore := cltest.NewKeyStore(t, db, pgtest.NewQConfig(true))
- kb, err := keyStore.OCR().Create()
- require.NoError(t, err)
+
ethKeyStore := keyStore.Eth()
_, transmitterAddress := cltest.MustInsertRandomKey(t, ethKeyStore, 0)
require.NoError(t, keyStore.OCR().Add(cltest.DefaultOCRKey))
config := configtest2.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) {
- t := true
- c.P2P.V1.Enabled = &t
+ c.P2P.V1.Enabled = ptr(true)
c.P2P.V1.DefaultBootstrapPeers = &[]string{
"/dns4/chain.link/tcp/1234/p2p/16Uiu2HAm58SP7UL8zsnpeuwHfytLocaqgnyaYKP8wu7qRdrixLju",
"/dns4/chain.link/tcp/1235/p2p/16Uiu2HAm58SP7UL8zsnpeuwHfytLocaqgnyaYKP8wu7qRdrixLju",
}
+ kb, err := keyStore.OCR().Create()
+ require.NoError(t, err)
kbid := models.MustSha256HashFromHex(kb.ID())
c.OCR.KeyBundleID = &kbid
taddress := ethkey.EIP55AddressFromAddress(transmitterAddress)
@@ -82,8 +82,7 @@ func TestRunner(t *testing.T) {
pipelineORM := pipeline.NewORM(db, logger.TestLogger(t), config.Database(), config.JobPipeline().MaxSuccessfulRuns())
btORM := bridges.NewORM(db, logger.TestLogger(t), config.Database())
relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, Client: ethClient, GeneralConfig: config, KeyStore: ethKeyStore})
- legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
- require.NoError(t, err)
+ legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
c := clhttptest.NewTestLocalOnlyHTTPClient()
runner := pipeline.NewRunner(pipelineORM, btORM, config.JobPipeline(), config.WebServer(), legacyChains, nil, nil, logger.TestLogger(t), c, c)
@@ -119,8 +118,7 @@ func TestRunner(t *testing.T) {
// Need a job in order to create a run
jb := MakeVoterTurnoutOCRJobSpecWithHTTPURL(t, transmitterAddress, httpURL, bridgeVT.Name.String(), bridgeER.Name.String())
- err = jobORM.CreateJob(jb)
- require.NoError(t, err)
+ require.NoError(t, jobORM.CreateJob(jb))
require.NotNil(t, jb.PipelineSpec)
m, err := bridges.MarshalBridgeMetaData(big.NewInt(10), big.NewInt(100))
@@ -171,12 +169,12 @@ func TestRunner(t *testing.T) {
jb := makeOCRJobSpecFromToml(t, fmt.Sprintf(`
type = "offchainreporting"
schemaVersion = 1
+ evmChainID = "0"
observationSource = """
ds1 [type=bridge name="%s"];
"""
`, bridge.Name.String()))
- err = jobORM.CreateJob(jb)
- require.NoError(t, err)
+ require.NoError(t, jobORM.CreateJob(jb))
// Should not be able to delete a bridge in use.
jids, err := jobORM.FindJobIDsWithBridge(bridge.Name.String())
require.NoError(t, err)
@@ -196,7 +194,7 @@ func TestRunner(t *testing.T) {
// Reference a different one
legacyChains := cltest.NewLegacyChainsWithMockChain(t, nil, config)
- jb, err2 := ocr.ValidatedOracleSpecToml(legacyChains, fmt.Sprintf(`
+ jb, err := ocr.ValidatedOracleSpecToml(legacyChains, fmt.Sprintf(`
type = "offchainreporting"
schemaVersion = 1
evmChainID = 0
@@ -219,7 +217,7 @@ func TestRunner(t *testing.T) {
answer1 [type=median index=0];
"""
`, placeHolderAddress.String()))
- require.NoError(t, err2)
+ require.NoError(t, err)
// Should error creating it
err = jobORM.CreateJob(&jb)
require.Error(t, err)
@@ -437,6 +435,7 @@ answer1 [type=median index=0];
schemaVersion = 1
contractAddress = "%s"
isBootstrapPeer = false
+ evmChainID = "0"
observationSource = """
ds1 [type=http method=GET url="%s" allowunrestrictednetworkaccess="true" %s];
ds1_parse [type=jsonparse path="USD" lax=true];
@@ -474,6 +473,7 @@ ds1 -> ds1_parse;
schemaVersion = 1
contractAddress = "%s"
isBootstrapPeer = true
+ evmChainID = "0"
`
s = fmt.Sprintf(s, cltest.NewEIP55Address())
jb, err := ocr.ValidatedOracleSpecToml(legacyChains, s)
@@ -512,6 +512,7 @@ ds1 -> ds1_parse;
contractAddress = "%s"
isBootstrapPeer = false
observationTimeout = "15s"
+ evmChainID = "0"
observationSource = """
ds1 [type=http method=GET url="%s" allowunrestrictednetworkaccess="true" %s];
ds1_parse [type=jsonparse path="USD" lax=true];
@@ -689,7 +690,7 @@ ds1 -> ds1_parse;
serv := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
time.Sleep(1 * time.Millisecond)
res.WriteHeader(http.StatusOK)
- _, err = res.Write([]byte(`{"USD":10.1}`))
+ _, err := res.Write([]byte(`{"USD":10.1}`))
require.NoError(t, err)
}))
defer serv.Close()
@@ -767,8 +768,7 @@ func TestRunner_Success_Callback_AsyncJob(t *testing.T) {
app := cltest.NewApplicationWithConfig(t, cfg, ethClient, cltest.UseRealExternalInitiatorManager)
keyStore := cltest.NewKeyStore(t, app.GetSqlxDB(), pgtest.NewQConfig(true))
relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: app.GetSqlxDB(), Client: ethClient, GeneralConfig: cfg, KeyStore: keyStore.Eth()})
- legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
- require.NoError(t, err)
+ legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
require.NoError(t, app.Start(testutils.Context(t)))
var (
@@ -911,7 +911,7 @@ func TestRunner_Success_Callback_AsyncJob(t *testing.T) {
{
url, err := url.Parse(responseURL)
require.NoError(t, err)
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
body := strings.NewReader(`{"value": {"data":{"result":"123.45"}}}`)
response, cleanup := client.Patch(url.Path, body)
defer cleanup()
@@ -950,8 +950,7 @@ func TestRunner_Error_Callback_AsyncJob(t *testing.T) {
app := cltest.NewApplicationWithConfig(t, cfg, ethClient, cltest.UseRealExternalInitiatorManager)
keyStore := cltest.NewKeyStore(t, app.GetSqlxDB(), pgtest.NewQConfig(true))
relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: app.GetSqlxDB(), Client: ethClient, GeneralConfig: cfg, KeyStore: keyStore.Eth()})
- legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
- require.NoError(t, err)
+ legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
require.NoError(t, app.Start(testutils.Context(t)))
@@ -1093,7 +1092,7 @@ func TestRunner_Error_Callback_AsyncJob(t *testing.T) {
{
url, err := url.Parse(responseURL)
require.NoError(t, err)
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
body := strings.NewReader(`{"error": "something exploded in EA"}`)
response, cleanup := client.Patch(url.Path, body)
defer cleanup()
diff --git a/core/services/job/spawner.go b/core/services/job/spawner.go
index d5c716ab5fd..d766faa092a 100644
--- a/core/services/job/spawner.go
+++ b/core/services/job/spawner.go
@@ -42,6 +42,7 @@ type (
spawner struct {
orm ORM
config Config
+ checker services.Checker
jobTypeDelegates map[Type]Delegate
activeJobs map[int32]activeJob
activeJobsMu sync.RWMutex
@@ -82,11 +83,12 @@ type (
var _ Spawner = (*spawner)(nil)
-func NewSpawner(orm ORM, config Config, jobTypeDelegates map[Type]Delegate, db *sqlx.DB, lggr logger.Logger, lbDependentAwaiters []utils.DependentAwaiter) *spawner {
+func NewSpawner(orm ORM, config Config, checker services.Checker, jobTypeDelegates map[Type]Delegate, db *sqlx.DB, lggr logger.Logger, lbDependentAwaiters []utils.DependentAwaiter) *spawner {
namedLogger := lggr.Named("JobSpawner")
s := &spawner{
orm: orm,
config: config,
+ checker: checker,
jobTypeDelegates: jobTypeDelegates,
q: pg.NewQ(db, namedLogger, config),
lggr: namedLogger,
@@ -155,7 +157,8 @@ func (js *spawner) stopAllServices() {
// stopService removes the job from memory and stop the services.
// It will always delete the job from memory even if closing the services fail.
func (js *spawner) stopService(jobID int32) {
- js.lggr.Debugw("Stopping services for job", "jobID", jobID)
+ lggr := js.lggr.With("jobID", jobID)
+ lggr.Debug("Stopping services for job")
js.activeJobsMu.Lock()
defer js.activeJobsMu.Unlock()
@@ -163,26 +166,32 @@ func (js *spawner) stopService(jobID int32) {
for i := len(aj.services) - 1; i >= 0; i-- {
service := aj.services[i]
- err := service.Close()
- if err != nil {
- js.lggr.Criticalw("Error stopping job service", "jobID", jobID, "err", err, "subservice", i, "serviceType", reflect.TypeOf(service))
+ sLggr := lggr.With("subservice", i, "serviceType", reflect.TypeOf(service))
+ if c, ok := service.(services.Checkable); ok {
+ if err := js.checker.Unregister(c.Name()); err != nil {
+ sLggr.Warnw("Failed to unregister service from health checker", "err", err)
+ }
+ }
+ if err := service.Close(); err != nil {
+ sLggr.Criticalw("Error stopping job service", "err", err)
js.SvcErrBuffer.Append(pkgerrors.Wrap(err, "error stopping job service"))
} else {
- js.lggr.Debugw("Stopped job service", "jobID", jobID, "subservice", i, "serviceType", fmt.Sprintf("%T", service))
+ sLggr.Debug("Stopped job service")
}
}
- js.lggr.Debugw("Stopped all services for job", "jobID", jobID)
+ lggr.Debug("Stopped all services for job")
delete(js.activeJobs, jobID)
}
func (js *spawner) StartService(ctx context.Context, jb Job, qopts ...pg.QOpt) error {
+ lggr := js.lggr.With("jobID", jb.ID)
js.activeJobsMu.Lock()
defer js.activeJobsMu.Unlock()
delegate, exists := js.jobTypeDelegates[jb.Type]
if !exists {
- js.lggr.Errorw("Job type has not been registered with job.Spawner", "type", jb.Type, "jobID", jb.ID)
+ lggr.Errorw("Job type has not been registered with job.Spawner", "type", jb.Type)
return pkgerrors.Errorf("unregistered type %q for job: %d", jb.Type, jb.ID)
}
// We always add the active job in the activeJob map, even in the case
@@ -201,7 +210,7 @@ func (js *spawner) StartService(ctx context.Context, jb Job, qopts ...pg.QOpt) e
srvs, err := delegate.ServicesForSpec(jb, qopts...)
if err != nil {
- js.lggr.Errorw("Error creating services for job", "jobID", jb.ID, "err", err)
+ lggr.Errorw("Error creating services for job", "err", err)
cctx, cancel := js.chStop.NewCtx()
defer cancel()
js.orm.TryRecordError(jb.ID, err.Error(), pg.WithParentCtx(cctx))
@@ -209,18 +218,25 @@ func (js *spawner) StartService(ctx context.Context, jb Job, qopts ...pg.QOpt) e
return pkgerrors.Wrapf(err, "failed to create services for job: %d", jb.ID)
}
- js.lggr.Debugw("JobSpawner: Starting services for job", "jobID", jb.ID, "count", len(srvs))
+ lggr.Debugw("JobSpawner: Starting services for job", "count", len(srvs))
var ms services.MultiStart
for _, srv := range srvs {
err = ms.Start(ctx, srv)
if err != nil {
- js.lggr.Critical("Error starting service for job", "jobID", jb.ID, "err", err)
+ lggr.Criticalw("Error starting service for job", "err", err)
return err
}
+ if c, ok := srv.(services.Checkable); ok {
+ err = js.checker.Register(c)
+ if err != nil {
+ lggr.Errorw("Error registering service with health checker", "err", err)
+ return err
+ }
+ }
aj.services = append(aj.services, srv)
}
- js.lggr.Debugw("JobSpawner: Finished starting services for job", "jobID", jb.ID, "count", len(srvs))
+ lggr.Debugw("JobSpawner: Finished starting services for job", "count", len(srvs))
js.activeJobs[jb.ID] = aj
return nil
}
diff --git a/core/services/job/spawner_test.go b/core/services/job/spawner_test.go
index de6ca541e59..7dbf811f783 100644
--- a/core/services/job/spawner_test.go
+++ b/core/services/job/spawner_test.go
@@ -4,6 +4,8 @@ import (
"testing"
"time"
+ "github.com/smartcontractkit/chainlink/v2/core/services"
+
"github.com/onsi/gomega"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
@@ -67,7 +69,7 @@ type relayGetter struct {
}
func (g *relayGetter) Get(id relay.ID) (loop.Relayer, error) {
- return evmrelayer.NewLoopRelayAdapter(g.r, g.e), nil
+ return evmrelayer.NewLoopRelayServerAdapter(g.r, g.e), nil
}
func TestSpawner_CreateJobDeleteJob(t *testing.T) {
@@ -94,14 +96,13 @@ func TestSpawner_CreateJobDeleteJob(t *testing.T) {
Return(nil).Maybe()
relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, Client: ethClient, GeneralConfig: config, KeyStore: ethKeyStore})
- legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
- require.NoError(t, err)
+ legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
t.Run("should respect its dependents", func(t *testing.T) {
lggr := logger.TestLogger(t)
orm := NewTestORM(t, db, legacyChains, pipeline.NewORM(db, lggr, config.Database(), config.JobPipeline().MaxSuccessfulRuns()), bridges.NewORM(db, lggr, config.Database()), keyStore, config.Database())
a := utils.NewDependentAwaiter()
a.AddDependents(1)
- spawner := job.NewSpawner(orm, config.Database(), map[job.Type]job.Delegate{}, db, lggr, []utils.DependentAwaiter{a})
+ spawner := job.NewSpawner(orm, config.Database(), noopChecker{}, map[job.Type]job.Delegate{}, db, lggr, []utils.DependentAwaiter{a})
// Starting the spawner should signal to the dependents
result := make(chan bool)
go func() {
@@ -140,7 +141,7 @@ func TestSpawner_CreateJobDeleteJob(t *testing.T) {
dB := ocr.NewDelegate(nil, orm, nil, nil, nil, monitoringEndpoint, legacyChains, logger.TestLogger(t), config.Database(), mailMon)
delegateB := &delegate{jobB.Type, []job.ServiceCtx{serviceB1, serviceB2}, 0, make(chan struct{}), dB}
- spawner := job.NewSpawner(orm, config.Database(), map[job.Type]job.Delegate{
+ spawner := job.NewSpawner(orm, config.Database(), noopChecker{}, map[job.Type]job.Delegate{
jobA.Type: delegateA,
jobB.Type: delegateB,
}, db, lggr, nil)
@@ -190,7 +191,7 @@ func TestSpawner_CreateJobDeleteJob(t *testing.T) {
mailMon := srvctest.Start(t, utils.NewMailboxMonitor(t.Name()))
d := ocr.NewDelegate(nil, orm, nil, nil, nil, monitoringEndpoint, legacyChains, logger.TestLogger(t), config.Database(), mailMon)
delegateA := &delegate{jobA.Type, []job.ServiceCtx{serviceA1, serviceA2}, 0, nil, d}
- spawner := job.NewSpawner(orm, config.Database(), map[job.Type]job.Delegate{
+ spawner := job.NewSpawner(orm, config.Database(), noopChecker{}, map[job.Type]job.Delegate{
jobA.Type: delegateA,
}, db, lggr, nil)
@@ -224,7 +225,7 @@ func TestSpawner_CreateJobDeleteJob(t *testing.T) {
mailMon := srvctest.Start(t, utils.NewMailboxMonitor(t.Name()))
d := ocr.NewDelegate(nil, orm, nil, nil, nil, monitoringEndpoint, legacyChains, logger.TestLogger(t), config.Database(), mailMon)
delegateA := &delegate{jobA.Type, []job.ServiceCtx{serviceA1, serviceA2}, 0, nil, d}
- spawner := job.NewSpawner(orm, config.Database(), map[job.Type]job.Delegate{
+ spawner := job.NewSpawner(orm, config.Database(), noopChecker{}, map[job.Type]job.Delegate{
jobA.Type: delegateA,
}, db, lggr, nil)
@@ -280,11 +281,17 @@ func TestSpawner_CreateJobDeleteJob(t *testing.T) {
lggr := logger.TestLogger(t)
relayExtenders := evmtest.NewChainRelayExtenders(t, testopts)
assert.Equal(t, relayExtenders.Len(), 1)
- legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
- require.NoError(t, err)
+ 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,
@@ -302,7 +309,7 @@ func TestSpawner_CreateJobDeleteJob(t *testing.T) {
keyStore.OCR2(), keyStore.DKGSign(), keyStore.DKGEncrypt(), ethKeyStore, testRelayGetter, mailMon, nil)
delegateOCR2 := &delegate{jobOCR2VRF.Type, []job.ServiceCtx{}, 0, nil, d}
- spawner := job.NewSpawner(orm, config.Database(), map[job.Type]job.Delegate{
+ spawner := job.NewSpawner(orm, config.Database(), noopChecker{}, map[job.Type]job.Delegate{
jobOCR2VRF.Type: delegateOCR2,
}, db, lggr, nil)
@@ -324,3 +331,17 @@ func TestSpawner_CreateJobDeleteJob(t *testing.T) {
spawner.Close()
})
}
+
+type noopChecker struct{}
+
+func (n noopChecker) Register(service services.Checkable) error { return nil }
+
+func (n noopChecker) Unregister(name string) error { return nil }
+
+func (n noopChecker) IsReady() (ready bool, errors map[string]error) { return true, nil }
+
+func (n noopChecker) IsHealthy() (healthy bool, errors map[string]error) { return true, nil }
+
+func (n noopChecker) Start() error { return nil }
+
+func (n noopChecker) Close() error { return nil }
diff --git a/core/services/keeper/integration_test.go b/core/services/keeper/integration_test.go
index 2177d418e53..39431063bcd 100644
--- a/core/services/keeper/integration_test.go
+++ b/core/services/keeper/integration_test.go
@@ -405,6 +405,7 @@ func TestKeeperForwarderEthIntegration(t *testing.T) {
c.EVM[0].MinIncomingConfirmations = ptr[uint32](1) // disable reorg protection for this test
c.EVM[0].HeadTracker.MaxBufferSize = ptr[uint32](100) // helps prevent missed heads
c.EVM[0].Transactions.ForwardersEnabled = ptr(true) // Enable Operator Forwarder flow
+ c.EVM[0].ChainID = (*utils.Big)(testutils.SimulatedChainID)
})
scopedConfig := evmtest.NewChainScopedConfig(t, config)
korm := keeper.NewORM(db, logger.TestLogger(t), scopedConfig.Database())
@@ -430,6 +431,7 @@ func TestKeeperForwarderEthIntegration(t *testing.T) {
KeeperSpec: &job.KeeperSpec{
FromAddress: nodeAddressEIP55,
ContractAddress: regAddrEIP55,
+ EVMChainID: (*utils.Big)(testutils.SimulatedChainID),
},
SchemaVersion: 1,
ForwardingAllowed: true,
@@ -538,7 +540,7 @@ func TestMaxPerformDataSize(t *testing.T) {
backend.Commit()
// setup app
- config, db := heavyweight.FullTestDBV2(t, fmt.Sprintf("keeper_max_perform_data_test"), func(c *chainlink.Config, s *chainlink.Secrets) {
+ config, db := heavyweight.FullTestDBV2(t, "keeper_max_perform_data_test", func(c *chainlink.Config, s *chainlink.Secrets) {
c.Keeper.MaxGracePeriod = ptr[int64](0) // avoid waiting to re-submit for upkeeps
c.Keeper.Registry.SyncInterval = models.MustNewDuration(24 * time.Hour) // disable full sync ticker for test
c.Keeper.Registry.MaxPerformDataSize = ptr(uint32(maxPerformDataSize)) // set the max perform data size
diff --git a/core/services/keeper/registry_synchronizer_helper_test.go b/core/services/keeper/registry_synchronizer_helper_test.go
index c3fadc8bcf4..6b9bb815a89 100644
--- a/core/services/keeper/registry_synchronizer_helper_test.go
+++ b/core/services/keeper/registry_synchronizer_helper_test.go
@@ -44,8 +44,7 @@ func setupRegistrySync(t *testing.T, version keeper.RegistryVersion) (
lbMock.On("AddDependents", 1).Maybe()
j := cltest.MustInsertKeeperJob(t, db, korm, cltest.NewEIP55Address(), cltest.NewEIP55Address())
relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, Client: ethClient, LogBroadcaster: lbMock, GeneralConfig: cfg, KeyStore: keyStore.Eth()})
- legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
- require.NoError(t, err)
+ legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
ch := evmtest.MustGetDefaultChain(t, legacyChains)
jpv2 := cltest.NewJobPipelineV2(t, cfg.WebServer(), cfg.JobPipeline(), cfg.Database(), legacyChains, db, keyStore, nil, nil)
contractAddress := j.KeeperSpec.ContractAddress.Address()
diff --git a/core/services/keeper/upkeep_executer.go b/core/services/keeper/upkeep_executer.go
index 249d3217469..435b245792c 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/keeper/upkeep_executer_test.go b/core/services/keeper/upkeep_executer_test.go
index 0f15f3949ba..702633e1d08 100644
--- a/core/services/keeper/upkeep_executer_test.go
+++ b/core/services/keeper/upkeep_executer_test.go
@@ -72,22 +72,23 @@ func setup(t *testing.T, estimator gas.EvmFeeEstimator, overrideFn func(c *chain
})
db := pgtest.NewSqlxDB(t)
keyStore := cltest.NewKeyStore(t, db, cfg.Database())
- ethClient := evmtest.NewEthClientMockWithDefaultChain(t)
+ ethClient := evmtest.NewEthClientMock(t)
+ ethClient.On("ConfiguredChainID").Return(cfg.EVMConfigs()[0].ChainID.ToInt()).Maybe()
+ ethClient.On("IsL2").Return(false).Maybe()
ethClient.On("HeadByNumber", mock.Anything, mock.Anything).Maybe().Return(&evmtypes.Head{Number: 1, Hash: utils.NewHash()}, nil)
txm := txmmocks.NewMockEvmTxManager(t)
relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{TxManager: txm, DB: db, Client: ethClient, KeyStore: keyStore.Eth(), GeneralConfig: cfg, GasEstimator: estimator})
- legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
- require.NoError(t, err)
+ legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
jpv2 := cltest.NewJobPipelineV2(t, cfg.WebServer(), cfg.JobPipeline(), cfg.Database(), legacyChains, db, keyStore, nil, nil)
ch := evmtest.MustGetDefaultChain(t, legacyChains)
orm := keeper.NewORM(db, logger.TestLogger(t), ch.Config().Database())
registry, job := cltest.MustInsertKeeperRegistry(t, db, orm, keyStore.Eth(), 0, 1, 20)
+
lggr := logger.TestLogger(t)
executer := keeper.NewUpkeepExecuter(job, orm, jpv2.Pr, ethClient, ch.HeadBroadcaster(), ch.GasEstimator(), lggr, ch.Config().Keeper(), job.KeeperSpec.FromAddress.Address())
upkeep := cltest.MustInsertUpkeepForRegistry(t, db, ch.Config().Database(), registry)
- err = executer.Start(testutils.Context(t))
+ require.NoError(t, executer.Start(testutils.Context(t)))
t.Cleanup(func() { executer.Close() })
- require.NoError(t, err)
return db, cfg, ethClient, executer, registry, upkeep, job, jpv2, txm, keyStore, ch, orm
}
@@ -124,7 +125,10 @@ func Test_UpkeepExecuter_PerformsUpkeep_Happy(t *testing.T) {
t.Parallel()
t.Run("runs upkeep on triggering block number", func(t *testing.T) {
- db, config, ethMock, executer, registry, upkeep, job, jpv2, txm, _, _, _ := setup(t, mockEstimator(t), nil)
+ db, config, ethMock, executer, registry, upkeep, job, jpv2, txm, _, _, _ := setup(t, mockEstimator(t),
+ func(c *chainlink.Config, s *chainlink.Secrets) {
+ c.EVM[0].ChainID = (*utils.Big)(testutils.SimulatedChainID)
+ })
gasLimit := 5_000_000 + config.Keeper().Registry().PerformGasOverhead()
@@ -167,6 +171,7 @@ func Test_UpkeepExecuter_PerformsUpkeep_Happy(t *testing.T) {
runTest := func(t *testing.T, eip1559 bool) {
db, config, ethMock, executer, registry, upkeep, job, jpv2, txm, _, _, _ := setup(t, mockEstimator(t), func(c *chainlink.Config, s *chainlink.Secrets) {
c.EVM[0].GasEstimator.EIP1559DynamicFees = &eip1559
+ c.EVM[0].ChainID = (*utils.Big)(testutils.SimulatedChainID)
})
gasLimit := 5_000_000 + config.Keeper().Registry().PerformGasOverhead()
@@ -217,10 +222,12 @@ func Test_UpkeepExecuter_PerformsUpkeep_Happy(t *testing.T) {
})
t.Run("errors if submission key not found", func(t *testing.T) {
- _, _, ethMock, executer, registry, _, job, jpv2, _, keyStore, _, _ := setup(t, mockEstimator(t), nil)
+ _, _, ethMock, executer, registry, _, job, jpv2, _, keyStore, _, _ := setup(t, mockEstimator(t), func(c *chainlink.Config, s *chainlink.Secrets) {
+ c.EVM[0].ChainID = (*utils.Big)(testutils.SimulatedChainID)
+ })
// replace expected key with random one
- _, err := keyStore.Eth().Create(&cltest.FixtureChainID)
+ _, err := keyStore.Eth().Create(testutils.SimulatedChainID)
require.NoError(t, err)
_, err = keyStore.Eth().Delete(job.KeeperSpec.FromAddress.Hex())
require.NoError(t, err)
@@ -267,7 +274,9 @@ func Test_UpkeepExecuter_PerformsUpkeep_Happy(t *testing.T) {
})
t.Run("triggers if heads are skipped but later heads arrive within range", func(t *testing.T) {
- db, config, ethMock, executer, registry, upkeep, job, jpv2, txm, _, _, _ := setup(t, mockEstimator(t), nil)
+ db, config, ethMock, executer, registry, upkeep, job, jpv2, txm, _, _, _ := setup(t, mockEstimator(t), func(c *chainlink.Config, s *chainlink.Secrets) {
+ c.EVM[0].ChainID = (*utils.Big)(testutils.SimulatedChainID)
+ })
etxs := []cltest.Awaiter{
cltest.NewAwaiter(),
@@ -306,7 +315,10 @@ func Test_UpkeepExecuter_PerformsUpkeep_Error(t *testing.T) {
g := gomega.NewWithT(t)
- db, _, ethMock, executer, registry, _, _, _, _, _, _, _ := setup(t, mockEstimator(t), nil)
+ db, _, ethMock, executer, registry, _, _, _, _, _, _, _ := setup(t, mockEstimator(t),
+ func(c *chainlink.Config, s *chainlink.Secrets) {
+ c.EVM[0].ChainID = (*utils.Big)(testutils.SimulatedChainID)
+ })
var wasCalled atomic.Bool
registryMock := cltest.NewContractMockReceiver(t, ethMock, keeper.Registry1_1ABI, registry.ContractAddress.Address())
@@ -318,7 +330,7 @@ func Test_UpkeepExecuter_PerformsUpkeep_Error(t *testing.T) {
executer.OnNewLongestChain(testutils.Context(t), &head)
g.Eventually(wasCalled.Load).Should(gomega.Equal(true))
- cltest.AssertCountStays(t, db, "eth_txes", 0)
+ cltest.AssertCountStays(t, db, "evm.txes", 0)
}
func ptr[T any](t T) *T { return &t }
diff --git a/core/services/keystore/cosmos.go b/core/services/keystore/cosmos.go
index 07abafa3efd..c06dfcdbcea 100644
--- a/core/services/keystore/cosmos.go
+++ b/core/services/keystore/cosmos.go
@@ -1,10 +1,12 @@
package keystore
import (
+ "context"
"fmt"
"github.com/pkg/errors"
+ "github.com/smartcontractkit/chainlink-relay/pkg/loop"
"github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/cosmoskey"
)
@@ -144,3 +146,38 @@ func (ks *cosmos) getByID(id string) (cosmoskey.Key, error) {
}
return key, nil
}
+
+// CosmosLoopKeystore implements the [github.com/smartcontractkit/chainlink-relay/pkg/loop.Keystore] interface and
+// handles signing for Cosmos messages.
+type CosmosLoopKeystore struct {
+ Cosmos
+}
+
+var _ loop.Keystore = &CosmosLoopKeystore{}
+
+func (lk *CosmosLoopKeystore) Sign(ctx context.Context, id string, hash []byte) ([]byte, error) {
+ k, err := lk.Get(id)
+ if err != nil {
+ return nil, err
+ }
+ // loopp spec requires passing nil hash to check existence of id
+ if hash == nil {
+ return nil, nil
+ }
+
+ return k.ToPrivKey().Sign(hash)
+}
+
+func (lk *CosmosLoopKeystore) Accounts(ctx context.Context) ([]string, error) {
+ keys, err := lk.GetAll()
+ if err != nil {
+ return nil, err
+ }
+
+ accounts := []string{}
+ for _, k := range keys {
+ accounts = append(accounts, k.PublicKeyStr())
+ }
+
+ return accounts, nil
+}
diff --git a/core/services/keystore/eth.go b/core/services/keystore/eth.go
index ca776cf10e1..9909f398bf4 100644
--- a/core/services/keystore/eth.go
+++ b/core/services/keystore/eth.go
@@ -240,7 +240,7 @@ func (ks *eth) Add(address common.Address, chainID *big.Int, qopts ...pg.QOpt) e
// caller must hold lock!
func (ks *eth) addKey(address common.Address, chainID *big.Int, qopts ...pg.QOpt) error {
state := new(ethkey.State)
- sql := `INSERT INTO evm_key_states (address, next_nonce, disabled, evm_chain_id, created_at, updated_at)
+ sql := `INSERT INTO evm.key_states (address, next_nonce, disabled, evm_chain_id, created_at, updated_at)
VALUES ($1, 0, false, $2, NOW(), NOW())
RETURNING *;`
q := ks.orm.q.WithOpts(qopts...)
@@ -267,7 +267,7 @@ func (ks *eth) Enable(address common.Address, chainID *big.Int, qopts ...pg.QOpt
func (ks *eth) enable(address common.Address, chainID *big.Int, qopts ...pg.QOpt) error {
state := new(ethkey.State)
q := ks.orm.q.WithOpts(qopts...)
- sql := `UPDATE evm_key_states SET disabled = false, updated_at = NOW() WHERE address = $1 AND evm_chain_id = $2
+ sql := `UPDATE evm.key_states SET disabled = false, updated_at = NOW() WHERE address = $1 AND evm_chain_id = $2
RETURNING *;`
if err := q.Get(state, sql, address, chainID.String()); err != nil {
return errors.Wrap(err, "failed to enable state")
@@ -291,7 +291,7 @@ func (ks *eth) Disable(address common.Address, chainID *big.Int, qopts ...pg.QOp
func (ks *eth) disable(address common.Address, chainID *big.Int, qopts ...pg.QOpt) error {
state := new(ethkey.State)
q := ks.orm.q.WithOpts(qopts...)
- sql := `UPDATE evm_key_states SET disabled = false, updated_at = NOW() WHERE address = $1 AND evm_chain_id = $2
+ sql := `UPDATE evm.key_states SET disabled = false, updated_at = NOW() WHERE address = $1 AND evm_chain_id = $2
RETURNING id, next_nonce, address, evm_chain_id, disabled, created_at, updated_at;`
if err := q.Get(state, sql, address, chainID.String()); err != nil {
return errors.Wrap(err, "failed to enable state")
@@ -305,7 +305,7 @@ func (ks *eth) disable(address common.Address, chainID *big.Int, qopts ...pg.QOp
// Reset the key/chain nonce to the given one
func (ks *eth) Reset(address common.Address, chainID *big.Int, nonce int64, qopts ...pg.QOpt) error {
q := ks.orm.q.WithOpts(qopts...)
- res, err := q.Exec(`UPDATE evm_key_states SET next_nonce = $1 WHERE address = $2 AND evm_chain_id = $3`, nonce, address, chainID.String())
+ res, err := q.Exec(`UPDATE evm.key_states SET next_nonce = $1 WHERE address = $2 AND evm_chain_id = $3`, nonce, address, chainID.String())
if err != nil {
return errors.Wrap(err, "failed to reset state")
}
@@ -337,7 +337,7 @@ func (ks *eth) Delete(id string) (ethkey.KeyV2, error) {
return ethkey.KeyV2{}, err
}
err = ks.safeRemoveKey(key, func(tx pg.Queryer) error {
- _, err2 := tx.Exec(`DELETE FROM evm_key_states WHERE address = $1`, key.Address)
+ _, err2 := tx.Exec(`DELETE FROM evm.key_states WHERE address = $1`, key.Address)
return err2
})
if err != nil {
@@ -587,7 +587,7 @@ func (ks *eth) XXXTestingOnlySetState(state ethkey.State) {
panic(fmt.Sprintf("key not found with ID %s", state.KeyID()))
}
*existingState = state
- sql := `UPDATE evm_key_states SET address = :address, next_nonce = :next_nonce, is_disabled = :is_disabled, evm_chain_id = :evm_chain_id, updated_at = NOW()
+ sql := `UPDATE evm.key_states SET address = :address, next_nonce = :next_nonce, is_disabled = :is_disabled, evm_chain_id = :evm_chain_id, updated_at = NOW()
WHERE address = :address;`
_, err := ks.orm.q.NamedExec(sql, state)
if err != nil {
@@ -669,7 +669,7 @@ func (ks *eth) addWithNonce(key ethkey.KeyV2, chainID *big.Int, nonce int64, isD
defer ks.lock.Unlock()
err = ks.safeAddKey(key, func(tx pg.Queryer) (merr error) {
state := new(ethkey.State)
- sql := `INSERT INTO evm_key_states (address, next_nonce, disabled, evm_chain_id, created_at, updated_at)
+ sql := `INSERT INTO evm.key_states (address, next_nonce, disabled, evm_chain_id, created_at, updated_at)
VALUES ($1, $2, $3, $4, NOW(), NOW()) RETURNING *;`
if err = ks.orm.q.Get(state, sql, key.Address, nonce, isDisabled, chainID); err != nil {
return errors.Wrap(err, "failed to insert evm_key_state")
diff --git a/core/services/keystore/eth_test.go b/core/services/keystore/eth_test.go
index 678f11ea503..78131bec133 100644
--- a/core/services/keystore/eth_test.go
+++ b/core/services/keystore/eth_test.go
@@ -38,10 +38,10 @@ func Test_EthKeyStore(t *testing.T) {
reset := func() {
keyStore.ResetXXXTestOnly()
require.NoError(t, utils.JustError(db.Exec("DELETE FROM encrypted_key_rings")))
- require.NoError(t, utils.JustError(db.Exec("DELETE FROM evm_key_states")))
+ require.NoError(t, utils.JustError(db.Exec("DELETE FROM evm.key_states")))
require.NoError(t, keyStore.Unlock(cltest.Password))
}
- const statesTableName = "evm_key_states"
+ const statesTableName = "evm.key_states"
t.Run("Create / GetAll / Get", func(t *testing.T) {
defer reset()
@@ -104,7 +104,7 @@ func Test_EthKeyStore(t *testing.T) {
cltest.AssertCount(t, db, statesTableName, 0)
})
- t.Run("Delete removes key even if eth_txes are present", func(t *testing.T) {
+ t.Run("Delete removes key even if evm.txes are present", func(t *testing.T) {
defer reset()
key, err := ethKeyStore.Create(&cltest.FixtureChainID)
require.NoError(t, err)
@@ -170,7 +170,7 @@ func Test_EthKeyStore(t *testing.T) {
require.NoError(t, err)
key2, err := ethKeyStore.Create(big.NewInt(1337))
require.NoError(t, err)
- testutils.AssertCount(t, db, "evm_key_states", 2)
+ testutils.AssertCount(t, db, "evm.key_states", 2)
keys, err := ethKeyStore.GetAll()
require.NoError(t, err)
assert.Len(t, keys, 2)
@@ -363,7 +363,7 @@ func Test_EthKeyStore_E2E(t *testing.T) {
reset := func() {
keyStore.ResetXXXTestOnly()
require.NoError(t, utils.JustError(db.Exec("DELETE FROM encrypted_key_rings")))
- require.NoError(t, utils.JustError(db.Exec("DELETE FROM evm_key_states")))
+ require.NoError(t, utils.JustError(db.Exec("DELETE FROM evm.key_states")))
require.NoError(t, keyStore.Unlock(cltest.Password))
}
@@ -552,10 +552,10 @@ func Test_EthKeyStore_EnsureKeys(t *testing.T) {
keyStore := cltest.NewKeyStore(t, db, cfg.Database())
ks := keyStore.Eth()
- testutils.AssertCount(t, db, "evm_key_states", 0)
+ testutils.AssertCount(t, db, "evm.key_states", 0)
err := ks.EnsureKeys(testutils.FixtureChainID, testutils.SimulatedChainID)
require.NoError(t, err)
- testutils.AssertCount(t, db, "evm_key_states", 2)
+ testutils.AssertCount(t, db, "evm.key_states", 2)
keys, err := ks.GetAll()
require.NoError(t, err)
assert.Len(t, keys, 2)
@@ -570,7 +570,7 @@ func Test_EthKeyStore_EnsureKeys(t *testing.T) {
// Add one enabled key
_, err := ks.Create(testutils.FixtureChainID)
require.NoError(t, err)
- testutils.AssertCount(t, db, "evm_key_states", 1)
+ testutils.AssertCount(t, db, "evm.key_states", 1)
keys, err := ks.GetAll()
require.NoError(t, err)
assert.Len(t, keys, 1)
@@ -578,7 +578,7 @@ func Test_EthKeyStore_EnsureKeys(t *testing.T) {
// this adds one more key for the additional chain
err = ks.EnsureKeys(testutils.FixtureChainID, testutils.SimulatedChainID)
require.NoError(t, err)
- testutils.AssertCount(t, db, "evm_key_states", 2)
+ testutils.AssertCount(t, db, "evm.key_states", 2)
keys, err = ks.GetAll()
require.NoError(t, err)
assert.Len(t, keys, 2)
@@ -593,7 +593,7 @@ func Test_EthKeyStore_EnsureKeys(t *testing.T) {
// Add one enabled key
k, err := ks.Create(testutils.FixtureChainID)
require.NoError(t, err)
- testutils.AssertCount(t, db, "evm_key_states", 1)
+ testutils.AssertCount(t, db, "evm.key_states", 1)
keys, err := ks.GetAll()
require.NoError(t, err)
assert.Len(t, keys, 1)
@@ -605,7 +605,7 @@ func Test_EthKeyStore_EnsureKeys(t *testing.T) {
// this does nothing
err = ks.EnsureKeys(testutils.FixtureChainID)
require.NoError(t, err)
- testutils.AssertCount(t, db, "evm_key_states", 1)
+ testutils.AssertCount(t, db, "evm.key_states", 1)
keys, err = ks.GetAll()
require.NoError(t, err)
assert.Len(t, keys, 1)
@@ -728,7 +728,7 @@ func Test_IncrementNextSequence(t *testing.T) {
err = ks.IncrementNextSequence(evmAddr1, testutils.FixtureChainID, evmtypes.Nonce(randNonce))
require.NoError(t, err)
var nonce int64
- require.NoError(t, db.Get(&nonce, `SELECT next_nonce FROM evm_key_states WHERE address = $1 AND evm_chain_id = $2`, addr1, testutils.FixtureChainID.String()))
+ require.NoError(t, db.Get(&nonce, `SELECT next_nonce FROM evm.key_states WHERE address = $1 AND evm_chain_id = $2`, addr1, testutils.FixtureChainID.String()))
assert.Equal(t, randNonce+1, nonce)
err = ks.IncrementNextSequence(evmAddr1, testutils.SimulatedChainID, evmtypes.Nonce(randNonce+1))
@@ -745,7 +745,7 @@ func Test_IncrementNextSequence(t *testing.T) {
assert.Contains(t, err.Error(), fmt.Sprintf("key with address %s does not exist", randAddr2.Hex()))
// verify it didnt get changed by any erroring calls
- require.NoError(t, db.Get(&nonce, `SELECT next_nonce FROM evm_key_states WHERE address = $1 AND evm_chain_id = $2`, addr1, testutils.FixtureChainID.String()))
+ require.NoError(t, db.Get(&nonce, `SELECT next_nonce FROM evm.key_states WHERE address = $1 AND evm_chain_id = $2`, addr1, testutils.FixtureChainID.String()))
assert.Equal(t, randNonce+1, nonce)
}
@@ -768,7 +768,7 @@ func Test_EthKeyStore_Delete(t *testing.T) {
require.NoError(t, ks.Add(addr1, testutils.SimulatedChainID))
require.NoError(t, ks.Enable(addr1, testutils.SimulatedChainID))
- testutils.AssertCount(t, db, "evm_key_states", 4)
+ testutils.AssertCount(t, db, "evm.key_states", 4)
keys, err := ks.GetAll()
require.NoError(t, err)
assert.Len(t, keys, 3)
@@ -781,7 +781,7 @@ func Test_EthKeyStore_Delete(t *testing.T) {
require.NoError(t, err)
assert.Equal(t, addr1, deletedK.Address)
- testutils.AssertCount(t, db, "evm_key_states", 2)
+ testutils.AssertCount(t, db, "evm.key_states", 2)
keys, err = ks.GetAll()
require.NoError(t, err)
assert.Len(t, keys, 2)
diff --git a/core/services/keystore/keys/cosmoskey/key.go b/core/services/keystore/keys/cosmoskey/key.go
index 6783232e8b7..3e516a21ab5 100644
--- a/core/services/keystore/keys/cosmoskey/key.go
+++ b/core/services/keystore/keys/cosmoskey/key.go
@@ -12,7 +12,6 @@ import (
"github.com/ethereum/go-ethereum/crypto"
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
- "github.com/cosmos/cosmos-sdk/types"
)
var secpSigningAlgo, _ = keyring.NewSigningAlgoFromString(string(hd.Secp256k1Type), []keyring.SignatureAlgo{hd.Secp256k1})
@@ -78,10 +77,8 @@ func (key Key) PublicKey() (pubKey cryptotypes.PubKey) {
return key.k.PubKey()
}
-// PublicKeyStr returns the cosmos address of the public key
func (key Key) PublicKeyStr() string {
- addr := types.AccAddress(key.k.PubKey().Address())
- return addr.String()
+ return fmt.Sprintf("%X", key.k.PubKey().Bytes())
}
func (key Key) Raw() Raw {
diff --git a/core/services/keystore/master.go b/core/services/keystore/master.go
index 4a8333d8448..ab4c3256c5c 100644
--- a/core/services/keystore/master.go
+++ b/core/services/keystore/master.go
@@ -51,7 +51,6 @@ type Master interface {
StarkNet() StarkNet
VRF() VRF
Unlock(password string) error
- Migrate(vrfPassword string, f DefaultEVMChainIDFunc) error
IsEmpty() (bool, error)
}
@@ -151,93 +150,6 @@ func (ks *master) IsEmpty() (bool, error) {
return count == 0, nil
}
-func (ks *master) Migrate(vrfPssword string, f DefaultEVMChainIDFunc) error {
- ks.lock.Lock()
- defer ks.lock.Unlock()
- if ks.isLocked() {
- return ErrLocked
- }
- csaKeys, err := ks.csa.GetV1KeysAsV2()
- if err != nil {
- return err
- }
- for _, csaKey := range csaKeys {
- if _, exists := ks.keyRing.CSA[csaKey.ID()]; exists {
- continue
- }
- ks.logger.Debugf("Migrating CSA key %s", csaKey.ID())
- ks.keyRing.CSA[csaKey.ID()] = csaKey
- }
- ocrKeys, err := ks.ocr.GetV1KeysAsV2()
- if err != nil {
- return err
- }
- for _, ocrKey := range ocrKeys {
- if _, exists := ks.keyRing.OCR[ocrKey.ID()]; exists {
- continue
- }
- ks.logger.Debugf("Migrating OCR key %s", ocrKey.ID())
- ks.keyRing.OCR[ocrKey.ID()] = ocrKey
- }
- p2pKeys, err := ks.p2p.GetV1KeysAsV2()
- if err != nil {
- return err
- }
- for _, p2pKey := range p2pKeys {
- if _, exists := ks.keyRing.P2P[p2pKey.ID()]; exists {
- continue
- }
- ks.logger.Debugf("Migrating P2P key %s", p2pKey.ID())
- ks.keyRing.P2P[p2pKey.ID()] = p2pKey
- }
- vrfKeys, err := ks.vrf.GetV1KeysAsV2(vrfPssword)
- if err != nil {
- return err
- }
- for _, vrfKey := range vrfKeys {
- if _, exists := ks.keyRing.VRF[vrfKey.ID()]; exists {
- continue
- }
- ks.logger.Debugf("Migrating VRF key %s", vrfKey.ID())
- ks.keyRing.VRF[vrfKey.ID()] = vrfKey
- }
- if err = ks.keyManager.save(); err != nil {
- return err
- }
- ethKeys, nonces, fundings, err := ks.eth.getV1KeysAsV2()
- if err != nil {
- return err
- }
- if len(ethKeys) > 0 {
- chainID, err := f()
- if err != nil {
- return errors.Wrapf(err, `%d legacy eth keys detected, but no default EVM chain ID was specified
-
-PLEASE READ THIS ADDITIONAL INFO
-
-If you are running Chainlink with EVM.Enabled=false and don't care about EVM keys at all, you can run the following SQL to remove any lingering eth keys that may have been autogenerated by an older version of Chainlink, and boot the node again:
-
-pqsl> TRUNCATE keys;
-
-WARNING: This will PERMANENTLY AND IRRECOVERABLY delete any legacy eth keys, so please be absolutely sure this is what you want before you run this. Consider taking a database backup first`, len(ethKeys))
- }
- for i, ethKey := range ethKeys {
- if _, exists := ks.keyRing.Eth[ethKey.ID()]; exists {
- continue
- }
- ks.logger.Debugf("Migrating Eth key %s (and pegging to chain ID %s)", ethKey.ID(), chainID.String())
- // Note that V1 keys that were "funding" will be migrated as "disabled"
- if err = ks.eth.addWithNonce(ethKey, chainID, nonces[i], fundings[i]); err != nil {
- return err
- }
- if err = ks.keyManager.save(); err != nil {
- return err
- }
- }
- }
- return nil
-}
-
type keyManager struct {
orm ksORM
scryptParams utils.ScryptParams
diff --git a/core/services/keystore/mocks/master.go b/core/services/keystore/mocks/master.go
index ec55dc21089..e8b4775d662 100644
--- a/core/services/keystore/mocks/master.go
+++ b/core/services/keystore/mocks/master.go
@@ -116,20 +116,6 @@ func (_m *Master) IsEmpty() (bool, error) {
return r0, r1
}
-// Migrate provides a mock function with given fields: vrfPassword, f
-func (_m *Master) Migrate(vrfPassword string, f keystore.DefaultEVMChainIDFunc) error {
- ret := _m.Called(vrfPassword, f)
-
- var r0 error
- if rf, ok := ret.Get(0).(func(string, keystore.DefaultEVMChainIDFunc) error); ok {
- r0 = rf(vrfPassword, f)
- } else {
- r0 = ret.Error(0)
- }
-
- return r0
-}
-
// OCR provides a mock function with given fields:
func (_m *Master) OCR() keystore.OCR {
ret := _m.Called()
diff --git a/core/services/keystore/orm.go b/core/services/keystore/orm.go
index d71b8378532..1396b544205 100644
--- a/core/services/keystore/orm.go
+++ b/core/services/keystore/orm.go
@@ -67,8 +67,8 @@ func (orm ksORM) getEncryptedKeyRing() (kr encryptedKeyRing, err error) {
func (orm ksORM) loadKeyStates() (*keyStates, error) {
ks := newKeyStates()
var ethkeystates []*ethkey.State
- if err := orm.q.Select(ðkeystates, `SELECT id, address, evm_chain_id, next_nonce, disabled, created_at, updated_at FROM evm_key_states`); err != nil {
- return ks, errors.Wrap(err, "error loading evm_key_states from DB")
+ if err := orm.q.Select(ðkeystates, `SELECT id, address, evm_chain_id, next_nonce, disabled, created_at, updated_at FROM evm.key_states`); err != nil {
+ return ks, errors.Wrap(err, "error loading evm.key_states from DB")
}
for _, state := range ethkeystates {
ks.add(state)
@@ -76,20 +76,20 @@ func (orm ksORM) loadKeyStates() (*keyStates, error) {
return ks, nil
}
-// getNextNonce returns evm_key_states.next_nonce for the given address
+// getNextNonce returns evm.key_states.next_nonce for the given address
func (orm ksORM) getNextNonce(address common.Address, chainID *big.Int, qopts ...pg.QOpt) (nonce int64, err error) {
q := orm.q.WithOpts(qopts...)
- err = q.Get(&nonce, "SELECT next_nonce FROM evm_key_states WHERE address = $1 AND evm_chain_id = $2 AND disabled = false", address, chainID.String())
+ err = q.Get(&nonce, "SELECT next_nonce FROM evm.key_states WHERE address = $1 AND evm_chain_id = $2 AND disabled = false", address, chainID.String())
if errors.Is(err, sql.ErrNoRows) {
return 0, errors.Wrapf(sql.ErrNoRows, "key with address %s is not enabled for chain %s", address.Hex(), chainID.String())
}
return nonce, errors.Wrap(err, "failed to load next nonce")
}
-// incrementNextNonce increments evm_key_states.next_nonce by 1
+// incrementNextNonce increments evm.key_states.next_nonce by 1
func (orm ksORM) incrementNextNonce(address common.Address, chainID *big.Int, currentNonce int64, qopts ...pg.QOpt) (incrementedNonce int64, err error) {
q := orm.q.WithOpts(qopts...)
- err = q.Get(&incrementedNonce, "UPDATE evm_key_states SET next_nonce = next_nonce + 1, updated_at = NOW() WHERE address = $1 AND next_nonce = $2 AND evm_chain_id = $3 AND disabled = false RETURNING next_nonce", address, currentNonce, chainID.String())
+ err = q.Get(&incrementedNonce, "UPDATE evm.key_states SET next_nonce = next_nonce + 1, updated_at = NOW() WHERE address = $1 AND next_nonce = $2 AND evm_chain_id = $3 AND disabled = false RETURNING next_nonce", address, currentNonce, chainID.String())
return incrementedNonce, errors.Wrap(err, "IncrementNextNonce failed to update keys")
}
diff --git a/core/services/mocks/checker.go b/core/services/mocks/checker.go
index cfccc2537f8..8a6541bba36 100644
--- a/core/services/mocks/checker.go
+++ b/core/services/mocks/checker.go
@@ -78,13 +78,13 @@ func (_m *Checker) IsReady() (bool, map[string]error) {
return r0, r1
}
-// Register provides a mock function with given fields: name, service
-func (_m *Checker) Register(name string, service services.Checkable) error {
- ret := _m.Called(name, service)
+// Register provides a mock function with given fields: service
+func (_m *Checker) Register(service services.Checkable) error {
+ ret := _m.Called(service)
var r0 error
- if rf, ok := ret.Get(0).(func(string, services.Checkable) error); ok {
- r0 = rf(name, service)
+ if rf, ok := ret.Get(0).(func(services.Checkable) error); ok {
+ r0 = rf(service)
} else {
r0 = ret.Error(0)
}
diff --git a/core/services/nurse.go b/core/services/nurse.go
index a0d3443568a..33230ddae02 100644
--- a/core/services/nurse.go
+++ b/core/services/nurse.go
@@ -67,7 +67,7 @@ const (
func NewNurse(cfg Config, log logger.Logger) *Nurse {
return &Nurse{
cfg: cfg,
- log: log.Named("nurse"),
+ log: log.Named("Nurse"),
checks: make(map[string]CheckFunc),
chGather: make(chan gatherRequest, 1),
chStop: make(chan struct{}),
@@ -75,7 +75,7 @@ func NewNurse(cfg Config, log logger.Logger) *Nurse {
}
func (n *Nurse) Start() error {
- return n.StartOnce("nurse", func() error {
+ return n.StartOnce("Nurse", func() error {
// This must be set *once*, and it must occur as early as possible
if n.cfg.MemProfileRate() != runtime.MemProfileRate {
runtime.MemProfileRate = n.cfg.BlockProfileRate()
@@ -137,7 +137,7 @@ func (n *Nurse) Start() error {
}
func (n *Nurse) Close() error {
- return n.StopOnce("nurse", func() error {
+ return n.StopOnce("Nurse", func() error {
n.log.Debug("Nurse closing...")
defer n.log.Debug("Nurse closed")
close(n.chStop)
diff --git a/core/services/ocr/contract_tracker.go b/core/services/ocr/contract_tracker.go
index 99057937db6..0c7e288bd43 100644
--- a/core/services/ocr/contract_tracker.go
+++ b/core/services/ocr/contract_tracker.go
@@ -94,6 +94,12 @@ type (
}
)
+func (t *OCRContractTracker) HealthReport() map[string]error {
+ return map[string]error{t.Name(): t.Healthy()}
+}
+
+func (t *OCRContractTracker) Name() string { return t.logger.Name() }
+
// NewOCRContractTracker makes a new OCRContractTracker
func NewOCRContractTracker(
contract *offchain_aggregator_wrapper.OffchainAggregator,
diff --git a/core/services/ocr/delegate.go b/core/services/ocr/delegate.go
index c5ace522ccb..9ed22d01e72 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)
@@ -297,7 +297,7 @@ func (d *Delegate) ServicesForSpec(jb job.Job, qopts ...pg.QOpt) (services []job
enhancedTelemChan := make(chan ocrcommon.EnhancedTelemetryData, 100)
if ocrcommon.ShouldCollectEnhancedTelemetry(&jb) {
- enhancedTelemService := ocrcommon.NewEnhancedTelemetryService(&jb, enhancedTelemChan, make(chan struct{}), d.monitoringEndpointGen.GenMonitoringEndpoint(concreteSpec.ContractAddress.String(), synchronization.EnhancedEA), lggr.Named("Enhanced Telemetry"))
+ enhancedTelemService := ocrcommon.NewEnhancedTelemetryService(&jb, enhancedTelemChan, make(chan struct{}), d.monitoringEndpointGen.GenMonitoringEndpoint(concreteSpec.ContractAddress.String(), synchronization.EnhancedEA), lggr.Named("EnhancedTelemetry"))
services = append(services, enhancedTelemService)
}
diff --git a/core/services/ocr2/delegate.go b/core/services/ocr2/delegate.go
index 39d5e939f3b..2086eaa6a80 100644
--- a/core/services/ocr2/delegate.go
+++ b/core/services/ocr2/delegate.go
@@ -23,7 +23,6 @@ import (
ocr2keepers20runner "github.com/smartcontractkit/ocr2keepers/pkg/v2/runner"
ocr2keepers21config "github.com/smartcontractkit/ocr2keepers/pkg/v3/config"
ocr2keepers21 "github.com/smartcontractkit/ocr2keepers/pkg/v3/plugin"
- ocr2keepers21types "github.com/smartcontractkit/ocr2keepers/pkg/v3/types"
"github.com/smartcontractkit/ocr2vrf/altbn_128"
dkgpkg "github.com/smartcontractkit/ocr2vrf/dkg"
"github.com/smartcontractkit/ocr2vrf/ocr2vrf"
@@ -266,7 +265,7 @@ func (d *Delegate) cleanupEVM(jb job.Job, q pg.Queryer, relayID relay.ID) error
// an inconsistent state. This assumes UnregisterFilter will return nil if the filter wasn't found
// at all (no rows deleted).
spec := jb.OCR2OracleSpec
- chain, err := d.legacyChains.Get(relayID.ChainID.String())
+ chain, err := d.legacyChains.Get(relayID.ChainID)
if err != nil {
d.lggr.Error("cleanupEVM: failed to chain get chain %s", "err", relayID.ChainID, err)
return nil
@@ -275,12 +274,12 @@ func (d *Delegate) cleanupEVM(jb job.Job, q pg.Queryer, relayID relay.ID) error
var filters []string
switch spec.PluginType {
- case job.OCR2VRF:
+ case types.OCR2VRF:
filters, err = ocr2coordinator.FilterNamesFromSpec(spec)
if err != nil {
d.lggr.Errorw("failed to derive ocr2vrf filter names from spec", "err", err, "spec", spec)
}
- case job.OCR2Keeper:
+ case types.OCR2Keeper:
filters, err = ocr2keeper.FilterNamesFromSpec20(spec)
if err != nil {
d.lggr.Errorw("failed to derive ocr2keeper filter names from spec", "err", err, "spec", spec)
@@ -291,7 +290,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(),
@@ -346,7 +345,7 @@ func (d *Delegate) ServicesForSpec(jb job.Job, qopts ...pg.QOpt) ([]job.ServiceC
if rid.Network == relay.EVM {
lggr = logger.Sugared(lggr.With("evmChainID", rid.ChainID))
- chain, err2 := d.legacyChains.Get(rid.ChainID.String())
+ chain, err2 := d.legacyChains.Get(rid.ChainID)
if err2 != nil {
return nil, fmt.Errorf("ServicesForSpec: could not get EVM chain %s: %w", rid.ChainID, err2)
}
@@ -372,7 +371,7 @@ func (d *Delegate) ServicesForSpec(jb job.Job, qopts ...pg.QOpt) ([]job.ServiceC
if err != nil {
return nil, err
}
- if err := libocr2.SanityCheckLocalConfig(lc); err != nil {
+ if err = libocr2.SanityCheckLocalConfig(lc); err != nil {
return nil, err
}
lggr.Infow("OCR2 job using local config",
@@ -402,26 +401,26 @@ 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 {
- case job.Mercury:
+ case types.Mercury:
return d.newServicesMercury(ctx, lggr, jb, runResults, bootstrapPeers, kb, ocrDB, lc, ocrLogger)
- case job.Median:
+ case types.Median:
return d.newServicesMedian(ctx, lggr, jb, runResults, bootstrapPeers, kb, ocrDB, lc, ocrLogger)
- case job.DKG:
+ case types.DKG:
return d.newServicesDKG(lggr, jb, bootstrapPeers, kb, ocrDB, lc, ocrLogger)
- case job.OCR2VRF:
+ case types.OCR2VRF:
return d.newServicesOCR2VRF(lggr, jb, runResults, bootstrapPeers, kb, ocrDB, lc)
- case job.OCR2Keeper:
+ case types.OCR2Keeper:
return d.newServicesOCR2Keepers(lggr, jb, runResults, bootstrapPeers, kb, ocrDB, lc, ocrLogger)
- case job.OCR2Functions:
+ case types.Functions:
const (
_ int32 = iota
thresholdPluginId
@@ -438,7 +437,7 @@ func (d *Delegate) ServicesForSpec(jb job.Job, qopts ...pg.QOpt) ([]job.ServiceC
func GetEVMEffectiveTransmitterID(jb *job.Job, chain evm.Chain, lggr logger.SugaredLogger) (string, error) {
spec := jb.OCR2OracleSpec
- if spec.PluginType == job.Mercury {
+ if spec.PluginType == types.Mercury {
return spec.TransmitterID.String, nil
}
@@ -449,7 +448,7 @@ func GetEVMEffectiveTransmitterID(jb *job.Job, chain evm.Chain, lggr logger.Suga
if err != nil {
return "", err
}
- if len(sendingKeys) > 1 && spec.PluginType != job.OCR2VRF {
+ if len(sendingKeys) > 1 && spec.PluginType != types.OCR2VRF {
return "", errors.New("only ocr2 vrf should have more than 1 sending key")
}
spec.TransmitterID = null.StringFrom(sendingKeys[0])
@@ -480,7 +479,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,
@@ -510,18 +509,19 @@ func (d *Delegate) newServicesMercury(
if err != nil {
return nil, fmt.Errorf("failed to get relay %s is it enabled?: %w", spec.Relay, err)
}
- chain, err := d.legacyChains.Get(rid.ChainID.String())
+ chain, err := d.legacyChains.Get(rid.ChainID)
if err != nil {
return nil, fmt.Errorf("mercury services: failed to get chain %s: %w", rid.ChainID, err)
}
- mercuryProvider, err2 := relayer.NewMercuryProvider(ctx,
+ 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(),
+ ProviderType: string(spec.PluginType),
}, types.PluginArgs{
TransmitterID: transmitterID,
PluginConfig: spec.PluginConfig.Bytes(),
@@ -530,6 +530,11 @@ func (d *Delegate) newServicesMercury(
return nil, err2
}
+ mercuryProvider, ok := provider.(types.MercuryProvider)
+ if !ok {
+ return nil, errors.New("could not coerce PluginProvider to MercuryProvider")
+ }
+
oracleArgsNoPlugin := libocr2.MercuryOracleArgs{
BinaryNetworkEndpointFactory: d.peerWrapper.Peer2,
V2Bootstrappers: bootstrapPeers,
@@ -549,7 +554,7 @@ func (d *Delegate) newServicesMercury(
mercuryServices, err2 := mercury.NewServices(jb, mercuryProvider, d.pipelineRunner, runResults, lggr, oracleArgsNoPlugin, d.cfg.JobPipeline(), chEnhancedTelem, chain, d.mercuryORM, (mercuryutils.FeedID)(*spec.FeedID))
if ocrcommon.ShouldCollectEnhancedTelemetryMercury(&jb) {
- enhancedTelemService := ocrcommon.NewEnhancedTelemetryService(&jb, chEnhancedTelem, make(chan struct{}), d.monitoringEndpointGen.GenMonitoringEndpoint(spec.FeedID.String(), synchronization.EnhancedEAMercury), lggr.Named("Enhanced Telemetry Mercury"))
+ enhancedTelemService := ocrcommon.NewEnhancedTelemetryService(&jb, chEnhancedTelem, make(chan struct{}), d.monitoringEndpointGen.GenMonitoringEndpoint(spec.FeedID.String(), synchronization.EnhancedEAMercury), lggr.Named("EnhancedTelemetryMercury"))
mercuryServices = append(mercuryServices, enhancedTelemService)
}
@@ -560,7 +565,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,
@@ -594,7 +599,7 @@ func (d *Delegate) newServicesMedian(
medianServices, err2 := median.NewMedianServices(ctx, jb, d.isNewlyCreatedJob, relayer, d.pipelineRunner, runResults, lggr, oracleArgsNoPlugin, mConfig, enhancedTelemChan, errorLog)
if ocrcommon.ShouldCollectEnhancedTelemetry(&jb) {
- enhancedTelemService := ocrcommon.NewEnhancedTelemetryService(&jb, enhancedTelemChan, make(chan struct{}), d.monitoringEndpointGen.GenMonitoringEndpoint(spec.ContractID, synchronization.EnhancedEA), lggr.Named("Enhanced Telemetry"))
+ enhancedTelemService := ocrcommon.NewEnhancedTelemetryService(&jb, enhancedTelemChan, make(chan struct{}), d.monitoringEndpointGen.GenMonitoringEndpoint(spec.ContractID, synchronization.EnhancedEA), lggr.Named("EnhancedTelemetry"))
medianServices = append(medianServices, enhancedTelemService)
}
@@ -619,7 +624,7 @@ func (d *Delegate) newServicesDKG(
return nil, fmt.Errorf("DKG services: expected EVM relayer got %s", rid.Network)
}
- chain, err2 := d.legacyChains.Get(rid.ChainID.String())
+ chain, err2 := d.legacyChains.Get(rid.ChainID)
if err2 != nil {
return nil, fmt.Errorf("DKG services: failed to get chain %s: %w", rid.ChainID, err2)
}
@@ -627,7 +632,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(),
@@ -672,7 +677,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,
@@ -687,7 +692,7 @@ func (d *Delegate) newServicesOCR2VRF(
if rid.Network != relay.EVM {
return nil, fmt.Errorf("VRF services: expected EVM relayer got %s", rid.Network)
}
- chain, err2 := d.legacyChains.Get(rid.ChainID.String())
+ chain, err2 := d.legacyChains.Get(rid.ChainID)
if err2 != nil {
return nil, fmt.Errorf("VRF services: failed to get chain (%s): %w", rid.ChainID, err2)
}
@@ -712,7 +717,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(),
@@ -727,7 +732,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{
@@ -860,7 +865,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,
@@ -890,7 +895,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,
@@ -913,12 +918,12 @@ func (d *Delegate) newServicesOCR2Keepers21(
return nil, fmt.Errorf("keeper2 services: expected EVM relayer got %s", rid.Network)
}
- chain, err2 := d.legacyChains.Get(rid.ChainID.String())
+ chain, err2 := d.legacyChains.Get(rid.ChainID)
if err2 != nil {
return nil, fmt.Errorf("keeper2 services: failed to get chain %s: %w", rid.ChainID, err2)
}
- keeperProvider, services, err2 := ocr2keeper.EVMDependencies21(jb, d.db, lggr, chain, d.pipelineRunner, mc, kb)
+ keeperProvider, services, err2 := ocr2keeper.EVMDependencies21(jb, d.db, lggr, chain, d.pipelineRunner, mc, kb, d.cfg.Database())
if err2 != nil {
return nil, errors.Wrap(err2, "could not build dependencies for ocr2 keepers")
}
@@ -1009,7 +1014,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,
@@ -1026,7 +1031,7 @@ func (d *Delegate) newServicesOCR2Keepers20(
if rid.Network != relay.EVM {
return nil, fmt.Errorf("keepers2.0 services: expected EVM relayer got %s", rid.Network)
}
- chain, err2 := d.legacyChains.Get(rid.ChainID.String())
+ chain, err2 := d.legacyChains.Get(rid.ChainID)
if err2 != nil {
return nil, fmt.Errorf("keepers2.0 services: failed to get chain (%s): %w", rid.ChainID, err2)
}
@@ -1143,7 +1148,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,
@@ -1161,7 +1166,7 @@ func (d *Delegate) newServicesOCR2Functions(
if rid.Network != relay.EVM {
return nil, fmt.Errorf("functions services: expected EVM relayer got %s", rid.Network)
}
- chain, err := d.legacyChains.Get(rid.ChainID.String())
+ chain, err := d.legacyChains.Get(rid.ChainID)
if err != nil {
return nil, fmt.Errorf("functions services: failed to get chain %s: %w", rid.ChainID, err)
}
@@ -1170,7 +1175,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,
@@ -1215,6 +1220,8 @@ func (d *Delegate) newServicesOCR2Functions(
ReportingPluginFactory: nil, // To be set by NewFunctionsServices
}
+ noopMonitoringEndpoint := telemetry.NoopAgent{}
+
thresholdOracleArgs := libocr2.OCR2OracleArgs{
BinaryNetworkEndpointFactory: d.peerWrapper.Peer2,
V2Bootstrappers: bootstrapPeers,
@@ -1223,11 +1230,12 @@ func (d *Delegate) newServicesOCR2Functions(
Database: thresholdOcrDB,
LocalConfig: lc,
Logger: ocrLogger,
- MonitoringEndpoint: d.monitoringEndpointGen.GenMonitoringEndpoint(spec.ContractID, synchronization.OCR2Threshold),
- OffchainConfigDigester: thresholdProvider.OffchainConfigDigester(),
- OffchainKeyring: kb,
- OnchainKeyring: kb,
- ReportingPluginFactory: nil, // To be set by NewFunctionsServices
+ // Telemetry ingress for OCR2Threshold is currently not supported so a noop monitoring endpoint is being used
+ MonitoringEndpoint: &noopMonitoringEndpoint,
+ OffchainConfigDigester: thresholdProvider.OffchainConfigDigester(),
+ OffchainKeyring: kb,
+ OnchainKeyring: kb,
+ ReportingPluginFactory: nil, // To be set by NewFunctionsServices
}
s4OracleArgs := libocr2.OCR2OracleArgs{
@@ -1238,11 +1246,12 @@ func (d *Delegate) newServicesOCR2Functions(
Database: s4OcrDB,
LocalConfig: lc,
Logger: ocrLogger,
- MonitoringEndpoint: d.monitoringEndpointGen.GenMonitoringEndpoint(spec.ContractID, synchronization.OCR2S4),
- OffchainConfigDigester: s4Provider.OffchainConfigDigester(),
- OffchainKeyring: kb,
- OnchainKeyring: kb,
- ReportingPluginFactory: nil, // To be set by NewFunctionsServices
+ // Telemetry ingress for OCR2S4 is currently not supported so a noop monitoring endpoint is being used
+ MonitoringEndpoint: &noopMonitoringEndpoint,
+ OffchainConfigDigester: s4Provider.OffchainConfigDigester(),
+ OffchainKeyring: kb,
+ OnchainKeyring: kb,
+ ReportingPluginFactory: nil, // To be set by NewFunctionsServices
}
encryptedThresholdKeyShare := d.cfg.Threshold().ThresholdKeyShare()
@@ -1312,10 +1321,3 @@ func (l *logWriter) Write(p []byte) (n int, err error) {
n = len(p)
return
}
-
-type mockRecoverableProvider struct {
-}
-
-func (_m *mockRecoverableProvider) GetRecoveryProposals(ctx context.Context) ([]ocr2keepers21types.UpkeepPayload, error) {
- return nil, nil
-}
diff --git a/core/services/ocr2/delegate_test.go b/core/services/ocr2/delegate_test.go
index af4c9355b0a..97c9faa44d4 100644
--- a/core/services/ocr2/delegate_test.go
+++ b/core/services/ocr2/delegate_test.go
@@ -8,6 +8,7 @@ import (
"github.com/stretchr/testify/require"
"gopkg.in/guregu/null.v4"
+ "github.com/smartcontractkit/chainlink-relay/pkg/types"
evmcfg "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/toml"
txmmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr/mocks"
"github.com/smartcontractkit/chainlink/v2/core/internal/cltest"
@@ -45,12 +46,11 @@ func TestGetEVMEffectiveTransmitterID(t *testing.T) {
txManager := txmmocks.NewMockEvmTxManager(t)
relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth(), TxManager: txManager})
require.True(t, relayExtenders.Len() > 0)
- legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
- require.NoError(t, err)
+ legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
type testCase struct {
name string
- pluginType job.OCR2PluginType
+ pluginType types.OCR2PluginType
transmitterID null.String
sendingKeys []any
expectedError bool
@@ -76,7 +76,7 @@ func TestGetEVMEffectiveTransmitterID(t *testing.T) {
testCases := []testCase{
{
name: "mercury plugin should just return transmitterID",
- pluginType: job.Mercury,
+ pluginType: types.Mercury,
transmitterID: null.StringFrom("Mercury transmitterID"),
expectedTransmitterID: "Mercury transmitterID",
},
@@ -92,7 +92,7 @@ func TestGetEVMEffectiveTransmitterID(t *testing.T) {
},
{
name: "when transmitterID is not defined and plugin is ocr2vrf, it should allow>1 sendingKeys and set transmitterID to the first one",
- pluginType: job.OCR2VRF,
+ pluginType: types.OCR2VRF,
sendingKeys: []any{"0x7e57000000000000000000000000000000000000", "0x7e57000000000000000000000000000000000001", "0x7e57000000000000000000000000000000000002"},
expectedTransmitterID: "0x7e57000000000000000000000000000000000000",
},
@@ -110,7 +110,7 @@ func TestGetEVMEffectiveTransmitterID(t *testing.T) {
},
{
name: "when forwarders are enabled and when transmitterID is not defined, it should use first sendingKey to retrieve forwarder address",
- pluginType: job.OCR2VRF,
+ pluginType: types.OCR2VRF,
forwardingEnabled: true,
sendingKeys: []any{"0x7e57000000000000000000000000000000000001", "0x7e57000000000000000000000000000000000002"},
getForwarderForEOAArg: common.HexToAddress("0x7e57000000000000000000000000000000000001"),
@@ -118,7 +118,7 @@ func TestGetEVMEffectiveTransmitterID(t *testing.T) {
},
{
name: "when forwarders are enabled but forwarder address fails to be retrieved and when transmitterID is not defined, it should default to using first sendingKey",
- pluginType: job.OCR2VRF,
+ pluginType: types.OCR2VRF,
forwardingEnabled: true,
sendingKeys: []any{"0x7e57000000000000000000000000000000000001", "0x7e57000000000000000000000000000000000002"},
getForwarderForEOAArg: common.HexToAddress("0x7e57000000000000000000000000000000000001"),
@@ -172,7 +172,7 @@ func TestGetEVMEffectiveTransmitterID(t *testing.T) {
})
}
- t.Run("when forwarders are enabled and chainset retrieval fails, error should be handled", func(t *testing.T) {
+ t.Run("when forwarders are enabled and chain retrieval fails, error should be handled", func(t *testing.T) {
jb, err := ocr2validate.ValidatedOracleSpecToml(config.OCR2(), config.Insecure(), testspecs.OCR2EVMSpecMinimal)
require.NoError(t, err)
jb.ForwardingAllowed = true
diff --git a/core/services/ocr2/models/models.go b/core/services/ocr2/models/models.go
index 970c0aa7e0a..4d3b8bf532c 100644
--- a/core/services/ocr2/models/models.go
+++ b/core/services/ocr2/models/models.go
@@ -1,11 +1,8 @@
package models
type MercuryCredentials struct {
- URL string
- Username string
- Password string
-}
-
-func (mc *MercuryCredentials) Validate() bool {
- return mc.URL != "" && mc.Username != "" && mc.Password != ""
+ LegacyURL string
+ URL string
+ Username string
+ Password string
}
diff --git a/core/services/ocr2/plugins/functions/config/config.go b/core/services/ocr2/plugins/functions/config/config.go
index d373de57376..3f35d1dba9b 100644
--- a/core/services/ocr2/plugins/functions/config/config.go
+++ b/core/services/ocr2/plugins/functions/config/config.go
@@ -10,6 +10,7 @@ import (
"github.com/smartcontractkit/libocr/offchainreporting2/types"
+ "github.com/smartcontractkit/chainlink/v2/core/assets"
"github.com/smartcontractkit/chainlink/v2/core/services/gateway/connector"
"github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/common"
"github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/functions"
@@ -19,27 +20,29 @@ import (
// This config is part of the job spec and is loaded only once on node boot/job creation.
type PluginConfig struct {
- EnableRequestSignatureCheck bool `json:"enableRequestSignatureCheck"`
- DONID string `json:"donID"`
- ContractVersion uint32 `json:"contractVersion"`
- MinIncomingConfirmations uint32 `json:"minIncomingConfirmations"`
- RequestTimeoutSec uint32 `json:"requestTimeoutSec"`
- RequestTimeoutCheckFrequencySec uint32 `json:"requestTimeoutCheckFrequencySec"`
- RequestTimeoutBatchLookupSize uint32 `json:"requestTimeoutBatchLookupSize"`
- PruneMaxStoredRequests uint32 `json:"pruneMaxStoredRequests"`
- PruneCheckFrequencySec uint32 `json:"pruneCheckFrequencySec"`
- PruneBatchSize uint32 `json:"pruneBatchSize"`
- ListenerEventHandlerTimeoutSec uint32 `json:"listenerEventHandlerTimeoutSec"`
- ListenerEventsCheckFrequencyMillis uint32 `json:"listenerEventsCheckFrequencyMillis"`
- ContractUpdateCheckFrequencySec uint32 `json:"contractUpdateCheckFrequencySec"`
- MaxRequestSizeBytes uint32 `json:"maxRequestSizeBytes"`
- MaxRequestSizesList []uint32 `json:"maxRequestSizesList"`
- MaxSecretsSizesList []uint32 `json:"maxSecretsSizesList"`
- GatewayConnectorConfig *connector.ConnectorConfig `json:"gatewayConnectorConfig"`
- OnchainAllowlist *functions.OnchainAllowlistConfig `json:"onchainAllowlist"`
- RateLimiter *common.RateLimiterConfig `json:"rateLimiter"`
- S4Constraints *s4.Constraints `json:"s4Constraints"`
- DecryptionQueueConfig *DecryptionQueueConfig `json:"decryptionQueueConfig"`
+ EnableRequestSignatureCheck bool `json:"enableRequestSignatureCheck"`
+ DONID string `json:"donID"`
+ ContractVersion uint32 `json:"contractVersion"`
+ MinIncomingConfirmations uint32 `json:"minIncomingConfirmations"`
+ RequestTimeoutSec uint32 `json:"requestTimeoutSec"`
+ RequestTimeoutCheckFrequencySec uint32 `json:"requestTimeoutCheckFrequencySec"`
+ RequestTimeoutBatchLookupSize uint32 `json:"requestTimeoutBatchLookupSize"`
+ PruneMaxStoredRequests uint32 `json:"pruneMaxStoredRequests"`
+ PruneCheckFrequencySec uint32 `json:"pruneCheckFrequencySec"`
+ PruneBatchSize uint32 `json:"pruneBatchSize"`
+ ListenerEventHandlerTimeoutSec uint32 `json:"listenerEventHandlerTimeoutSec"`
+ ListenerEventsCheckFrequencyMillis uint32 `json:"listenerEventsCheckFrequencyMillis"`
+ ContractUpdateCheckFrequencySec uint32 `json:"contractUpdateCheckFrequencySec"`
+ MaxRequestSizeBytes uint32 `json:"maxRequestSizeBytes"`
+ MaxRequestSizesList []uint32 `json:"maxRequestSizesList"`
+ MaxSecretsSizesList []uint32 `json:"maxSecretsSizesList"`
+ MinimumSubscriptionBalance assets.Link `json:"minimumSubscriptionBalance"`
+ GatewayConnectorConfig *connector.ConnectorConfig `json:"gatewayConnectorConfig"`
+ OnchainAllowlist *functions.OnchainAllowlistConfig `json:"onchainAllowlist"`
+ OnchainSubscriptions *functions.OnchainSubscriptionsConfig `json:"onchainSubscriptions"`
+ RateLimiter *common.RateLimiterConfig `json:"rateLimiter"`
+ S4Constraints *s4.Constraints `json:"s4Constraints"`
+ DecryptionQueueConfig *DecryptionQueueConfig `json:"decryptionQueueConfig"`
}
type DecryptionQueueConfig struct {
diff --git a/core/services/ocr2/plugins/functions/integration_tests/v1/internal/testutils.go b/core/services/ocr2/plugins/functions/integration_tests/v1/internal/testutils.go
index f25abf9c1d4..c376213ed13 100644
--- a/core/services/ocr2/plugins/functions/integration_tests/v1/internal/testutils.go
+++ b/core/services/ocr2/plugins/functions/integration_tests/v1/internal/testutils.go
@@ -113,18 +113,19 @@ func CreateAndFundSubscriptions(t *testing.T, b *backends.SimulatedBackend, owne
allowed, err := allowListContract.HasAccess(nilOpts, owner.From, []byte{})
require.NoError(t, err)
if !allowed {
- message, err := allowListContract.GetMessage(nilOpts, owner.From, owner.From)
- require.NoError(t, err)
- privateKey, err := crypto.HexToECDSA(allowListPrivateKey[2:])
- require.NoError(t, err)
- flatSignature, err := crypto.Sign(message[:], privateKey)
- require.NoError(t, err)
+ message, err2 := allowListContract.GetMessage(nilOpts, owner.From, owner.From)
+ require.NoError(t, err2)
+ privateKey, err2 := crypto.HexToECDSA(allowListPrivateKey[2:])
+ require.NoError(t, err2)
+ flatSignature, err2 := crypto.Sign(message[:], privateKey)
+ require.NoError(t, err2)
var r [32]byte
copy(r[:], flatSignature[:32])
var s [32]byte
copy(s[:], flatSignature[32:64])
v := flatSignature[65]
- allowListContract.AcceptTermsOfService(owner, owner.From, owner.From, r, s, v)
+ _, err2 = allowListContract.AcceptTermsOfService(owner, owner.From, owner.From, r, s, v)
+ require.NoError(t, err2)
}
_, err = routerContract.CreateSubscription(owner)
@@ -191,11 +192,13 @@ func StartNewChainWithContracts(t *testing.T, nClients int) (*bind.TransactOpts,
var handleOracleFulfillmentSelector [4]byte
copy(handleOracleFulfillmentSelector[:], handleOracleFulfillmentSelectorSlice[:4])
functionsRouterConfig := functions_router.FunctionsRouterConfig{
- MaxConsumersPerSubscription: uint16(100),
- AdminFee: big.NewInt(0),
- HandleOracleFulfillmentSelector: handleOracleFulfillmentSelector,
- MaxCallbackGasLimits: []uint32{300_000, 500_000, 1_000_000},
- GasForCallExactCheck: 5000,
+ MaxConsumersPerSubscription: uint16(100),
+ AdminFee: big.NewInt(0),
+ HandleOracleFulfillmentSelector: handleOracleFulfillmentSelector,
+ MaxCallbackGasLimits: []uint32{300_000, 500_000, 1_000_000},
+ GasForCallExactCheck: 5000,
+ SubscriptionDepositMinimumRequests: 10,
+ SubscriptionDepositJuels: big.NewInt(9 * 1e18), // 9 LINK
}
routerAddress, _, routerContract, err := functions_router.DeployFunctionsRouter(owner, b, linkAddr, functionsRouterConfig)
require.NoError(t, err)
@@ -213,7 +216,6 @@ func StartNewChainWithContracts(t *testing.T, nClients int) (*bind.TransactOpts,
// Deploy Coordinator contract (matches updateConfig() in FunctionsBilling.sol)
coordinatorConfig := functions_coordinator.FunctionsBillingConfig{
- MaxCallbackGasLimit: uint32(450_000),
FeedStalenessSeconds: uint32(86_400),
GasOverheadBeforeCallback: uint32(325_000),
GasOverheadAfterCallback: uint32(50_000),
diff --git a/core/services/ocr2/plugins/functions/plugin.go b/core/services/ocr2/plugins/functions/plugin.go
index 3a13c0caba8..6cc7da97d00 100644
--- a/core/services/ocr2/plugins/functions/plugin.go
+++ b/core/services/ocr2/plugins/functions/plugin.go
@@ -13,6 +13,7 @@ import (
"github.com/smartcontractkit/libocr/commontypes"
libocr2 "github.com/smartcontractkit/libocr/offchainreporting2plus"
+ "github.com/smartcontractkit/chainlink/v2/core/assets"
"github.com/smartcontractkit/chainlink/v2/core/bridges"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm"
"github.com/smartcontractkit/chainlink/v2/core/logger"
@@ -130,17 +131,21 @@ func NewFunctionsServices(functionsOracleArgs, thresholdOracleArgs, s4OracleArgs
}
allServices = append(allServices, job.NewServiceAdapter(functionsReportingPluginOracle))
- if pluginConfig.GatewayConnectorConfig != nil && s4Storage != nil && pluginConfig.OnchainAllowlist != nil && pluginConfig.RateLimiter != nil {
+ if pluginConfig.GatewayConnectorConfig != nil && s4Storage != nil && pluginConfig.OnchainAllowlist != nil && pluginConfig.RateLimiter != nil && pluginConfig.OnchainSubscriptions != nil {
allowlist, err2 := gwFunctions.NewOnchainAllowlist(conf.Chain.Client(), *pluginConfig.OnchainAllowlist, conf.Logger)
if err2 != nil {
- return nil, errors.Wrap(err, "failed to call NewOnchainAllowlist while creating a Functions Reporting Plugin")
+ return nil, errors.Wrap(err, "failed to create OnchainAllowlist")
}
rateLimiter, err2 := hc.NewRateLimiter(*pluginConfig.RateLimiter)
if err2 != nil {
return nil, errors.Wrap(err, "failed to create a RateLimiter")
}
+ subscriptions, err2 := gwFunctions.NewOnchainSubscriptions(conf.Chain.Client(), *pluginConfig.OnchainSubscriptions, conf.Logger)
+ if err2 != nil {
+ return nil, errors.Wrap(err, "failed to create a OnchainSubscriptions")
+ }
connectorLogger := conf.Logger.Named("GatewayConnector").With("jobName", conf.Job.PipelineSpec.JobName)
- connector, err2 := NewConnector(pluginConfig.GatewayConnectorConfig, conf.EthKeystore, conf.Chain.ID(), s4Storage, allowlist, rateLimiter, connectorLogger)
+ connector, err2 := NewConnector(pluginConfig.GatewayConnectorConfig, conf.EthKeystore, conf.Chain.ID(), s4Storage, allowlist, rateLimiter, subscriptions, pluginConfig.MinimumSubscriptionBalance, connectorLogger)
if err2 != nil {
return nil, errors.Wrap(err, "failed to create a GatewayConnector")
}
@@ -167,7 +172,7 @@ func NewFunctionsServices(functionsOracleArgs, thresholdOracleArgs, s4OracleArgs
return allServices, nil
}
-func NewConnector(gwcCfg *connector.ConnectorConfig, ethKeystore keystore.Eth, chainID *big.Int, s4Storage s4.Storage, allowlist gwFunctions.OnchainAllowlist, rateLimiter *hc.RateLimiter, lggr logger.Logger) (connector.GatewayConnector, error) {
+func NewConnector(gwcCfg *connector.ConnectorConfig, ethKeystore keystore.Eth, chainID *big.Int, s4Storage s4.Storage, allowlist gwFunctions.OnchainAllowlist, rateLimiter *hc.RateLimiter, subscriptions gwFunctions.OnchainSubscriptions, minimumBalance assets.Link, lggr logger.Logger) (connector.GatewayConnector, error) {
enabledKeys, err := ethKeystore.EnabledKeysForChain(chainID)
if err != nil {
return nil, err
@@ -180,7 +185,7 @@ func NewConnector(gwcCfg *connector.ConnectorConfig, ethKeystore keystore.Eth, c
signerKey := enabledKeys[idx].ToEcdsaPrivKey()
nodeAddress := enabledKeys[idx].ID()
- handler, err := functions.NewFunctionsConnectorHandler(nodeAddress, signerKey, s4Storage, allowlist, rateLimiter, lggr)
+ handler, err := functions.NewFunctionsConnectorHandler(nodeAddress, signerKey, s4Storage, allowlist, rateLimiter, subscriptions, minimumBalance, lggr)
if err != nil {
return nil, err
}
diff --git a/core/services/ocr2/plugins/functions/plugin_test.go b/core/services/ocr2/plugins/functions/plugin_test.go
index 6b1e6f6e4c8..2e35672e920 100644
--- a/core/services/ocr2/plugins/functions/plugin_test.go
+++ b/core/services/ocr2/plugins/functions/plugin_test.go
@@ -8,6 +8,7 @@ import (
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
+ "github.com/smartcontractkit/chainlink/v2/core/assets"
"github.com/smartcontractkit/chainlink/v2/core/logger"
"github.com/smartcontractkit/chainlink/v2/core/services/gateway/connector"
hc "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/common"
@@ -31,10 +32,11 @@ func TestNewConnector_Success(t *testing.T) {
ethKeystore := ksmocks.NewEth(t)
s4Storage := s4mocks.NewStorage(t)
allowlist := gfmocks.NewOnchainAllowlist(t)
+ subscriptions := gfmocks.NewOnchainSubscriptions(t)
rateLimiter, err := hc.NewRateLimiter(hc.RateLimiterConfig{GlobalRPS: 100.0, GlobalBurst: 100, PerSenderRPS: 100.0, PerSenderBurst: 100})
require.NoError(t, err)
ethKeystore.On("EnabledKeysForChain", mock.Anything).Return([]ethkey.KeyV2{keyV2}, nil)
- _, err = functions.NewConnector(gwcCfg, ethKeystore, chainID, s4Storage, allowlist, rateLimiter, logger.TestLogger(t))
+ _, err = functions.NewConnector(gwcCfg, ethKeystore, chainID, s4Storage, allowlist, rateLimiter, subscriptions, *assets.NewLinkFromJuels(0), logger.TestLogger(t))
require.NoError(t, err)
}
@@ -53,9 +55,10 @@ func TestNewConnector_NoKeyForConfiguredAddress(t *testing.T) {
ethKeystore := ksmocks.NewEth(t)
s4Storage := s4mocks.NewStorage(t)
allowlist := gfmocks.NewOnchainAllowlist(t)
+ subscriptions := gfmocks.NewOnchainSubscriptions(t)
rateLimiter, err := hc.NewRateLimiter(hc.RateLimiterConfig{GlobalRPS: 100.0, GlobalBurst: 100, PerSenderRPS: 100.0, PerSenderBurst: 100})
require.NoError(t, err)
ethKeystore.On("EnabledKeysForChain", mock.Anything).Return([]ethkey.KeyV2{{Address: common.HexToAddress(addresses[1])}}, nil)
- _, err = functions.NewConnector(gwcCfg, ethKeystore, chainID, s4Storage, allowlist, rateLimiter, logger.TestLogger(t))
+ _, err = functions.NewConnector(gwcCfg, ethKeystore, chainID, s4Storage, allowlist, rateLimiter, subscriptions, *assets.NewLinkFromJuels(0), logger.TestLogger(t))
require.Error(t, err)
}
diff --git a/core/services/ocr2/plugins/functions/reporting.go b/core/services/ocr2/plugins/functions/reporting.go
index 7f532439c6a..f2e2f86aba2 100644
--- a/core/services/ocr2/plugins/functions/reporting.go
+++ b/core/services/ocr2/plugins/functions/reporting.go
@@ -4,7 +4,9 @@ import (
"context"
"fmt"
+ "github.com/ethereum/go-ethereum/common"
"github.com/google/uuid"
+ "github.com/pkg/errors"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
"google.golang.org/protobuf/proto"
@@ -60,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",
@@ -117,6 +124,21 @@ func (f FunctionsReportingPluginFactory) NewReportingPlugin(rpConfig types.Repor
return &plugin, info, nil
}
+// Check if requestCoordinator can be included together with reportCoordinator.
+// Return new reportCoordinator (if previous was nil) and error.
+func ShouldIncludeCoordinator(requestCoordinator *common.Address, reportCoordinator *common.Address) (*common.Address, error) {
+ if requestCoordinator == nil || *requestCoordinator == (common.Address{}) {
+ return reportCoordinator, errors.New("missing/zero request coordinator address")
+ }
+ if reportCoordinator == nil {
+ return requestCoordinator, nil
+ }
+ if *reportCoordinator != *requestCoordinator {
+ return reportCoordinator, errors.New("coordinator contract address mismatch")
+ }
+ return reportCoordinator, nil
+}
+
// Query() complies with ReportingPlugin
func (r *functionsReporting) Query(ctx context.Context, ts types.ReportTimestamp) (types.Query, error) {
r.logger.Debug("FunctionsReporting Query start", commontypes.LogFields{
@@ -132,8 +154,21 @@ func (r *functionsReporting) Query(ctx context.Context, ts types.ReportTimestamp
queryProto := encoding.Query{}
var idStrs []string
+ var reportCoordinator *common.Address
for _, result := range results {
result := result
+ if r.contractVersion == 1 {
+ reportCoordinator, err = ShouldIncludeCoordinator(result.CoordinatorContractAddress, reportCoordinator)
+ if err != nil {
+ r.logger.Debug("FunctionsReporting Query: skipping request with mismatched coordinator contract address", commontypes.LogFields{
+ "requestID": formatRequestId(result.RequestID[:]),
+ "requestCoordinator": result.CoordinatorContractAddress,
+ "reportCoordinator": reportCoordinator,
+ "error": err,
+ })
+ continue
+ }
+ }
queryProto.RequestIDs = append(queryProto.RequestIDs, result.RequestID[:])
idStrs = append(idStrs, formatRequestId(result.RequestID[:]))
}
@@ -235,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)
@@ -288,6 +324,7 @@ func (r *functionsReporting) Report(ctx context.Context, ts types.ReportTimestam
var allAggregated []*encoding.ProcessedRequest
var allIdStrs []string
var totalCallbackGas uint32
+ var reportCoordinator *common.Address
for _, reqId := range uniqueQueryIds {
observations := reqIdToObservationList[reqId]
if !CanAggregate(r.genericConfig.N, r.genericConfig.F, observations) {
@@ -330,6 +367,20 @@ func (r *functionsReporting) Report(ctx context.Context, ts types.ReportTimestam
"requestID": reqId,
"nObservations": len(observations),
})
+ if r.contractVersion == 1 {
+ var requestCoordinator common.Address
+ requestCoordinator.SetBytes(aggregated.CoordinatorContract)
+ reportCoordinator, err = ShouldIncludeCoordinator(&requestCoordinator, reportCoordinator)
+ if err != nil {
+ r.logger.Error("FunctionsReporting Report: skipping request with mismatched coordinator contract address", commontypes.LogFields{
+ "requestID": reqId,
+ "requestCoordinator": requestCoordinator,
+ "reportCoordinator": reportCoordinator,
+ "error": err,
+ })
+ continue
+ }
+ }
allAggregated = append(allAggregated, aggregated)
allIdStrs = append(allIdStrs, reqId)
}
diff --git a/core/services/ocr2/plugins/functions/reporting_test.go b/core/services/ocr2/plugins/functions/reporting_test.go
index e08a0aca7a0..6d5126c9390 100644
--- a/core/services/ocr2/plugins/functions/reporting_test.go
+++ b/core/services/ocr2/plugins/functions/reporting_test.go
@@ -134,6 +134,26 @@ func TestFunctionsReporting_Query(t *testing.T) {
require.Equal(t, reqs[1].RequestID[:], queryProto.RequestIDs[1])
}
+func TestFunctionsReporting_Query_HandleCoordinatorMismatch(t *testing.T) {
+ t.Parallel()
+ const batchSize = 10
+ plugin, orm, _ := preparePlugin(t, batchSize, 1, 1000000)
+ reqs := []functions_srv.Request{newRequest(), newRequest()}
+ reqs[0].CoordinatorContractAddress = &common.Address{1}
+ reqs[1].CoordinatorContractAddress = &common.Address{2}
+ orm.On("FindOldestEntriesByState", functions_srv.RESULT_READY, uint32(batchSize), mock.Anything).Return(reqs, nil)
+
+ q, err := plugin.Query(testutils.Context(t), types.ReportTimestamp{})
+ require.NoError(t, err)
+
+ queryProto := &encoding.Query{}
+ err = proto.Unmarshal(q, queryProto)
+ require.NoError(t, err)
+ require.Equal(t, 1, len(queryProto.RequestIDs))
+ require.Equal(t, reqs[0].RequestID[:], queryProto.RequestIDs[0])
+ // reqs[1] should be excluded from this query because it has a different coordinator address
+}
+
func TestFunctionsReporting_Observation(t *testing.T) {
t.Parallel()
plugin, orm, _ := preparePlugin(t, 10, 0, 0)
@@ -239,10 +259,10 @@ func TestFunctionsReporting_Report_WithGasLimitAndMetadata(t *testing.T) {
reqId1, reqId2, reqId3 := newRequestID(), newRequestID(), newRequestID()
compResult := []byte("aaa")
gasLimit1, gasLimit2 := uint32(100_000), uint32(200_000)
- coordinatorContract1, coordinatorContract2 := common.Address{1}, common.Address{2}
+ coordinatorContract := common.Address{1}
meta1, meta2 := []byte("meta1"), []byte("meta2")
- procReq1 := newProcessedRequestWithMeta(reqId1, compResult, []byte{}, gasLimit1, coordinatorContract1[:], meta1)
- procReq2 := newProcessedRequestWithMeta(reqId2, compResult, []byte{}, gasLimit2, coordinatorContract2[:], meta2)
+ procReq1 := newProcessedRequestWithMeta(reqId1, compResult, []byte{}, gasLimit1, coordinatorContract[:], meta1)
+ procReq2 := newProcessedRequestWithMeta(reqId2, compResult, []byte{}, gasLimit2, coordinatorContract[:], meta2)
query := newMarshalledQuery(t, reqId1, reqId2, reqId3, reqId1, reqId2) // duplicates should be ignored
obs := []types.AttributedObservation{
@@ -262,18 +282,48 @@ func TestFunctionsReporting_Report_WithGasLimitAndMetadata(t *testing.T) {
require.Equal(t, reqId1[:], decoded[0].RequestID)
require.Equal(t, compResult, decoded[0].Result)
require.Equal(t, []byte{}, decoded[0].Error)
- require.Equal(t, coordinatorContract1[:], decoded[0].CoordinatorContract)
+ require.Equal(t, coordinatorContract[:], decoded[0].CoordinatorContract)
require.Equal(t, meta1, decoded[0].OnchainMetadata)
// CallbackGasLimit is not ABI-encoded
require.Equal(t, reqId2[:], decoded[1].RequestID)
require.Equal(t, compResult, decoded[1].Result)
require.Equal(t, []byte{}, decoded[1].Error)
- require.Equal(t, coordinatorContract2[:], decoded[1].CoordinatorContract)
+ require.Equal(t, coordinatorContract[:], decoded[1].CoordinatorContract)
require.Equal(t, meta2, decoded[1].OnchainMetadata)
// CallbackGasLimit is not ABI-encoded
}
+func TestFunctionsReporting_Report_HandleCoordinatorMismatch(t *testing.T) {
+ t.Parallel()
+ plugin, _, codec := preparePlugin(t, 10, 1, 300000)
+ reqId1, reqId2, reqId3 := newRequestID(), newRequestID(), newRequestID()
+ compResult, meta := []byte("aaa"), []byte("meta")
+ coordinatorContractA, coordinatorContractB := common.Address{1}, common.Address{2}
+ procReq1 := newProcessedRequestWithMeta(reqId1, compResult, []byte{}, 0, coordinatorContractA[:], meta)
+ procReq2 := newProcessedRequestWithMeta(reqId2, compResult, []byte{}, 0, coordinatorContractB[:], meta)
+ procReq3 := newProcessedRequestWithMeta(reqId3, compResult, []byte{}, 0, coordinatorContractA[:], meta)
+
+ query := newMarshalledQuery(t, reqId1, reqId2, reqId3, reqId1, reqId2) // duplicates should be ignored
+ obs := []types.AttributedObservation{
+ newObservation(t, 1, procReq2, procReq3, procReq1),
+ newObservation(t, 2, procReq1, procReq2, procReq3),
+ newObservation(t, 3, procReq3, procReq1, procReq2),
+ }
+
+ produced, reportBytes, err := plugin.Report(testutils.Context(t), types.ReportTimestamp{}, query, obs)
+ require.True(t, produced)
+ require.NoError(t, err)
+
+ decoded, err := codec.DecodeReport(reportBytes)
+ require.NoError(t, err)
+ require.Equal(t, 2, len(decoded))
+
+ require.Equal(t, reqId1[:], decoded[0].RequestID)
+ require.Equal(t, reqId3[:], decoded[1].RequestID)
+ // reqId2 should be excluded from this report because it has a different coordinator address
+}
+
func TestFunctionsReporting_Report_CallbackGasLimitExceeded(t *testing.T) {
t.Parallel()
plugin, _, codec := preparePlugin(t, 10, 1, 200000)
@@ -438,3 +488,34 @@ func TestFunctionsReporting_ShouldTransmitAcceptedReport(t *testing.T) {
require.NoError(t, err)
require.True(t, should)
}
+
+func TestFunctionsReporting_ShouldIncludeCoordinator(t *testing.T) {
+ t.Parallel()
+
+ zeroAddr, coord1, coord2 := &common.Address{}, &common.Address{1}, &common.Address{2}
+
+ // should never pass nil requestCoordinator
+ newCoord, err := functions.ShouldIncludeCoordinator(nil, nil)
+ require.Error(t, err)
+ require.Nil(t, newCoord)
+
+ // should never pass zero requestCoordinator
+ newCoord, err = functions.ShouldIncludeCoordinator(zeroAddr, nil)
+ require.Error(t, err)
+ require.Nil(t, newCoord)
+
+ // overwrite nil reportCoordinator
+ newCoord, err = functions.ShouldIncludeCoordinator(coord1, nil)
+ require.NoError(t, err)
+ require.Equal(t, coord1, newCoord)
+
+ // same address is fine
+ newCoord, err = functions.ShouldIncludeCoordinator(coord1, newCoord)
+ require.NoError(t, err)
+ require.Equal(t, coord1, newCoord)
+
+ // different address is not accepted
+ newCoord, err = functions.ShouldIncludeCoordinator(coord2, newCoord)
+ require.Error(t, err)
+ require.Equal(t, coord1, newCoord)
+}
diff --git a/core/services/ocr2/plugins/median/services.go b/core/services/ocr2/plugins/median/services.go
index 8ff97c2cc56..8d121083f3f 100644
--- a/core/services/ocr2/plugins/median/services.go
+++ b/core/services/ocr2/plugins/median/services.go
@@ -3,6 +3,7 @@ package median
import (
"context"
"encoding/json"
+ "errors"
"fmt"
"time"
@@ -48,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,
@@ -67,12 +68,13 @@ func NewMedianServices(ctx context.Context,
}
spec := jb.OCR2OracleSpec
- provider, err := relayer.NewMedianProvider(ctx, types.RelayArgs{
+ 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(),
+ ProviderType: string(spec.PluginType),
}, types.PluginArgs{
TransmitterID: spec.TransmitterID.String,
PluginConfig: spec.PluginConfig.Bytes(),
@@ -80,6 +82,12 @@ func NewMedianServices(ctx context.Context,
if err != nil {
return
}
+
+ medianProvider, ok := provider.(types.MedianProvider)
+ if !ok {
+ return nil, errors.New("could not coerce PluginProvider to MedianProvider")
+ }
+
srvs = append(srvs, provider)
argsNoPlugin.ContractTransmitter = provider.ContractTransmitter()
argsNoPlugin.ContractConfigTracker = provider.ContractConfigTracker()
@@ -113,11 +121,11 @@ func NewMedianServices(ctx context.Context,
abort()
return
}
- median := loop.NewMedianService(lggr, telem, cmdFn, provider, dataSource, juelsPerFeeCoinSource, errorLog)
+ median := loop.NewMedianService(lggr, telem, cmdFn, medianProvider, dataSource, juelsPerFeeCoinSource, errorLog)
argsNoPlugin.ReportingPluginFactory = median
srvs = append(srvs, median)
} else {
- argsNoPlugin.ReportingPluginFactory, err = NewPlugin(lggr).NewMedianFactory(ctx, provider, dataSource, juelsPerFeeCoinSource, errorLog)
+ argsNoPlugin.ReportingPluginFactory, err = NewPlugin(lggr).NewMedianFactory(ctx, medianProvider, dataSource, juelsPerFeeCoinSource, errorLog)
if err != nil {
err = fmt.Errorf("failed to create median factory: %w", err)
abort()
diff --git a/core/services/ocr2/plugins/mercury/helpers_test.go b/core/services/ocr2/plugins/mercury/helpers_test.go
index e93f161916a..ddb521ff9ca 100644
--- a/core/services/ocr2/plugins/mercury/helpers_test.go
+++ b/core/services/ocr2/plugins/mercury/helpers_test.go
@@ -22,7 +22,14 @@ import (
"go.uber.org/zap/zaptest/observer"
"github.com/smartcontractkit/libocr/commontypes"
+ "github.com/smartcontractkit/libocr/offchainreporting2/chains/evmutil"
+ ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types"
+ "github.com/smartcontractkit/chainlink/v2/core/internal/cltest"
+ "github.com/smartcontractkit/chainlink/v2/core/internal/cltest/heavyweight"
+ "github.com/smartcontractkit/chainlink/v2/core/internal/testutils"
+ "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/keystest"
+ "github.com/smartcontractkit/chainlink/v2/core/logger"
"github.com/smartcontractkit/chainlink/v2/core/services/chainlink"
"github.com/smartcontractkit/chainlink/v2/core/services/keystore/chaintype"
"github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/csakey"
@@ -30,17 +37,10 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/p2pkey"
"github.com/smartcontractkit/chainlink/v2/core/services/ocr2/validate"
"github.com/smartcontractkit/chainlink/v2/core/services/ocrbootstrap"
+ "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury"
"github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/wsrpc/pb"
- "github.com/smartcontractkit/chainlink/v2/core/utils"
-
- relaymercury "github.com/smartcontractkit/chainlink-relay/pkg/reportingplugins/mercury"
-
- "github.com/smartcontractkit/chainlink/v2/core/internal/cltest"
- "github.com/smartcontractkit/chainlink/v2/core/internal/cltest/heavyweight"
- "github.com/smartcontractkit/chainlink/v2/core/internal/testutils"
- "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/keystest"
- "github.com/smartcontractkit/chainlink/v2/core/logger"
"github.com/smartcontractkit/chainlink/v2/core/store/models"
+ "github.com/smartcontractkit/chainlink/v2/core/utils"
)
var _ pb.MercuryServer = &mercuryServer{}
@@ -51,13 +51,14 @@ type request struct {
}
type mercuryServer struct {
- privKey ed25519.PrivateKey
- reqsCh chan request
- t *testing.T
+ privKey ed25519.PrivateKey
+ reqsCh chan request
+ t *testing.T
+ buildReport func() []byte
}
-func NewMercuryServer(t *testing.T, privKey ed25519.PrivateKey, reqsCh chan request) *mercuryServer {
- return &mercuryServer{privKey, reqsCh, t}
+func NewMercuryServer(t *testing.T, privKey ed25519.PrivateKey, reqsCh chan request, buildReport func() []byte) *mercuryServer {
+ return &mercuryServer{privKey, reqsCh, t, buildReport}
}
func (s *mercuryServer) Transmit(ctx context.Context, req *pb.TransmitRequest) (*pb.TransmitResponse, error) {
@@ -85,9 +86,12 @@ func (s *mercuryServer) LatestReport(ctx context.Context, lrr *pb.LatestReportRe
out.Report = new(pb.Report)
out.Report.FeedId = lrr.FeedId
- price := big.NewInt(123456789)
- encodedPrice, _ := relaymercury.EncodeValueInt192(price)
- out.Report.Price = encodedPrice
+ report := s.buildReport()
+ payload, err := mercury.PayloadTypes.Pack(evmutil.RawReportContext(ocrtypes.ReportContext{}), report, [][32]byte{}, [][32]byte{}, [32]byte{})
+ if err != nil {
+ panic(err)
+ }
+ out.Report.Payload = payload
return out, nil
}
diff --git a/core/services/ocr2/plugins/mercury/integration_test.go b/core/services/ocr2/plugins/mercury/integration_test.go
index b75855b8db5..aab1cadc5a5 100644
--- a/core/services/ocr2/plugins/mercury/integration_test.go
+++ b/core/services/ocr2/plugins/mercury/integration_test.go
@@ -25,7 +25,7 @@ import (
"github.com/shopspring/decimal"
"github.com/smartcontractkit/libocr/commontypes"
"github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper"
- ocr3confighelper "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3confighelper"
+ "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3confighelper"
ocr2types "github.com/smartcontractkit/libocr/offchainreporting2plus/types"
"github.com/smartcontractkit/wsrpc/credentials"
"github.com/stretchr/testify/assert"
@@ -34,6 +34,9 @@ import (
"go.uber.org/zap/zaptest/observer"
relaymercury "github.com/smartcontractkit/chainlink-relay/pkg/reportingplugins/mercury"
+ relaycodecv1 "github.com/smartcontractkit/chainlink-relay/pkg/reportingplugins/mercury/v1"
+ relaycodecv2 "github.com/smartcontractkit/chainlink-relay/pkg/reportingplugins/mercury/v2"
+ relaycodecv3 "github.com/smartcontractkit/chainlink-relay/pkg/reportingplugins/mercury/v3"
"github.com/smartcontractkit/chainlink/v2/core/assets"
"github.com/smartcontractkit/chainlink/v2/core/bridges"
@@ -64,7 +67,7 @@ var (
}
rawReportingPluginConfig = relaymercury.OffchainConfig{
ExpirationWindow: 1,
- BaseUSDFeeCents: 100,
+ BaseUSDFee: decimal.NewFromInt(100),
}
)
@@ -149,7 +152,13 @@ func TestIntegration_MercuryV1(t *testing.T) {
reqs := make(chan request)
serverKey := csakey.MustNewV2XXXTestingOnly(big.NewInt(-1))
serverPubKey := serverKey.PublicKey
- srv := NewMercuryServer(t, ed25519.PrivateKey(serverKey.Raw()), reqs)
+ srv := NewMercuryServer(t, ed25519.PrivateKey(serverKey.Raw()), reqs, func() []byte {
+ report, err := (&reportcodecv1.ReportCodec{}).BuildReport(relaycodecv1.ReportFields{BenchmarkPrice: big.NewInt(234567), Bid: big.NewInt(1), Ask: big.NewInt(1), CurrentBlockHash: make([]byte, 32)})
+ if err != nil {
+ panic(err)
+ }
+ return report
+ })
clientCSAKeys := make([]csakey.KeyV2, n+1)
clientPubKeys := make([]ed25519.PublicKey, n+1)
for i := 0; i < n+1; i++ {
@@ -494,7 +503,13 @@ func TestIntegration_MercuryV2(t *testing.T) {
reqs := make(chan request)
serverKey := csakey.MustNewV2XXXTestingOnly(big.NewInt(-1))
serverPubKey := serverKey.PublicKey
- srv := NewMercuryServer(t, ed25519.PrivateKey(serverKey.Raw()), reqs)
+ srv := NewMercuryServer(t, ed25519.PrivateKey(serverKey.Raw()), reqs, func() []byte {
+ report, err := (&reportcodecv2.ReportCodec{}).BuildReport(relaycodecv2.ReportFields{BenchmarkPrice: big.NewInt(234567), LinkFee: big.NewInt(1), NativeFee: big.NewInt(1)})
+ if err != nil {
+ panic(err)
+ }
+ return report
+ })
clientCSAKeys := make([]csakey.KeyV2, n+1)
clientPubKeys := make([]ed25519.PublicKey, n+1)
for i := 0; i < n+1; i++ {
@@ -686,7 +701,7 @@ func TestIntegration_MercuryV2(t *testing.T) {
continue // already saw all oracles for this feed
}
- expectedFee := relaymercury.CalculateFee(big.NewInt(123456789), rawReportingPluginConfig.BaseUSDFeeCents)
+ expectedFee := relaymercury.CalculateFee(big.NewInt(234567), rawReportingPluginConfig.BaseUSDFee)
expectedExpiresAt := reportElems["observationsTimestamp"].(uint32) + rawReportingPluginConfig.ExpirationWindow
assert.GreaterOrEqual(t, int(reportElems["observationsTimestamp"].(uint32)), int(testStartTimeStamp))
@@ -766,7 +781,13 @@ func TestIntegration_MercuryV3(t *testing.T) {
reqs := make(chan request)
serverKey := csakey.MustNewV2XXXTestingOnly(big.NewInt(-1))
serverPubKey := serverKey.PublicKey
- srv := NewMercuryServer(t, ed25519.PrivateKey(serverKey.Raw()), reqs)
+ srv := NewMercuryServer(t, ed25519.PrivateKey(serverKey.Raw()), reqs, func() []byte {
+ report, err := (&reportcodecv3.ReportCodec{}).BuildReport(relaycodecv3.ReportFields{BenchmarkPrice: big.NewInt(234567), Bid: big.NewInt(1), Ask: big.NewInt(1), LinkFee: big.NewInt(1), NativeFee: big.NewInt(1)})
+ if err != nil {
+ panic(err)
+ }
+ return report
+ })
clientCSAKeys := make([]csakey.KeyV2, n+1)
clientPubKeys := make([]ed25519.PublicKey, n+1)
for i := 0; i < n+1; i++ {
@@ -962,7 +983,7 @@ func TestIntegration_MercuryV3(t *testing.T) {
continue // already saw all oracles for this feed
}
- expectedFee := relaymercury.CalculateFee(big.NewInt(123456789), rawReportingPluginConfig.BaseUSDFeeCents)
+ expectedFee := relaymercury.CalculateFee(big.NewInt(234567), rawReportingPluginConfig.BaseUSDFee)
expectedExpiresAt := reportElems["observationsTimestamp"].(uint32) + rawReportingPluginConfig.ExpirationWindow
assert.GreaterOrEqual(t, int(reportElems["observationsTimestamp"].(uint32)), int(testStartTimeStamp))
diff --git a/core/services/ocr2/plugins/mercury/plugin.go b/core/services/ocr2/plugins/mercury/plugin.go
index 557c83fd11e..31fb8ab8c4b 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,
@@ -67,7 +67,7 @@ func NewServices(
runResults,
chEnhancedTelem,
chainHeadTracker,
- ocr2Provider.ContractTransmitter(),
+ ocr2Provider.MercuryServerFetcher(),
pluginConfig.InitialBlockNumber.Ptr(),
feedID,
)
@@ -79,7 +79,7 @@ func NewServices(
)
case 2:
ds := mercuryv2.NewDataSource(
- // TODO: Needs ORM to carry timestamps over
+ orm,
pipelineRunner,
jb,
*jb.PipelineSpec,
@@ -87,7 +87,7 @@ func NewServices(
lggr,
runResults,
chEnhancedTelem,
- ocr2Provider.ContractTransmitter(),
+ ocr2Provider.MercuryServerFetcher(),
*pluginConfig.LinkFeedID,
*pluginConfig.NativeFeedID,
)
@@ -99,6 +99,7 @@ func NewServices(
)
case 3:
ds := mercuryv3.NewDataSource(
+ orm,
pipelineRunner,
jb,
*jb.PipelineSpec,
@@ -106,7 +107,7 @@ func NewServices(
lggr,
runResults,
chEnhancedTelem,
- ocr2Provider.ContractTransmitter(),
+ ocr2Provider.MercuryServerFetcher(),
*pluginConfig.LinkFeedID,
*pluginConfig.NativeFeedID,
)
diff --git a/core/services/ocr2/plugins/ocr2keeper/evm20/registry.go b/core/services/ocr2/plugins/ocr2keeper/evm20/registry.go
index 82cad9d4a5b..3f574158e31 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/block_subscriber.go b/core/services/ocr2/plugins/ocr2keeper/evm21/block_subscriber.go
index ca74eb85e1a..9766d988767 100644
--- a/core/services/ocr2/plugins/ocr2keeper/evm21/block_subscriber.go
+++ b/core/services/ocr2/plugins/ocr2keeper/evm21/block_subscriber.go
@@ -29,11 +29,15 @@ const (
blockHistorySize = int64(256)
)
+var (
+ BlockSubscriberServiceName = "BlockSubscriber"
+)
+
type BlockSubscriber struct {
- sync utils.StartStopOnce
+ utils.StartStopOnce
+ threadCtrl utils.ThreadControl
+
mu sync.RWMutex
- ctx context.Context
- cancel context.CancelFunc
hb httypes.HeadBroadcaster
lp logpoller.LogPoller
headC chan *evmtypes.Head
@@ -46,13 +50,15 @@ type BlockSubscriber struct {
latestBlock atomic.Pointer[ocr2keepers.BlockKey]
blockHistorySize int64
blockSize int64
+ finalityDepth uint32
lggr logger.Logger
}
var _ ocr2keepers.BlockSubscriber = &BlockSubscriber{}
-func NewBlockSubscriber(hb httypes.HeadBroadcaster, lp logpoller.LogPoller, lggr logger.Logger) *BlockSubscriber {
+func NewBlockSubscriber(hb httypes.HeadBroadcaster, lp logpoller.LogPoller, finalityDepth uint32, lggr logger.Logger) *BlockSubscriber {
return &BlockSubscriber{
+ threadCtrl: utils.NewThreadControl(),
hb: hb,
lp: lp,
headC: make(chan *evmtypes.Head, channelSize),
@@ -60,6 +66,7 @@ func NewBlockSubscriber(hb httypes.HeadBroadcaster, lp logpoller.LogPoller, lggr
blocks: map[int64]string{},
blockHistorySize: blockHistorySize,
blockSize: lookbackDepth,
+ finalityDepth: finalityDepth,
latestBlock: atomic.Pointer[ocr2keepers.BlockKey]{},
lggr: lggr.Named("BlockSubscriber"),
}
@@ -81,8 +88,8 @@ func (bs *BlockSubscriber) getBlockRange(ctx context.Context) ([]uint64, error)
return blocks, nil
}
-func (bs *BlockSubscriber) initializeBlocks(blocks []uint64) error {
- logpollerBlocks, err := bs.lp.GetBlocksRange(bs.ctx, blocks, pg.WithParentCtx(bs.ctx))
+func (bs *BlockSubscriber) initializeBlocks(ctx context.Context, blocks []uint64) error {
+ logpollerBlocks, err := bs.lp.GetBlocksRange(ctx, blocks)
if err != nil {
return err
}
@@ -127,67 +134,61 @@ func (bs *BlockSubscriber) cleanup() {
bs.lggr.Infof("lastClearedBlock is set to %d", bs.lastClearedBlock)
}
-func (bs *BlockSubscriber) Start(ctx context.Context) error {
- bs.lggr.Info("block subscriber started.")
- return bs.sync.StartOnce("BlockSubscriber", func() error {
- bs.mu.Lock()
- defer bs.mu.Unlock()
- bs.ctx, bs.cancel = context.WithCancel(context.Background())
- // initialize the blocks map with the recent blockSize blocks
- blocks, err := bs.getBlockRange(bs.ctx)
- if err != nil {
- bs.lggr.Errorf("failed to get block range", err)
- }
- err = bs.initializeBlocks(blocks)
- if err != nil {
- bs.lggr.Errorf("failed to get log poller blocks", err)
- }
-
- _, bs.unsubscribe = bs.hb.Subscribe(&headWrapper{headC: bs.headC, lggr: bs.lggr})
+func (bs *BlockSubscriber) initialize(ctx context.Context) {
+ bs.mu.Lock()
+ defer bs.mu.Unlock()
+ // initialize the blocks map with the recent blockSize blocks
+ blocks, err := bs.getBlockRange(ctx)
+ if err != nil {
+ bs.lggr.Errorf("failed to get block range", err)
+ }
+ err = bs.initializeBlocks(ctx, blocks)
+ if err != nil {
+ bs.lggr.Errorf("failed to get log poller blocks", err)
+ }
+ _, bs.unsubscribe = bs.hb.Subscribe(&headWrapper{headC: bs.headC, lggr: bs.lggr})
+}
+func (bs *BlockSubscriber) Start(ctx context.Context) error {
+ return bs.StartOnce(BlockSubscriberServiceName, func() error {
+ bs.lggr.Info("block subscriber started.")
+ bs.initialize(ctx)
// poll from head broadcaster channel and push to subscribers
- {
- go func(ctx context.Context) {
- for {
- select {
- case h := <-bs.headC:
- if h != nil {
- bs.processHead(h)
- }
- case <-ctx.Done():
- return
+ bs.threadCtrl.Go(func(ctx context.Context) {
+ for {
+ select {
+ case h := <-bs.headC:
+ if h != nil {
+ bs.processHead(h)
}
+ case <-ctx.Done():
+ return
}
- }(bs.ctx)
- }
-
- // clean up block maps
- {
- go func(ctx context.Context) {
- ticker := time.NewTicker(cleanUpInterval)
- for {
- select {
- case <-ticker.C:
- bs.cleanup()
- case <-ctx.Done():
- ticker.Stop()
- return
- }
+ }
+ })
+ // cleanup old blocks
+ bs.threadCtrl.Go(func(ctx context.Context) {
+ ticker := time.NewTicker(cleanUpInterval)
+ defer ticker.Stop()
+
+ for {
+ select {
+ case <-ticker.C:
+ bs.cleanup()
+ case <-ctx.Done():
+ return
}
- }(bs.ctx)
- }
+ }
+ })
return nil
})
}
func (bs *BlockSubscriber) Close() error {
- bs.lggr.Info("stop block subscriber")
- return bs.sync.StopOnce("BlockSubscriber", func() error {
- bs.mu.Lock()
- defer bs.mu.Unlock()
-
- bs.cancel()
+ return bs.StopOnce(BlockSubscriberServiceName, func() error {
+ bs.lggr.Info("stop block subscriber")
+ bs.threadCtrl.Close()
bs.unsubscribe()
return nil
})
@@ -228,12 +229,21 @@ func (bs *BlockSubscriber) processHead(h *evmtypes.Head) {
// when re-org happens, new heads will have pointers to the new blocks
i := int64(0)
for cp := h; cp != nil; cp = cp.Parent {
- if cp != h && bs.blocks[cp.Number] != cp.Hash.Hex() {
- bs.lggr.Warnf("overriding block %d old hash %s with new hash %s due to re-org", cp.Number, bs.blocks[cp.Number], cp.Hash.Hex())
+ // we don't stop when a matching (block number/hash) entry is seen in the map because parent linked list may be
+ // cut short during a re-org if head broadcaster backfill is not complete. This can cause some re-orged blocks
+ // left in the map. for example, re-org happens for block 98, 99, 100. next head 101 from broadcaster has parent list
+ // of 100, so block 100 and 101 are updated. when next head 102 arrives, it has full parent history of finality depth.
+ // if we stop when we see a block number/hash match, we won't look back and correct block 98 and 99.
+ // hence, we make a compromise here and check previous max(finality depth, blockSize) blocks and update the map.
+ existingHash, ok := bs.blocks[cp.Number]
+ if !ok {
+ bs.lggr.Debugf("filling block %d with new hash %s", cp.Number, cp.Hash.Hex())
+ } else if existingHash != cp.Hash.Hex() {
+ bs.lggr.Warnf("overriding block %d old hash %s with new hash %s due to re-org", cp.Number, existingHash, cp.Hash.Hex())
}
bs.blocks[cp.Number] = cp.Hash.Hex()
i++
- if i > bs.blockSize {
+ if i > int64(bs.finalityDepth) || i > bs.blockSize {
break
}
}
diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/block_subscriber_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/block_subscriber_test.go
index 19dfa7d9281..618ea83d4e9 100644
--- a/core/services/ocr2/plugins/ocr2keeper/evm21/block_subscriber_test.go
+++ b/core/services/ocr2/plugins/ocr2keeper/evm21/block_subscriber_test.go
@@ -22,13 +22,14 @@ import (
const historySize = 4
const blockSize = int64(4)
+const finality = uint32(4)
func TestBlockSubscriber_Subscribe(t *testing.T) {
lggr := logger.TestLogger(t)
var hb types.HeadBroadcaster
var lp logpoller.LogPoller
- bs := NewBlockSubscriber(hb, lp, lggr)
+ bs := NewBlockSubscriber(hb, lp, finality, lggr)
bs.blockHistorySize = historySize
bs.blockSize = blockSize
subId, _, err := bs.Subscribe()
@@ -47,7 +48,7 @@ func TestBlockSubscriber_Unsubscribe(t *testing.T) {
var hb types.HeadBroadcaster
var lp logpoller.LogPoller
- bs := NewBlockSubscriber(hb, lp, lggr)
+ bs := NewBlockSubscriber(hb, lp, finality, lggr)
bs.blockHistorySize = historySize
bs.blockSize = blockSize
subId, _, err := bs.Subscribe()
@@ -65,7 +66,7 @@ func TestBlockSubscriber_Unsubscribe_Failure(t *testing.T) {
var hb types.HeadBroadcaster
var lp logpoller.LogPoller
- bs := NewBlockSubscriber(hb, lp, lggr)
+ bs := NewBlockSubscriber(hb, lp, finality, lggr)
bs.blockHistorySize = historySize
bs.blockSize = blockSize
err := bs.Unsubscribe(2)
@@ -97,7 +98,7 @@ func TestBlockSubscriber_GetBlockRange(t *testing.T) {
t.Run(tc.Name, func(t *testing.T) {
lp := new(mocks.LogPoller)
lp.On("LatestBlock", mock.Anything).Return(tc.LatestBlock, tc.LatestBlockErr)
- bs := NewBlockSubscriber(hb, lp, lggr)
+ bs := NewBlockSubscriber(hb, lp, finality, lggr)
bs.blockHistorySize = historySize
bs.blockSize = blockSize
blocks, err := bs.getBlockRange(testutils.Context(t))
@@ -155,10 +156,10 @@ func TestBlockSubscriber_InitializeBlocks(t *testing.T) {
t.Run(tc.Name, func(t *testing.T) {
lp := new(mocks.LogPoller)
lp.On("GetBlocksRange", mock.Anything, tc.Blocks, mock.Anything).Return(tc.PollerBlocks, tc.Error)
- bs := NewBlockSubscriber(hb, lp, lggr)
+ bs := NewBlockSubscriber(hb, lp, finality, lggr)
bs.blockHistorySize = historySize
bs.blockSize = blockSize
- err := bs.initializeBlocks(tc.Blocks)
+ err := bs.initializeBlocks(testutils.Context(t), tc.Blocks)
if tc.Error != nil {
assert.Equal(t, tc.Error.Error(), err.Error())
@@ -213,7 +214,7 @@ func TestBlockSubscriber_BuildHistory(t *testing.T) {
for _, tc := range tests {
t.Run(tc.Name, func(t *testing.T) {
- bs := NewBlockSubscriber(hb, lp, lggr)
+ bs := NewBlockSubscriber(hb, lp, finality, lggr)
bs.blockHistorySize = historySize
bs.blockSize = blockSize
bs.blocks = tc.Blocks
@@ -258,7 +259,7 @@ func TestBlockSubscriber_Cleanup(t *testing.T) {
for _, tc := range tests {
t.Run(tc.Name, func(t *testing.T) {
- bs := NewBlockSubscriber(hb, lp, lggr)
+ bs := NewBlockSubscriber(hb, lp, finality, lggr)
bs.blockHistorySize = historySize
bs.blockSize = blockSize
bs.blocks = tc.Blocks
@@ -300,7 +301,7 @@ func TestBlockSubscriber_Start(t *testing.T) {
lp.On("GetBlocksRange", mock.Anything, blocks, mock.Anything).Return(pollerBlocks, nil)
- bs := NewBlockSubscriber(hb, lp, lggr)
+ bs := NewBlockSubscriber(hb, lp, finality, lggr)
bs.blockHistorySize = historySize
bs.blockSize = blockSize
err := bs.Start(context.Background())
diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/core/interfaces.go b/core/services/ocr2/plugins/ocr2keeper/evm21/core/interfaces.go
index e6d9bb3d8a7..d9417c72a19 100644
--- a/core/services/ocr2/plugins/ocr2keeper/evm21/core/interfaces.go
+++ b/core/services/ocr2/plugins/ocr2keeper/evm21/core/interfaces.go
@@ -10,5 +10,5 @@ import (
//
//go:generate mockery --quiet --name UpkeepStateReader --output ./mocks/ --case=underscore
type UpkeepStateReader interface {
- SelectByWorkIDsInRange(ctx context.Context, start, end int64, workIDs ...string) ([]ocr2keepers.UpkeepState, error)
+ SelectByWorkIDs(ctx context.Context, workIDs ...string) ([]ocr2keepers.UpkeepState, error)
}
diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/core/mocks/upkeep_state_reader.go b/core/services/ocr2/plugins/ocr2keeper/evm21/core/mocks/upkeep_state_reader.go
index 09a5f299463..9644f843fe5 100644
--- a/core/services/ocr2/plugins/ocr2keeper/evm21/core/mocks/upkeep_state_reader.go
+++ b/core/services/ocr2/plugins/ocr2keeper/evm21/core/mocks/upkeep_state_reader.go
@@ -15,32 +15,32 @@ type UpkeepStateReader struct {
mock.Mock
}
-// SelectByWorkIDsInRange provides a mock function with given fields: ctx, start, end, workIDs
-func (_m *UpkeepStateReader) SelectByWorkIDsInRange(ctx context.Context, start int64, end int64, workIDs ...string) ([]types.UpkeepState, error) {
+// SelectByWorkIDs provides a mock function with given fields: ctx, workIDs
+func (_m *UpkeepStateReader) SelectByWorkIDs(ctx context.Context, workIDs ...string) ([]types.UpkeepState, error) {
_va := make([]interface{}, len(workIDs))
for _i := range workIDs {
_va[_i] = workIDs[_i]
}
var _ca []interface{}
- _ca = append(_ca, ctx, start, end)
+ _ca = append(_ca, ctx)
_ca = append(_ca, _va...)
ret := _m.Called(_ca...)
var r0 []types.UpkeepState
var r1 error
- if rf, ok := ret.Get(0).(func(context.Context, int64, int64, ...string) ([]types.UpkeepState, error)); ok {
- return rf(ctx, start, end, workIDs...)
+ if rf, ok := ret.Get(0).(func(context.Context, ...string) ([]types.UpkeepState, error)); ok {
+ return rf(ctx, workIDs...)
}
- if rf, ok := ret.Get(0).(func(context.Context, int64, int64, ...string) []types.UpkeepState); ok {
- r0 = rf(ctx, start, end, workIDs...)
+ if rf, ok := ret.Get(0).(func(context.Context, ...string) []types.UpkeepState); ok {
+ r0 = rf(ctx, workIDs...)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]types.UpkeepState)
}
}
- if rf, ok := ret.Get(1).(func(context.Context, int64, int64, ...string) error); ok {
- r1 = rf(ctx, start, end, workIDs...)
+ if rf, ok := ret.Get(1).(func(context.Context, ...string) error); ok {
+ r1 = rf(ctx, workIDs...)
} else {
r1 = ret.Error(1)
}
diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/core/payload_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/core/payload_test.go
index f7b245ffce0..1ca280c0d2d 100644
--- a/core/services/ocr2/plugins/ocr2keeper/evm21/core/payload_test.go
+++ b/core/services/ocr2/plugins/ocr2keeper/evm21/core/payload_test.go
@@ -40,11 +40,12 @@ func TestWorkID(t *testing.T) {
BlockNumber: 123,
BlockHash: common.HexToHash("0xabcdef"),
LogTriggerExtension: &ocr2keepers.LogTriggerExtension{
- Index: 1,
- TxHash: common.HexToHash("0x12345"),
+ Index: 1,
+ TxHash: common.HexToHash("0x12345"),
+ BlockHash: common.HexToHash("0xabcdef"),
},
},
- expected: "db0e245ff4e7551d6c862d9a0eb5466624e1439ad1db262a7a3d6137d892d0a3",
+ expected: "aaa208331dfafff7a681e3358d082a2e78633dd05c8fb2817c391888cadb2912",
},
{
name: "happy path example from an actual tx",
@@ -53,11 +54,12 @@ func TestWorkID(t *testing.T) {
BlockNumber: 39344455,
BlockHash: common.HexToHash("0xb41258d18cd44ebf7a0d70de011f2bc4a67c9b68e8b6dada864045d8543bb020"),
LogTriggerExtension: &ocr2keepers.LogTriggerExtension{
- Index: 41,
- TxHash: common.HexToHash("0x44079b1b33aff337dbf17b9e12c5724ecab979c50c8201a9814a488ff3e22384"),
+ Index: 41,
+ TxHash: common.HexToHash("0x44079b1b33aff337dbf17b9e12c5724ecab979c50c8201a9814a488ff3e22384"),
+ BlockHash: common.HexToHash("0xb41258d18cd44ebf7a0d70de011f2bc4a67c9b68e8b6dada864045d8543bb020"),
},
},
- expected: "cdb4cfd9b4855b28d243d099c41b832da6b2d99dda3e7d09b900899afd09328f",
+ expected: "ef1b6acac8aa3682a8a08f666a13cfa165f7e811a16ea9fa0817f437fc4d110d",
},
{
name: "empty upkeepID",
@@ -124,7 +126,7 @@ func TestNewUpkeepPayload(t *testing.T) {
},
},
check: []byte("check-data-111"),
- workID: "d2fc1c0d626b480a4180f30b89142ae727c85e0b4dc0a82645bcef8062ff932a",
+ workID: "d8e7c8907a0b60b637ce71ff4f757edf076e270d52c51f6e4d46a3b0696e0a39",
},
}
diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/core/trigger.go b/core/services/ocr2/plugins/ocr2keeper/evm21/core/trigger.go
index 9999aefbd25..79273479596 100644
--- a/core/services/ocr2/plugins/ocr2keeper/evm21/core/trigger.go
+++ b/core/services/ocr2/plugins/ocr2keeper/evm21/core/trigger.go
@@ -16,7 +16,7 @@ type triggerWrapper = automation_utils_2_1.KeeperRegistryBase21LogTrigger
var ErrABINotParsable = fmt.Errorf("error parsing abi")
-// according to the upkeep type of the given id.
+// PackTrigger packs the trigger data according to the upkeep type of the given id. it will remove the first 4 bytes of function selector.
func PackTrigger(id *big.Int, trig triggerWrapper) ([]byte, error) {
var trigger []byte
var err error
@@ -41,10 +41,11 @@ func PackTrigger(id *big.Int, trig triggerWrapper) ([]byte, error) {
trigger, err = utilsABI.Pack("_conditionalTrigger", &trig)
case ocr2keepers.LogTrigger:
logTrig := automation_utils_2_1.KeeperRegistryBase21LogTrigger{
- BlockNum: trig.BlockNum,
- BlockHash: trig.BlockHash,
- LogIndex: trig.LogIndex,
- TxHash: trig.TxHash,
+ BlockNum: trig.BlockNum,
+ BlockHash: trig.BlockHash,
+ LogBlockHash: trig.LogBlockHash,
+ LogIndex: trig.LogIndex,
+ TxHash: trig.TxHash,
}
trigger, err = utilsABI.Pack("_logTrigger", &logTrig)
default:
@@ -98,6 +99,7 @@ func UnpackTrigger(id *big.Int, raw []byte) (triggerWrapper, error) {
}
copy(triggerW.BlockHash[:], converted.BlockHash[:])
copy(triggerW.TxHash[:], converted.TxHash[:])
+ copy(triggerW.LogBlockHash[:], converted.LogBlockHash[:])
return triggerW, nil
default:
return triggerWrapper{}, fmt.Errorf("unknown trigger type: %d", upkeepType)
diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/core/trigger_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/core/trigger_test.go
index 5fa5ae5c910..0233e40679d 100644
--- a/core/services/ocr2/plugins/ocr2keeper/evm21/core/trigger_test.go
+++ b/core/services/ocr2/plugins/ocr2keeper/evm21/core/trigger_test.go
@@ -23,13 +23,14 @@ func TestPackUnpackTrigger(t *testing.T) {
"happy flow log trigger",
append([]byte{1}, common.LeftPadBytes([]byte{1}, 15)...),
triggerWrapper{
- BlockNum: 1,
- BlockHash: common.HexToHash("0x01111111"),
- LogIndex: 1,
- TxHash: common.HexToHash("0x01111111"),
+ BlockNum: 1,
+ BlockHash: common.HexToHash("0x01111111"),
+ LogIndex: 1,
+ TxHash: common.HexToHash("0x01111111"),
+ LogBlockHash: common.HexToHash("0x01111abc"),
},
func() []byte {
- b, _ := hexutil.Decode("0x0000000000000000000000000000000000000000000000000000000001111111000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000001111111")
+ b, _ := hexutil.Decode("0x0000000000000000000000000000000000000000000000000000000001111abc0000000000000000000000000000000000000000000000000000000001111111000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000001111111")
return b
}(),
nil,
diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/core/utils.go b/core/services/ocr2/plugins/ocr2keeper/evm21/core/utils.go
new file mode 100644
index 00000000000..6a31b938fc6
--- /dev/null
+++ b/core/services/ocr2/plugins/ocr2keeper/evm21/core/utils.go
@@ -0,0 +1,39 @@
+package core
+
+import (
+ "context"
+ "math/big"
+ "strings"
+
+ "github.com/ethereum/go-ethereum/common"
+
+ "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client"
+ "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types"
+)
+
+// GetTxBlock calls eth_getTransactionReceipt on the eth client to obtain a tx receipt
+func GetTxBlock(ctx context.Context, client client.Client, txHash common.Hash) (*big.Int, common.Hash, error) {
+ receipt := types.Receipt{}
+ err := client.CallContext(ctx, &receipt, "eth_getTransactionReceipt", txHash)
+ if err != nil {
+ if strings.Contains(err.Error(), "not yet been implemented") {
+ // workaround for simulated chains
+ // Exploratory: fix this properly (e.g. in the simulated backend)
+ r, err1 := client.TransactionReceipt(ctx, txHash)
+ if err1 != nil {
+ return nil, common.Hash{}, err1
+ }
+ if r.Status != 1 {
+ return nil, common.Hash{}, nil
+ }
+ return r.BlockNumber, r.BlockHash, nil
+ }
+ return nil, common.Hash{}, err
+ }
+
+ if receipt.Status != 1 {
+ return nil, common.Hash{}, nil
+ }
+
+ return receipt.GetBlockNumber(), receipt.GetBlockHash(), nil
+}
diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/core/utils_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/core/utils_test.go
new file mode 100644
index 00000000000..443a639505a
--- /dev/null
+++ b/core/services/ocr2/plugins/ocr2keeper/evm21/core/utils_test.go
@@ -0,0 +1,73 @@
+package core
+
+import (
+ "fmt"
+ "math/big"
+ "testing"
+
+ "github.com/ethereum/go-ethereum/common"
+ "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/internal/testutils"
+
+ "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types"
+)
+
+func TestUtils_GetTxBlock(t *testing.T) {
+ tests := []struct {
+ name string
+ txHash common.Hash
+ ethCallError error
+ receipt *types.Receipt
+ status uint64
+ }{
+ {
+ name: "success",
+ txHash: common.HexToHash("0xc48fbf05edaf18f6aaa7de24de28528546b874bb03728d624ca407b8fed582a3"),
+ receipt: &types.Receipt{
+ Status: 1,
+ BlockNumber: big.NewInt(2000),
+ },
+ status: 1,
+ },
+ {
+ name: "failure - eth call error",
+ txHash: common.HexToHash("0xc48fbf05edaf18f6aaa7de24de28528546b874bb03728d624ca407b8fed582a3"),
+ ethCallError: fmt.Errorf("eth call failed"),
+ },
+ {
+ name: "failure - tx does not exist",
+ txHash: common.HexToHash("0xc48fbf05edaf18f6aaa7de24de28528546b874bb03728d624ca407b8fed582a3"),
+ receipt: &types.Receipt{
+ Status: 0,
+ },
+ status: 0,
+ },
+ }
+
+ for _, tt := range tests {
+ client := new(evmClientMocks.Client)
+ client.On("CallContext", mock.Anything, mock.Anything, "eth_getTransactionReceipt", tt.txHash).
+ Return(tt.ethCallError).Run(func(args mock.Arguments) {
+ receipt := tt.receipt
+ if receipt != nil {
+ res := args.Get(1).(*types.Receipt)
+ res.Status = receipt.Status
+ res.TxHash = receipt.TxHash
+ res.BlockNumber = receipt.BlockNumber
+ res.BlockHash = receipt.BlockHash
+ }
+ })
+
+ bn, bh, err := GetTxBlock(testutils.Context(t), client, tt.txHash)
+ if tt.ethCallError != nil {
+ assert.Equal(t, tt.ethCallError, err)
+ } else {
+ assert.Equal(t, tt.status, tt.receipt.Status)
+ assert.Equal(t, tt.receipt.BlockNumber, bn)
+ assert.Equal(t, tt.receipt.BlockHash, bh)
+ }
+ }
+}
diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/encoding/encoder.go b/core/services/ocr2/plugins/ocr2keeper/evm21/encoding/encoder.go
index 62a359a7231..239de099c01 100644
--- a/core/services/ocr2/plugins/ocr2keeper/evm21/encoding/encoder.go
+++ b/core/services/ocr2/plugins/ocr2keeper/evm21/encoding/encoder.go
@@ -68,6 +68,7 @@ func (e reportEncoder) Encode(results ...ocr2keepers.CheckResult) ([]byte, error
case ocr2keepers.LogTrigger:
triggerW.TxHash = result.Trigger.LogTriggerExtension.TxHash
triggerW.LogIndex = result.Trigger.LogTriggerExtension.Index
+ triggerW.LogBlockHash = result.Trigger.LogTriggerExtension.BlockHash
default:
// no special handling here for conditional triggers
}
@@ -86,7 +87,7 @@ func (e reportEncoder) Encode(results ...ocr2keepers.CheckResult) ([]byte, error
return e.packer.PackReport(report)
}
-// Extract the plugin will call this function to accept/transmit reports
+// Extract extracts a slice of reported upkeeps (upkeep id, trigger, and work id) from raw bytes. the plugin will call this function to accept/transmit reports.
func (e reportEncoder) Extract(raw []byte) ([]ocr2keepers.ReportedUpkeep, error) {
report, err := e.packer.UnpackReport(raw)
if err != nil {
@@ -110,6 +111,7 @@ func (e reportEncoder) Extract(raw []byte) ([]ocr2keepers.ReportedUpkeep, error)
trigger.LogTriggerExtension = &ocr2keepers.LogTriggerExtension{}
trigger.LogTriggerExtension.TxHash = triggerW.TxHash
trigger.LogTriggerExtension.Index = triggerW.LogIndex
+ trigger.LogTriggerExtension.BlockHash = triggerW.LogBlockHash
default:
}
workID := core.UpkeepWorkID(*id, trigger)
diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/encoding/encoder_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/encoding/encoder_test.go
index a7fe7f536b1..36435a93bab 100644
--- a/core/services/ocr2/plugins/ocr2keeper/evm21/encoding/encoder_test.go
+++ b/core/services/ocr2/plugins/ocr2keeper/evm21/encoding/encoder_test.go
@@ -37,7 +37,7 @@ func TestReportEncoder_EncodeExtract(t *testing.T) {
[]ocr2keepers.CheckResult{
newResult(1, 1, core.GenUpkeepID(ocr2keepers.LogTrigger, "123"), 1, 1),
},
- 704,
+ 736,
1,
1,
nil,
@@ -49,7 +49,7 @@ func TestReportEncoder_EncodeExtract(t *testing.T) {
newResult(1, 1, core.GenUpkeepID(ocr2keepers.ConditionTrigger, "20"), 1, 1),
newResult(1, 1, core.GenUpkeepID(ocr2keepers.ConditionTrigger, "30"), 1, 1),
},
- 1280,
+ 1312,
3,
3,
nil,
@@ -61,7 +61,7 @@ func TestReportEncoder_EncodeExtract(t *testing.T) {
newResult(1, 1, core.GenUpkeepID(ocr2keepers.ConditionTrigger, "20"), 1, 1),
newResult(1, 1, core.GenUpkeepID(ocr2keepers.LogTrigger, "10"), 1, 1),
},
- 1280,
+ 1312,
1000,
2000,
nil,
@@ -110,8 +110,9 @@ func newResult(block int64, checkBlock ocr2keepers.BlockNumber, id ocr2keepers.U
if tp == ocr2keepers.LogTrigger {
trig.LogTriggerExtension = &ocr2keepers.LogTriggerExtension{
- Index: 1,
- TxHash: common.HexToHash("0x1234567890123456789012345678901234567890123456789012345678901234"),
+ Index: 1,
+ TxHash: common.HexToHash("0x1234567890123456789012345678901234567890123456789012345678901234"),
+ BlockHash: common.HexToHash("0xaaaaaaaa90123456789012345678901234567890123456789012345678901234"),
}
}
diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/encoding/interface.go b/core/services/ocr2/plugins/ocr2keeper/evm21/encoding/interface.go
index e896a144aa8..1f36cadb4d7 100644
--- a/core/services/ocr2/plugins/ocr2keeper/evm21/encoding/interface.go
+++ b/core/services/ocr2/plugins/ocr2keeper/evm21/encoding/interface.go
@@ -29,6 +29,8 @@ const (
UpkeepFailureReasonMercuryAccessNotAllowed UpkeepFailureReason = 32
UpkeepFailureReasonTxHashNoLongerExists UpkeepFailureReason = 33
UpkeepFailureReasonInvalidRevertDataInput UpkeepFailureReason = 34
+ UpkeepFailureReasonSimulationFailed UpkeepFailureReason = 35
+ UpkeepFailureReasonTxHashReorged UpkeepFailureReason = 36
// pipeline execution error
NoPipelineError PipelineExecutionState = 0
@@ -40,6 +42,7 @@ const (
MercuryUnmarshalError PipelineExecutionState = 6
InvalidMercuryRequest PipelineExecutionState = 7
InvalidMercuryResponse PipelineExecutionState = 8 // this will only happen if Mercury server sends bad responses
+ UpkeepNotAuthorized PipelineExecutionState = 9
)
type UpkeepInfo = iregistry21.KeeperRegistryBase21UpkeepInfo
@@ -48,8 +51,9 @@ type Packer interface {
UnpackCheckResult(payload ocr2keepers.UpkeepPayload, raw string) (ocr2keepers.CheckResult, error)
UnpackCheckCallbackResult(callbackResp []byte) (PipelineExecutionState, bool, []byte, uint8, *big.Int, error)
UnpackPerformResult(raw string) (PipelineExecutionState, bool, error)
- UnpackUpkeepInfo(id *big.Int, raw string) (UpkeepInfo, error)
UnpackLogTriggerConfig(raw []byte) (automation_utils_2_1.LogTriggerConfig, error)
PackReport(report automation_utils_2_1.KeeperRegistryBase21Report) ([]byte, error)
UnpackReport(raw []byte) (automation_utils_2_1.KeeperRegistryBase21Report, error)
+ PackGetUpkeepPrivilegeConfig(upkeepId *big.Int) ([]byte, error)
+ UnpackGetUpkeepPrivilegeConfig(resp []byte) ([]byte, error)
}
diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/encoding/packer.go b/core/services/ocr2/plugins/ocr2keeper/evm21/encoding/packer.go
index c710b31291f..824a98172bd 100644
--- a/core/services/ocr2/plugins/ocr2keeper/evm21/encoding/packer.go
+++ b/core/services/ocr2/plugins/ocr2keeper/evm21/encoding/packer.go
@@ -66,6 +66,21 @@ func (p *abiPacker) UnpackCheckResult(payload ocr2keepers.UpkeepPayload, raw str
return result, nil
}
+func (p *abiPacker) PackGetUpkeepPrivilegeConfig(upkeepId *big.Int) ([]byte, error) {
+ return p.abi.Pack("getUpkeepPrivilegeConfig", upkeepId)
+}
+
+func (p *abiPacker) UnpackGetUpkeepPrivilegeConfig(resp []byte) ([]byte, error) {
+ out, err := p.abi.Methods["getUpkeepPrivilegeConfig"].Outputs.UnpackValues(resp)
+ if err != nil {
+ return nil, fmt.Errorf("%w: unpack getUpkeepPrivilegeConfig return", err)
+ }
+
+ bts := *abi.ConvertType(out[0], new([]byte)).(*[]byte)
+
+ return bts, nil
+}
+
func (p *abiPacker) UnpackCheckCallbackResult(callbackResp []byte) (PipelineExecutionState, bool, []byte, uint8, *big.Int, error) {
out, err := p.abi.Methods["checkCallback"].Outputs.UnpackValues(callbackResp)
if err != nil {
@@ -94,22 +109,6 @@ func (p *abiPacker) UnpackPerformResult(raw string) (PipelineExecutionState, boo
return NoPipelineError, *abi.ConvertType(out[0], new(bool)).(*bool), nil
}
-func (p *abiPacker) UnpackUpkeepInfo(id *big.Int, raw string) (UpkeepInfo, error) {
- b, err := hexutil.Decode(raw)
- if err != nil {
- return UpkeepInfo{}, err
- }
-
- out, err := p.abi.Methods["getUpkeep"].Outputs.UnpackValues(b)
- if err != nil {
- return UpkeepInfo{}, fmt.Errorf("%w: unpack getUpkeep return: %s", err, raw)
- }
-
- info := *abi.ConvertType(out[0], new(UpkeepInfo)).(*UpkeepInfo)
-
- return info, nil
-}
-
// UnpackLogTriggerConfig unpacks the log trigger config from the given raw data
func (p *abiPacker) UnpackLogTriggerConfig(raw []byte) (automation_utils_2_1.LogTriggerConfig, error) {
var cfg automation_utils_2_1.LogTriggerConfig
diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/encoding/packer_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/encoding/packer_test.go
index ccc84765baa..b333a695bf8 100644
--- a/core/services/ocr2/plugins/ocr2keeper/evm21/encoding/packer_test.go
+++ b/core/services/ocr2/plugins/ocr2keeper/evm21/encoding/packer_test.go
@@ -1,6 +1,7 @@
package encoding
import (
+ "encoding/json"
"fmt"
"math/big"
"strings"
@@ -355,6 +356,97 @@ func TestPacker_PackReport_UnpackReport(t *testing.T) {
assert.Equal(t, hexutil.Encode(res), expected)
}
+func TestPacker_PackGetUpkeepPrivilegeConfig(t *testing.T) {
+ tests := []struct {
+ name string
+ upkeepId *big.Int
+ raw []byte
+ errored bool
+ }{
+ {
+ name: "happy path",
+ upkeepId: func() *big.Int {
+ id, _ := new(big.Int).SetString("52236098515066839510538748191966098678939830769967377496848891145101407612976", 10)
+
+ return id
+ }(),
+ raw: func() []byte {
+ b, _ := hexutil.Decode("0x19d97a94737c9583000000000000000000000001ea8ed6d0617dd5b3b87374020efaf030")
+
+ return b
+ }(),
+ errored: false,
+ },
+ }
+
+ for _, test := range tests {
+ t.Run(test.name, func(t *testing.T) {
+ packer, err := newPacker()
+ require.NoError(t, err, "valid packer required for test")
+
+ b, err := packer.PackGetUpkeepPrivilegeConfig(test.upkeepId)
+
+ if !test.errored {
+ require.NoError(t, err, "no error expected from packing")
+
+ assert.Equal(t, test.raw, b, "raw bytes for output should match expected")
+ } else {
+ assert.NotNil(t, err, "error expected from packing function")
+ }
+ })
+ }
+}
+
+func TestPacker_UnpackGetUpkeepPrivilegeConfig(t *testing.T) {
+ tests := []struct {
+ name string
+ raw []byte
+ errored bool
+ }{
+ {
+ name: "happy path",
+ raw: func() []byte {
+ b, _ := hexutil.Decode("0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000177b226d657263757279456e61626c6564223a747275657d000000000000000000")
+
+ return b
+ }(),
+ errored: false,
+ },
+ {
+ name: "error empty config",
+ raw: func() []byte {
+ b, _ := hexutil.Decode("0x")
+
+ return b
+ }(),
+ errored: true,
+ },
+ }
+
+ for _, test := range tests {
+ t.Run(test.name, func(t *testing.T) {
+ packer, err := newPacker()
+ require.NoError(t, err, "valid packer required for test")
+
+ b, err := packer.UnpackGetUpkeepPrivilegeConfig(test.raw)
+
+ if !test.errored {
+ require.NoError(t, err, "should unpack bytes from abi encoded value")
+
+ // the actual struct to unmarshal into is not available to this
+ // package so basic json encoding is the limit of the following test
+ var data map[string]interface{}
+ err = json.Unmarshal(b, &data)
+
+ assert.NoError(t, err, "packed data should unmarshal using json encoding")
+ assert.Equal(t, []byte(`{"mercuryEnabled":true}`), b)
+ } else {
+ assert.NotNil(t, err, "error expected from unpack function")
+ }
+ })
+ }
+}
+
func newPacker() (*abiPacker, error) {
keepersABI, err := abi.JSON(strings.NewReader(iregistry21.IKeeperRegistryMasterABI))
if err != nil {
diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/block_time.go b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/block_time.go
index 1d8500bcc61..9fc35dd84be 100644
--- a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/block_time.go
+++ b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/block_time.go
@@ -11,7 +11,7 @@ import (
)
var (
- defaultSampleSize = int64(10)
+ defaultSampleSize = int64(10000)
defaultBlockTime = time.Second * 1
)
@@ -34,39 +34,28 @@ func (r *blockTimeResolver) BlockTime(ctx context.Context, blockSampleSize int64
if err != nil {
return 0, fmt.Errorf("failed to get latest block from poller: %w", err)
}
- if latest < blockSampleSize {
+ if latest <= blockSampleSize {
return defaultBlockTime, nil
}
- blockTimes, err := r.getSampleTimestamps(ctx, blockSampleSize, latest)
+ start, end := latest-blockSampleSize, latest
+ startTime, endTime, err := r.getSampleTimestamps(ctx, uint64(start), uint64(end))
if err != nil {
return 0, err
}
- var sumDiff time.Duration
- for i := range blockTimes {
- if i != int(blockSampleSize-1) {
- sumDiff += blockTimes[i].Sub(blockTimes[i+1])
- }
- }
-
- return sumDiff / time.Duration(blockSampleSize-1), nil
+ return endTime.Sub(startTime) / time.Duration(blockSampleSize), nil
}
-func (r *blockTimeResolver) getSampleTimestamps(ctx context.Context, blockSampleSize, latest int64) ([]time.Time, error) {
- blockSample := make([]uint64, blockSampleSize)
- for i := range blockSample {
- blockSample[i] = uint64(latest - blockSampleSize + int64(i))
- }
- blocks, err := r.poller.GetBlocksRange(ctx, blockSample)
+func (r *blockTimeResolver) getSampleTimestamps(ctx context.Context, start, end uint64) (time.Time, time.Time, error) {
+ blocks, err := r.poller.GetBlocksRange(ctx, []uint64{start, end})
if err != nil {
- return nil, fmt.Errorf("failed to get block range from poller: %w", err)
+ return time.Time{}, time.Time{}, fmt.Errorf("failed to get block range from poller: %w", err)
}
sort.Slice(blocks, func(i, j int) bool {
- return blocks[i].BlockNumber > blocks[j].BlockNumber
+ return blocks[i].BlockNumber < blocks[j].BlockNumber
})
- blockTimes := make([]time.Time, blockSampleSize)
- for i, b := range blocks {
- blockTimes[i] = b.BlockTimestamp
+ if len(blocks) < 2 {
+ return time.Time{}, time.Time{}, fmt.Errorf("failed to fetch blocks %d, %d from log poller", start, end)
}
- return blockTimes, nil
+ return blocks[0].BlockTimestamp, blocks[1].BlockTimestamp, nil
}
diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/block_time_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/block_time_test.go
index 55437ff6721..0ad9990e185 100644
--- a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/block_time_test.go
+++ b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/block_time_test.go
@@ -52,10 +52,8 @@ func TestBlockTimeResolver_BlockTime(t *testing.T) {
20,
nil,
[]logpoller.LogPollerBlock{
- {BlockTimestamp: now.Add(-time.Second * (2 * 4)), BlockNumber: 1},
- {BlockTimestamp: now.Add(-time.Second * (2 * 3)), BlockNumber: 2},
- {BlockTimestamp: now.Add(-time.Second * (2 * 2)), BlockNumber: 3},
- {BlockTimestamp: now.Add(-time.Second * 2), BlockNumber: 4},
+ {BlockTimestamp: now.Add(-time.Second * (2 * 4)), BlockNumber: 16},
+ {BlockTimestamp: now, BlockNumber: 20},
},
nil,
2 * time.Second,
diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/buffer.go b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/buffer.go
index 1977795f6e8..b06a3ca809f 100644
--- a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/buffer.go
+++ b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/buffer.go
@@ -1,26 +1,45 @@
package logprovider
import (
+ "encoding/hex"
"math/big"
"sort"
"sync"
"sync/atomic"
+ "github.com/smartcontractkit/ocr2keepers/pkg/v3/random"
+ ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg/v3/types"
+
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller"
"github.com/smartcontractkit/chainlink/v2/core/logger"
)
var (
- // AllowedLogsPerBlock is the maximum number of logs allowed per upkeep in a block.
- AllowedLogsPerBlock = 128
- // BufferMaxBlockSize is the maximum number of blocks in the buffer.
- BufferMaxBlockSize = 1024
+ // maxLogsPerUpkeepInBlock is the maximum number of logs allowed per upkeep in a block.
+ maxLogsPerUpkeepInBlock = 32
+ // maxLogsPerBlock is the maximum number of blocks in the buffer.
+ maxLogsPerBlock = 1024
)
// fetchedLog holds the log and the ID of the upkeep
type fetchedLog struct {
upkeepID *big.Int
log logpoller.Log
+ // cachedLogID is the cached log identifier, used for sorting.
+ // It is calculated lazily, and cached for performance.
+ cachedLogID string
+}
+
+func (l *fetchedLog) getLogID() string {
+ if len(l.cachedLogID) == 0 {
+ ext := ocr2keepers.LogTriggerExtension{
+ Index: uint32(l.log.LogIndex),
+ }
+ copy(ext.TxHash[:], l.log.TxHash[:])
+ copy(ext.BlockHash[:], l.log.BlockHash[:])
+ l.cachedLogID = hex.EncodeToString(ext.LogIdentifier())
+ }
+ return l.cachedLogID
}
// fetchedBlock holds the logs fetched for a block
@@ -33,9 +52,46 @@ type fetchedBlock struct {
visited []fetchedLog
}
+func (b *fetchedBlock) Append(lggr logger.Logger, fl fetchedLog, maxBlockLogs, maxUpkeepLogs int) (fetchedLog, bool) {
+ has, upkeepLogs := b.has(fl.upkeepID, fl.log)
+ if has {
+ // Skipping known logs
+ return fetchedLog{}, false
+ }
+ // lggr.Debugw("Adding log", "i", i, "blockBlock", currentBlock.blockNumber, "logBlock", log.BlockNumber, "id", id)
+ b.logs = append(b.logs, fl)
+
+ // drop logs if we reached limits.
+ if upkeepLogs+1 > maxUpkeepLogs {
+ // in case we have logs overflow for a particular upkeep, we drop a log of that upkeep,
+ // based on shared, random (per block) order of the logs in the block.
+ b.Sort()
+ var dropped fetchedLog
+ currentLogs := make([]fetchedLog, 0, len(b.logs)-1)
+ for _, l := range b.logs {
+ if dropped.upkeepID == nil && l.upkeepID.Cmp(fl.upkeepID) == 0 {
+ dropped = l
+ continue
+ }
+ currentLogs = append(currentLogs, l)
+ }
+ b.logs = currentLogs
+ return dropped, true
+ } else if len(b.logs)+len(b.visited) > maxBlockLogs {
+ // in case we have logs overflow in the buffer level, we drop a log based on
+ // shared, random (per block) order of the logs in the block.
+ b.Sort()
+ dropped := b.logs[0]
+ b.logs = b.logs[1:]
+ return dropped, true
+ }
+
+ return fetchedLog{}, true
+}
+
// Has returns true if the block has the log,
// and the number of logs for that upkeep in the block.
-func (b fetchedBlock) Has(id *big.Int, log logpoller.Log) (bool, int) {
+func (b fetchedBlock) has(id *big.Int, log logpoller.Log) (bool, int) {
allLogs := append(b.logs, b.visited...)
upkeepLogs := 0
for _, l := range allLogs {
@@ -43,13 +99,41 @@ func (b fetchedBlock) Has(id *big.Int, log logpoller.Log) (bool, int) {
continue
}
upkeepLogs++
- if l.log.BlockNumber == log.BlockNumber && l.log.TxHash == log.TxHash && l.log.LogIndex == log.LogIndex {
+ if l.log.BlockHash == log.BlockHash && l.log.TxHash == log.TxHash && l.log.LogIndex == log.LogIndex {
return true, upkeepLogs
}
}
return false, upkeepLogs
}
+func (b fetchedBlock) Clone() fetchedBlock {
+ logs := make([]fetchedLog, len(b.logs))
+ copy(logs, b.logs)
+ visited := make([]fetchedLog, len(b.visited))
+ copy(visited, b.visited)
+ return fetchedBlock{
+ blockNumber: b.blockNumber,
+ logs: logs,
+ visited: visited,
+ }
+}
+
+// Sort by log identifiers, shuffled using a pseduorandom souce that is shared across all nodes
+// for a given block.
+func (b *fetchedBlock) Sort() {
+ randSeed := random.GetRandomKeySource(nil, uint64(b.blockNumber))
+
+ shuffledLogIDs := make(map[string]string, len(b.logs))
+ for _, log := range b.logs {
+ logID := log.getLogID()
+ shuffledLogIDs[logID] = random.ShuffleString(logID, randSeed)
+ }
+
+ sort.SliceStable(b.logs, func(i, j int) bool {
+ return shuffledLogIDs[b.logs[i].getLogID()] < shuffledLogIDs[b.logs[j].getLogID()]
+ })
+}
+
// logEventBuffer is a circular/ring buffer of fetched logs.
// Each entry in the buffer represents a block,
// and holds the logs fetched for that block.
@@ -85,6 +169,7 @@ func (b *logEventBuffer) bufferSize() int {
}
// enqueue adds logs (if not exist) to the buffer, returning the number of logs added
+// minus the number of logs dropped.
func (b *logEventBuffer) enqueue(id *big.Int, logs ...logpoller.Log) int {
b.lock.Lock()
defer b.lock.Unlock()
@@ -95,7 +180,8 @@ func (b *logEventBuffer) enqueue(id *big.Int, logs ...logpoller.Log) int {
maxUpkeepLogs := int(b.maxUpkeepLogsPerBlock)
latestBlock := b.latestBlockSeen()
- added := 0
+ added, dropped := 0, 0
+
for _, log := range logs {
if log.BlockNumber == 0 {
// invalid log
@@ -113,23 +199,20 @@ func (b *logEventBuffer) enqueue(id *big.Int, logs ...logpoller.Log) int {
lggr.Debugw("Skipping log from old block", "currentBlock", currentBlock.blockNumber, "newBlock", log.BlockNumber)
continue
}
- if len(currentBlock.logs)+1 > maxBlockLogs {
- lggr.Debugw("Reached max logs number per block, dropping log", "blockNumber", log.BlockNumber,
- "blockHash", log.BlockHash, "txHash", log.TxHash, "logIndex", log.LogIndex)
+ droppedLog, ok := currentBlock.Append(lggr, fetchedLog{upkeepID: id, log: log}, maxBlockLogs, maxUpkeepLogs)
+ if !ok {
+ // Skipping known logs
continue
}
- if has, upkeepLogs := currentBlock.Has(id, log); has {
- // Skipping existing log
- continue
- } else if upkeepLogs+1 > maxUpkeepLogs {
- lggr.Debugw("Reached max logs number per upkeep, dropping log", "blockNumber", log.BlockNumber,
- "blockHash", log.BlockHash, "txHash", log.TxHash, "logIndex", log.LogIndex)
- continue
+ if droppedLog.upkeepID != nil {
+ dropped++
+ lggr.Debugw("Reached log buffer limits, dropping log", "blockNumber", droppedLog.log.BlockNumber,
+ "blockHash", droppedLog.log.BlockHash, "txHash", droppedLog.log.TxHash, "logIndex", droppedLog.log.LogIndex,
+ "upkeepID", droppedLog.upkeepID.String())
}
- // lggr.Debugw("Adding log", "i", i, "blockBlock", currentBlock.blockNumber, "logBlock", log.BlockNumber, "id", id)
- currentBlock.logs = append(currentBlock.logs, fetchedLog{upkeepID: id, log: log})
- b.blocks[i] = currentBlock
added++
+ b.blocks[i] = currentBlock
+
if log.BlockNumber > latestBlock {
latestBlock = log.BlockNumber
}
@@ -139,10 +222,10 @@ func (b *logEventBuffer) enqueue(id *big.Int, logs ...logpoller.Log) int {
atomic.StoreInt64(&b.latestBlock, latestBlock)
}
if added > 0 {
- lggr.Debugw("Added logs to buffer", "addedLogs", added, "latestBlock", latestBlock)
+ lggr.Debugw("Added logs to buffer", "addedLogs", added, "dropped", dropped, "latestBlock", latestBlock)
}
- return added
+ return added - dropped
}
// peek returns the logs in range [latestBlock-blocks, latestBlock]
@@ -184,41 +267,61 @@ func (b *logEventBuffer) peekRange(start, end int64) []fetchedLog {
}
// dequeueRange returns the logs between start and end inclusive.
-func (b *logEventBuffer) dequeueRange(start, end int64, upkeepLimit int) []fetchedLog {
+func (b *logEventBuffer) dequeueRange(start, end int64, upkeepLimit, totalLimit int) []fetchedLog {
b.lock.Lock()
defer b.lock.Unlock()
blocksInRange := b.getBlocksInRange(int(start), int(end))
+ fetchedBlocks := make([]fetchedBlock, 0, len(blocksInRange))
+ for _, block := range blocksInRange {
+ // Create clone of the blocks as they get processed and update underlying b.blocks
+ fetchedBlocks = append(fetchedBlocks, block.Clone())
+ }
+
+ // Sort the blocks in reverse order of block number so that latest logs
+ // are preferred while dequeueing.
+ sort.SliceStable(fetchedBlocks, func(i, j int) bool {
+ return fetchedBlocks[i].blockNumber > fetchedBlocks[j].blockNumber
+ })
logsCount := map[string]int{}
+ totalCount := 0
var results []fetchedLog
- for _, block := range blocksInRange {
- // double checking that we don't have any gaps in the range
+ for _, block := range fetchedBlocks {
if block.blockNumber < start || block.blockNumber > end {
+ // double checking that we don't have any gaps in the range
continue
}
+ if totalCount >= totalLimit {
+ // reached total limit, no need to process more blocks
+ break
+ }
+ // Sort the logs in random order that is shared across all nodes.
+ // This ensures that nodes across the network will process the same logs.
+ block.Sort()
var remainingLogs, blockResults []fetchedLog
for _, log := range block.logs {
+ if totalCount >= totalLimit {
+ remainingLogs = append(remainingLogs, log)
+ continue
+ }
if logsCount[log.upkeepID.String()] >= upkeepLimit {
remainingLogs = append(remainingLogs, log)
continue
}
- logsCount[log.upkeepID.String()]++
blockResults = append(blockResults, log)
+ logsCount[log.upkeepID.String()]++
+ totalCount++
}
if len(blockResults) == 0 {
continue
}
- block.visited = append(block.visited, blockResults...)
results = append(results, blockResults...)
+ block.visited = append(block.visited, blockResults...)
block.logs = remainingLogs
b.blocks[b.blockNumberIndex(block.blockNumber)] = block
}
- sort.SliceStable(results, func(i, j int) bool {
- return results[i].log.BlockNumber < results[j].log.BlockNumber
- })
-
if len(results) > 0 {
b.lggr.Debugw("Dequeued logs", "results", len(results), "start", start, "end", end)
}
diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/buffer_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/buffer_test.go
index de68dd31e22..5c8908f9be7 100644
--- a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/buffer_test.go
+++ b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/buffer_test.go
@@ -1,15 +1,18 @@
package logprovider
import (
+ "encoding/hex"
"fmt"
"math/big"
"testing"
"github.com/ethereum/go-ethereum/common"
+ ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg/v3/types"
"github.com/stretchr/testify/require"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller"
"github.com/smartcontractkit/chainlink/v2/core/logger"
+ "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21/core"
)
func TestLogEventBuffer_GetBlocksInRange(t *testing.T) {
@@ -236,7 +239,7 @@ func TestLogEventBuffer_EnqueueDequeue(t *testing.T) {
results := buf.peekRange(int64(1), int64(2))
require.Equal(t, 2, len(results))
verifyBlockNumbers(t, results, 1, 2)
- removed := buf.dequeueRange(int64(1), int64(2), 2)
+ removed := buf.dequeueRange(int64(1), int64(2), 2, 10)
require.Equal(t, 2, len(removed))
results = buf.peekRange(int64(1), int64(2))
require.Equal(t, 0, len(results))
@@ -256,7 +259,7 @@ func TestLogEventBuffer_EnqueueDequeue(t *testing.T) {
results := buf.peek(8)
require.Equal(t, 4, len(results))
verifyBlockNumbers(t, results, 1, 2, 3, 3)
- removed := buf.dequeueRange(1, 3, 5)
+ removed := buf.dequeueRange(1, 3, 5, 5)
require.Equal(t, 4, len(removed))
buf.lock.Lock()
require.Equal(t, 0, len(buf.blocks[0].logs))
@@ -303,7 +306,7 @@ func TestLogEventBuffer_EnqueueDequeue(t *testing.T) {
verifyBlockNumbers(t, results, 2, 3, 4, 4)
})
- t.Run("dequeue with limits", func(t *testing.T) {
+ t.Run("dequeue with limits returns latest block logs", func(t *testing.T) {
buf := newLogEventBuffer(logger.TestLogger(t), 3, 5, 10)
require.Equal(t, buf.enqueue(big.NewInt(1),
logpoller.Log{BlockNumber: 1, TxHash: common.HexToHash("0x1"), LogIndex: 0},
@@ -313,9 +316,20 @@ func TestLogEventBuffer_EnqueueDequeue(t *testing.T) {
logpoller.Log{BlockNumber: 5, TxHash: common.HexToHash("0x5"), LogIndex: 0},
), 5)
- logs := buf.dequeueRange(1, 5, 2)
+ logs := buf.dequeueRange(1, 5, 2, 10)
+ require.Equal(t, 2, len(logs))
+ require.Equal(t, int64(5), logs[0].log.BlockNumber)
+ require.Equal(t, int64(4), logs[1].log.BlockNumber)
+
+ require.Equal(t, buf.enqueue(big.NewInt(1),
+ logpoller.Log{BlockNumber: 4, TxHash: common.HexToHash("0x4"), LogIndex: 1},
+ logpoller.Log{BlockNumber: 5, TxHash: common.HexToHash("0x5"), LogIndex: 1},
+ ), 2)
+
+ logs = buf.dequeueRange(1, 5, 3, 2)
require.Equal(t, 2, len(logs))
})
+
t.Run("dequeue doesn't return same logs again", func(t *testing.T) {
buf := newLogEventBuffer(logger.TestLogger(t), 3, 5, 10)
require.Equal(t, buf.enqueue(big.NewInt(1),
@@ -324,19 +338,508 @@ func TestLogEventBuffer_EnqueueDequeue(t *testing.T) {
logpoller.Log{BlockNumber: 3, TxHash: common.HexToHash("0x3"), LogIndex: 0},
), 3)
- logs := buf.dequeueRange(3, 3, 2)
+ logs := buf.dequeueRange(3, 3, 2, 10)
fmt.Println(logs)
require.Equal(t, 1, len(logs))
- logs = buf.dequeueRange(3, 3, 2)
+ logs = buf.dequeueRange(3, 3, 2, 10)
fmt.Println(logs)
require.Equal(t, 0, len(logs))
})
}
+func TestLogEventBuffer_FetchedBlock_Append(t *testing.T) {
+ type appendArgs struct {
+ fl fetchedLog
+ maxBlockLogs, maxUpkeepLogs int
+ added, dropped bool
+ }
+
+ tests := []struct {
+ name string
+ blockNumber int64
+ logs []fetchedLog
+ visited []fetchedLog
+ toAdd []appendArgs
+ expected []fetchedLog
+ added bool
+ }{
+ {
+ name: "empty block",
+ blockNumber: 1,
+ logs: []fetchedLog{},
+ visited: []fetchedLog{},
+ toAdd: []appendArgs{
+ {
+ fl: fetchedLog{
+ log: logpoller.Log{
+ BlockNumber: 1,
+ TxHash: common.HexToHash("0x1"),
+ LogIndex: 0,
+ },
+ upkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "111").BigInt(),
+ },
+ maxBlockLogs: 10,
+ maxUpkeepLogs: 2,
+ added: true,
+ },
+ },
+ expected: []fetchedLog{
+ {
+ log: logpoller.Log{
+ BlockNumber: 1,
+ TxHash: common.HexToHash("0x1"),
+ LogIndex: 0,
+ },
+ upkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "111").BigInt(),
+ },
+ },
+ },
+ {
+ name: "existing log",
+ blockNumber: 1,
+ logs: []fetchedLog{
+ {
+ log: logpoller.Log{
+ BlockNumber: 1,
+ TxHash: common.HexToHash("0x1"),
+ LogIndex: 0,
+ },
+ upkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "111").BigInt(),
+ },
+ },
+ visited: []fetchedLog{},
+ toAdd: []appendArgs{
+ {
+ fl: fetchedLog{
+ log: logpoller.Log{
+ BlockNumber: 1,
+ TxHash: common.HexToHash("0x1"),
+ LogIndex: 0,
+ },
+ upkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "111").BigInt(),
+ },
+ maxBlockLogs: 10,
+ maxUpkeepLogs: 2,
+ added: false,
+ },
+ },
+ expected: []fetchedLog{
+ {
+ log: logpoller.Log{
+ BlockNumber: 1,
+ TxHash: common.HexToHash("0x1"),
+ LogIndex: 0,
+ },
+ upkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "111").BigInt(),
+ },
+ },
+ },
+ {
+ name: "visited log",
+ blockNumber: 1,
+ logs: []fetchedLog{},
+ visited: []fetchedLog{
+ {
+ log: logpoller.Log{
+ BlockNumber: 1,
+ TxHash: common.HexToHash("0x1"),
+ LogIndex: 0,
+ },
+ upkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "111").BigInt(),
+ },
+ },
+ toAdd: []appendArgs{
+ {
+ fl: fetchedLog{
+ log: logpoller.Log{
+ BlockNumber: 1,
+ TxHash: common.HexToHash("0x1"),
+ LogIndex: 0,
+ },
+ upkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "111").BigInt(),
+ },
+ maxBlockLogs: 10,
+ maxUpkeepLogs: 2,
+ added: false,
+ },
+ },
+ expected: []fetchedLog{},
+ },
+ {
+ name: "upkeep log limits",
+ blockNumber: 1,
+ logs: []fetchedLog{},
+ visited: []fetchedLog{},
+ toAdd: []appendArgs{
+ {
+ fl: fetchedLog{
+ log: logpoller.Log{
+ BlockNumber: 1,
+ TxHash: common.HexToHash("0x1"),
+ LogIndex: 0,
+ },
+ upkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "111").BigInt(),
+ },
+ maxBlockLogs: 10,
+ maxUpkeepLogs: 2,
+ added: true,
+ },
+ {
+ fl: fetchedLog{
+ log: logpoller.Log{
+ BlockNumber: 1,
+ TxHash: common.HexToHash("0x1"),
+ LogIndex: 1,
+ },
+ upkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "111").BigInt(),
+ },
+ maxBlockLogs: 10,
+ maxUpkeepLogs: 2,
+ added: true,
+ },
+ {
+ fl: fetchedLog{
+ log: logpoller.Log{
+ BlockNumber: 1,
+ TxHash: common.HexToHash("0x1"),
+ LogIndex: 2,
+ },
+ upkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "111").BigInt(),
+ },
+ maxBlockLogs: 10,
+ maxUpkeepLogs: 2,
+ added: true,
+ dropped: true,
+ },
+ },
+ expected: []fetchedLog{
+ {
+ log: logpoller.Log{
+ BlockNumber: 1,
+ TxHash: common.HexToHash("0x1"),
+ LogIndex: 1,
+ },
+ upkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "111").BigInt(),
+ },
+ {
+ log: logpoller.Log{
+ BlockNumber: 1,
+ TxHash: common.HexToHash("0x1"),
+ LogIndex: 2,
+ },
+ upkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "111").BigInt(),
+ },
+ },
+ },
+ {
+ name: "block log limits",
+ blockNumber: 1,
+ logs: []fetchedLog{},
+ visited: []fetchedLog{},
+ toAdd: []appendArgs{
+ {
+ fl: fetchedLog{
+ log: logpoller.Log{
+ BlockNumber: 1,
+ TxHash: common.HexToHash("0x1"),
+ LogIndex: 0,
+ },
+ upkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "111").BigInt(),
+ },
+ maxBlockLogs: 2,
+ maxUpkeepLogs: 4,
+ added: true,
+ },
+ {
+ fl: fetchedLog{
+ log: logpoller.Log{
+ BlockNumber: 1,
+ TxHash: common.HexToHash("0x1"),
+ LogIndex: 1,
+ },
+ upkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "111").BigInt(),
+ },
+ maxBlockLogs: 2,
+ maxUpkeepLogs: 4,
+ added: true,
+ },
+ {
+ fl: fetchedLog{
+ log: logpoller.Log{
+ BlockNumber: 1,
+ TxHash: common.HexToHash("0x1"),
+ LogIndex: 2,
+ },
+ upkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "111").BigInt(),
+ },
+ maxBlockLogs: 2,
+ maxUpkeepLogs: 4,
+ added: true,
+ dropped: true,
+ },
+ },
+ expected: []fetchedLog{
+ {
+ log: logpoller.Log{
+ BlockNumber: 1,
+ TxHash: common.HexToHash("0x1"),
+ LogIndex: 1,
+ },
+ upkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "111").BigInt(),
+ },
+ {
+ log: logpoller.Log{
+ BlockNumber: 1,
+ TxHash: common.HexToHash("0x1"),
+ LogIndex: 2,
+ },
+ upkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "111").BigInt(),
+ },
+ },
+ },
+ }
+
+ for _, tc := range tests {
+ t.Run(tc.name, func(t *testing.T) {
+ lggr := logger.TestLogger(t)
+ b := fetchedBlock{
+ blockNumber: tc.blockNumber,
+ logs: make([]fetchedLog, len(tc.logs)),
+ visited: make([]fetchedLog, len(tc.visited)),
+ }
+ copy(b.logs, tc.logs)
+ copy(b.visited, tc.visited)
+
+ for _, args := range tc.toAdd {
+ dropped, added := b.Append(lggr, args.fl, args.maxBlockLogs, args.maxUpkeepLogs)
+ require.Equal(t, args.added, added)
+ if args.dropped {
+ require.NotNil(t, dropped.upkeepID)
+ } else {
+ require.Nil(t, dropped.upkeepID)
+ }
+ }
+ // clear cached logIDs
+ for i := range b.logs {
+ b.logs[i].cachedLogID = ""
+ }
+ require.Equal(t, tc.expected, b.logs)
+ })
+ }
+}
+func TestLogEventBuffer_FetchedBlock_Sort(t *testing.T) {
+ tests := []struct {
+ name string
+ blockNumber int64
+ logs []fetchedLog
+ beforeSort []string
+ afterSort []string
+ iterations int
+ }{
+ {
+ name: "no logs",
+ blockNumber: 10,
+ logs: []fetchedLog{},
+ beforeSort: []string{},
+ afterSort: []string{},
+ },
+ {
+ name: "single log",
+ blockNumber: 1,
+ logs: []fetchedLog{
+ {
+ log: logpoller.Log{
+ BlockHash: common.HexToHash("0x111"),
+ BlockNumber: 1,
+ TxHash: common.HexToHash("0x1"),
+ LogIndex: 0,
+ },
+ },
+ },
+ beforeSort: []string{
+ "0000000000000000000000000000000000000000000000000000000000000111000000000000000000000000000000000000000000000000000000000000000100000000",
+ },
+ afterSort: []string{
+ "0000000000000000000000000000000000000000000000000000000000000111000000000000000000000000000000000000000000000000000000000000000100000000",
+ },
+ },
+ {
+ name: "multiple logs with 10 iterations",
+ blockNumber: 1,
+ logs: []fetchedLog{
+ {
+ log: logpoller.Log{
+ BlockNumber: 1,
+ BlockHash: common.HexToHash("0xa25ebae1099f3fbae2525ebae279f3ae25e"),
+ TxHash: common.HexToHash("0xb711bd1103927611ee41152aa8ae27f3330"),
+ LogIndex: 0,
+ },
+ upkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "111").BigInt(),
+ },
+ {
+ log: logpoller.Log{
+ BlockNumber: 1,
+ BlockHash: common.HexToHash("0xa25ebae1099f3fbae2525ebae279f3ae25e"),
+ TxHash: common.HexToHash("0xa651bd1109922111ee411525ebae27f3fb6"),
+ LogIndex: 0,
+ },
+ upkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "222").BigInt(),
+ },
+ {
+ log: logpoller.Log{
+ BlockNumber: 1,
+ BlockHash: common.HexToHash("0xa25ebae1099f3fbae2525ebae279f3ae25e"),
+ TxHash: common.HexToHash("0xa651bd1109922111ee411525ebae27f3fb6"),
+ LogIndex: 4,
+ },
+ upkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "111").BigInt(),
+ },
+ {
+ log: logpoller.Log{
+ BlockNumber: 1,
+ BlockHash: common.HexToHash("0xa25ebae1099f3fbae2525ebae279f3ae25e"),
+ TxHash: common.HexToHash("0xa651bd1109922111ee411525ebae27f3fb6"),
+ LogIndex: 3,
+ },
+ upkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "222").BigInt(),
+ },
+ {
+ log: logpoller.Log{
+ BlockNumber: 1,
+ BlockHash: common.HexToHash("0xa25ebae1099f3fbae2525ebae279f3ae25e"),
+ TxHash: common.HexToHash("0xa651bd1109922111ee411525ebae27f3fb6"),
+ LogIndex: 2,
+ },
+ upkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "111").BigInt(),
+ },
+ {
+ log: logpoller.Log{
+ BlockNumber: 1,
+ BlockHash: common.HexToHash("0xa25ebae1099f3fbae2525ebae279f3ae25e"),
+ TxHash: common.HexToHash("0xa651bd1109922111ee411525ebae27f3fb6"),
+ LogIndex: 5,
+ },
+ upkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "111").BigInt(),
+ },
+ {
+ log: logpoller.Log{
+ BlockNumber: 1,
+ BlockHash: common.HexToHash("0xa25ebae1099f3fbae2525ebae279f3ae25e"),
+ TxHash: common.HexToHash("0xa651bd1109922111ee411525ebae27f3fb6"),
+ LogIndex: 3,
+ },
+ upkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "111").BigInt(),
+ },
+ {
+ log: logpoller.Log{
+ BlockNumber: 1,
+ BlockHash: common.HexToHash("0xa25ebae1099f3fbae2525ebae279f3ae25e"),
+ TxHash: common.HexToHash("0xa651bd1109922111ee411525ebae27f3fb6"),
+ LogIndex: 1,
+ },
+ upkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "111").BigInt(),
+ },
+ },
+ beforeSort: []string{
+ "00000000000000000000000000000a25ebae1099f3fbae2525ebae279f3ae25e00000000000000000000000000000b711bd1103927611ee41152aa8ae27f333000000000",
+ "00000000000000000000000000000a25ebae1099f3fbae2525ebae279f3ae25e00000000000000000000000000000a651bd1109922111ee411525ebae27f3fb600000000",
+ "00000000000000000000000000000a25ebae1099f3fbae2525ebae279f3ae25e00000000000000000000000000000a651bd1109922111ee411525ebae27f3fb600000004",
+ "00000000000000000000000000000a25ebae1099f3fbae2525ebae279f3ae25e00000000000000000000000000000a651bd1109922111ee411525ebae27f3fb600000003",
+ "00000000000000000000000000000a25ebae1099f3fbae2525ebae279f3ae25e00000000000000000000000000000a651bd1109922111ee411525ebae27f3fb600000002",
+ "00000000000000000000000000000a25ebae1099f3fbae2525ebae279f3ae25e00000000000000000000000000000a651bd1109922111ee411525ebae27f3fb600000005",
+ "00000000000000000000000000000a25ebae1099f3fbae2525ebae279f3ae25e00000000000000000000000000000a651bd1109922111ee411525ebae27f3fb600000003",
+ "00000000000000000000000000000a25ebae1099f3fbae2525ebae279f3ae25e00000000000000000000000000000a651bd1109922111ee411525ebae27f3fb600000001",
+ },
+ afterSort: []string{
+ "00000000000000000000000000000a25ebae1099f3fbae2525ebae279f3ae25e00000000000000000000000000000b711bd1103927611ee41152aa8ae27f333000000000",
+ "00000000000000000000000000000a25ebae1099f3fbae2525ebae279f3ae25e00000000000000000000000000000a651bd1109922111ee411525ebae27f3fb600000000",
+ "00000000000000000000000000000a25ebae1099f3fbae2525ebae279f3ae25e00000000000000000000000000000a651bd1109922111ee411525ebae27f3fb600000001",
+ "00000000000000000000000000000a25ebae1099f3fbae2525ebae279f3ae25e00000000000000000000000000000a651bd1109922111ee411525ebae27f3fb600000002",
+ "00000000000000000000000000000a25ebae1099f3fbae2525ebae279f3ae25e00000000000000000000000000000a651bd1109922111ee411525ebae27f3fb600000003",
+ "00000000000000000000000000000a25ebae1099f3fbae2525ebae279f3ae25e00000000000000000000000000000a651bd1109922111ee411525ebae27f3fb600000003",
+ "00000000000000000000000000000a25ebae1099f3fbae2525ebae279f3ae25e00000000000000000000000000000a651bd1109922111ee411525ebae27f3fb600000004",
+ "00000000000000000000000000000a25ebae1099f3fbae2525ebae279f3ae25e00000000000000000000000000000a651bd1109922111ee411525ebae27f3fb600000005",
+ },
+ iterations: 10,
+ },
+ }
+
+ for _, tc := range tests {
+ t.Run(tc.name, func(t *testing.T) {
+ b := fetchedBlock{
+ blockNumber: tc.blockNumber,
+ logs: make([]fetchedLog, len(tc.logs)),
+ }
+ if tc.iterations == 0 {
+ tc.iterations = 1
+ }
+ // performing the same multiple times should yield the same result
+ // default is one iteration
+ for i := 0; i < tc.iterations; i++ {
+ copy(b.logs, tc.logs)
+ logIDs := getLogIds(b)
+ require.Equal(t, len(tc.beforeSort), len(logIDs))
+ require.Equal(t, tc.beforeSort, logIDs)
+ b.Sort()
+ logIDsAfterSort := getLogIds(b)
+ require.Equal(t, len(tc.afterSort), len(logIDsAfterSort))
+ require.Equal(t, tc.afterSort, logIDsAfterSort)
+ }
+ })
+ }
+}
+
+func TestLogEventBuffer_FetchedBlock_Clone(t *testing.T) {
+ b1 := fetchedBlock{
+ blockNumber: 1,
+ logs: []fetchedLog{
+ {
+ log: logpoller.Log{
+ BlockNumber: 1,
+ TxHash: common.HexToHash("0x1"),
+ LogIndex: 0,
+ },
+ upkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "111").BigInt(),
+ },
+ {
+ log: logpoller.Log{
+ BlockNumber: 1,
+ TxHash: common.HexToHash("0x1"),
+ LogIndex: 2,
+ },
+ upkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "111").BigInt(),
+ },
+ },
+ }
+
+ b2 := b1.Clone()
+ require.Equal(t, b1.blockNumber, b2.blockNumber)
+ require.Equal(t, len(b1.logs), len(b2.logs))
+ require.Equal(t, b1.logs[0].log.BlockNumber, b2.logs[0].log.BlockNumber)
+
+ b1.blockNumber = 2
+ b1.logs[0].log.BlockNumber = 2
+ require.NotEqual(t, b1.blockNumber, b2.blockNumber)
+ require.NotEqual(t, b1.logs[0].log.BlockNumber, b2.logs[0].log.BlockNumber)
+}
+
func verifyBlockNumbers(t *testing.T, logs []fetchedLog, bns ...int64) {
require.Equal(t, len(bns), len(logs), "expected length mismatch")
for i, log := range logs {
require.Equal(t, bns[i], log.log.BlockNumber, "wrong block number")
}
}
+
+func getLogIds(b fetchedBlock) []string {
+ logIDs := make([]string, len(b.logs))
+ for i, l := range b.logs {
+ ext := ocr2keepers.LogTriggerExtension{
+ TxHash: l.log.TxHash,
+ Index: uint32(l.log.LogIndex),
+ BlockHash: l.log.BlockHash,
+ }
+ logIDs[i] = hex.EncodeToString(ext.LogIdentifier())
+ }
+ return logIDs
+}
diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/factory.go b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/factory.go
index cbbb8db54dc..4b3fa8cb404 100644
--- a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/factory.go
+++ b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/factory.go
@@ -1,7 +1,10 @@
package logprovider
import (
+ "time"
+
"github.com/ethereum/go-ethereum/accounts/abi"
+ "golang.org/x/time/rate"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/client"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller"
@@ -9,11 +12,60 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21/core"
)
-func New(lggr logger.Logger, poller logpoller.LogPoller, c client.Client, utilsABI abi.ABI, stateStore core.UpkeepStateReader) (LogEventProvider, LogRecoverer) {
+// New creates a new log event provider and recoverer.
+// using default values for the options.
+func New(lggr logger.Logger, poller logpoller.LogPoller, c client.Client, utilsABI abi.ABI, stateStore core.UpkeepStateReader, finalityDepth uint32) (LogEventProvider, LogRecoverer) {
filterStore := NewUpkeepFilterStore()
packer := NewLogEventsPacker(utilsABI)
- provider := NewLogProvider(lggr, poller, packer, filterStore, nil)
- recoverer := NewLogRecoverer(lggr, poller, c, stateStore, packer, filterStore, 0, provider.opts.LookbackBlocks)
+ opts := NewOptions(int64(finalityDepth))
+ provider := NewLogProvider(lggr, poller, packer, filterStore, opts)
+ recoverer := NewLogRecoverer(lggr, poller, c, stateStore, packer, filterStore, opts)
return provider, recoverer
}
+
+// LogTriggersOptions holds the options for the log trigger components.
+type LogTriggersOptions struct {
+ // LookbackBlocks is the number of blocks the provider will look back for logs.
+ // The recoverer will scan for logs up to this depth.
+ // NOTE: MUST be set to a greater-or-equal to the chain's finality depth.
+ LookbackBlocks int64
+ // ReadInterval is the interval to fetch logs in the background.
+ ReadInterval time.Duration
+ // BlockRateLimit is the rate limit on the range of blocks the we fetch logs for.
+ BlockRateLimit rate.Limit
+ // blockLimitBurst is the burst upper limit on the range of blocks the we fetch logs for.
+ BlockLimitBurst int
+ // Finality depth is the number of blocks to wait before considering a block final.
+ FinalityDepth int64
+}
+
+func NewOptions(finalityDepth int64) LogTriggersOptions {
+ opts := new(LogTriggersOptions)
+ opts.Defaults(finalityDepth)
+ return *opts
+}
+
+// Defaults sets the default values for the options.
+// NOTE: o.LookbackBlocks should be set only from within tests
+func (o *LogTriggersOptions) Defaults(finalityDepth int64) {
+ if o.LookbackBlocks == 0 {
+ lookbackBlocks := int64(200)
+ if lookbackBlocks < finalityDepth {
+ lookbackBlocks = finalityDepth
+ }
+ o.LookbackBlocks = lookbackBlocks
+ }
+ if o.ReadInterval == 0 {
+ o.ReadInterval = time.Second
+ }
+ if o.BlockLimitBurst == 0 {
+ o.BlockLimitBurst = int(o.LookbackBlocks)
+ }
+ if o.BlockRateLimit == 0 {
+ o.BlockRateLimit = rate.Every(o.ReadInterval)
+ }
+ if o.FinalityDepth == 0 {
+ o.FinalityDepth = finalityDepth
+ }
+}
diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/filter.go b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/filter.go
new file mode 100644
index 00000000000..44780cbc4b1
--- /dev/null
+++ b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/filter.go
@@ -0,0 +1,86 @@
+package logprovider
+
+import (
+ "bytes"
+ "math/big"
+
+ "github.com/ethereum/go-ethereum/common"
+ "golang.org/x/time/rate"
+
+ "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller"
+)
+
+type upkeepFilter struct {
+ addr []byte
+ // selector is the filter selector in log trigger config
+ selector uint8
+ topics []common.Hash
+ upkeepID *big.Int
+ // configUpdateBlock is the block number the filter was last updated at
+ configUpdateBlock uint64
+ // lastPollBlock is the last block number the logs were fetched for this upkeep
+ // used by log event provider.
+ lastPollBlock int64
+ // blockLimiter is used to limit the number of blocks to fetch logs for an upkeep.
+ // used by log event provider.
+ blockLimiter *rate.Limiter
+ // lastRePollBlock is the last block number the logs were recovered for this upkeep
+ // used by log recoverer.
+ lastRePollBlock int64
+}
+
+func (f upkeepFilter) Clone() upkeepFilter {
+ topics := make([]common.Hash, len(f.topics))
+ copy(topics, f.topics)
+ addr := make([]byte, len(f.addr))
+ copy(addr, f.addr)
+ return upkeepFilter{
+ upkeepID: f.upkeepID,
+ selector: f.selector,
+ topics: topics,
+ addr: addr,
+ configUpdateBlock: f.configUpdateBlock,
+ lastPollBlock: f.lastPollBlock,
+ lastRePollBlock: f.lastRePollBlock,
+ blockLimiter: f.blockLimiter,
+ }
+}
+
+// Select returns a slice of logs which match the upkeep filter.
+func (f upkeepFilter) Select(logs ...logpoller.Log) []logpoller.Log {
+ var selected []logpoller.Log
+ for _, log := range logs {
+ if f.match(log) {
+ selected = append(selected, log)
+ }
+ }
+ return selected
+}
+
+// match returns a bool indicating if the log's topics data matches selector and indexed topics in upkeep filter.
+func (f upkeepFilter) match(log logpoller.Log) bool {
+ filters := f.topics[1:]
+ selector := f.selector
+
+ if selector == 0 {
+ // no filters
+ return true
+ }
+
+ for i, filter := range filters {
+ // bitwise AND the selector with the index to check
+ // if the filter is needed
+ mask := uint8(1 << uint8(i))
+ if selector&mask == uint8(0) {
+ continue
+ }
+ if len(log.Topics) <= i+1 {
+ // log doesn't have enough topics
+ return false
+ }
+ if !bytes.Equal(filter.Bytes(), log.Topics[i+1]) {
+ return false
+ }
+ }
+ return true
+}
diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/filter_store.go b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/filter_store.go
index 38b1e4e26f3..07173ac7073 100644
--- a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/filter_store.go
+++ b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/filter_store.go
@@ -3,9 +3,6 @@ package logprovider
import (
"math/big"
"sync"
-
- "github.com/ethereum/go-ethereum/common"
- "golang.org/x/time/rate"
)
type UpkeepFilterStore interface {
@@ -22,39 +19,6 @@ type UpkeepFilterStore interface {
var _ UpkeepFilterStore = &upkeepFilterStore{}
-type upkeepFilter struct {
- addr []byte
- topics []common.Hash
- upkeepID *big.Int
- // configUpdateBlock is the block number the filter was last updated at
- configUpdateBlock uint64
- // lastPollBlock is the last block number the logs were fetched for this upkeep
- // used by log event provider.
- lastPollBlock int64
- // blockLimiter is used to limit the number of blocks to fetch logs for an upkeep.
- // used by log event provider.
- blockLimiter *rate.Limiter
- // lastRePollBlock is the last block number the logs were recovered for this upkeep
- // used by log recoverer.
- lastRePollBlock int64
-}
-
-func (f upkeepFilter) Clone() upkeepFilter {
- topics := make([]common.Hash, len(f.topics))
- copy(topics, f.topics)
- addr := make([]byte, len(f.addr))
- copy(addr, f.addr)
- return upkeepFilter{
- upkeepID: f.upkeepID,
- topics: topics,
- addr: addr,
- configUpdateBlock: f.configUpdateBlock,
- lastPollBlock: f.lastPollBlock,
- lastRePollBlock: f.lastRePollBlock,
- blockLimiter: f.blockLimiter,
- }
-}
-
type upkeepFilterStore struct {
lock *sync.RWMutex
// filters is a map of upkeepID to upkeepFilter
diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/filter_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/filter_test.go
new file mode 100644
index 00000000000..8b3b836f87f
--- /dev/null
+++ b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/filter_test.go
@@ -0,0 +1,196 @@
+package logprovider
+
+import (
+ "math/big"
+ "testing"
+
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/common/hexutil"
+ "github.com/stretchr/testify/assert"
+
+ "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller"
+)
+
+func TestUpkeepFilter_Select(t *testing.T) {
+ var zeroBytes [32]byte
+ emptyTopic := common.BytesToHash(zeroBytes[:])
+ contractAddress := common.HexToAddress("0xB9F3af0c2CbfE108efd0E23F7b0a151Ea42f764E")
+ uid := big.NewInt(123456)
+ topic10 := "0x000000000000000000000000000000000000000000000000000000000000007b" // decimal 123 encoded
+ topic20 := "0x0000000000000000000000000000000000000000000000000000000000000001" // bool true encoded
+ topic30 := "0x00000000000000000000000082b8b466f4be252e56af8a00aa28838866686062" // address encoded
+ topic11 := "0x000000000000000000000000000000000000000000000000000000000000007a" // decimal 122 encoded
+ topic21 := "0x0000000000000000000000000000000000000000000000000000000000000000" // bool false encoded
+ topic31 := "0x000000000000000000000000f91a27d2f37a36f1e6acc681b07b1dd2e288aebc" // address encoded
+
+ log1 := logpoller.Log{
+ Topics: [][]byte{
+ contractAddress.Bytes(),
+ hexutil.MustDecode(topic10),
+ hexutil.MustDecode(topic20),
+ hexutil.MustDecode(topic30),
+ },
+ }
+ log2 := logpoller.Log{
+ Topics: [][]byte{
+ contractAddress.Bytes(),
+ hexutil.MustDecode(topic11),
+ hexutil.MustDecode(topic21),
+ hexutil.MustDecode(topic31),
+ },
+ }
+ log3 := logpoller.Log{
+ Topics: [][]byte{
+ contractAddress.Bytes(),
+ hexutil.MustDecode(topic11),
+ hexutil.MustDecode(topic20),
+ hexutil.MustDecode(topic31),
+ },
+ }
+ log4 := logpoller.Log{
+ Topics: [][]byte{
+ contractAddress.Bytes(),
+ hexutil.MustDecode(topic10),
+ hexutil.MustDecode(topic21),
+ hexutil.MustDecode(topic31),
+ },
+ }
+ log5 := logpoller.Log{
+ Topics: [][]byte{
+ contractAddress.Bytes(),
+ hexutil.MustDecode(topic10),
+ hexutil.MustDecode(topic20),
+ hexutil.MustDecode(topic30),
+ },
+ }
+
+ tests := []struct {
+ name string
+ filter upkeepFilter
+ logs []logpoller.Log
+ expectedLogs []logpoller.Log
+ }{
+ {
+ "no selector configured - all logs are returned",
+ upkeepFilter{
+ selector: 0,
+ topics: []common.Hash{contractAddress.Hash(), emptyTopic, emptyTopic, emptyTopic},
+ upkeepID: uid,
+ },
+ []logpoller.Log{
+ log1,
+ log2,
+ },
+ []logpoller.Log{
+ log1,
+ log2,
+ },
+ },
+ {
+ "selector is 1 - topics 1 is used to filter logs",
+ upkeepFilter{
+ selector: 1,
+ topics: []common.Hash{contractAddress.Hash(), common.HexToHash(topic10), emptyTopic, emptyTopic},
+ upkeepID: uid,
+ },
+ []logpoller.Log{
+ log1,
+ log2,
+ },
+ []logpoller.Log{
+ log1,
+ },
+ },
+ {
+ "selector is 2 - topic 2 is used to filter logs",
+ upkeepFilter{
+ selector: 2,
+ topics: []common.Hash{contractAddress.Hash(), emptyTopic, common.HexToHash(topic21), emptyTopic},
+ upkeepID: uid,
+ },
+ []logpoller.Log{
+ log1,
+ log2,
+ },
+ []logpoller.Log{
+ log2,
+ },
+ },
+ {
+ "selector is 3 - topics 1 2 are used to filter logs",
+ upkeepFilter{
+ selector: 3,
+ topics: []common.Hash{contractAddress.Hash(), common.HexToHash(topic10), common.HexToHash(topic21), emptyTopic},
+ upkeepID: uid,
+ },
+ []logpoller.Log{
+ log1,
+ log2,
+ log3,
+ log4,
+ },
+ []logpoller.Log{
+ log4,
+ },
+ },
+ {
+ "selector is 4 - topic 3 is used to filter logs",
+ upkeepFilter{
+ selector: 4,
+ topics: []common.Hash{contractAddress.Hash(), emptyTopic, emptyTopic, common.HexToHash(topic31)},
+ upkeepID: uid,
+ },
+ []logpoller.Log{
+ log1,
+ log2,
+ },
+ []logpoller.Log{
+ log2,
+ },
+ },
+ {
+ "selector is 5 - topics 1 3 are used to filter logs",
+ upkeepFilter{
+ selector: 5,
+ topics: []common.Hash{contractAddress.Hash(), common.HexToHash(topic11), emptyTopic, common.HexToHash(topic31)},
+ upkeepID: uid,
+ },
+ []logpoller.Log{
+ log1,
+ log2,
+ log3,
+ log4,
+ },
+ []logpoller.Log{
+ log2,
+ log3,
+ },
+ },
+ {
+ "selector is 7 - topics 1 2 3 are used to filter logs",
+ upkeepFilter{
+ selector: 7,
+ topics: []common.Hash{contractAddress.Hash(), common.HexToHash(topic10), common.HexToHash(topic20), common.HexToHash(topic30)},
+ upkeepID: uid,
+ },
+ []logpoller.Log{
+ log1,
+ log2,
+ log3,
+ log4,
+ log5,
+ },
+ []logpoller.Log{
+ log1,
+ log5,
+ },
+ },
+ }
+
+ for _, tc := range tests {
+ t.Run(tc.name, func(t *testing.T) {
+ filteredLogs := tc.filter.Select(tc.logs...)
+ assert.Equal(t, tc.expectedLogs, filteredLogs)
+ })
+ }
+}
diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/integration_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/integration_test.go
index 08d56c78c59..b5f229f6015 100644
--- a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/integration_test.go
+++ b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/integration_test.go
@@ -52,17 +52,19 @@ func TestIntegration_LogEventProvider(t *testing.T) {
db := setupDB(t)
defer db.Close()
- opts := &logprovider.LogEventProviderOptions{
- ReadInterval: time.Second / 2,
- }
+ opts := logprovider.NewOptions(200)
+ opts.ReadInterval = time.Second / 2
lp, ethClient, utilsABI := setupDependencies(t, db, backend)
filterStore := logprovider.NewUpkeepFilterStore()
- provider, _ := setup(logger.TestLogger(t), lp, nil, utilsABI, nil, filterStore, opts)
+ provider, _ := setup(logger.TestLogger(t), lp, nil, utilsABI, nil, filterStore, &opts)
logProvider := provider.(logprovider.LogEventProviderTest)
n := 10
- ids, addrs, contracts := deployUpkeepCounter(t, n, ethClient, backend, carrol, logProvider)
+ backend.Commit()
+ lp.PollAndSaveLogs(ctx, 1) // Ensure log poller has a latest block
+
+ ids, addrs, contracts := deployUpkeepCounter(ctx, t, n, ethClient, backend, carrol, logProvider)
lp.PollAndSaveLogs(ctx, int64(n))
go func() {
@@ -109,7 +111,7 @@ func TestIntegration_LogEventProvider(t *testing.T) {
// re-register filters
for i, id := range ids {
- err = logProvider2.RegisterFilter(logprovider.FilterOptions{
+ err = logProvider2.RegisterFilter(ctx, logprovider.FilterOptions{
UpkeepID: id,
TriggerConfig: newPlainLogTriggerConfig(addrs[i]),
// using block number at which the upkeep was registered,
@@ -139,7 +141,7 @@ func TestIntegration_LogEventProvider_UpdateConfig(t *testing.T) {
db := setupDB(t)
defer db.Close()
- opts := &logprovider.LogEventProviderOptions{
+ opts := &logprovider.LogTriggersOptions{
ReadInterval: time.Second / 2,
}
lp, ethClient, utilsABI := setupDependencies(t, db, backend)
@@ -147,7 +149,9 @@ func TestIntegration_LogEventProvider_UpdateConfig(t *testing.T) {
provider, _ := setup(logger.TestLogger(t), lp, nil, utilsABI, nil, filterStore, opts)
logProvider := provider.(logprovider.LogEventProviderTest)
- _, addrs, contracts := deployUpkeepCounter(t, 1, ethClient, backend, carrol, logProvider)
+ backend.Commit()
+ lp.PollAndSaveLogs(ctx, 1) // Ensure log poller has a latest block
+ _, addrs, contracts := deployUpkeepCounter(ctx, t, 1, ethClient, backend, carrol, logProvider)
lp.PollAndSaveLogs(ctx, int64(5))
require.Equal(t, 1, len(contracts))
require.Equal(t, 1, len(addrs))
@@ -159,14 +163,14 @@ func TestIntegration_LogEventProvider_UpdateConfig(t *testing.T) {
b, err := ethClient.BlockByHash(ctx, backend.Commit())
require.NoError(t, err)
bn := b.Number()
- err = logProvider.RegisterFilter(logprovider.FilterOptions{
+ err = logProvider.RegisterFilter(ctx, logprovider.FilterOptions{
UpkeepID: id,
TriggerConfig: cfg,
UpdateBlock: bn.Uint64(),
})
require.NoError(t, err)
// old block
- err = logProvider.RegisterFilter(logprovider.FilterOptions{
+ err = logProvider.RegisterFilter(ctx, logprovider.FilterOptions{
UpkeepID: id,
TriggerConfig: cfg,
UpdateBlock: bn.Uint64() - 1,
@@ -176,7 +180,7 @@ func TestIntegration_LogEventProvider_UpdateConfig(t *testing.T) {
b, err = ethClient.BlockByHash(ctx, backend.Commit())
require.NoError(t, err)
bn = b.Number()
- err = logProvider.RegisterFilter(logprovider.FilterOptions{
+ err = logProvider.RegisterFilter(ctx, logprovider.FilterOptions{
UpkeepID: id,
TriggerConfig: cfg,
UpdateBlock: bn.Uint64(),
@@ -191,7 +195,7 @@ func TestIntegration_LogEventProvider_UpdateConfig(t *testing.T) {
b, err := ethClient.BlockByHash(ctx, backend.Commit())
require.NoError(t, err)
bn := b.Number()
- err = logProvider.RegisterFilter(logprovider.FilterOptions{
+ err = logProvider.RegisterFilter(ctx, logprovider.FilterOptions{
UpkeepID: id,
TriggerConfig: cfg,
UpdateBlock: bn.Uint64(),
@@ -211,17 +215,18 @@ func TestIntegration_LogEventProvider_Backfill(t *testing.T) {
db := setupDB(t)
defer db.Close()
- opts := &logprovider.LogEventProviderOptions{
- ReadInterval: time.Second / 4,
- }
+ opts := logprovider.NewOptions(200)
+ opts.ReadInterval = time.Second / 4
lp, ethClient, utilsABI := setupDependencies(t, db, backend)
filterStore := logprovider.NewUpkeepFilterStore()
- provider, _ := setup(logger.TestLogger(t), lp, nil, utilsABI, nil, filterStore, opts)
+ provider, _ := setup(logger.TestLogger(t), lp, nil, utilsABI, nil, filterStore, &opts)
logProvider := provider.(logprovider.LogEventProviderTest)
n := 10
- _, _, contracts := deployUpkeepCounter(t, n, ethClient, backend, carrol, logProvider)
+ backend.Commit()
+ lp.PollAndSaveLogs(ctx, 1) // Ensure log poller has a latest block
+ _, _, contracts := deployUpkeepCounter(ctx, t, n, ethClient, backend, carrol, logProvider)
poll := pollFn(ctx, t, lp, ethClient)
@@ -252,7 +257,7 @@ func TestIntegration_LogEventProvider_Backfill(t *testing.T) {
func TestIntegration_LogEventProvider_RateLimit(t *testing.T) {
setupTest := func(
t *testing.T,
- opts *logprovider.LogEventProviderOptions,
+ opts *logprovider.LogTriggersOptions,
) (
context.Context,
*backends.SimulatedBackend,
@@ -275,6 +280,8 @@ func TestIntegration_LogEventProvider_RateLimit(t *testing.T) {
filterStore := logprovider.NewUpkeepFilterStore()
provider, _ := setup(logger.TestLogger(t), lp, nil, utilsABI, nil, filterStore, opts)
logProvider := provider.(logprovider.LogEventProviderTest)
+ backend.Commit()
+ lp.PollAndSaveLogs(ctx, 1) // Ensure log poller has a latest block
rounds := 5
numberOfUserContracts := 10
@@ -282,6 +289,7 @@ func TestIntegration_LogEventProvider_RateLimit(t *testing.T) {
// deployUpkeepCounter creates 'n' blocks and 'n' contracts
ids, _, contracts := deployUpkeepCounter(
+ ctx,
t,
numberOfUserContracts,
ethClient,
@@ -325,7 +333,8 @@ func TestIntegration_LogEventProvider_RateLimit(t *testing.T) {
// polling for logs at approximately the same rate as a chain produces
// blocks should not encounter rate limits
t.Run("should allow constant polls within the rate and burst limit", func(t *testing.T) {
- ctx, backend, poll, logProvider, ids, deferFunc := setupTest(t, &logprovider.LogEventProviderOptions{
+ ctx, backend, poll, logProvider, ids, deferFunc := setupTest(t, &logprovider.LogTriggersOptions{
+ LookbackBlocks: 200,
// BlockRateLimit is set low to ensure the test does not exceed the
// rate limit
BlockRateLimit: rate.Every(50 * time.Millisecond),
@@ -361,7 +370,8 @@ func TestIntegration_LogEventProvider_RateLimit(t *testing.T) {
})
t.Run("should produce a rate limit error for over burst limit", func(t *testing.T) {
- ctx, backend, poll, logProvider, ids, deferFunc := setupTest(t, &logprovider.LogEventProviderOptions{
+ ctx, backend, poll, logProvider, ids, deferFunc := setupTest(t, &logprovider.LogTriggersOptions{
+ LookbackBlocks: 200,
// BlockRateLimit is set low to ensure the test does not exceed the
// rate limit
BlockRateLimit: rate.Every(50 * time.Millisecond),
@@ -399,7 +409,7 @@ func TestIntegration_LogEventProvider_RateLimit(t *testing.T) {
})
t.Run("should allow polling after lookback number of blocks have passed", func(t *testing.T) {
- ctx, backend, poll, logProvider, ids, deferFunc := setupTest(t, &logprovider.LogEventProviderOptions{
+ ctx, backend, poll, logProvider, ids, deferFunc := setupTest(t, &logprovider.LogTriggersOptions{
// BlockRateLimit is set low to ensure the test does not exceed the
// rate limit
BlockRateLimit: rate.Every(50 * time.Millisecond),
@@ -462,23 +472,25 @@ func TestIntegration_LogRecoverer_Backfill(t *testing.T) {
defer db.Close()
lookbackBlocks := int64(200)
- opts := &logprovider.LogEventProviderOptions{
+ opts := &logprovider.LogTriggersOptions{
ReadInterval: time.Second / 4,
LookbackBlocks: lookbackBlocks,
}
lp, ethClient, utilsABI := setupDependencies(t, db, backend)
filterStore := logprovider.NewUpkeepFilterStore()
- origDefaultRecoveryInterval := logprovider.DefaultRecoveryInterval
- logprovider.DefaultRecoveryInterval = time.Millisecond * 200
+ origDefaultRecoveryInterval := logprovider.RecoveryInterval
+ logprovider.RecoveryInterval = time.Millisecond * 200
defer func() {
- logprovider.DefaultRecoveryInterval = origDefaultRecoveryInterval
+ logprovider.RecoveryInterval = origDefaultRecoveryInterval
}()
provider, recoverer := setup(logger.TestLogger(t), lp, nil, utilsABI, &mockUpkeepStateStore{}, filterStore, opts)
logProvider := provider.(logprovider.LogEventProviderTest)
- n := 10
+ backend.Commit()
+ lp.PollAndSaveLogs(ctx, 1) // Ensure log poller has a latest block
- _, _, contracts := deployUpkeepCounter(t, n, ethClient, backend, carrol, logProvider)
+ n := 10
+ _, _, contracts := deployUpkeepCounter(ctx, t, n, ethClient, backend, carrol, logProvider)
poll := pollFn(ctx, t, lp, ethClient)
@@ -603,6 +615,7 @@ func triggerEvents(
}
func deployUpkeepCounter(
+ ctx context.Context,
t *testing.T,
n int,
ethClient *evmclient.SimulatedBackendClient,
@@ -631,7 +644,7 @@ func deployUpkeepCounter(
b, err := ethClient.BlockByHash(context.Background(), backend.Commit())
require.NoError(t, err)
bn := b.Number()
- err = logProvider.RegisterFilter(logprovider.FilterOptions{
+ err = logProvider.RegisterFilter(ctx, logprovider.FilterOptions{
UpkeepID: id,
TriggerConfig: newPlainLogTriggerConfig(upkeepAddr),
UpdateBlock: bn.Uint64(),
@@ -662,14 +675,14 @@ func setupDependencies(t *testing.T, db *sqlx.DB, backend *backends.SimulatedBac
return lp, ethClient, utilsABI
}
-func setup(lggr logger.Logger, poller logpoller.LogPoller, c client.Client, utilsABI abi.ABI, stateStore kevmcore.UpkeepStateReader, filterStore logprovider.UpkeepFilterStore, opts *logprovider.LogEventProviderOptions) (logprovider.LogEventProvider, logprovider.LogRecoverer) {
+func setup(lggr logger.Logger, poller logpoller.LogPoller, c client.Client, utilsABI abi.ABI, stateStore kevmcore.UpkeepStateReader, filterStore logprovider.UpkeepFilterStore, opts *logprovider.LogTriggersOptions) (logprovider.LogEventProvider, logprovider.LogRecoverer) {
packer := logprovider.NewLogEventsPacker(utilsABI)
if opts == nil {
- opts = new(logprovider.LogEventProviderOptions)
- opts.Defaults()
+ o := logprovider.NewOptions(200)
+ opts = &o
}
- provider := logprovider.NewLogProvider(lggr, poller, packer, filterStore, opts)
- recoverer := logprovider.NewLogRecoverer(lggr, poller, c, stateStore, packer, filterStore, 0, opts.LookbackBlocks)
+ provider := logprovider.NewLogProvider(lggr, poller, packer, filterStore, *opts)
+ recoverer := logprovider.NewLogRecoverer(lggr, poller, c, stateStore, packer, filterStore, *opts)
return provider, recoverer
}
@@ -706,7 +719,7 @@ func setupDB(t *testing.T) *sqlx.DB {
type mockUpkeepStateStore struct {
}
-func (m *mockUpkeepStateStore) SelectByWorkIDsInRange(ctx context.Context, start, end int64, workIDs ...string) ([]ocr2keepers.UpkeepState, error) {
+func (m *mockUpkeepStateStore) SelectByWorkIDs(ctx context.Context, workIDs ...string) ([]ocr2keepers.UpkeepState, error) {
states := make([]ocr2keepers.UpkeepState, len(workIDs))
for i := range workIDs {
states[i] = ocr2keepers.UnknownState
diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/log_packer.go b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/log_packer.go
index c4e8d7e0da2..538839b011c 100644
--- a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/log_packer.go
+++ b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/log_packer.go
@@ -22,13 +22,13 @@ func NewLogEventsPacker(utilsABI abi.ABI) *logEventsPacker {
}
func (p *logEventsPacker) PackLogData(log logpoller.Log) ([]byte, error) {
- topics := [][32]byte{}
+ var topics [][32]byte
for _, topic := range log.GetTopics() {
topics = append(topics, topic)
}
b, err := p.abi.Pack("_log", &automation_utils_2_1.Log{
Index: big.NewInt(log.LogIndex),
- TxIndex: big.NewInt(0), // TODO: Add this to the logpoller
+ Timestamp: big.NewInt(log.BlockTimestamp.Unix()),
TxHash: log.TxHash,
BlockNumber: big.NewInt(log.BlockNumber),
BlockHash: log.BlockHash,
diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider.go b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider.go
index 377315a69eb..b62fb370847 100644
--- a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider.go
+++ b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider.go
@@ -22,17 +22,27 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/logger"
"github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21/core"
"github.com/smartcontractkit/chainlink/v2/core/services/pg"
+ "github.com/smartcontractkit/chainlink/v2/core/utils"
)
var (
+ LogProviderServiceName = "LogEventProvider"
+
ErrHeadNotAvailable = fmt.Errorf("head not available")
ErrBlockLimitExceeded = fmt.Errorf("block limit exceeded")
// AllowedLogsPerUpkeep is the maximum number of logs allowed per upkeep every single call.
AllowedLogsPerUpkeep = 5
+ // MaxPayloads is the maximum number of payloads to return per call.
+ MaxPayloads = 100
readJobQueueSize = 64
readLogsTimeout = 10 * time.Second
+
+ readMaxBatchSize = 32
+ // reorgBuffer is the number of blocks to add as a buffer to the block range when reading logs.
+ reorgBuffer = int64(32)
+ readerThreads = 4
)
// LogTriggerConfig is an alias for log trigger config.
@@ -46,7 +56,7 @@ type FilterOptions struct {
type LogTriggersLifeCycle interface {
// RegisterFilter registers the filter (if valid) for the given upkeepID.
- RegisterFilter(opts FilterOptions) error
+ RegisterFilter(ctx context.Context, opts FilterOptions) error
// UnregisterFilter removes the filter for the given upkeepID.
UnregisterFilter(upkeepID *big.Int) error
}
@@ -71,9 +81,10 @@ var _ LogEventProviderTest = &logEventProvider{}
// logEventProvider manages log filters for upkeeps and enables to read the log events.
type logEventProvider struct {
- lggr logger.Logger
+ utils.StartStopOnce
+ threadCtrl utils.ThreadControl
- cancel context.CancelFunc
+ lggr logger.Logger
poller logpoller.LogPoller
@@ -85,20 +96,17 @@ type logEventProvider struct {
filterStore UpkeepFilterStore
buffer *logEventBuffer
- opts *LogEventProviderOptions
+ opts LogTriggersOptions
currentPartitionIdx uint64
}
-func NewLogProvider(lggr logger.Logger, poller logpoller.LogPoller, packer LogDataPacker, filterStore UpkeepFilterStore, opts *LogEventProviderOptions) *logEventProvider {
- if opts == nil {
- opts = new(LogEventProviderOptions)
- }
- opts.Defaults()
+func NewLogProvider(lggr logger.Logger, poller logpoller.LogPoller, packer LogDataPacker, filterStore UpkeepFilterStore, opts LogTriggersOptions) *logEventProvider {
return &logEventProvider{
- packer: packer,
+ threadCtrl: utils.NewThreadControl(),
lggr: lggr.Named("KeepersRegistry.LogEventProvider"),
- buffer: newLogEventBuffer(lggr, int(opts.LookbackBlocks), BufferMaxBlockSize, AllowedLogsPerBlock),
+ packer: packer,
+ buffer: newLogEventBuffer(lggr, int(opts.LookbackBlocks), maxLogsPerBlock, maxLogsPerUpkeepInBlock),
poller: poller,
opts: opts,
filterStore: filterStore,
@@ -106,33 +114,22 @@ func NewLogProvider(lggr logger.Logger, poller logpoller.LogPoller, packer LogDa
}
func (p *logEventProvider) Start(context.Context) error {
- ctx, cancel := context.WithCancel(context.Background())
+ return p.StartOnce(LogProviderServiceName, func() error {
- p.lock.Lock()
- if p.cancel != nil {
- p.lock.Unlock()
- cancel() // Cancel the created context
- return errors.New("already started")
- }
- p.cancel = cancel
- p.lock.Unlock()
+ readQ := make(chan []*big.Int, readJobQueueSize)
- readQ := make(chan []*big.Int, readJobQueueSize)
+ p.lggr.Infow("starting log event provider", "readInterval", p.opts.ReadInterval, "readMaxBatchSize", readMaxBatchSize, "readers", readerThreads)
- p.lggr.Infow("starting log event provider", "readInterval", p.opts.ReadInterval, "readMaxBatchSize", p.opts.ReadBatchSize, "readers", p.opts.Readers)
+ for i := 0; i < readerThreads; i++ {
+ p.threadCtrl.Go(func(ctx context.Context) {
+ p.startReader(ctx, readQ)
+ })
+ }
- { // start readers
- go func(ctx context.Context) {
- for i := 0; i < p.opts.Readers; i++ {
- go p.startReader(ctx, readQ)
- }
- }(ctx)
- }
+ p.threadCtrl.Go(func(ctx context.Context) {
+ lggr := p.lggr.With("where", "scheduler")
- { // start scheduler
- lggr := p.lggr.With("where", "scheduler")
- go func(ctx context.Context) {
- err := p.scheduleReadJobs(ctx, func(ids []*big.Int) {
+ p.scheduleReadJobs(ctx, func(ids []*big.Int) {
select {
case readQ <- ids:
case <-ctx.Done():
@@ -140,31 +137,21 @@ func (p *logEventProvider) Start(context.Context) error {
lggr.Warnw("readQ is full, dropping ids", "ids", ids)
}
})
- if err != nil {
- lggr.Warnw("stopped scheduling read jobs with error", "err", err)
- }
- lggr.Debug("stopped scheduling read jobs")
- }(ctx)
- }
+ })
- return nil
+ return nil
+ })
}
func (p *logEventProvider) Close() error {
- p.lock.Lock()
- defer p.lock.Unlock()
-
- if cancel := p.cancel; cancel != nil {
- p.cancel = nil
- cancel()
- } else {
- return errors.New("already stopped")
- }
- return nil
+ return p.StopOnce(LogProviderServiceName, func() error {
+ p.threadCtrl.Close()
+ return nil
+ })
}
-func (p *logEventProvider) Name() string {
- return p.lggr.Name()
+func (p *logEventProvider) HealthReport() map[string]error {
+ return map[string]error{LogProviderServiceName: p.Healthy()}
}
func (p *logEventProvider) GetLatestPayloads(ctx context.Context) ([]ocr2keepers.UpkeepPayload, error) {
@@ -176,7 +163,7 @@ func (p *logEventProvider) GetLatestPayloads(ctx context.Context) ([]ocr2keepers
if start <= 0 {
start = 1
}
- logs := p.buffer.dequeueRange(start, latest, AllowedLogsPerUpkeep)
+ logs := p.buffer.dequeueRange(start, latest, AllowedLogsPerUpkeep, MaxPayloads)
// p.lggr.Debugw("got latest logs from buffer", "latest", latest, "diff", diff, "logs", len(logs))
@@ -230,7 +217,7 @@ func (p *logEventProvider) CurrentPartitionIdx() uint64 {
}
// scheduleReadJobs starts a scheduler that pushed ids to readQ for reading logs in the background.
-func (p *logEventProvider) scheduleReadJobs(pctx context.Context, execute func([]*big.Int)) error {
+func (p *logEventProvider) scheduleReadJobs(pctx context.Context, execute func([]*big.Int)) {
ctx, cancel := context.WithCancel(pctx)
defer cancel()
@@ -246,7 +233,7 @@ func (p *logEventProvider) scheduleReadJobs(pctx context.Context, execute func([
case <-ticker.C:
ids := p.getPartitionIds(h, int(partitionIdx))
if len(ids) > 0 {
- maxBatchSize := p.opts.ReadBatchSize
+ maxBatchSize := readMaxBatchSize
for len(ids) > maxBatchSize {
batch := ids[:maxBatchSize]
execute(batch)
@@ -258,7 +245,7 @@ func (p *logEventProvider) scheduleReadJobs(pctx context.Context, execute func([
partitionIdx++
atomic.StoreUint64(&p.currentPartitionIdx, partitionIdx)
case <-ctx.Done():
- return ctx.Err()
+ return
}
}
}
@@ -288,7 +275,7 @@ func (p *logEventProvider) startReader(pctx context.Context, readQ <-chan []*big
// getPartitionIds returns the upkeepIDs for the given partition and the number of partitions.
// Partitioning is done by hashing the upkeepID and taking the modulus of the number of partitions.
func (p *logEventProvider) getPartitionIds(hashFn hash.Hash, partition int) []*big.Int {
- numOfPartitions := p.filterStore.Size() / p.opts.ReadBatchSize
+ numOfPartitions := p.filterStore.Size() / readMaxBatchSize
if numOfPartitions < 1 {
numOfPartitions = 1
}
@@ -317,6 +304,10 @@ func (p *logEventProvider) updateFiltersLastPoll(entries []upkeepFilter) {
p.filterStore.UpdateFilters(func(orig, f upkeepFilter) upkeepFilter {
if f.lastPollBlock > orig.lastPollBlock {
orig.lastPollBlock = f.lastPollBlock
+ if f.lastPollBlock%10 == 0 {
+ // print log occasionally to avoid spamming logs
+ p.lggr.Debugw("Updated lastPollBlock", "lastPollBlock", f.lastPollBlock, "upkeepID", f.upkeepID)
+ }
}
return orig
}, entries...)
@@ -361,7 +352,7 @@ func (p *logEventProvider) readLogs(ctx context.Context, latest int64, filters [
// maxBurst will be used to increase the burst limit to allow a long range scan
maxBurst := int(lookbackBlocks + 1)
- for _, filter := range filters {
+ for i, filter := range filters {
if len(filter.addr) == 0 {
continue
}
@@ -378,12 +369,13 @@ func (p *logEventProvider) readLogs(ctx context.Context, latest int64, filters [
continue
}
// adding a buffer to check for reorged logs.
- start = start - p.opts.ReorgBuffer
+ start = start - reorgBuffer
// make sure start of the range is not before the config update block
if configUpdateBlock := int64(filter.configUpdateBlock); start < configUpdateBlock {
start = configUpdateBlock
}
- logs, err := p.poller.LogsWithSigs(start, latest, filter.topics, common.BytesToAddress(filter.addr), pg.WithParentCtx(ctx))
+ // query logs based on contract address, event sig, and blocks
+ logs, err := p.poller.LogsWithSigs(start, latest, []common.Hash{filter.topics[0]}, common.BytesToAddress(filter.addr), pg.WithParentCtx(ctx))
if err != nil {
// cancel limit reservation as we failed to get logs
resv.Cancel()
@@ -394,6 +386,8 @@ func (p *logEventProvider) readLogs(ctx context.Context, latest int64, filters [
merr = errors.Join(merr, fmt.Errorf("failed to get logs for upkeep %s: %w", filter.upkeepID.String(), err))
continue
}
+ filteredLogs := filter.Select(logs...)
+
// if this limiter's burst was set to the max ->
// reset it and cancel the reservation to allow further processing
if filter.blockLimiter.Burst() == maxBurst {
@@ -401,9 +395,11 @@ func (p *logEventProvider) readLogs(ctx context.Context, latest int64, filters [
filter.blockLimiter.SetBurst(p.opts.BlockLimitBurst)
}
- p.buffer.enqueue(filter.upkeepID, logs...)
+ p.buffer.enqueue(filter.upkeepID, filteredLogs...)
- filter.lastPollBlock = latest
+ // Update the lastPollBlock for filter in slice this is then
+ // updated into filter store in updateFiltersLastPoll
+ filters[i].lastPollBlock = latest
}
return merr
diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider_life_cycle.go b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider_life_cycle.go
index 4ddc93e376b..ab816adb1b3 100644
--- a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider_life_cycle.go
+++ b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider_life_cycle.go
@@ -2,6 +2,7 @@ package logprovider
import (
"bytes"
+ "context"
"errors"
"fmt"
"math/big"
@@ -11,14 +12,18 @@ import (
"golang.org/x/time/rate"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller"
+ "github.com/smartcontractkit/chainlink/v2/core/services/pg"
)
var (
// LogRetention is the amount of time to retain logs for.
LogRetention = 24 * time.Hour
+ // LogBackfillBuffer is the number of blocks from the latest block for which backfill is done when adding a filter in log poller
+ LogBackfillBuffer = 100
)
func (p *logEventProvider) RefreshActiveUpkeeps(ids ...*big.Int) ([]*big.Int, error) {
+ // Exploratory: investigate how we can batch the refresh
if len(ids) == 0 {
return nil, nil
}
@@ -53,7 +58,7 @@ func (p *logEventProvider) RefreshActiveUpkeeps(ids ...*big.Int) ([]*big.Int, er
return newIDs, merr
}
-func (p *logEventProvider) RegisterFilter(opts FilterOptions) error {
+func (p *logEventProvider) RegisterFilter(ctx context.Context, opts FilterOptions) error {
upkeepID, cfg := opts.UpkeepID, opts.TriggerConfig
if err := p.validateLogTriggerConfig(cfg); err != nil {
return fmt.Errorf("invalid log trigger config: %w", err)
@@ -77,11 +82,6 @@ func (p *logEventProvider) RegisterFilter(opts FilterOptions) error {
p.lggr.Debugf("filter for upkeep with id %s already registered with the same config", upkeepID.String())
return nil
}
- // removing filter so we can recreate it with updated values
- err := p.poller.UnregisterFilter(p.filterName(currentFilter.upkeepID))
- if err != nil {
- return fmt.Errorf("failed to unregister upkeep filter %s for update: %w", upkeepID.String(), err)
- }
filter = *currentFilter
} else { // new filter
filter = upkeepFilter{
@@ -92,11 +92,11 @@ func (p *logEventProvider) RegisterFilter(opts FilterOptions) error {
filter.lastPollBlock = 0
filter.lastRePollBlock = 0
filter.configUpdateBlock = opts.UpdateBlock
- filter.addr = lpFilter.Addresses[0].Bytes()
- filter.topics = make([]common.Hash, len(lpFilter.EventSigs))
- copy(filter.topics, lpFilter.EventSigs)
+ filter.selector = cfg.FilterSelector
+ filter.addr = cfg.ContractAddress.Bytes()
+ filter.topics = []common.Hash{cfg.Topic0, cfg.Topic1, cfg.Topic2, cfg.Topic3}
- if err := p.register(lpFilter, filter); err != nil {
+ if err := p.register(ctx, lpFilter, filter); err != nil {
return fmt.Errorf("failed to register upkeep filter %s: %w", filter.upkeepID.String(), err)
}
@@ -104,22 +104,52 @@ func (p *logEventProvider) RegisterFilter(opts FilterOptions) error {
}
// register registers the upkeep filter with the log poller and adds it to the filter store.
-func (p *logEventProvider) register(lpFilter logpoller.Filter, ufilter upkeepFilter) error {
+func (p *logEventProvider) register(ctx context.Context, lpFilter logpoller.Filter, ufilter upkeepFilter) error {
+ latest, err := p.poller.LatestBlock(pg.WithParentCtx(ctx))
+ if err != nil {
+ return fmt.Errorf("failed to get latest block while registering filter: %w", err)
+ }
+ lggr := p.lggr.With("upkeepID", ufilter.upkeepID.String())
+ logPollerHasFilter := p.poller.HasFilter(lpFilter.Name)
+ filterStoreHasFilter := p.filterStore.Has(ufilter.upkeepID)
+ if filterStoreHasFilter {
+ // removing filter in case of an update so we can recreate it with updated values
+ lggr.Debugw("Upserting upkeep filter")
+ err := p.poller.UnregisterFilter(lpFilter.Name)
+ if err != nil {
+ return fmt.Errorf("failed to upsert (unregister) upkeep filter %s: %w", ufilter.upkeepID.String(), err)
+ }
+ }
if err := p.poller.RegisterFilter(lpFilter); err != nil {
return err
}
p.filterStore.AddActiveUpkeeps(ufilter)
- p.poller.ReplayAsync(int64(ufilter.configUpdateBlock))
+ if logPollerHasFilter {
+ // already registered in DB before, no need to backfill
+ return nil
+ }
+ backfillBlock := latest - int64(LogBackfillBuffer)
+ if backfillBlock < 1 {
+ // New chain, backfill from start
+ backfillBlock = 1
+ }
+ if int64(ufilter.configUpdateBlock) > backfillBlock {
+ // backfill from config update block in case it is not too old
+ backfillBlock = int64(ufilter.configUpdateBlock)
+ }
+ // NOTE: replys are planned to be done as part of RegisterFilter within logpoller
+ lggr.Debugw("Backfilling logs for new upkeep filter", "backfillBlock", backfillBlock)
+ p.poller.ReplayAsync(backfillBlock)
return nil
}
func (p *logEventProvider) UnregisterFilter(upkeepID *big.Int) error {
- err := p.poller.UnregisterFilter(p.filterName(upkeepID))
- if err != nil {
- // TODO: mark as removed in filter store, so we'll
- // automatically retry on next refresh
- return fmt.Errorf("failed to unregister upkeep filter %s: %w", upkeepID.String(), err)
+ // Filter might have been unregistered already, only try to unregister if it exists
+ if p.poller.HasFilter(p.filterName(upkeepID)) {
+ if err := p.poller.UnregisterFilter(p.filterName(upkeepID)); err != nil {
+ return fmt.Errorf("failed to unregister upkeep filter %s: %w", upkeepID.String(), err)
+ }
}
p.filterStore.RemoveActiveUpkeeps(upkeepFilter{
upkeepID: upkeepID,
@@ -129,11 +159,11 @@ func (p *logEventProvider) UnregisterFilter(upkeepID *big.Int) error {
// newLogFilter creates logpoller.Filter from the given upkeep config
func (p *logEventProvider) newLogFilter(upkeepID *big.Int, cfg LogTriggerConfig) logpoller.Filter {
- topics := p.getFiltersBySelector(cfg.FilterSelector, cfg.Topic1[:], cfg.Topic2[:], cfg.Topic3[:])
- topics = append([]common.Hash{common.BytesToHash(cfg.Topic0[:])}, topics...)
return logpoller.Filter{
- Name: p.filterName(upkeepID),
- EventSigs: topics,
+ Name: p.filterName(upkeepID),
+ // log poller filter treats this event sigs slice as an array of topic0
+ // since we don't support multiple events right now, only put one topic0 here
+ EventSigs: []common.Hash{common.BytesToHash(cfg.Topic0[:])},
Addresses: []common.Address{cfg.ContractAddress},
Retention: LogRetention,
}
@@ -148,26 +178,12 @@ func (p *logEventProvider) validateLogTriggerConfig(cfg LogTriggerConfig) error
if bytes.Equal(cfg.Topic0[:], zeroBytes[:]) {
return errors.New("invalid topic0: zeroed")
}
- return nil
-}
-
-// getFiltersBySelector the filters based on the filterSelector
-func (p *logEventProvider) getFiltersBySelector(filterSelector uint8, filters ...[]byte) []common.Hash {
- var sigs []common.Hash
- var zeroBytes [32]byte
- for i, f := range filters {
- // bitwise AND the filterSelector with the index to check if the filter is needed
- mask := uint8(1 << uint8(i))
- a := filterSelector & mask
- if a == uint8(0) {
- continue
- }
- if bytes.Equal(f, zeroBytes[:]) {
- continue
- }
- sigs = append(sigs, common.BytesToHash(common.LeftPadBytes(f, 32)))
+ s := cfg.FilterSelector
+ if s >= 8 {
+ p.lggr.Error("filter selector %d is invalid", s)
+ return errors.New("invalid filter selector: larger or equal to 8")
}
- return sigs
+ return nil
}
func (p *logEventProvider) filterName(upkeepID *big.Int) string {
diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider_life_cycle_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider_life_cycle_test.go
index 3f9ddaa5af3..4b1ff06f316 100644
--- a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider_life_cycle_test.go
+++ b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider_life_cycle_test.go
@@ -1,11 +1,14 @@
package logprovider
import (
+ "context"
+ "fmt"
"math/big"
"testing"
"github.com/ethereum/go-ethereum/common"
ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg/v3/types"
+ "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
@@ -20,6 +23,8 @@ func TestLogEventProvider_LifeCycle(t *testing.T) {
errored bool
upkeepID *big.Int
upkeepCfg LogTriggerConfig
+ hasFilter bool
+ replyed bool
cfgUpdateBlock uint64
mockPoller bool
unregister bool
@@ -32,6 +37,8 @@ func TestLogEventProvider_LifeCycle(t *testing.T) {
ContractAddress: common.BytesToAddress(common.LeftPadBytes([]byte{1, 2, 3, 4}, 20)),
Topic0: common.BytesToHash(common.LeftPadBytes([]byte{1, 2, 3, 4}, 32)),
},
+ false,
+ true,
uint64(1),
true,
false,
@@ -41,6 +48,8 @@ func TestLogEventProvider_LifeCycle(t *testing.T) {
true,
big.NewInt(111),
LogTriggerConfig{},
+ false,
+ false,
uint64(0),
false,
false,
@@ -53,18 +62,22 @@ func TestLogEventProvider_LifeCycle(t *testing.T) {
ContractAddress: common.BytesToAddress(common.LeftPadBytes([]byte{}, 20)),
Topic0: common.BytesToHash(common.LeftPadBytes([]byte{}, 32)),
},
+ false,
+ false,
uint64(2),
false,
false,
},
{
- "existing config",
+ "existing config with old block",
true,
big.NewInt(111),
LogTriggerConfig{
ContractAddress: common.BytesToAddress(common.LeftPadBytes([]byte{1, 2, 3, 4}, 20)),
Topic0: common.BytesToHash(common.LeftPadBytes([]byte{1, 2, 3, 4}, 32)),
},
+ true,
+ false,
uint64(0),
true,
false,
@@ -77,21 +90,42 @@ func TestLogEventProvider_LifeCycle(t *testing.T) {
ContractAddress: common.BytesToAddress(common.LeftPadBytes([]byte{1, 2, 3, 4}, 20)),
Topic0: common.BytesToHash(common.LeftPadBytes([]byte{1, 2, 3, 4}, 32)),
},
+ true,
+ false,
uint64(2),
true,
true,
},
}
- mp := new(mocks.LogPoller)
- mp.On("RegisterFilter", mock.Anything).Return(nil)
- mp.On("UnregisterFilter", mock.Anything).Return(nil)
- mp.On("ReplayAsync", mock.Anything).Return(nil)
- p := NewLogProvider(logger.TestLogger(t), mp, &mockedPacker{}, NewUpkeepFilterStore(), nil)
+ p := NewLogProvider(logger.TestLogger(t), nil, &mockedPacker{}, NewUpkeepFilterStore(), NewOptions(200))
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
- err := p.RegisterFilter(FilterOptions{
+ ctx, cancel := context.WithCancel(context.Background())
+ defer cancel()
+
+ if tc.mockPoller {
+ lp := new(mocks.LogPoller)
+ lp.On("RegisterFilter", mock.Anything).Return(nil)
+ lp.On("UnregisterFilter", mock.Anything).Return(nil)
+ lp.On("LatestBlock", mock.Anything).Return(int64(0), nil)
+ hasFitlerTimes := 1
+ if tc.unregister {
+ hasFitlerTimes = 2
+ }
+ lp.On("HasFilter", p.filterName(tc.upkeepID)).Return(tc.hasFilter).Times(hasFitlerTimes)
+ if tc.replyed {
+ lp.On("ReplayAsync", mock.Anything).Return(nil).Times(1)
+ } else {
+ lp.On("ReplayAsync", mock.Anything).Return(nil).Times(0)
+ }
+ p.lock.Lock()
+ p.poller = lp
+ p.lock.Unlock()
+ }
+
+ err := p.RegisterFilter(ctx, FilterOptions{
UpkeepID: tc.upkeepID,
TriggerConfig: tc.upkeepCfg,
UpdateBlock: tc.cfgUpdateBlock,
@@ -109,14 +143,18 @@ func TestLogEventProvider_LifeCycle(t *testing.T) {
}
func TestEventLogProvider_RefreshActiveUpkeeps(t *testing.T) {
+ ctx, cancel := context.WithCancel(context.Background())
+ defer cancel()
mp := new(mocks.LogPoller)
mp.On("RegisterFilter", mock.Anything).Return(nil)
mp.On("UnregisterFilter", mock.Anything).Return(nil)
+ mp.On("HasFilter", mock.Anything).Return(false)
+ mp.On("LatestBlock", mock.Anything).Return(int64(0), nil)
mp.On("ReplayAsync", mock.Anything).Return(nil)
- p := NewLogProvider(logger.TestLogger(t), mp, &mockedPacker{}, NewUpkeepFilterStore(), nil)
+ p := NewLogProvider(logger.TestLogger(t), mp, &mockedPacker{}, NewUpkeepFilterStore(), NewOptions(200))
- require.NoError(t, p.RegisterFilter(FilterOptions{
+ require.NoError(t, p.RegisterFilter(ctx, FilterOptions{
UpkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "1111").BigInt(),
TriggerConfig: LogTriggerConfig{
ContractAddress: common.BytesToAddress(common.LeftPadBytes([]byte{1, 2, 3, 4}, 20)),
@@ -124,7 +162,7 @@ func TestEventLogProvider_RefreshActiveUpkeeps(t *testing.T) {
},
UpdateBlock: uint64(0),
}))
- require.NoError(t, p.RegisterFilter(FilterOptions{
+ require.NoError(t, p.RegisterFilter(ctx, FilterOptions{
UpkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "2222").BigInt(),
TriggerConfig: LogTriggerConfig{
ContractAddress: common.BytesToAddress(common.LeftPadBytes([]byte{1, 2, 3, 4}, 20)),
@@ -137,6 +175,7 @@ func TestEventLogProvider_RefreshActiveUpkeeps(t *testing.T) {
newIds, err := p.RefreshActiveUpkeeps()
require.NoError(t, err)
require.Len(t, newIds, 0)
+ mp.On("HasFilter", p.filterName(core.GenUpkeepID(ocr2keepers.LogTrigger, "2222").BigInt())).Return(true)
newIds, err = p.RefreshActiveUpkeeps(
core.GenUpkeepID(ocr2keepers.LogTrigger, "2222").BigInt(),
core.GenUpkeepID(ocr2keepers.LogTrigger, "1234").BigInt(),
@@ -146,134 +185,56 @@ func TestEventLogProvider_RefreshActiveUpkeeps(t *testing.T) {
require.Equal(t, 1, p.filterStore.Size())
}
-func TestLogEventProvider_GetFiltersBySelector(t *testing.T) {
- var zeroBytes [32]byte
+func TestLogEventProvider_ValidateLogTriggerConfig(t *testing.T) {
+ contractAddress := common.HexToAddress("0xB9F3af0c2CbfE108efd0E23F7b0a151Ea42f764E")
+ eventSig := common.HexToHash("0x3bdab8bffae631cfee411525ebae27f3fb61b10c662c09ec2a7dbb5854c87e8c")
tests := []struct {
- name string
- filterSelector uint8
- filters [][]byte
- expectedSigs []common.Hash
+ name string
+ cfg LogTriggerConfig
+ expectedErr error
}{
{
- "invalid filters",
- 1,
- [][]byte{
- zeroBytes[:],
- },
- []common.Hash{},
- },
- {
- "selector 000",
- 0,
- [][]byte{
- {1},
- },
- []common.Hash{},
- },
- {
- "selector 001",
- 1,
- [][]byte{
- {1},
- {2},
- {3},
- },
- []common.Hash{
- common.BytesToHash(common.LeftPadBytes([]byte{1}, 32)),
- },
- },
- {
- "selector 010",
- 2,
- [][]byte{
- {1},
- {2},
- {3},
- },
- []common.Hash{
- common.BytesToHash(common.LeftPadBytes([]byte{2}, 32)),
- },
- },
- {
- "selector 011",
- 3,
- [][]byte{
- {1},
- {2},
- {3},
- },
- []common.Hash{
- common.BytesToHash(common.LeftPadBytes([]byte{1}, 32)),
- common.BytesToHash(common.LeftPadBytes([]byte{2}, 32)),
- },
- },
- {
- "selector 100",
- 4,
- [][]byte{
- {1},
- {2},
- {3},
- },
- []common.Hash{
- common.BytesToHash(common.LeftPadBytes([]byte{3}, 32)),
+ "success",
+ LogTriggerConfig{
+ ContractAddress: contractAddress,
+ FilterSelector: 0,
+ Topic0: eventSig,
},
+ nil,
},
{
- "selector 101",
- 5,
- [][]byte{
- {1},
- {2},
- {3},
- },
- []common.Hash{
- common.BytesToHash(common.LeftPadBytes([]byte{1}, 32)),
- common.BytesToHash(common.LeftPadBytes([]byte{3}, 32)),
+ "invalid contract address",
+ LogTriggerConfig{
+ ContractAddress: common.Address{},
+ FilterSelector: 0,
+ Topic0: eventSig,
},
+ fmt.Errorf("invalid contract address: zeroed"),
},
{
- "selector 110",
- 6,
- [][]byte{
- {1},
- {2},
- {3},
- },
- []common.Hash{
- common.BytesToHash(common.LeftPadBytes([]byte{2}, 32)),
- common.BytesToHash(common.LeftPadBytes([]byte{3}, 32)),
+ "invalid topic0",
+ LogTriggerConfig{
+ ContractAddress: contractAddress,
+ FilterSelector: 0,
},
+ fmt.Errorf("invalid topic0: zeroed"),
},
{
- "selector 111",
- 7,
- [][]byte{
- {1},
- {2},
- {3},
- },
- []common.Hash{
- common.BytesToHash(common.LeftPadBytes([]byte{1}, 32)),
- common.BytesToHash(common.LeftPadBytes([]byte{2}, 32)),
- common.BytesToHash(common.LeftPadBytes([]byte{3}, 32)),
+ "success",
+ LogTriggerConfig{
+ ContractAddress: contractAddress,
+ FilterSelector: 8,
+ Topic0: eventSig,
},
+ fmt.Errorf("invalid filter selector: larger or equal to 8"),
},
}
- p := NewLogProvider(logger.TestLogger(t), nil, &mockedPacker{}, NewUpkeepFilterStore(), nil)
-
+ p := NewLogProvider(logger.TestLogger(t), nil, &mockedPacker{}, NewUpkeepFilterStore(), NewOptions(200))
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
- sigs := p.getFiltersBySelector(tc.filterSelector, tc.filters...)
- if len(sigs) != len(tc.expectedSigs) {
- t.Fatalf("expected %v, got %v", len(tc.expectedSigs), len(sigs))
- }
- for i := range sigs {
- if sigs[i] != tc.expectedSigs[i] {
- t.Fatalf("expected %v, got %v", tc.expectedSigs[i], sigs[i])
- }
- }
+ err := p.validateLogTriggerConfig(tc.cfg)
+ assert.Equal(t, tc.expectedErr, err)
})
}
}
diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider_opts.go b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider_opts.go
deleted file mode 100644
index 1a09e99ec08..00000000000
--- a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider_opts.go
+++ /dev/null
@@ -1,52 +0,0 @@
-package logprovider
-
-import (
- "time"
-
- "golang.org/x/time/rate"
-)
-
-// LogEventProviderOptions holds the options for the log event provider.
-type LogEventProviderOptions struct {
- // LookbackBlocks is the number of blocks to look back for logs.
- LookbackBlocks int64
- // ReorgBuffer is the number of blocks to add as a buffer to the lookback.
- ReorgBuffer int64
- // BlockRateLimit is the rate limit on the range of blocks the we fetch logs for.
- BlockRateLimit rate.Limit
- // BlockLimitBurst is the burst upper limit on the range of blocks the we fetch logs for.
- BlockLimitBurst int
- // ReadInterval is the interval to fetch logs in the background.
- ReadInterval time.Duration
- // ReadBatchSize is the max number of items in one read batch / partition.
- ReadBatchSize int
- // Readers is the number of reader workers to spawn.
- Readers int
-}
-
-// Defaults sets the default values for the options.
-func (o *LogEventProviderOptions) Defaults() {
- if o.LookbackBlocks == 0 {
- // TODO: Ensure lookback blocks is at least as large as Finality Depth to
- // ensure recoverer does not go beyond finality depth
- o.LookbackBlocks = 200
- }
- if o.ReorgBuffer == 0 {
- o.ReorgBuffer = 32
- }
- if o.BlockRateLimit == 0 {
- o.BlockRateLimit = rate.Every(time.Second)
- }
- if o.BlockLimitBurst == 0 {
- o.BlockLimitBurst = int(o.LookbackBlocks)
- }
- if o.ReadInterval == 0 {
- o.ReadInterval = time.Second
- }
- if o.ReadBatchSize == 0 {
- o.ReadBatchSize = 32
- }
- if o.Readers == 0 {
- o.Readers = 4
- }
-}
diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider_test.go
index 7c1aa84ac4b..db22886cbb7 100644
--- a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider_test.go
+++ b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider_test.go
@@ -22,7 +22,7 @@ import (
)
func TestLogEventProvider_GetFilters(t *testing.T) {
- p := NewLogProvider(logger.TestLogger(t), nil, &mockedPacker{}, NewUpkeepFilterStore(), nil)
+ p := NewLogProvider(logger.TestLogger(t), nil, &mockedPacker{}, NewUpkeepFilterStore(), NewOptions(200))
_, f := newEntry(p, 1)
p.filterStore.AddActiveUpkeeps(f)
@@ -64,7 +64,7 @@ func TestLogEventProvider_GetFilters(t *testing.T) {
}
func TestLogEventProvider_UpdateEntriesLastPoll(t *testing.T) {
- p := NewLogProvider(logger.TestLogger(t), nil, &mockedPacker{}, NewUpkeepFilterStore(), nil)
+ p := NewLogProvider(logger.TestLogger(t), nil, &mockedPacker{}, NewUpkeepFilterStore(), NewOptions(200))
n := 10
@@ -178,10 +178,10 @@ func TestLogEventProvider_ScheduleReadJobs(t *testing.T) {
defer cancel()
readInterval := 10 * time.Millisecond
- p := NewLogProvider(logger.TestLogger(t), mp, &mockedPacker{}, NewUpkeepFilterStore(), &LogEventProviderOptions{
- ReadBatchSize: tc.maxBatchSize,
- ReadInterval: readInterval,
- })
+ opts := NewOptions(200)
+ opts.ReadInterval = readInterval
+
+ p := NewLogProvider(logger.TestLogger(t), mp, &mockedPacker{}, NewUpkeepFilterStore(), opts)
var ids []*big.Int
for i, id := range tc.ids {
@@ -193,7 +193,7 @@ func TestLogEventProvider_ScheduleReadJobs(t *testing.T) {
reads := make(chan []*big.Int, 100)
go func(ctx context.Context) {
- _ = p.scheduleReadJobs(ctx, func(ids []*big.Int) {
+ p.scheduleReadJobs(ctx, func(ids []*big.Int) {
select {
case reads <- ids:
default:
@@ -246,6 +246,7 @@ func TestLogEventProvider_ReadLogs(t *testing.T) {
mp.On("RegisterFilter", mock.Anything).Return(nil)
mp.On("ReplayAsync", mock.Anything).Return()
+ mp.On("HasFilter", mock.Anything).Return(false)
mp.On("UnregisterFilter", mock.Anything, mock.Anything).Return(nil)
mp.On("LatestBlock", mock.Anything).Return(int64(1), nil)
mp.On("LogsWithSigs", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return([]logpoller.Log{
@@ -255,13 +256,14 @@ func TestLogEventProvider_ReadLogs(t *testing.T) {
},
}, nil)
- p := NewLogProvider(logger.TestLogger(t), mp, &mockedPacker{}, NewUpkeepFilterStore(), nil)
+ filterStore := NewUpkeepFilterStore()
+ p := NewLogProvider(logger.TestLogger(t), mp, &mockedPacker{}, filterStore, NewOptions(200))
var ids []*big.Int
for i := 0; i < 10; i++ {
cfg, f := newEntry(p, i+1)
ids = append(ids, f.upkeepID)
- require.NoError(t, p.RegisterFilter(FilterOptions{
+ require.NoError(t, p.RegisterFilter(ctx, FilterOptions{
UpkeepID: f.upkeepID,
TriggerConfig: cfg,
}))
@@ -277,6 +279,15 @@ func TestLogEventProvider_ReadLogs(t *testing.T) {
require.NoError(t, p.ReadLogs(ctx, ids[:2]...))
logs := p.buffer.peek(10)
require.Len(t, logs, 2)
+
+ var updatedFilters []upkeepFilter
+ filterStore.RangeFiltersByIDs(func(i int, f upkeepFilter) {
+ updatedFilters = append(updatedFilters, f.Clone())
+ }, ids[:2]...)
+ for _, f := range updatedFilters {
+ // Last poll block should be updated
+ require.Equal(t, int64(1), f.lastPollBlock)
+ }
})
// TODO: test rate limiting
diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/recoverer.go b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/recoverer.go
index 6dd5f8fe56a..3994f1d8413 100644
--- a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/recoverer.go
+++ b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/recoverer.go
@@ -1,11 +1,13 @@
package logprovider
import (
+ "bytes"
"context"
"crypto/rand"
"errors"
"fmt"
"io"
+ "math"
"math/big"
"sort"
"sync"
@@ -13,6 +15,7 @@ import (
"time"
"github.com/ethereum/go-ethereum/common"
+ "github.com/smartcontractkit/ocr2keepers/pkg/v3/random"
ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg/v3/types"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/client"
@@ -20,17 +23,30 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/logger"
"github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21/core"
"github.com/smartcontractkit/chainlink/v2/core/services/pg"
+ "github.com/smartcontractkit/chainlink/v2/core/utils"
)
var (
- ErrNotFound = errors.New("not found")
- DefaultRecoveryInterval = 5 * time.Second
- // TODO: Reduce these intervals to allow sending same proposals again if they were not fulfilled
- RecoveryCacheTTL = 24*time.Hour - time.Second
- GCInterval = time.Hour
-
- recoveryBatchSize = 10
- recoveryLogsBuffer = int64(50)
+ LogRecovererServiceName = "LogRecoverer"
+
+ // RecoveryInterval is the interval at which the recovery scanning processing is triggered
+ RecoveryInterval = 5 * time.Second
+ // RecoveryCacheTTL is the time to live for the recovery cache
+ RecoveryCacheTTL = 10 * time.Minute
+ // GCInterval is the interval at which the recovery cache is cleaned up
+ GCInterval = RecoveryCacheTTL - time.Second
+ // MaxProposals is the maximum number of proposals that can be returned by GetRecoveryProposals
+ MaxProposals = 20
+ // recoveryBatchSize is the number of filters to recover in a single batch
+ recoveryBatchSize = 10
+ // recoveryLogsBuffer is the number of blocks to be used as a safety buffer when reading logs
+ recoveryLogsBuffer = int64(200)
+ recoveryLogsBurst = int64(500)
+ // blockTimeUpdateCadence is the cadence at which the chain's blocktime is re-calculated
+ blockTimeUpdateCadence = 10 * time.Minute
+ // maxPendingPayloadsPerUpkeep is the number of logs we can have pending for a single upkeep
+ // at any given time
+ maxPendingPayloadsPerUpkeep = 500
)
type LogRecoverer interface {
@@ -41,11 +57,16 @@ type LogRecoverer interface {
io.Closer
}
-// TODO: Ensure that the logs enqueued into pending reach a final state
+type visitedRecord struct {
+ visitedAt time.Time
+ payload ocr2keepers.UpkeepPayload
+}
+
type logRecoverer struct {
- lggr logger.Logger
+ utils.StartStopOnce
+ threadCtrl utils.ThreadControl
- cancel context.CancelFunc
+ lggr logger.Logger
lookbackBlocks *atomic.Int64
blockTime *atomic.Int64
@@ -54,106 +75,117 @@ type logRecoverer struct {
lock sync.RWMutex
pending []ocr2keepers.UpkeepPayload
- visited map[string]time.Time
+ visited map[string]visitedRecord
- filterStore UpkeepFilterStore
- states core.UpkeepStateReader
- packer LogDataPacker
- poller logpoller.LogPoller
- client client.Client
+ filterStore UpkeepFilterStore
+ states core.UpkeepStateReader
+ packer LogDataPacker
+ poller logpoller.LogPoller
+ client client.Client
+ blockTimeResolver *blockTimeResolver
+
+ finalityDepth int64
}
var _ LogRecoverer = &logRecoverer{}
-func NewLogRecoverer(lggr logger.Logger, poller logpoller.LogPoller, client client.Client, stateStore core.UpkeepStateReader, packer LogDataPacker, filterStore UpkeepFilterStore, interval time.Duration, lookbackBlocks int64) *logRecoverer {
- if interval == 0 {
- interval = DefaultRecoveryInterval
- }
-
+func NewLogRecoverer(lggr logger.Logger, poller logpoller.LogPoller, client client.Client, stateStore core.UpkeepStateReader, packer LogDataPacker, filterStore UpkeepFilterStore, opts LogTriggersOptions) *logRecoverer {
rec := &logRecoverer{
- lggr: lggr.Named("LogRecoverer"),
+ lggr: lggr.Named(LogRecovererServiceName),
+
+ threadCtrl: utils.NewThreadControl(),
blockTime: &atomic.Int64{},
lookbackBlocks: &atomic.Int64{},
- interval: interval,
+ interval: opts.ReadInterval * 5,
- pending: make([]ocr2keepers.UpkeepPayload, 0),
- visited: make(map[string]time.Time),
- poller: poller,
- filterStore: filterStore,
- states: stateStore,
- packer: packer,
- client: client,
+ pending: make([]ocr2keepers.UpkeepPayload, 0),
+ visited: make(map[string]visitedRecord),
+ poller: poller,
+ filterStore: filterStore,
+ states: stateStore,
+ packer: packer,
+ client: client,
+ blockTimeResolver: newBlockTimeResolver(poller),
+
+ finalityDepth: opts.FinalityDepth,
}
- rec.lookbackBlocks.Store(lookbackBlocks)
+ rec.lookbackBlocks.Store(opts.LookbackBlocks)
rec.blockTime.Store(int64(defaultBlockTime))
return rec
}
-func (r *logRecoverer) Start(pctx context.Context) error {
- ctx, cancel := context.WithCancel(context.Background())
+// Start starts the log recoverer, which runs 3 threads in the background:
+// 1. Recovery thread: scans for logs that were missed by the log poller
+// 2. Cleanup thread: cleans up the cache of logs that were already processed
+// 3. Block time thread: updates the block time of the chain
+func (r *logRecoverer) Start(ctx context.Context) error {
+ return r.StartOnce(LogRecovererServiceName, func() error {
+ r.updateBlockTime(ctx)
- r.lock.Lock()
- if r.cancel != nil {
- r.lock.Unlock()
- cancel() // Cancel the created context
- return errors.New("already started")
- }
- r.cancel = cancel
- r.lock.Unlock()
+ r.lggr.Infow("starting log recoverer", "blockTime", r.blockTime.Load(), "lookbackBlocks", r.lookbackBlocks.Load(), "interval", r.interval)
- blockTimeResolver := newBlockTimeResolver(r.poller)
- blockTime, err := blockTimeResolver.BlockTime(ctx, defaultSampleSize)
- if err != nil {
- // TODO: TBD exit or just log a warning
- // return fmt.Errorf("failed to compute block time: %w", err)
- r.lggr.Warnw("failed to compute block time", "err", err)
- }
- if blockTime > 0 {
- r.blockTime.Store(int64(blockTime))
- }
-
- r.lggr.Infow("starting log recoverer", "blockTime", r.blockTime.Load(), "lookbackBlocks", r.lookbackBlocks.Load(), "interval", r.interval)
-
- {
- go func(ctx context.Context, interval time.Duration) {
- ticker := time.NewTicker(interval)
- defer ticker.Stop()
-
- gcTicker := time.NewTicker(GCInterval)
- defer gcTicker.Stop()
+ r.threadCtrl.Go(func(ctx context.Context) {
+ recoveryTicker := time.NewTicker(r.interval)
+ defer recoveryTicker.Stop()
for {
select {
- case <-ticker.C:
+ case <-recoveryTicker.C:
if err := r.recover(ctx); err != nil {
r.lggr.Warnw("failed to recover logs", "err", err)
}
- case <-gcTicker.C:
+ case <-ctx.Done():
+ return
+ }
+ }
+ })
+
+ r.threadCtrl.Go(func(ctx context.Context) {
+ cleanupTicker := time.NewTicker(utils.WithJitter(GCInterval))
+ defer cleanupTicker.Stop()
+
+ for {
+ select {
+ case <-cleanupTicker.C:
r.clean(ctx)
+ cleanupTicker.Reset(utils.WithJitter(GCInterval))
case <-ctx.Done():
return
}
}
- }(ctx, r.interval)
- }
+ })
- return nil
+ r.threadCtrl.Go(func(ctx context.Context) {
+ blockTimeTicker := time.NewTicker(blockTimeUpdateCadence)
+ defer blockTimeTicker.Stop()
+
+ for {
+ select {
+ case <-blockTimeTicker.C:
+ r.updateBlockTime(ctx)
+ blockTimeTicker.Reset(utils.WithJitter(blockTimeUpdateCadence))
+ case <-ctx.Done():
+ return
+ }
+ }
+ })
+
+ return nil
+ })
}
func (r *logRecoverer) Close() error {
- r.lock.Lock()
- defer r.lock.Unlock()
+ return r.StopOnce(LogRecovererServiceName, func() error {
+ r.threadCtrl.Close()
+ return nil
+ })
+}
- if cancel := r.cancel; cancel != nil {
- r.cancel = nil
- cancel()
- } else {
- return errors.New("already stopped")
- }
- return nil
+func (r *logRecoverer) HealthReport() map[string]error {
+ return map[string]error{LogRecovererServiceName: r.Healthy()}
}
func (r *logRecoverer) GetProposalData(ctx context.Context, proposal ocr2keepers.CoordinatedBlockProposal) ([]byte, error) {
@@ -174,31 +206,34 @@ func (r *logRecoverer) getLogTriggerCheckData(ctx context.Context, proposal ocr2
return nil, err
}
- // TODO: Ensure start block is above upkeep creation block
start, offsetBlock := r.getRecoveryWindow(latest)
if proposal.Trigger.LogTriggerExtension == nil {
return nil, errors.New("missing log trigger extension")
}
- logBlock := int64(proposal.Trigger.LogTriggerExtension.BlockNumber)
- if logBlock == 0 {
- var number *big.Int
- number, _, err = r.getTxBlock(proposal.Trigger.LogTriggerExtension.TxHash)
- if err != nil {
- return nil, err
- }
- if number == nil {
- return nil, errors.New("failed to get tx block")
- }
- logBlock = number.Int64()
+
+ // Verify the log is still present on chain, not reorged and is within recoverable range
+ // Do not trust the logBlockNumber from proposal since it's not included in workID
+ logBlockHash := common.BytesToHash(proposal.Trigger.LogTriggerExtension.BlockHash[:])
+ bn, bh, err := core.GetTxBlock(ctx, r.client, proposal.Trigger.LogTriggerExtension.TxHash)
+ if err != nil {
+ return nil, err
+ }
+ if bn == nil {
+ return nil, errors.New("failed to get tx block")
+ }
+ if bh.Hex() != logBlockHash.Hex() {
+ return nil, errors.New("log tx reorged")
}
+ logBlock := bn.Int64()
if isRecoverable := logBlock < offsetBlock && logBlock > start; !isRecoverable {
return nil, errors.New("log block is not recoverable")
}
- upkeepStates, err := r.states.SelectByWorkIDsInRange(ctx, int64(logBlock)-1, offsetBlock, proposal.WorkID)
+
+ // Check if the log was already performed or ineligible
+ upkeepStates, err := r.states.SelectByWorkIDs(ctx, proposal.WorkID)
if err != nil {
return nil, err
}
-
for _, upkeepState := range upkeepStates {
switch upkeepState {
case ocr2keepers.Performed, ocr2keepers.Ineligible:
@@ -216,11 +251,15 @@ func (r *logRecoverer) getLogTriggerCheckData(ctx context.Context, proposal ocr2
if len(filter.addr) == 0 {
return nil, fmt.Errorf("invalid filter found for upkeepID %s", proposal.UpkeepID.String())
}
+ if filter.configUpdateBlock > uint64(logBlock) {
+ return nil, fmt.Errorf("log block %d is before the filter configUpdateBlock %d for upkeepID %s", logBlock, filter.configUpdateBlock, proposal.UpkeepID.String())
+ }
logs, err := r.poller.LogsWithSigs(logBlock-1, logBlock+1, filter.topics, common.BytesToAddress(filter.addr), pg.WithParentCtx(ctx))
if err != nil {
return nil, fmt.Errorf("could not read logs: %w", err)
}
+ logs = filter.Select(logs...)
for _, log := range logs {
trigger := logToTrigger(log)
@@ -240,17 +279,12 @@ func (r *logRecoverer) getLogTriggerCheckData(ctx context.Context, proposal ocr2
return nil, fmt.Errorf("no log found for upkeepID %v and trigger %+v", proposal.UpkeepID, proposal.Trigger)
}
-func (r *logRecoverer) getTxBlock(txHash common.Hash) (*big.Int, common.Hash, error) {
- // TODO: do manual eth_getTransactionReceipt call to get block number and hash
- txr, err := r.client.TransactionReceipt(context.Background(), txHash)
+func (r *logRecoverer) GetRecoveryProposals(ctx context.Context) ([]ocr2keepers.UpkeepPayload, error) {
+ latestBlock, err := r.poller.LatestBlock(pg.WithParentCtx(ctx))
if err != nil {
- return nil, common.Hash{}, err
+ return nil, fmt.Errorf("%w: %s", ErrHeadNotAvailable, err)
}
- return txr.BlockNumber, txr.BlockHash, nil
-}
-
-func (r *logRecoverer) GetRecoveryProposals(ctx context.Context) ([]ocr2keepers.UpkeepPayload, error) {
r.lock.Lock()
defer r.lock.Unlock()
@@ -258,21 +292,32 @@ func (r *logRecoverer) GetRecoveryProposals(ctx context.Context) ([]ocr2keepers.
return nil, nil
}
+ allLogsCounter := 0
logsCount := map[string]int{}
+ r.sortPending(uint64(latestBlock))
+
var results, pending []ocr2keepers.UpkeepPayload
for _, payload := range r.pending {
+ if allLogsCounter >= MaxProposals {
+ // we have enough proposals, pushed the rest are pushed back to pending
+ pending = append(pending, payload)
+ continue
+ }
uid := payload.UpkeepID.String()
if logsCount[uid] >= AllowedLogsPerUpkeep {
+ // we have enough proposals for this upkeep, the rest are pushed back to pending
pending = append(pending, payload)
continue
}
- logsCount[uid]++
results = append(results, payload)
+ logsCount[uid]++
+ allLogsCounter++
}
+
r.pending = pending
- r.lggr.Debugf("found %d pending payloads", len(pending))
+ r.lggr.Debugf("found %d recoverable payloads", len(results))
return results, nil
}
@@ -316,16 +361,23 @@ func (r *logRecoverer) recover(ctx context.Context) error {
// recoverFilter recovers logs for a single upkeep filter.
func (r *logRecoverer) recoverFilter(ctx context.Context, f upkeepFilter, startBlock, offsetBlock int64) error {
- start := f.lastRePollBlock
+ start := f.lastRePollBlock + 1 // NOTE: we expect f.lastRePollBlock + 1 <= offsetBlock, as others would have been filtered out
// ensure we don't recover logs from before the filter was created
- // NOTE: we expect that filter with configUpdateBlock > offsetBlock were already filtered out.
if configUpdateBlock := int64(f.configUpdateBlock); start < configUpdateBlock {
+ // NOTE: we expect that configUpdateBlock <= offsetBlock, as others would have been filtered out
start = configUpdateBlock
}
if start < startBlock {
start = startBlock
}
end := start + recoveryLogsBuffer
+ if offsetBlock-end > 100*recoveryLogsBuffer {
+ // If recoverer is lagging by a lot (more than 100x recoveryLogsBuffer), allow
+ // a range of recoveryLogsBurst
+ // Exploratory: Store lastRePollBlock in DB to prevent bursts during restarts
+ // (while also taking into account existing pending payloads)
+ end = start + recoveryLogsBurst
+ }
if end > offsetBlock {
end = offsetBlock
}
@@ -334,6 +386,7 @@ func (r *logRecoverer) recoverFilter(ctx context.Context, f upkeepFilter, startB
if err != nil {
return fmt.Errorf("could not read logs: %w", err)
}
+ logs = f.Select(logs...)
workIDs := make([]string, 0)
for _, log := range logs {
@@ -347,7 +400,7 @@ func (r *logRecoverer) recoverFilter(ctx context.Context, f upkeepFilter, startB
workIDs = append(workIDs, core.UpkeepWorkID(*upkeepId, trigger))
}
- states, err := r.states.SelectByWorkIDsInRange(ctx, start, end, workIDs...)
+ states, err := r.states.SelectByWorkIDs(ctx, workIDs...)
if err != nil {
return fmt.Errorf("could not read states: %w", err)
}
@@ -356,27 +409,33 @@ func (r *logRecoverer) recoverFilter(ctx context.Context, f upkeepFilter, startB
}
filteredLogs := r.filterFinalizedStates(f, logs, states)
- added, alreadyPending := r.populatePending(f, filteredLogs)
+ added, alreadyPending, ok := r.populatePending(f, filteredLogs)
if added > 0 {
- r.lggr.Debugw("found missed logs", "count", added, "upkeepID", f.upkeepID)
- } else if alreadyPending == 0 {
- r.filterStore.UpdateFilters(func(uf1, uf2 upkeepFilter) upkeepFilter {
- uf1.lastRePollBlock = end
- return uf1
- }, f)
+ r.lggr.Debugw("found missed logs", "added", added, "alreadyPending", alreadyPending, "upkeepID", f.upkeepID)
}
+ if !ok {
+ r.lggr.Debugw("failed to add all logs to pending", "upkeepID", f.upkeepID)
+ return nil
+ }
+ r.filterStore.UpdateFilters(func(uf1, uf2 upkeepFilter) upkeepFilter {
+ uf1.lastRePollBlock = end
+ r.lggr.Debugw("Updated lastRePollBlock", "lastRePollBlock", end, "upkeepID", uf1.upkeepID)
+ return uf1
+ }, f)
return nil
}
// populatePending adds the logs to the pending list if they are not already pending.
-// returns the number of logs added and the number of logs that were already pending.
-func (r *logRecoverer) populatePending(f upkeepFilter, filteredLogs []logpoller.Log) (int, int) {
+// returns the number of logs added, the number of logs that were already pending,
+// and a flag that indicates whether some errors happened while we are trying to add to pending q.
+func (r *logRecoverer) populatePending(f upkeepFilter, filteredLogs []logpoller.Log) (int, int, bool) {
r.lock.Lock()
defer r.lock.Unlock()
pendingSizeBefore := len(r.pending)
alreadyPending := 0
+ errs := make([]error, 0)
for _, log := range filteredLogs {
trigger := logToTrigger(log)
// Set the checkBlock and Hash to zero so that the checkPipeline uses the latest block
@@ -404,14 +463,20 @@ func (r *logRecoverer) populatePending(f upkeepFilter, filteredLogs []logpoller.
continue
}
// r.lggr.Debugw("adding a payload to pending", "payload", payload)
- r.visited[wid] = time.Now()
- r.pending = append(r.pending, payload)
+ if err := r.addPending(payload); err != nil {
+ errs = append(errs, err)
+ } else {
+ r.visited[wid] = visitedRecord{
+ visitedAt: time.Now(),
+ payload: payload,
+ }
+ }
}
- return len(r.pending) - pendingSizeBefore, alreadyPending
+ return len(r.pending) - pendingSizeBefore, alreadyPending, len(errs) == 0
}
// filterFinalizedStates filters out the log upkeeps that have already been completed (performed or ineligible).
-func (r *logRecoverer) filterFinalizedStates(f upkeepFilter, logs []logpoller.Log, states []ocr2keepers.UpkeepState) []logpoller.Log {
+func (r *logRecoverer) filterFinalizedStates(_ upkeepFilter, logs []logpoller.Log, states []ocr2keepers.UpkeepState) []logpoller.Log {
filtered := make([]logpoller.Log, 0)
for i, log := range logs {
@@ -430,7 +495,16 @@ func (r *logRecoverer) getRecoveryWindow(latest int64) (int64, int64) {
lookbackBlocks := r.lookbackBlocks.Load()
blockTime := r.blockTime.Load()
blocksInDay := int64(24*time.Hour) / blockTime
- return latest - blocksInDay, latest - lookbackBlocks
+ start := latest - blocksInDay
+ // Exploratory: Instead of subtracting finality depth to account for finalized performs
+ // keep two pointers of lastRePollBlock for soft and hard finalization, i.e. manage
+ // unfinalized perform logs better
+ end := latest - lookbackBlocks - r.finalityDepth
+ if start > end {
+ // In this case, allow starting from more than a day behind
+ start = end
+ }
+ return start, end
}
// getFilterBatch returns a batch of filters that are ready to be recovered.
@@ -438,7 +512,7 @@ func (r *logRecoverer) getFilterBatch(offsetBlock int64) []upkeepFilter {
filters := r.filterStore.GetFilters(func(f upkeepFilter) bool {
// ensure we work only on filters that are ready to be recovered
// no need to recover in case f.configUpdateBlock is after offsetBlock
- return f.lastRePollBlock <= offsetBlock && int64(f.configUpdateBlock) <= offsetBlock
+ return f.lastRePollBlock < offsetBlock && int64(f.configUpdateBlock) <= offsetBlock
})
sort.Slice(filters, func(i, j int) bool {
@@ -503,18 +577,147 @@ func logToTrigger(log logpoller.Log) ocr2keepers.Trigger {
}
func (r *logRecoverer) clean(ctx context.Context) {
+ r.lock.RLock()
+ var expired []string
+ for id, t := range r.visited {
+ if time.Since(t.visitedAt) > RecoveryCacheTTL {
+ expired = append(expired, id)
+ }
+ }
+ r.lock.RUnlock()
+ lggr := r.lggr.With("where", "clean")
+ if len(expired) == 0 {
+ lggr.Debug("no expired upkeeps")
+ return
+ }
+ err := r.tryExpire(ctx, expired...)
+ if err != nil {
+ lggr.Warnw("failed to clean visited upkeeps", "err", err)
+ }
+}
+
+func (r *logRecoverer) tryExpire(ctx context.Context, ids ...string) error {
+ latestBlock, err := r.poller.LatestBlock(pg.WithParentCtx(ctx))
+ if err != nil {
+ return fmt.Errorf("failed to get latest block: %w", err)
+ }
+ sort.Slice(ids, func(i, j int) bool {
+ return ids[i] < ids[j]
+ })
+ states, err := r.states.SelectByWorkIDs(ctx, ids...)
+ if err != nil {
+ return fmt.Errorf("failed to get states: %w", err)
+ }
+ lggr := r.lggr.With("where", "clean")
+ start, _ := r.getRecoveryWindow(latestBlock)
r.lock.Lock()
defer r.lock.Unlock()
+ var removed int
+ for i, state := range states {
+ switch state {
+ case ocr2keepers.UnknownState:
+ // in case the state is unknown, we can't be sure if the upkeep was performed or not
+ // so we push it back to the pending list
+ rec, ok := r.visited[ids[i]]
+ if !ok {
+ // in case it was removed by another thread
+ continue
+ }
+ if logBlock := rec.payload.Trigger.LogTriggerExtension.BlockNumber; int64(logBlock) < start {
+ // we can't recover this log anymore, so we remove it from the visited list
+ lggr.Debugw("removing expired log: old block", "upkeepID", rec.payload.UpkeepID,
+ "latestBlock", latestBlock, "logBlock", logBlock, "start", start)
+ r.removePending(rec.payload.WorkID)
+ delete(r.visited, ids[i])
+ removed++
+ continue
+ }
+ if err := r.addPending(rec.payload); err == nil {
+ rec.visitedAt = time.Now()
+ r.visited[ids[i]] = rec
+ }
+ default:
+ delete(r.visited, ids[i])
+ removed++
+ }
+ }
- cleaned := 0
- for id, t := range r.visited {
- if time.Since(t) > RecoveryCacheTTL {
- delete(r.visited, id)
- cleaned++
+ if removed > 0 {
+ lggr.Debugw("expired upkeeps", "expired", len(ids), "cleaned", removed)
+ }
+
+ return nil
+}
+
+// addPending adds a payload to the pending list if it's not already there.
+// NOTE: the lock must be held before calling this function.
+func (r *logRecoverer) addPending(payload ocr2keepers.UpkeepPayload) error {
+ var exist bool
+ pending := r.pending
+ upkeepPayloads := 0
+ for _, p := range pending {
+ if bytes.Equal(p.UpkeepID[:], payload.UpkeepID[:]) {
+ upkeepPayloads++
+ }
+ if p.WorkID == payload.WorkID {
+ exist = true
+ }
+ }
+ if upkeepPayloads >= maxPendingPayloadsPerUpkeep {
+ return fmt.Errorf("upkeep %v has too many payloads in pending queue", payload.UpkeepID)
+ }
+ if !exist {
+ r.pending = append(pending, payload)
+ }
+ return nil
+}
+
+// removePending removes a payload from the pending list.
+// NOTE: the lock must be held before calling this function.
+func (r *logRecoverer) removePending(workID string) {
+ updated := make([]ocr2keepers.UpkeepPayload, 0, len(r.pending))
+ for _, p := range r.pending {
+ if p.WorkID != workID {
+ updated = append(updated, p)
}
}
+ r.pending = updated
+}
+
+// sortPending sorts the pending list by a random order based on the normalized latest block number.
+// Divided by 10 to ensure that nodes with similar block numbers won't end up with different order.
+// NOTE: the lock must be held before calling this function.
+func (r *logRecoverer) sortPending(latestBlock uint64) {
+ normalized := latestBlock / 100
+ if normalized == 0 {
+ normalized = 1
+ }
+ randSeed := random.GetRandomKeySource(nil, normalized)
- if cleaned > 0 {
- r.lggr.Debugw("gc: cleaned visited upkeeps", "cleaned", cleaned)
+ shuffledIDs := make(map[string]string, len(r.pending))
+ for _, p := range r.pending {
+ shuffledIDs[p.WorkID] = random.ShuffleString(p.WorkID, randSeed)
+ }
+
+ sort.SliceStable(r.pending, func(i, j int) bool {
+ return shuffledIDs[r.pending[i].WorkID] < shuffledIDs[r.pending[j].WorkID]
+ })
+}
+
+func (r *logRecoverer) updateBlockTime(ctx context.Context) {
+ blockTime, err := r.blockTimeResolver.BlockTime(ctx, defaultSampleSize)
+ if err != nil {
+ r.lggr.Warnw("failed to compute block time", "err", err)
+ return
+ }
+ if blockTime > 0 {
+ currentBlockTime := r.blockTime.Load()
+ newBlockTime := int64(blockTime)
+ if currentBlockTime > 0 && (int64(math.Abs(float64(currentBlockTime-newBlockTime)))*100/currentBlockTime) > 20 {
+ r.lggr.Warnf("updating blocktime from %d to %d, this change is larger than 20%", currentBlockTime, newBlockTime)
+ } else {
+ r.lggr.Debugf("updating blocktime from %d to %d", currentBlockTime, newBlockTime)
+ }
+ r.blockTime.Store(newBlockTime)
}
}
diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/recoverer_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/recoverer_test.go
index ed2ce1b0347..2fdf04f76c7 100644
--- a/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/recoverer_test.go
+++ b/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/recoverer_test.go
@@ -3,13 +3,13 @@ package logprovider
import (
"context"
"fmt"
+ "math"
"math/big"
"sort"
"testing"
"time"
"github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
"github.com/pkg/errors"
ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg/v3/types"
"github.com/stretchr/testify/assert"
@@ -19,6 +19,8 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/client"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller"
lpmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller/mocks"
+ "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types"
+ "github.com/smartcontractkit/chainlink/v2/core/internal/testutils"
"github.com/smartcontractkit/chainlink/v2/core/logger"
"github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21/core"
"github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21/core/mocks"
@@ -29,7 +31,9 @@ import (
func TestLogRecoverer_GetRecoverables(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
- r := NewLogRecoverer(logger.TestLogger(t), nil, nil, nil, nil, nil, time.Millisecond*10, 0)
+ lp := &lpmocks.LogPoller{}
+ lp.On("LatestBlock", mock.Anything).Return(int64(100), nil)
+ r := NewLogRecoverer(logger.TestLogger(t), lp, nil, nil, nil, nil, NewOptions(200))
tests := []struct {
name string
@@ -95,6 +99,119 @@ func TestLogRecoverer_GetRecoverables(t *testing.T) {
}
}
+func TestLogRecoverer_Clean(t *testing.T) {
+ oldLogsOffset := int64(20)
+
+ tests := []struct {
+ name string
+ pending []ocr2keepers.UpkeepPayload
+ visited map[string]visitedRecord
+ states []ocr2keepers.UpkeepState
+ wantPending []ocr2keepers.UpkeepPayload
+ wantVisited []string
+ }{
+ {
+ "empty",
+ []ocr2keepers.UpkeepPayload{},
+ map[string]visitedRecord{},
+ []ocr2keepers.UpkeepState{},
+ []ocr2keepers.UpkeepPayload{},
+ []string{},
+ },
+ {
+ "clean expired",
+ []ocr2keepers.UpkeepPayload{
+ {WorkID: "1", UpkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "1")},
+ {WorkID: "2", UpkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "2")},
+ {WorkID: "3", UpkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "3")},
+ },
+ map[string]visitedRecord{
+ "1": visitedRecord{time.Now(), ocr2keepers.UpkeepPayload{
+ WorkID: "1",
+ Trigger: ocr2keepers.Trigger{
+ LogTriggerExtension: &ocr2keepers.LogTriggerExtension{
+ BlockNumber: ocr2keepers.BlockNumber(oldLogsOffset * 2),
+ },
+ },
+ }},
+ "2": visitedRecord{time.Now(), ocr2keepers.UpkeepPayload{
+ WorkID: "2",
+ Trigger: ocr2keepers.Trigger{
+ LogTriggerExtension: &ocr2keepers.LogTriggerExtension{
+ BlockNumber: ocr2keepers.BlockNumber(oldLogsOffset * 2),
+ },
+ },
+ }},
+ "3": visitedRecord{time.Now().Add(-time.Hour), ocr2keepers.UpkeepPayload{
+ WorkID: "3",
+ Trigger: ocr2keepers.Trigger{
+ LogTriggerExtension: &ocr2keepers.LogTriggerExtension{
+ BlockNumber: ocr2keepers.BlockNumber(oldLogsOffset - 10),
+ },
+ },
+ }},
+ "4": visitedRecord{time.Now().Add(-time.Hour), ocr2keepers.UpkeepPayload{
+ WorkID: "4",
+ Trigger: ocr2keepers.Trigger{
+ LogTriggerExtension: &ocr2keepers.LogTriggerExtension{
+ BlockNumber: ocr2keepers.BlockNumber(oldLogsOffset + 10),
+ },
+ },
+ }},
+ },
+ []ocr2keepers.UpkeepState{
+ ocr2keepers.UnknownState,
+ ocr2keepers.UnknownState,
+ },
+ []ocr2keepers.UpkeepPayload{
+ {WorkID: "1", UpkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "1")},
+ {WorkID: "2", UpkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "2")},
+ {WorkID: "4", UpkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "4")},
+ },
+ []string{"1", "2", "4"},
+ },
+ }
+
+ for _, tc := range tests {
+ t.Run(tc.name, func(t *testing.T) {
+ ctx, cancel := context.WithCancel(testutils.Context(t))
+ defer cancel()
+
+ lookbackBlocks := int64(100)
+ r, _, lp, statesReader := setupTestRecoverer(t, time.Millisecond*50, lookbackBlocks)
+ start, _ := r.getRecoveryWindow(0)
+ block24h := int64(math.Abs(float64(start)))
+
+ lp.On("LatestBlock", mock.Anything).Return(block24h+oldLogsOffset, nil)
+ statesReader.On("SelectByWorkIDs", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(tc.states, nil)
+
+ r.lock.Lock()
+ r.pending = tc.pending
+ r.visited = tc.visited
+ r.lock.Unlock()
+
+ r.clean(ctx)
+
+ r.lock.RLock()
+ defer r.lock.RUnlock()
+
+ pending := r.pending
+ require.Equal(t, len(tc.wantPending), len(pending))
+ sort.Slice(pending, func(i, j int) bool {
+ return pending[i].WorkID < pending[j].WorkID
+ })
+ for i := range pending {
+ require.Equal(t, tc.wantPending[i].WorkID, pending[i].WorkID)
+ }
+ require.Equal(t, len(tc.wantVisited), len(r.visited))
+ for _, id := range tc.wantVisited {
+ _, ok := r.visited[id]
+ require.True(t, ok)
+ }
+ })
+ }
+}
+
func TestLogRecoverer_Recover(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
@@ -111,6 +228,7 @@ func TestLogRecoverer_Recover(t *testing.T) {
logsErr error
recoverErr error
proposalsWorkIDs []string
+ lastRePollBlocks []int64
}{
{
"no filters",
@@ -124,6 +242,7 @@ func TestLogRecoverer_Recover(t *testing.T) {
nil,
nil,
[]string{},
+ []int64{},
},
{
"latest block error",
@@ -137,6 +256,7 @@ func TestLogRecoverer_Recover(t *testing.T) {
nil,
fmt.Errorf("test error"),
[]string{},
+ []int64{},
},
{
"states error",
@@ -165,6 +285,7 @@ func TestLogRecoverer_Recover(t *testing.T) {
nil,
nil,
[]string{},
+ []int64{0},
},
{
"get logs error",
@@ -186,11 +307,12 @@ func TestLogRecoverer_Recover(t *testing.T) {
fmt.Errorf("test error"),
nil,
[]string{},
+ []int64{0},
},
{
"happy flow",
100,
- 200,
+ 500,
nil,
[]upkeepFilter{
{
@@ -206,7 +328,15 @@ func TestLogRecoverer_Recover(t *testing.T) {
topics: []common.Hash{
common.HexToHash("0x2"),
},
- configUpdateBlock: 150, // should be filtered out
+ configUpdateBlock: 450, // should be filtered out
+ },
+ {
+ upkeepID: big.NewInt(3),
+ addr: common.HexToAddress("0x2").Bytes(),
+ topics: []common.Hash{
+ common.HexToHash("0x2"),
+ },
+ lastRePollBlock: 450, // should be filtered out, as its higher than latest-lookback
},
},
[]ocr2keepers.UpkeepState{ocr2keepers.UnknownState},
@@ -221,7 +351,69 @@ func TestLogRecoverer_Recover(t *testing.T) {
},
nil,
nil,
- []string{"84c83c79c2be2c3eabd8d35986a2a798d9187564d7f4f8f96c5a0f40f50bed3f"},
+ []string{"c207451fa897f9bb13b09d54d8655edf0644e027c53521b4a92eafbb64ba4d14"},
+ []int64{201, 0, 450},
+ },
+ {
+ "lastRePollBlock updated with burst when lagging behind",
+ 100,
+ 50000,
+ nil,
+ []upkeepFilter{
+ {
+ upkeepID: big.NewInt(1),
+ addr: common.HexToAddress("0x1").Bytes(),
+ topics: []common.Hash{
+ common.HexToHash("0x1"),
+ },
+ lastRePollBlock: 99, // Should be updated with burst
+ },
+ },
+ []ocr2keepers.UpkeepState{ocr2keepers.UnknownState},
+ nil,
+ []logpoller.Log{
+ {
+ BlockNumber: 2,
+ TxHash: common.HexToHash("0x111"),
+ LogIndex: 1,
+ BlockHash: common.HexToHash("0x2"),
+ },
+ },
+ nil,
+ nil,
+ []string{"c207451fa897f9bb13b09d54d8655edf0644e027c53521b4a92eafbb64ba4d14"},
+ []int64{600},
+ },
+ {
+ "recovery starts at configUpdateBlock if higher than lastRePollBlock",
+ 100,
+ 5000,
+ nil,
+ []upkeepFilter{
+ {
+ upkeepID: big.NewInt(1),
+ addr: common.HexToAddress("0x1").Bytes(),
+ topics: []common.Hash{
+ common.HexToHash("0x1"),
+ },
+ lastRePollBlock: 100,
+ configUpdateBlock: 500,
+ },
+ },
+ []ocr2keepers.UpkeepState{ocr2keepers.UnknownState},
+ nil,
+ []logpoller.Log{
+ {
+ BlockNumber: 2,
+ TxHash: common.HexToHash("0x111"),
+ LogIndex: 1,
+ BlockHash: common.HexToHash("0x2"),
+ },
+ },
+ nil,
+ nil,
+ []string{"c207451fa897f9bb13b09d54d8655edf0644e027c53521b4a92eafbb64ba4d14"},
+ []int64{700}, // should be configUpdateBlock + recoveryLogsBuffer
},
}
@@ -233,7 +425,7 @@ func TestLogRecoverer_Recover(t *testing.T) {
filterStore.AddActiveUpkeeps(tc.active...)
lp.On("LatestBlock", mock.Anything).Return(tc.latestBlock, tc.latestBlockErr)
lp.On("LogsWithSigs", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(tc.logs, tc.logsErr)
- statesReader.On("SelectByWorkIDsInRange", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(tc.states, tc.statesErr)
+ statesReader.On("SelectByWorkIDs", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(tc.states, tc.statesErr)
err := recoverer.recover(ctx)
if tc.recoverErr != nil {
@@ -241,6 +433,13 @@ func TestLogRecoverer_Recover(t *testing.T) {
return
}
require.NoError(t, err)
+ for i, active := range tc.active {
+ filters := filterStore.GetFilters(func(f upkeepFilter) bool {
+ return f.upkeepID.String() == active.upkeepID.String()
+ })
+ require.Equal(t, 1, len(filters))
+ require.Equal(t, tc.lastRePollBlocks[i], filters[0].lastRePollBlock)
+ }
proposals, err := recoverer.GetRecoveryProposals(ctx)
require.NoError(t, err)
@@ -258,7 +457,7 @@ func TestLogRecoverer_Recover(t *testing.T) {
}
func TestLogRecoverer_SelectFilterBatch(t *testing.T) {
- n := (recoveryBatchSize*2 + 2)
+ n := recoveryBatchSize*2 + 2
filters := []upkeepFilter{}
for i := 0; i < n; i++ {
filters = append(filters, upkeepFilter{
@@ -435,8 +634,8 @@ func TestLogRecoverer_GetProposalData(t *testing.T) {
},
},
client: &mockClient{
- TransactionReceiptFn: func(ctx context.Context, txHash common.Hash) (*types.Receipt, error) {
- return nil, errors.New("tx receipt boom")
+ CallContextFn: func(ctx context.Context, receipt *types.Receipt, method string, args ...interface{}) error {
+ return errors.New("tx receipt boom")
},
},
expectErr: true,
@@ -463,8 +662,8 @@ func TestLogRecoverer_GetProposalData(t *testing.T) {
},
},
client: &mockClient{
- TransactionReceiptFn: func(ctx context.Context, txHash common.Hash) (*types.Receipt, error) {
- return &types.Receipt{}, nil
+ CallContextFn: func(ctx context.Context, receipt *types.Receipt, method string, args ...interface{}) error {
+ return nil
},
},
expectErr: true,
@@ -491,10 +690,10 @@ func TestLogRecoverer_GetProposalData(t *testing.T) {
},
},
client: &mockClient{
- TransactionReceiptFn: func(ctx context.Context, txHash common.Hash) (*types.Receipt, error) {
- return &types.Receipt{
- BlockNumber: big.NewInt(200),
- }, nil
+ CallContextFn: func(ctx context.Context, receipt *types.Receipt, method string, args ...interface{}) error {
+ receipt.Status = 1
+ receipt.BlockNumber = big.NewInt(200)
+ return nil
},
},
expectErr: true,
@@ -520,9 +719,48 @@ func TestLogRecoverer_GetProposalData(t *testing.T) {
return 100, nil
},
},
+ client: &mockClient{
+ CallContextFn: func(ctx context.Context, receipt *types.Receipt, method string, args ...interface{}) error {
+ receipt.Status = 1
+ receipt.BlockNumber = big.NewInt(200)
+ return nil
+ },
+ },
expectErr: true,
wantErr: errors.New("log block is not recoverable"),
},
+ {
+ name: "if a log block has does not match, an error is returned",
+ proposal: ocr2keepers.CoordinatedBlockProposal{
+ UpkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "123"),
+ Trigger: ocr2keepers.Trigger{
+ LogTriggerExtension: &ocr2keepers.LogTriggerExtension{
+ BlockNumber: 200,
+ BlockHash: common.HexToHash("0x2"),
+ },
+ },
+ },
+ filterStore: &mockFilterStore{
+ HasFn: func(id *big.Int) bool {
+ return true
+ },
+ },
+ logPoller: &mockLogPoller{
+ LatestBlockFn: func(qopts ...pg.QOpt) (int64, error) {
+ return 100, nil
+ },
+ },
+ client: &mockClient{
+ CallContextFn: func(ctx context.Context, receipt *types.Receipt, method string, args ...interface{}) error {
+ receipt.Status = 1
+ receipt.BlockNumber = big.NewInt(200)
+ receipt.BlockHash = common.HexToHash("0x1")
+ return nil
+ },
+ },
+ expectErr: true,
+ wantErr: errors.New("log tx reorged"),
+ },
{
name: "if a log block is recoverable, when the upkeep state reader errors, an error is returned",
proposal: ocr2keepers.CoordinatedBlockProposal{
@@ -540,14 +778,21 @@ func TestLogRecoverer_GetProposalData(t *testing.T) {
},
logPoller: &mockLogPoller{
LatestBlockFn: func(qopts ...pg.QOpt) (int64, error) {
- return 100, nil
+ return 300, nil
},
},
stateReader: &mockStateReader{
- SelectByWorkIDsInRangeFn: func(ctx context.Context, start, end int64, workIDs ...string) ([]ocr2keepers.UpkeepState, error) {
+ SelectByWorkIDsFn: func(ctx context.Context, workIDs ...string) ([]ocr2keepers.UpkeepState, error) {
return nil, errors.New("upkeep state boom")
},
},
+ client: &mockClient{
+ CallContextFn: func(ctx context.Context, receipt *types.Receipt, method string, args ...interface{}) error {
+ receipt.Status = 1
+ receipt.BlockNumber = big.NewInt(80)
+ return nil
+ },
+ },
expectErr: true,
wantErr: errors.New("upkeep state boom"),
},
@@ -568,11 +813,18 @@ func TestLogRecoverer_GetProposalData(t *testing.T) {
},
logPoller: &mockLogPoller{
LatestBlockFn: func(qopts ...pg.QOpt) (int64, error) {
- return 100, nil
+ return 300, nil
+ },
+ },
+ client: &mockClient{
+ CallContextFn: func(ctx context.Context, receipt *types.Receipt, method string, args ...interface{}) error {
+ receipt.Status = 1
+ receipt.BlockNumber = big.NewInt(80)
+ return nil
},
},
stateReader: &mockStateReader{
- SelectByWorkIDsInRangeFn: func(ctx context.Context, start, end int64, workIDs ...string) ([]ocr2keepers.UpkeepState, error) {
+ SelectByWorkIDsFn: func(ctx context.Context, workIDs ...string) ([]ocr2keepers.UpkeepState, error) {
return []ocr2keepers.UpkeepState{
ocr2keepers.Ineligible,
}, nil
@@ -601,11 +853,18 @@ func TestLogRecoverer_GetProposalData(t *testing.T) {
},
logPoller: &mockLogPoller{
LatestBlockFn: func(qopts ...pg.QOpt) (int64, error) {
- return 100, nil
+ return 300, nil
+ },
+ },
+ client: &mockClient{
+ CallContextFn: func(ctx context.Context, receipt *types.Receipt, method string, args ...interface{}) error {
+ receipt.Status = 1
+ receipt.BlockNumber = big.NewInt(80)
+ return nil
},
},
stateReader: &mockStateReader{
- SelectByWorkIDsInRangeFn: func(ctx context.Context, start, end int64, workIDs ...string) ([]ocr2keepers.UpkeepState, error) {
+ SelectByWorkIDsFn: func(ctx context.Context, workIDs ...string) ([]ocr2keepers.UpkeepState, error) {
return []ocr2keepers.UpkeepState{
ocr2keepers.UnknownState,
}, nil
@@ -626,14 +885,21 @@ func TestLogRecoverer_GetProposalData(t *testing.T) {
},
logPoller: &mockLogPoller{
LatestBlockFn: func(qopts ...pg.QOpt) (int64, error) {
- return 100, nil
+ return 300, nil
},
LogsWithSigsFn: func(start, end int64, eventSigs []common.Hash, address common.Address, qopts ...pg.QOpt) ([]logpoller.Log, error) {
return nil, errors.New("logs with sigs boom")
},
},
+ client: &mockClient{
+ CallContextFn: func(ctx context.Context, receipt *types.Receipt, method string, args ...interface{}) error {
+ receipt.Status = 1
+ receipt.BlockNumber = big.NewInt(80)
+ return nil
+ },
+ },
stateReader: &mockStateReader{
- SelectByWorkIDsInRangeFn: func(ctx context.Context, start, end int64, workIDs ...string) ([]ocr2keepers.UpkeepState, error) {
+ SelectByWorkIDsFn: func(ctx context.Context, workIDs ...string) ([]ocr2keepers.UpkeepState, error) {
return []ocr2keepers.UpkeepState{
ocr2keepers.UnknownState,
}, nil
@@ -654,7 +920,7 @@ func TestLogRecoverer_GetProposalData(t *testing.T) {
},
logPoller: &mockLogPoller{
LatestBlockFn: func(qopts ...pg.QOpt) (int64, error) {
- return 100, nil
+ return 300, nil
},
LogsWithSigsFn: func(start, end int64, eventSigs []common.Hash, address common.Address, qopts ...pg.QOpt) ([]logpoller.Log, error) {
return []logpoller.Log{
@@ -664,8 +930,15 @@ func TestLogRecoverer_GetProposalData(t *testing.T) {
}, nil
},
},
+ client: &mockClient{
+ CallContextFn: func(ctx context.Context, receipt *types.Receipt, method string, args ...interface{}) error {
+ receipt.Status = 1
+ receipt.BlockNumber = big.NewInt(80)
+ return nil
+ },
+ },
stateReader: &mockStateReader{
- SelectByWorkIDsInRangeFn: func(ctx context.Context, start, end int64, workIDs ...string) ([]ocr2keepers.UpkeepState, error) {
+ SelectByWorkIDsFn: func(ctx context.Context, workIDs ...string) ([]ocr2keepers.UpkeepState, error) {
return []ocr2keepers.UpkeepState{
ocr2keepers.UnknownState,
}, nil
@@ -691,11 +964,11 @@ func TestLogRecoverer_GetProposalData(t *testing.T) {
}
return t
}(),
- WorkID: "d91c6f090b8477f434cf775182e4ff12c90618ba4da5b8ec06aa719768b7743a",
+ WorkID: "7f775793422d178c90e99c3bbdf05181bc6bb6ce13170e87c92ac396bb7ddda0",
},
logPoller: &mockLogPoller{
LatestBlockFn: func(qopts ...pg.QOpt) (int64, error) {
- return 100, nil
+ return 300, nil
},
LogsWithSigsFn: func(start, end int64, eventSigs []common.Hash, address common.Address, qopts ...pg.QOpt) ([]logpoller.Log, error) {
return []logpoller.Log{
@@ -708,8 +981,16 @@ func TestLogRecoverer_GetProposalData(t *testing.T) {
}, nil
},
},
+ client: &mockClient{
+ CallContextFn: func(ctx context.Context, receipt *types.Receipt, method string, args ...interface{}) error {
+ receipt.Status = 1
+ receipt.BlockNumber = big.NewInt(80)
+ receipt.BlockHash = [32]byte{1}
+ return nil
+ },
+ },
stateReader: &mockStateReader{
- SelectByWorkIDsInRangeFn: func(ctx context.Context, start, end int64, workIDs ...string) ([]ocr2keepers.UpkeepState, error) {
+ SelectByWorkIDsFn: func(ctx context.Context, workIDs ...string) ([]ocr2keepers.UpkeepState, error) {
return []ocr2keepers.UpkeepState{
ocr2keepers.UnknownState,
}, nil
@@ -734,11 +1015,11 @@ func TestLogRecoverer_GetProposalData(t *testing.T) {
}
return t
}(),
- WorkID: "d91c6f090b8477f434cf775182e4ff12c90618ba4da5b8ec06aa719768b7743a",
+ WorkID: "7f775793422d178c90e99c3bbdf05181bc6bb6ce13170e87c92ac396bb7ddda0",
},
logPoller: &mockLogPoller{
LatestBlockFn: func(qopts ...pg.QOpt) (int64, error) {
- return 100, nil
+ return 300, nil
},
LogsWithSigsFn: func(start, end int64, eventSigs []common.Hash, address common.Address, qopts ...pg.QOpt) ([]logpoller.Log, error) {
return []logpoller.Log{
@@ -756,8 +1037,16 @@ func TestLogRecoverer_GetProposalData(t *testing.T) {
}, nil
},
},
+ client: &mockClient{
+ CallContextFn: func(ctx context.Context, receipt *types.Receipt, method string, args ...interface{}) error {
+ receipt.Status = 1
+ receipt.BlockNumber = big.NewInt(80)
+ receipt.BlockHash = [32]byte{1}
+ return nil
+ },
+ },
stateReader: &mockStateReader{
- SelectByWorkIDsInRangeFn: func(ctx context.Context, start, end int64, workIDs ...string) ([]ocr2keepers.UpkeepState, error) {
+ SelectByWorkIDsFn: func(ctx context.Context, workIDs ...string) ([]ocr2keepers.UpkeepState, error) {
return []ocr2keepers.UpkeepState{
ocr2keepers.UnknownState,
}, nil
@@ -772,6 +1061,7 @@ func TestLogRecoverer_GetProposalData(t *testing.T) {
if !tc.skipFilter {
filterStore.AddActiveUpkeeps(upkeepFilter{
addr: []byte("test"),
+ topics: []common.Hash{common.HexToHash("0x1"), common.HexToHash("0x2"), common.HexToHash("0x3"), common.HexToHash("0x4")},
upkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "123").BigInt(),
})
}
@@ -801,6 +1091,98 @@ func TestLogRecoverer_GetProposalData(t *testing.T) {
}
}
+func TestLogRecoverer_pending(t *testing.T) {
+ tests := []struct {
+ name string
+ maxPerUpkeep int
+ exist []ocr2keepers.UpkeepPayload
+ new []ocr2keepers.UpkeepPayload
+ errored []bool
+ want []ocr2keepers.UpkeepPayload
+ }{
+ {
+ name: "empty",
+ maxPerUpkeep: 10,
+ exist: []ocr2keepers.UpkeepPayload{},
+ new: []ocr2keepers.UpkeepPayload{},
+ errored: []bool{},
+ want: []ocr2keepers.UpkeepPayload{},
+ },
+ {
+ name: "add new and existing",
+ maxPerUpkeep: 10,
+ exist: []ocr2keepers.UpkeepPayload{
+ {WorkID: "1", UpkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "1")},
+ },
+ new: []ocr2keepers.UpkeepPayload{
+ {WorkID: "1", UpkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "1")},
+ {WorkID: "2", UpkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "2")},
+ },
+ errored: []bool{false, false},
+ want: []ocr2keepers.UpkeepPayload{
+ {WorkID: "1", UpkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "1")},
+ {WorkID: "2", UpkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "2")},
+ },
+ },
+ {
+ name: "exceed limits for upkeep",
+ maxPerUpkeep: 3,
+ exist: []ocr2keepers.UpkeepPayload{
+ {WorkID: "1", UpkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "1")},
+ {WorkID: "2", UpkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "1")},
+ {WorkID: "3", UpkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "1")},
+ },
+ new: []ocr2keepers.UpkeepPayload{
+ {WorkID: "4", UpkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "1")},
+ },
+ errored: []bool{true},
+ want: []ocr2keepers.UpkeepPayload{
+ {WorkID: "1", UpkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "1")},
+ {WorkID: "2", UpkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "1")},
+ {WorkID: "3", UpkeepID: core.GenUpkeepID(ocr2keepers.LogTrigger, "1")},
+ },
+ },
+ }
+
+ for _, tc := range tests {
+ t.Run(tc.name, func(t *testing.T) {
+ origMaxPendingPayloadsPerUpkeep := maxPendingPayloadsPerUpkeep
+ maxPendingPayloadsPerUpkeep = tc.maxPerUpkeep
+ defer func() {
+ maxPendingPayloadsPerUpkeep = origMaxPendingPayloadsPerUpkeep
+ }()
+
+ r := NewLogRecoverer(logger.TestLogger(t), nil, nil, nil, nil, nil, NewOptions(200))
+ r.lock.Lock()
+ r.pending = tc.exist
+ for i, p := range tc.new {
+ err := r.addPending(p)
+ if tc.errored[i] {
+ require.Error(t, err)
+ continue
+ }
+ require.NoError(t, err)
+ }
+ pending := r.pending
+ require.GreaterOrEqual(t, len(pending), len(tc.new))
+ require.Equal(t, len(tc.want), len(pending))
+ sort.Slice(pending, func(i, j int) bool {
+ return pending[i].WorkID < pending[j].WorkID
+ })
+ for i := range pending {
+ require.Equal(t, tc.want[i].WorkID, pending[i].WorkID)
+ }
+ r.lock.Unlock()
+ for _, p := range tc.want {
+ r.removePending(p.WorkID)
+ }
+ r.lock.Lock()
+ defer r.lock.Unlock()
+ require.Equal(t, 0, len(r.pending))
+ })
+ }
+}
+
type mockFilterStore struct {
UpkeepFilterStore
HasFn func(id *big.Int) bool
@@ -830,25 +1212,29 @@ func (p *mockLogPoller) LatestBlock(qopts ...pg.QOpt) (int64, error) {
type mockClient struct {
client.Client
- TransactionReceiptFn func(ctx context.Context, txHash common.Hash) (*types.Receipt, error)
+ CallContextFn func(ctx context.Context, receipt *types.Receipt, method string, args ...interface{}) error
}
-func (c *mockClient) TransactionReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error) {
- return c.TransactionReceiptFn(ctx, txHash)
+func (c *mockClient) CallContext(ctx context.Context, r interface{}, method string, args ...interface{}) error {
+ receipt := r.(*types.Receipt)
+ return c.CallContextFn(ctx, receipt, method, args)
}
type mockStateReader struct {
- SelectByWorkIDsInRangeFn func(ctx context.Context, start, end int64, workIDs ...string) ([]ocr2keepers.UpkeepState, error)
+ SelectByWorkIDsFn func(ctx context.Context, workIDs ...string) ([]ocr2keepers.UpkeepState, error)
}
-func (r *mockStateReader) SelectByWorkIDsInRange(ctx context.Context, start, end int64, workIDs ...string) ([]ocr2keepers.UpkeepState, error) {
- return r.SelectByWorkIDsInRangeFn(ctx, start, end, workIDs...)
+func (r *mockStateReader) SelectByWorkIDs(ctx context.Context, workIDs ...string) ([]ocr2keepers.UpkeepState, error) {
+ return r.SelectByWorkIDsFn(ctx, workIDs...)
}
func setupTestRecoverer(t *testing.T, interval time.Duration, lookbackBlocks int64) (*logRecoverer, UpkeepFilterStore, *lpmocks.LogPoller, *mocks.UpkeepStateReader) {
lp := new(lpmocks.LogPoller)
statesReader := new(mocks.UpkeepStateReader)
filterStore := NewUpkeepFilterStore()
- recoverer := NewLogRecoverer(logger.TestLogger(t), lp, nil, statesReader, &mockedPacker{}, filterStore, interval, lookbackBlocks)
+ opts := NewOptions(lookbackBlocks)
+ opts.ReadInterval = interval / 5
+ opts.LookbackBlocks = lookbackBlocks
+ recoverer := NewLogRecoverer(logger.TestLogger(t), lp, nil, statesReader, &mockedPacker{}, filterStore, opts)
return recoverer, filterStore, lp, statesReader
}
diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/payload_builder.go b/core/services/ocr2/plugins/ocr2keeper/evm21/payload_builder.go
index 9351aa71d65..b14e687b5d1 100644
--- a/core/services/ocr2/plugins/ocr2keeper/evm21/payload_builder.go
+++ b/core/services/ocr2/plugins/ocr2keeper/evm21/payload_builder.go
@@ -33,7 +33,7 @@ func (b *payloadBuilder) BuildPayloads(ctx context.Context, proposals ...ocr2kee
var payload ocr2keepers.UpkeepPayload
if b.upkeepList.IsActive(proposal.UpkeepID.BigInt()) {
b.lggr.Debugf("building payload for coordinated block proposal %+v", proposal)
- checkData := []byte{}
+ var checkData []byte
var err error
switch core.GetUpkeepType(proposal.UpkeepID) {
case ocr2keepers.LogTrigger:
diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/payload_builder_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/payload_builder_test.go
index 6c0ef78bbc4..e75084ff968 100644
--- a/core/services/ocr2/plugins/ocr2keeper/evm21/payload_builder_test.go
+++ b/core/services/ocr2/plugins/ocr2keeper/evm21/payload_builder_test.go
@@ -184,7 +184,6 @@ func TestNewPayloadBuilder(t *testing.T) {
BlockNumber: 1,
BlockHash: [32]byte{1},
},
- CheckData: make([]byte, 0),
},
},
},
diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/registry.go b/core/services/ocr2/plugins/ocr2keeper/evm21/registry.go
index fabfcca8248..590e5138b3e 100644
--- a/core/services/ocr2/plugins/ocr2keeper/evm21/registry.go
+++ b/core/services/ocr2/plugins/ocr2keeper/evm21/registry.go
@@ -13,10 +13,10 @@ import (
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
coreTypes "github.com/ethereum/go-ethereum/core/types"
- "github.com/pkg/errors"
-
"github.com/patrickmn/go-cache"
+ "github.com/pkg/errors"
ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg/v3/types"
+ "go.uber.org/multierr"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/client"
@@ -36,17 +36,19 @@ const (
// defaultAllowListExpiration decides how long an upkeep's allow list info will be valid for.
defaultAllowListExpiration = 20 * time.Minute
// allowListCleanupInterval decides when the expired items in allowList cache will be deleted.
- allowListCleanupInterval = 5 * time.Minute
+ allowListCleanupInterval = 5 * time.Minute
+ logTriggerRefreshBatchSize = 32
)
var (
- ErrLogReadFailure = fmt.Errorf("failure reading logs")
- ErrHeadNotAvailable = fmt.Errorf("head not available")
- ErrInitializationFailure = fmt.Errorf("failed to initialize registry")
- ErrContextCancelled = fmt.Errorf("context was cancelled")
- ErrABINotParsable = fmt.Errorf("error parsing abi")
- ActiveUpkeepIDBatchSize int64 = 1000
- FetchUpkeepConfigBatchSize = 10
+ RegistryServiceName = "AutomationRegistry"
+
+ ErrLogReadFailure = fmt.Errorf("failure reading logs")
+ ErrHeadNotAvailable = fmt.Errorf("head not available")
+ ErrInitializationFailure = fmt.Errorf("failed to initialize registry")
+ ErrContextCancelled = fmt.Errorf("context was cancelled")
+ ErrABINotParsable = fmt.Errorf("error parsing abi")
+ ActiveUpkeepIDBatchSize int64 = 1000
// This is the interval at which active upkeep list is fully refreshed from chain
refreshInterval = 15 * time.Minute
// This is the lookback for polling upkeep state event logs from latest block
@@ -73,15 +75,18 @@ func NewEvmRegistry(
lggr logger.Logger,
addr common.Address,
client evm.Chain,
- feedLookupCompatibleABI, keeperRegistryABI abi.ABI,
+ streamsLookupCompatibleABI, keeperRegistryABI abi.ABI,
registry *iregistry21.IKeeperRegistryMaster,
mc *models.MercuryCredentials,
al ActiveUpkeepList,
logEventProvider logprovider.LogEventProvider,
packer encoding.Packer,
blockSub *BlockSubscriber,
+ finalityDepth uint32,
) *EvmRegistry {
return &EvmRegistry{
+ ctx: context.Background(),
+ threadCtrl: utils.NewThreadControl(),
lggr: lggr.Named("EvmRegistry"),
poller: client.LogPoller(),
addr: addr,
@@ -95,12 +100,13 @@ func NewEvmRegistry(
chLog: make(chan logpoller.Log, 1000),
mercury: &MercuryConfig{
cred: mc,
- abi: feedLookupCompatibleABI,
+ abi: streamsLookupCompatibleABI,
allowListCache: cache.New(defaultAllowListExpiration, allowListCleanupInterval),
},
hc: http.DefaultClient,
logEventProvider: logEventProvider,
bs: blockSub,
+ finalityDepth: finalityDepth,
}
}
@@ -122,7 +128,8 @@ type MercuryConfig struct {
}
type EvmRegistry struct {
- sync utils.StartStopOnce
+ utils.StartStopOnce
+ threadCtrl utils.ThreadControl
lggr logger.Logger
poller logpoller.LogPoller
addr common.Address
@@ -132,13 +139,11 @@ type EvmRegistry struct {
abi abi.ABI
packer encoding.Packer
chLog chan logpoller.Log
- reInit *time.Timer
mu sync.RWMutex
logProcessed map[string]bool
active ActiveUpkeepList
lastPollBlock int64
ctx context.Context
- cancel context.CancelFunc
headFunc func(ocr2keepers.BlockKey)
runState int
runError error
@@ -146,6 +151,7 @@ type EvmRegistry struct {
hc HttpClient
bs *BlockSubscriber
logEventProvider logprovider.LogEventProvider
+ finalityDepth uint32
}
func (r *EvmRegistry) Name() string {
@@ -153,109 +159,82 @@ func (r *EvmRegistry) Name() string {
}
func (r *EvmRegistry) Start(ctx context.Context) error {
- return r.sync.StartOnce("AutomationRegistry", func() error {
- r.mu.Lock()
- defer r.mu.Unlock()
- r.ctx, r.cancel = context.WithCancel(context.Background())
- r.reInit = time.NewTimer(refreshInterval)
-
+ return r.StartOnce(RegistryServiceName, func() error {
if err := r.registerEvents(r.chainID, r.addr); err != nil {
return fmt.Errorf("logPoller error while registering automation events: %w", err)
}
- // refresh the active upkeep keys; if the reInit timer returns, do it again
- {
- go func(cx context.Context, tmr *time.Timer, lggr logger.Logger, f func() error) {
- err := f()
- if err != nil {
- lggr.Errorf("failed to initialize upkeeps", err)
- }
+ r.threadCtrl.Go(func(ctx context.Context) {
+ lggr := r.lggr.With("where", "upkeeps_referesh")
+ err := r.refreshActiveUpkeeps()
+ if err != nil {
+ lggr.Errorf("failed to initialize upkeeps", err)
+ }
- for {
- select {
- case <-tmr.C:
- err = f()
- if err != nil {
- lggr.Errorf("failed to re-initialize upkeeps", err)
- }
- tmr.Reset(refreshInterval)
- case <-cx.Done():
- return
+ ticker := time.NewTicker(refreshInterval)
+ defer ticker.Stop()
+
+ for {
+ select {
+ case <-ticker.C:
+ err = r.refreshActiveUpkeeps()
+ if err != nil {
+ lggr.Errorf("failed to refresh upkeeps", err)
}
+ case <-ctx.Done():
+ return
}
- }(r.ctx, r.reInit, r.lggr, r.refreshActiveUpkeeps)
- }
-
- // start polling logs on an interval
- {
- go func(cx context.Context, lggr logger.Logger, f func() error) {
- ticker := time.NewTicker(time.Second)
- for {
- select {
- case <-ticker.C:
- err := f()
- if err != nil {
- lggr.Errorf("failed to poll logs for upkeeps", err)
- }
- case <-cx.Done():
- ticker.Stop()
- return
+ }
+ })
+
+ r.threadCtrl.Go(func(ctx context.Context) {
+ lggr := r.lggr.With("where", "logs_polling")
+ ticker := time.NewTicker(time.Second)
+ defer ticker.Stop()
+
+ for {
+ select {
+ case <-ticker.C:
+ err := r.pollUpkeepStateLogs()
+ if err != nil {
+ lggr.Errorf("failed to poll logs for upkeeps", err)
}
+ case <-ctx.Done():
+ return
}
- }(r.ctx, r.lggr, r.pollUpkeepStateLogs)
- }
-
- // run process to process logs from log channel
- {
- go func(cx context.Context, ch chan logpoller.Log, lggr logger.Logger, f func(logpoller.Log) error) {
- for {
- select {
- case l := <-ch:
- err := f(l)
- if err != nil {
- lggr.Errorf("failed to process log for upkeep", err)
- }
- case <-cx.Done():
- return
+ }
+ })
+
+ r.threadCtrl.Go(func(ctx context.Context) {
+ lggr := r.lggr.With("where", "logs_processing")
+ ch := r.chLog
+
+ for {
+ select {
+ case l := <-ch:
+ err := r.processUpkeepStateLog(l)
+ if err != nil {
+ lggr.Errorf("failed to process log for upkeep", err)
}
+ case <-ctx.Done():
+ return
}
- }(r.ctx, r.chLog, r.lggr, r.processUpkeepStateLog)
- }
+ }
+ })
- r.runState = 1
return nil
})
}
func (r *EvmRegistry) Close() error {
- return r.sync.StopOnce("AutomationRegistry", func() error {
- r.mu.Lock()
- defer r.mu.Unlock()
- r.cancel()
- r.runState = 0
- r.runError = nil
+ return r.StopOnce(RegistryServiceName, func() error {
+ r.threadCtrl.Close()
return nil
})
}
-func (r *EvmRegistry) Ready() error {
- r.mu.RLock()
- defer r.mu.RUnlock()
-
- if r.runState == 1 {
- return nil
- }
- return r.sync.Ready()
-}
-
func (r *EvmRegistry) HealthReport() map[string]error {
- r.mu.RLock()
- defer r.mu.RUnlock()
-
- if r.runState > 1 {
- r.sync.SvcErrBuffer.Append(fmt.Errorf("failed run state: %w", r.runError))
- }
- return map[string]error{r.Name(): r.sync.Healthy()}
+ return map[string]error{RegistryServiceName: r.Healthy()}
}
func (r *EvmRegistry) refreshActiveUpkeeps() error {
@@ -271,18 +250,12 @@ func (r *EvmRegistry) refreshActiveUpkeeps() error {
}
r.active.Reset(ids...)
- return r.refreshLogTriggerUpkeeps(ids)
-}
-
-// refreshLogTriggerUpkeeps refreshes the active upkeep ids for log trigger upkeeps
-//
-// TODO: check for updated config for log trigger upkeeps and update it, currently we ignore them.
-func (r *EvmRegistry) refreshLogTriggerUpkeeps(ids []*big.Int) error {
- logTriggerIDs := make([]*big.Int, 0)
+ var logTriggerIDs []*big.Int
for _, id := range ids {
uid := &ocr2keepers.UpkeepIdentifier{}
if ok := uid.FromBigInt(id); !ok {
r.lggr.Warnf("failed to parse upkeep id %s", id.String())
+ continue
}
switch core.GetUpkeepType(*uid) {
case ocr2keepers.LogTrigger:
@@ -290,15 +263,97 @@ func (r *EvmRegistry) refreshLogTriggerUpkeeps(ids []*big.Int) error {
default:
}
}
- newUpkeeps, err := r.logEventProvider.RefreshActiveUpkeeps(logTriggerIDs...)
+
+ _, err = r.logEventProvider.RefreshActiveUpkeeps(logTriggerIDs...)
if err != nil {
return fmt.Errorf("failed to refresh active upkeep ids in log event provider: %w", err)
}
+
+ // Try to refersh log trigger config for all log upkeeps
+ return r.refreshLogTriggerUpkeeps(logTriggerIDs)
+}
+
+// refreshLogTriggerUpkeeps refreshes the active upkeep ids for log trigger upkeeps
+func (r *EvmRegistry) refreshLogTriggerUpkeeps(ids []*big.Int) error {
+ var err error
+ for i := 0; i < len(ids); i += logTriggerRefreshBatchSize {
+ end := i + logTriggerRefreshBatchSize
+ if end > len(ids) {
+ end = len(ids)
+ }
+ idBatch := ids[i:end]
+
+ if batchErr := r.refreshLogTriggerUpkeepsBatch(idBatch); batchErr != nil {
+ multierr.AppendInto(&err, batchErr)
+ }
+
+ time.Sleep(500 * time.Millisecond)
+ }
+
+ return err
+}
+
+func (r *EvmRegistry) refreshLogTriggerUpkeepsBatch(logTriggerIDs []*big.Int) error {
+ var logTriggerHashes []common.Hash
+ for _, id := range logTriggerIDs {
+ logTriggerHashes = append(logTriggerHashes, common.BigToHash(id))
+ }
+
+ unpausedLogs, err := r.poller.IndexedLogs(iregistry21.IKeeperRegistryMasterUpkeepUnpaused{}.Topic(), r.addr, 1, logTriggerHashes, int(r.finalityDepth), pg.WithParentCtx(r.ctx))
+ if err != nil {
+ return err
+ }
+ configSetLogs, err := r.poller.IndexedLogs(iregistry21.IKeeperRegistryMasterUpkeepTriggerConfigSet{}.Topic(), r.addr, 1, logTriggerHashes, int(r.finalityDepth), pg.WithParentCtx(r.ctx))
+ if err != nil {
+ return err
+ }
+
+ logs := append(unpausedLogs, configSetLogs...)
+
+ configSetBlockNumbers := map[string]uint64{}
+ unpausedBlockNumbers := map[string]uint64{}
+ perUpkeepConfig := map[string][]byte{}
+
+ for _, log := range logs {
+ rawLog := log.ToGethLog()
+ abilog, err := r.registry.ParseLog(rawLog)
+ if err != nil {
+ return err
+ }
+ switch l := abilog.(type) {
+ case *iregistry21.IKeeperRegistryMasterUpkeepTriggerConfigSet:
+ if rawLog.BlockNumber > configSetBlockNumbers[l.Id.String()] {
+ configSetBlockNumbers[l.Id.String()] = rawLog.BlockNumber
+ perUpkeepConfig[l.Id.String()] = l.TriggerConfig
+ }
+ case *iregistry21.IKeeperRegistryMasterUpkeepUnpaused:
+ if rawLog.BlockNumber > unpausedBlockNumbers[l.Id.String()] {
+ unpausedBlockNumbers[l.Id.String()] = rawLog.BlockNumber
+ }
+ }
+ }
+
var merr error
- for _, id := range newUpkeeps {
- // TODO: find the ConfigSet/UpkeepUnpaused events for this upkeep and pass cfg and block number
- // block number should be taken from UpkeepUnpaused if it's block is higher than ConfigSet
- if err := r.updateTriggerConfig(id, nil, 0); err != nil {
+ for _, id := range logTriggerIDs {
+ logBlock, ok := configSetBlockNumbers[id.String()]
+ if !ok {
+ r.lggr.Warnf("unable to find finalized config set block number for %s, using 0 as config start block", id.String())
+ // Use zero as config update block so it can be updated if an actual event is found later
+ logBlock = 0
+ }
+
+ config, ok := perUpkeepConfig[id.String()]
+ if !ok {
+ r.lggr.Warnf("unable to find per finalized log config for %s, will fetch latest config from chain", id.String())
+ // Set it to empty bytes so that latest config is fetched within r.updateTriggerConfig
+ config = []byte{}
+ }
+
+ // In case an upkeep was paused then unpaused after a config set event, start the config from the unpaused block number
+ if unpausedBlockNumbers[id.String()] > logBlock {
+ logBlock = unpausedBlockNumbers[id.String()]
+ }
+ if err := r.updateTriggerConfig(id, config, logBlock); err != nil {
merr = goerrors.Join(merr, fmt.Errorf("failed to update trigger config for upkeep id %s: %w", id.String(), err))
}
}
@@ -407,9 +462,9 @@ func RegistryUpkeepFilterName(addr common.Address) string {
return logpoller.FilterName("KeeperRegistry Events", addr.String())
}
-func (r *EvmRegistry) registerEvents(chainID uint64, addr common.Address) error {
- // Add log filters for the log poller so that it can poll and find the logs that
- // we need
+// registerEvents registers upkeep state events from keeper registry on log poller
+func (r *EvmRegistry) registerEvents(_ uint64, addr common.Address) error {
+ // Add log filters for the log poller so that it can poll and find the logs that we need
return r.poller.RegisterFilter(logpoller.Filter{
Name: RegistryUpkeepFilterName(addr),
EventSigs: upkeepStateEvents,
@@ -417,7 +472,7 @@ func (r *EvmRegistry) registerEvents(chainID uint64, addr common.Address) error
})
}
-// Removes an upkeepID from active list and unregisters the log filter for log upkeeps
+// removeFromActive removes an upkeepID from active list and unregisters the log filter for log upkeeps
func (r *EvmRegistry) removeFromActive(id *big.Int) {
r.active.Remove(id)
@@ -488,6 +543,7 @@ func (r *EvmRegistry) getLatestIDsFromContract(ctx context.Context) ([]*big.Int,
return ids, nil
}
+// updateTriggerConfig updates the trigger config for an upkeep. it will re-register a filter for this upkeep.
func (r *EvmRegistry) updateTriggerConfig(id *big.Int, cfg []byte, logBlock uint64) error {
uid := &ocr2keepers.UpkeepIdentifier{}
uid.FromBigInt(id)
@@ -502,9 +558,11 @@ func (r *EvmRegistry) updateTriggerConfig(id *big.Int, cfg []byte, logBlock uint
}
parsed, err := r.packer.UnpackLogTriggerConfig(cfg)
if err != nil {
- return errors.Wrap(err, "failed to unpack log upkeep config")
+ // Upkeep has been setup with improper config. Log a warning and ignore the upkeep.
+ r.lggr.Warnw("failed to unpack log upkeep config", "upkeepID", id.String(), "err", err)
+ return nil
}
- if err := r.logEventProvider.RegisterFilter(logprovider.FilterOptions{
+ if err := r.logEventProvider.RegisterFilter(r.ctx, logprovider.FilterOptions{
TriggerConfig: logprovider.LogTriggerConfig(parsed),
UpkeepID: id,
UpdateBlock: logBlock,
@@ -517,7 +575,7 @@ func (r *EvmRegistry) updateTriggerConfig(id *big.Int, cfg []byte, logBlock uint
return nil
}
-// updateTriggerConfig gets invoked upon changes in the trigger config of an upkeep.
+// fetchTriggerConfig fetches trigger config in raw bytes for an upkeep.
func (r *EvmRegistry) fetchTriggerConfig(id *big.Int) ([]byte, error) {
opts := r.buildCallOpts(r.ctx, nil)
cfg, err := r.registry.GetUpkeepTriggerConfig(opts, id)
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 07462208113..d3530994702 100644
--- a/core/services/ocr2/plugins/ocr2keeper/evm21/registry_check_pipeline.go
+++ b/core/services/ocr2/plugins/ocr2keeper/evm21/registry_check_pipeline.go
@@ -16,9 +16,9 @@ import (
)
const (
- // validCheckBlockRange decides the max distance between the check block and the current block
- // allowed in checkPipeline
- validCheckBlockRange = 128
+ // checkBlockTooOldRange is the number of blocks that can be behind the latest block before
+ // we return a CheckBlockTooOld error
+ checkBlockTooOldRange = 128
)
type checkResult struct {
@@ -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)
@@ -64,7 +67,7 @@ func (r *EvmRegistry) doCheck(ctx context.Context, keys []ocr2keepers.UpkeepPayl
return
}
- upkeepResults = r.feedLookup(ctx, upkeepResults)
+ upkeepResults = r.streamsLookup(ctx, upkeepResults)
upkeepResults, err = r.simulatePerformUpkeeps(ctx, upkeepResults)
if err != nil {
@@ -97,40 +100,23 @@ func (r *EvmRegistry) getBlockHash(blockNumber *big.Int) (common.Hash, error) {
return blocks[0].BlockHash, nil
}
-func (r *EvmRegistry) getTxBlock(txHash common.Hash) (*big.Int, common.Hash, error) {
- // TODO: do manual eth_getTransactionReceipt call to get block number and hash
- txr, err := r.client.TransactionReceipt(r.ctx, txHash)
- if err != nil {
- return nil, common.Hash{}, err
- }
-
- return txr.BlockNumber, txr.BlockHash, nil
-}
-
// verifyCheckBlock checks that the check block and hash are valid, returns the pipeline execution state and retryable
-func (r *EvmRegistry) verifyCheckBlock(ctx context.Context, checkBlock, upkeepId *big.Int, checkHash common.Hash) (state encoding.PipelineExecutionState, retryable bool) {
- // verify check block number is not too old
- latestBlock := r.bs.latestBlock.Load()
- if int64(latestBlock.Number)-checkBlock.Int64() > validCheckBlockRange {
- r.lggr.Warnf("latest block is %d, check block number %s is too old for upkeepId %s", r.bs.latestBlock.Load(), checkBlock, upkeepId)
- return encoding.CheckBlockTooOld, false
- }
- r.lggr.Warnf("latestBlock=%d checkBlock=%d", r.bs.latestBlock.Load(), checkBlock.Int64())
-
- var h string
- var ok bool
+func (r *EvmRegistry) verifyCheckBlock(_ context.Context, checkBlock, upkeepId *big.Int, checkHash common.Hash) (state encoding.PipelineExecutionState, retryable bool) {
// verify check block number and hash are valid
- h, ok = r.bs.queryBlocksMap(checkBlock.Int64())
- if !ok {
- r.lggr.Warnf("check block %s does not exist in block subscriber for upkeepId %s, querying eth client", checkBlock, upkeepId)
- b, err := r.getBlockHash(checkBlock)
- if err != nil {
- r.lggr.Warnf("failed to query block %s: %s", checkBlock, err.Error())
- return encoding.RpcFlakyFailure, true
- }
- h = b.Hex()
+ h, ok := r.bs.queryBlocksMap(checkBlock.Int64())
+ // if this block number/hash combo exists in block subscriber, this check block and hash still exist on chain and are valid
+ // the block hash in block subscriber might be slightly outdated, if it doesn't match then we fetch the latest from RPC.
+ if ok && h == checkHash.Hex() {
+ r.lggr.Debugf("check block hash %s exists on chain at block number %d for upkeepId %s", checkHash.Hex(), checkBlock, upkeepId)
+ return encoding.NoPipelineError, false
+ }
+ r.lggr.Warnf("check block %s does not exist in block subscriber or hash does not match for upkeepId %s. this may be caused by block subscriber outdated due to re-org, querying eth client to confirm", checkBlock, upkeepId)
+ b, err := r.getBlockHash(checkBlock)
+ if err != nil {
+ r.lggr.Warnf("failed to query block %s: %s", checkBlock, err.Error())
+ return encoding.RpcFlakyFailure, true
}
- if checkHash.Hex() != h {
+ if checkHash.Hex() != b.Hex() {
r.lggr.Warnf("check block %s hash do not match. %s from block subscriber vs %s from trigger for upkeepId %s", checkBlock, h, checkHash.Hex(), upkeepId)
return encoding.CheckBlockInvalid, false
}
@@ -141,19 +127,30 @@ func (r *EvmRegistry) verifyCheckBlock(ctx 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)
+ // if this block number/hash combo exists in block subscriber, this block and tx still exists on chain and is valid
+ // the block hash in block subscriber might be slightly outdated, if it doesn't match then we fetch the latest from RPC.
if ok && h == logBlockHash.Hex() {
- r.lggr.Debugf("tx hash %s exists on chain at block number %d for upkeepId %s", hexutil.Encode(p.Trigger.LogTriggerExtension.TxHash[:]), logBlockNumber, upkeepId)
+ r.lggr.Debugf("tx hash %s exists on chain at block number %d, block hash %s for upkeepId %s", hexutil.Encode(p.Trigger.LogTriggerExtension.TxHash[:]), logBlockHash.Hex(), logBlockNumber, upkeepId)
return encoding.UpkeepFailureReasonNone, encoding.NoPipelineError, false
}
- r.lggr.Debugf("log block %d does not exist in block subscriber for upkeepId %s, querying eth client", logBlockNumber, upkeepId)
+ // if this block does not exist in the block subscriber, the block which this log lived on was probably re-orged
+ // hence, check eth client for this log's tx hash to confirm
+ r.lggr.Debugf("log block %d does not exist in block subscriber or block hash does not match for upkeepId %s. this may be caused by block subscriber outdated due to re-org, querying eth client to confirm", logBlockNumber, upkeepId)
} else {
r.lggr.Debugf("log block not provided, querying eth client for tx hash %s for upkeepId %s", hexutil.Encode(p.Trigger.LogTriggerExtension.TxHash[:]), upkeepId)
}
// query eth client as a fallback
- bn, _, err := r.getTxBlock(p.Trigger.LogTriggerExtension.TxHash)
+ bn, bh, err := core.GetTxBlock(r.ctx, r.client, p.Trigger.LogTriggerExtension.TxHash)
if err != nil {
// primitive way of checking errors
if strings.Contains(err.Error(), "missing required field") || strings.Contains(err.Error(), "not found") {
@@ -166,6 +163,10 @@ func (r *EvmRegistry) verifyLogExists(upkeepId *big.Int, p ocr2keepers.UpkeepPay
r.lggr.Warnf("tx hash %s does not exist on chain for upkeepId %s.", hexutil.Encode(p.Trigger.LogTriggerExtension.TxHash[:]), upkeepId)
return encoding.UpkeepFailureReasonTxHashNoLongerExists, encoding.NoPipelineError, false
}
+ if bh.Hex() != logBlockHash.Hex() {
+ r.lggr.Warnf("tx hash %s reorged from expected blockhash %s to %s for upkeepId %s.", hexutil.Encode(p.Trigger.LogTriggerExtension.TxHash[:]), logBlockHash.Hex(), bh.Hex(), upkeepId)
+ return encoding.UpkeepFailureReasonTxHashReorged, encoding.NoPipelineError, false
+ }
r.lggr.Debugf("tx hash %s exists on chain for upkeepId %s", hexutil.Encode(p.Trigger.LogTriggerExtension.TxHash[:]), upkeepId)
return encoding.UpkeepFailureReasonNone, encoding.NoPipelineError, false
}
@@ -251,10 +252,25 @@ func (r *EvmRegistry) checkUpkeeps(ctx context.Context, payloads []ocr2keepers.U
for i, req := range checkReqs {
index := indices[i]
if req.Error != nil {
- // individual upkeep failed in a batch call, retryable
- r.lggr.Warnf("error encountered in check result for upkeepId %s: %s", results[index].UpkeepID.String(), req.Error)
- results[index].Retryable = true
- results[index].PipelineExecutionState = uint8(encoding.RpcFlakyFailure)
+ 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 && 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(), latestBlockNumber, req.Error)
+ results[index].Retryable = false
+ results[index].PipelineExecutionState = uint8(encoding.CheckBlockTooOld)
+ } else {
+ // individual upkeep failed in a batch call, likely a flay RPC error, consider retryable
+ r.lggr.Warnf("rpc error encountered in check result for upkeepId %s: %s", results[index].UpkeepID.String(), req.Error)
+ results[index].Retryable = true
+ results[index].PipelineExecutionState = uint8(encoding.RpcFlakyFailure)
+ }
} else {
var err error
results[index], err = r.packer.UnpackCheckResult(payloads[index], *checkResults[i])
@@ -341,6 +357,7 @@ func (r *EvmRegistry) simulatePerformUpkeeps(ctx context.Context, checkResults [
if !simulatePerformSuccess {
r.lggr.Warnf("upkeepId %s is not eligible after simulation of perform", checkResults[idx].UpkeepID.String())
checkResults[performToKeyIdx[i]].Eligible = false
+ checkResults[performToKeyIdx[i]].IneligibilityReason = uint8(encoding.UpkeepFailureReasonSimulationFailed)
}
}
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 88016f07f15..ee213643194 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
@@ -8,7 +8,6 @@ import (
"testing"
"github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/rpc"
ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg/v3/types"
@@ -17,6 +16,7 @@ import (
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/types"
"github.com/smartcontractkit/chainlink/v2/core/logger"
"github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21/core"
"github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21/encoding"
@@ -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
@@ -85,23 +85,10 @@ func TestRegistry_VerifyCheckBlock(t *testing.T) {
retryable bool
makeEthCall bool
}{
- {
- name: "check block number too told",
- checkBlock: big.NewInt(500),
- latestBlock: ocr2keepers.BlockKey{Number: 800},
- upkeepId: big.NewInt(12345),
- checkHash: common.HexToHash("0x5bff03de234fe771ac0d685f9ee0fb0b757ea02ec9e6f10e8e2ee806db1b6b83"),
- payload: ocr2keepers.UpkeepPayload{
- UpkeepID: upkeepId,
- Trigger: ocr2keepers.NewTrigger(500, common.HexToHash("0x5bff03de234fe771ac0d685f9ee0fb0b757ea02ec9e6f10e8e2ee806db1b6b83")),
- WorkID: "work",
- },
- state: encoding.CheckBlockTooOld,
- },
{
name: "for an invalid check block number, if hash does not match the check hash, return CheckBlockInvalid",
checkBlock: big.NewInt(500),
- latestBlock: ocr2keepers.BlockKey{Number: 560},
+ latestBlock: &ocr2keepers.BlockKey{Number: 560},
upkeepId: big.NewInt(12345),
checkHash: common.HexToHash("0x5bff03de234fe771ac0d685f9ee0fb0b757ea02ec9e6f10e8e2ee806db1b6b83"),
payload: ocr2keepers.UpkeepPayload{
@@ -125,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{
@@ -149,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{
@@ -157,6 +144,15 @@ func TestRegistry_VerifyCheckBlock(t *testing.T) {
Trigger: ocr2keepers.NewTrigger(500, common.HexToHash("0x5bff03de234fe771ac0d685f9ee0fb0b757ea02ec9e6f10e8e2ee806db1b6b83")),
WorkID: "work",
},
+ poller: &mockLogPoller{
+ GetBlocksRangeFn: func(ctx context.Context, numbers []uint64, qopts ...pg.QOpt) ([]logpoller.LogPollerBlock, error) {
+ return []logpoller.LogPollerBlock{
+ {
+ BlockHash: common.HexToHash("0xcba5cf9e2bb32373c76015384e1098912d9510a72481c78057fcb088209167de"),
+ },
+ }, nil
+ },
+ },
blocks: map[int64]string{
500: "0xa518faeadcc423338c62572da84dda35fe44b34f521ce88f6081b703b250cca4",
},
@@ -165,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{
@@ -186,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,
@@ -208,12 +204,17 @@ func TestRegistry_VerifyCheckBlock(t *testing.T) {
type mockLogPoller struct {
logpoller.LogPoller
GetBlocksRangeFn func(ctx context.Context, numbers []uint64, qopts ...pg.QOpt) ([]logpoller.LogPollerBlock, error)
+ IndexedLogsFn func(eventSig common.Hash, address common.Address, topicIndex int, topicValues []common.Hash, confs int, qopts ...pg.QOpt) ([]logpoller.Log, error)
}
func (p *mockLogPoller) GetBlocksRange(ctx context.Context, numbers []uint64, qopts ...pg.QOpt) ([]logpoller.LogPollerBlock, error) {
return p.GetBlocksRangeFn(ctx, numbers, qopts...)
}
+func (p *mockLogPoller) IndexedLogs(eventSig common.Hash, address common.Address, topicIndex int, topicValues []common.Hash, confs int, qopts ...pg.QOpt) ([]logpoller.Log, error) {
+ return p.IndexedLogsFn(eventSig, address, topicIndex, topicValues, confs, qopts...)
+}
+
func TestRegistry_VerifyLogExists(t *testing.T) {
lggr := logger.TestLogger(t)
upkeepId := ocr2keepers.UpkeepIdentifier{}
@@ -272,7 +273,27 @@ func TestRegistry_VerifyLogExists(t *testing.T) {
blocks: map[int64]string{
500: "0xb2173b4b75f23f56b7b2b6b2cc5fa9ed1079b9d1655b12b40fdb4dbf59006419",
},
- receipt: &types.Receipt{},
+ receipt: &types.Receipt{Status: 0},
+ },
+ {
+ name: "eth client returns a matching block but different hash",
+ upkeepId: big.NewInt(12345),
+ payload: ocr2keepers.UpkeepPayload{
+ UpkeepID: upkeepId,
+ Trigger: ocr2keepers.NewLogTrigger(550, common.HexToHash("0x5bff03de234fe771ac0d685f9ee0fb0b757ea02ec9e6f10e8e2ee806db1b6b83"), extension1),
+ WorkID: "work",
+ },
+ reason: encoding.UpkeepFailureReasonTxHashReorged,
+ retryable: false,
+ blocks: map[int64]string{
+ 500: "0xa518faeadcc423338c62572da84dda35fe44b34f521ce88f6081b703b250cca4",
+ },
+ makeEthCall: true,
+ receipt: &types.Receipt{
+ Status: 1,
+ BlockNumber: big.NewInt(550),
+ BlockHash: common.HexToHash("0x5bff03de234fe771ac0d685f9ee0fb0b757ea02ec9e6f10e8e2ee806db1b6b83"),
+ },
},
{
name: "eth client returns a matching block",
@@ -289,8 +310,9 @@ func TestRegistry_VerifyLogExists(t *testing.T) {
},
makeEthCall: true,
receipt: &types.Receipt{
+ Status: 1,
BlockNumber: big.NewInt(550),
- BlockHash: common.HexToHash("0x5bff03de234fe771ac0d685f9ee0fb0b757ea02ec9e6f10e8e2ee806db1b6b83"),
+ BlockHash: common.HexToHash("0x3df0e926f3e21ec1195ffe007a2899214905eb02e768aa89ce0b94accd7f3d71"),
},
},
{
@@ -322,8 +344,16 @@ func TestRegistry_VerifyLogExists(t *testing.T) {
if tc.makeEthCall {
client := new(evmClientMocks.Client)
- client.On("TransactionReceipt", mock.Anything, common.HexToHash("0xc8def8abdcf3a4eaaf6cc13bff3e4e2a7168d86ea41dbbf97451235aa76c3651")).
- Return(tc.receipt, tc.ethCallErr)
+ client.On("CallContext", mock.Anything, mock.Anything, "eth_getTransactionReceipt", common.BytesToHash(tc.payload.Trigger.LogTriggerExtension.TxHash[:])).
+ Return(tc.ethCallErr).Run(func(args mock.Arguments) {
+ if tc.receipt != nil {
+ res := args.Get(1).(*types.Receipt)
+ res.Status = tc.receipt.Status
+ res.TxHash = tc.receipt.TxHash
+ res.BlockNumber = tc.receipt.BlockNumber
+ res.BlockHash = tc.receipt.BlockHash
+ }
+ })
e.client = client
}
@@ -354,7 +384,7 @@ func TestRegistry_CheckUpkeeps(t *testing.T) {
BlockNumber: 550,
}
- trigger0 := ocr2keepers.NewTrigger(150, common.HexToHash("0x1c77db0abe32327cf3ea9de2aadf79876f9e6b6dfcee9d4719a8a2dc8ca289d0"))
+ trigger0 := ocr2keepers.NewTrigger(575, common.HexToHash("0x1c77db0abe32327cf3ea9de2aadf79876f9e6b6dfcee9d4719a8a2dc8ca289d0"))
trigger1 := ocr2keepers.NewLogTrigger(560, common.HexToHash("0x9840e5b709bfccf6a1b44f34c884bc39403f57923f3f5ead6243cc090546b857"), extension1)
trigger2 := ocr2keepers.NewLogTrigger(570, common.HexToHash("0x1222d75217e2dd461cc77e4091c37abe76277430d97f1963a822b4e94ebb83fc"), extension2)
@@ -362,11 +392,12 @@ 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
receipts map[string]*types.Receipt
+ poller logpoller.LogPoller
ethCallErrors map[string]error
}{
{
@@ -394,11 +425,12 @@ func TestRegistry_CheckUpkeeps(t *testing.T) {
550: "0x9840e5b709bfccf6a1b44f34c884bc39403f57923f3f5ead6243cc090546b857",
560: "0x9840e5b709bfccf6a1b44f34c884bc39403f57923f3f5ead6243cc090546b857",
570: "0x1222d75217e2dd461cc77e4091c37abe76277430d97f1963a822b4e94ebb83fc",
+ 575: "0x9840e5b709bfccf6a1b44f34c884bc39403f57923f3f5ead6243cc090546b857",
},
- latestBlock: ocr2keepers.BlockKey{Number: 580},
+ latestBlock: &ocr2keepers.BlockKey{Number: 580},
results: []ocr2keepers.CheckResult{
{
- PipelineExecutionState: uint8(encoding.CheckBlockTooOld),
+ PipelineExecutionState: uint8(encoding.CheckBlockInvalid),
Retryable: false,
Eligible: false,
IneligibilityReason: 0,
@@ -440,11 +472,15 @@ func TestRegistry_CheckUpkeeps(t *testing.T) {
ethCalls: map[string]bool{
uid1.String(): true,
},
- receipts: map[string]*types.Receipt{
- //uid1.String(): {
- // BlockNumber: big.NewInt(550),
- // BlockHash: common.HexToHash("0x5bff03de234fe771ac0d685f9ee0fb0b757ea02ec9e6f10e8e2ee806db1b6b83"),
- //},
+ receipts: map[string]*types.Receipt{},
+ poller: &mockLogPoller{
+ GetBlocksRangeFn: func(ctx context.Context, numbers []uint64, qopts ...pg.QOpt) ([]logpoller.LogPollerBlock, error) {
+ return []logpoller.LogPollerBlock{
+ {
+ BlockHash: common.HexToHash("0xcba5cf9e2bb32373c76015384e1098912d9510a72481c78057fcb088209167de"),
+ },
+ }, nil
+ },
},
ethCallErrors: map[string]error{
uid1.String(): fmt.Errorf("error"),
@@ -458,17 +494,27 @@ 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,
+ lggr: lggr,
+ bs: bs,
+ poller: tc.poller,
}
client := new(evmClientMocks.Client)
for _, i := range tc.inputs {
uid := i.UpkeepID.String()
if tc.ethCalls[uid] {
- client.On("TransactionReceipt", mock.Anything, common.HexToHash("0xc8def8abdcf3a4eaaf6cc13bff3e4e2a7168d86ea41dbbf97451235aa76c3651")).
- Return(tc.receipts[uid], tc.ethCallErrors[uid])
+ client.On("CallContext", mock.Anything, mock.Anything, "eth_getTransactionReceipt", common.HexToHash("0xc8def8abdcf3a4eaaf6cc13bff3e4e2a7168d86ea41dbbf97451235aa76c3651")).
+ Return(tc.ethCallErrors[uid]).Run(func(args mock.Arguments) {
+ receipt := tc.receipts[uid]
+ if receipt != nil {
+ res := args.Get(1).(*types.Receipt)
+ res.Status = receipt.Status
+ res.TxHash = receipt.TxHash
+ res.BlockNumber = receipt.BlockNumber
+ res.BlockHash = receipt.BlockHash
+ }
+ })
}
}
e.client = client
diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/registry_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/registry_test.go
index e17145ff81e..b6b123de485 100644
--- a/core/services/ocr2/plugins/ocr2keeper/evm21/registry_test.go
+++ b/core/services/ocr2/plugins/ocr2keeper/evm21/registry_test.go
@@ -1,18 +1,31 @@
package evm
import (
+ "context"
+ "errors"
"fmt"
"math/big"
"testing"
"time"
+ "github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
-
+ coreTypes "github.com/ethereum/go-ethereum/core/types"
+ "github.com/smartcontractkit/ocr2keepers/pkg/v3/types"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
+ types3 "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker/types"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller/mocks"
+ "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated"
+ "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/automation_utils_2_1"
+ iregistry21 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/i_keeper_registry_master_wrapper_2_1"
+ "github.com/smartcontractkit/chainlink/v2/core/logger"
+ "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21/core"
+ "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21/encoding"
+ "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider"
+ "github.com/smartcontractkit/chainlink/v2/core/services/pg"
"github.com/smartcontractkit/chainlink/v2/core/utils"
)
@@ -182,3 +195,369 @@ func TestPollLogs(t *testing.T) {
})
}
}
+
+func TestRegistry_refreshLogTriggerUpkeeps(t *testing.T) {
+ for _, tc := range []struct {
+ name string
+ ids []*big.Int
+ logEventProvider logprovider.LogEventProvider
+ poller logpoller.LogPoller
+ registry Registry
+ packer encoding.Packer
+ expectsErr bool
+ wantErr error
+ }{
+ {
+ name: "an error is returned when fetching indexed logs for IKeeperRegistryMasterUpkeepUnpaused errors",
+ ids: []*big.Int{
+ core.GenUpkeepID(types.LogTrigger, "abc").BigInt(),
+ },
+ logEventProvider: &mockLogEventProvider{
+ RefreshActiveUpkeepsFn: func(ids ...*big.Int) ([]*big.Int, error) {
+ // of the ids specified in the test, only one is a valid log trigger upkeep
+ assert.Equal(t, 1, len(ids))
+ return ids, nil
+ },
+ },
+ poller: &mockLogPoller{
+ IndexedLogsFn: func(eventSig common.Hash, address common.Address, topicIndex int, topicValues []common.Hash, confs int, qopts ...pg.QOpt) ([]logpoller.Log, error) {
+ if eventSig == (iregistry21.IKeeperRegistryMasterUpkeepUnpaused{}.Topic()) {
+ return nil, errors.New("indexed logs boom")
+ }
+ return nil, nil
+ },
+ },
+ expectsErr: true,
+ wantErr: errors.New("indexed logs boom"),
+ },
+ {
+ name: "an error is returned when fetching indexed logs for IKeeperRegistryMasterUpkeepTriggerConfigSet errors",
+ ids: []*big.Int{
+ core.GenUpkeepID(types.LogTrigger, "abc").BigInt(),
+ core.GenUpkeepID(types.ConditionTrigger, "abc").BigInt(),
+ big.NewInt(-1),
+ },
+ logEventProvider: &mockLogEventProvider{
+ RefreshActiveUpkeepsFn: func(ids ...*big.Int) ([]*big.Int, error) {
+ // of the ids specified in the test, only one is a valid log trigger upkeep
+ assert.Equal(t, 1, len(ids))
+ return ids, nil
+ },
+ },
+ poller: &mockLogPoller{
+ IndexedLogsFn: func(eventSig common.Hash, address common.Address, topicIndex int, topicValues []common.Hash, confs int, qopts ...pg.QOpt) ([]logpoller.Log, error) {
+ if eventSig == (iregistry21.IKeeperRegistryMasterUpkeepTriggerConfigSet{}.Topic()) {
+ return nil, errors.New("indexed logs boom")
+ }
+ return nil, nil
+ },
+ },
+ expectsErr: true,
+ wantErr: errors.New("indexed logs boom"),
+ },
+ {
+ name: "an error is returned when parsing the logs using the registry errors",
+ ids: []*big.Int{
+ core.GenUpkeepID(types.LogTrigger, "abc").BigInt(),
+ core.GenUpkeepID(types.ConditionTrigger, "abc").BigInt(),
+ big.NewInt(-1),
+ },
+ logEventProvider: &mockLogEventProvider{
+ RefreshActiveUpkeepsFn: func(ids ...*big.Int) ([]*big.Int, error) {
+ // of the ids specified in the test, only one is a valid log trigger upkeep
+ assert.Equal(t, 1, len(ids))
+ return ids, nil
+ },
+ },
+ poller: &mockLogPoller{
+ IndexedLogsFn: func(eventSig common.Hash, address common.Address, topicIndex int, topicValues []common.Hash, confs int, qopts ...pg.QOpt) ([]logpoller.Log, error) {
+ return []logpoller.Log{
+ {},
+ }, nil
+ },
+ },
+ registry: &mockRegistry{
+ ParseLogFn: func(log coreTypes.Log) (generated.AbigenLog, error) {
+ return nil, errors.New("parse log boom")
+ },
+ },
+ expectsErr: true,
+ wantErr: errors.New("parse log boom"),
+ },
+ {
+ name: "an error is returned when registering the filter errors",
+ ids: []*big.Int{
+ core.GenUpkeepID(types.LogTrigger, "abc").BigInt(),
+ core.GenUpkeepID(types.ConditionTrigger, "abc").BigInt(),
+ big.NewInt(-1),
+ },
+ logEventProvider: &mockLogEventProvider{
+ RefreshActiveUpkeepsFn: func(ids ...*big.Int) ([]*big.Int, error) {
+ // of the ids specified in the test, only one is a valid log trigger upkeep
+ assert.Equal(t, 1, len(ids))
+ return ids, nil
+ },
+ RegisterFilterFn: func(opts logprovider.FilterOptions) error {
+ return errors.New("register filter boom")
+ },
+ },
+ poller: &mockLogPoller{
+ IndexedLogsFn: func(eventSig common.Hash, address common.Address, topicIndex int, topicValues []common.Hash, confs int, qopts ...pg.QOpt) ([]logpoller.Log, error) {
+ return []logpoller.Log{
+ {
+ BlockNumber: 1,
+ },
+ {
+ BlockNumber: 2,
+ },
+ }, nil
+ },
+ },
+ registry: &mockRegistry{
+ ParseLogFn: func(log coreTypes.Log) (generated.AbigenLog, error) {
+ if log.BlockNumber == 1 {
+ return &iregistry21.IKeeperRegistryMasterUpkeepTriggerConfigSet{
+ TriggerConfig: []byte{1, 2, 3},
+ Id: core.GenUpkeepID(types.LogTrigger, "abc").BigInt(),
+ }, nil
+ }
+ return &iregistry21.IKeeperRegistryMasterUpkeepUnpaused{
+ Id: core.GenUpkeepID(types.LogTrigger, "abc").BigInt(),
+ }, nil
+ },
+ GetUpkeepTriggerConfigFn: func(opts *bind.CallOpts, upkeepId *big.Int) ([]byte, error) {
+ return nil, nil
+ },
+ },
+ packer: &mockPacker{
+ UnpackLogTriggerConfigFn: func(raw []byte) (automation_utils_2_1.LogTriggerConfig, error) {
+ return automation_utils_2_1.LogTriggerConfig{}, nil
+ },
+ },
+ expectsErr: true,
+ wantErr: errors.New("failed to update trigger config for upkeep id 452312848583266388373324160190187140521564213162920931037143039228013182976: failed to register log filter: register filter boom"),
+ },
+ {
+ name: "log trigger upkeeps are refreshed without error",
+ ids: []*big.Int{
+ core.GenUpkeepID(types.LogTrigger, "abc").BigInt(),
+ core.GenUpkeepID(types.LogTrigger, "def").BigInt(),
+ core.GenUpkeepID(types.ConditionTrigger, "abc").BigInt(),
+ big.NewInt(-1),
+ },
+ logEventProvider: &mockLogEventProvider{
+ RefreshActiveUpkeepsFn: func(ids ...*big.Int) ([]*big.Int, error) {
+ // of the ids specified in the test, only two are a valid log trigger upkeep
+ assert.Equal(t, 2, len(ids))
+ return ids, nil
+ },
+ RegisterFilterFn: func(opts logprovider.FilterOptions) error {
+ return nil
+ },
+ },
+ poller: &mockLogPoller{
+ IndexedLogsFn: func(eventSig common.Hash, address common.Address, topicIndex int, topicValues []common.Hash, confs int, qopts ...pg.QOpt) ([]logpoller.Log, error) {
+ return []logpoller.Log{
+ {
+ BlockNumber: 2,
+ },
+ {
+ BlockNumber: 1,
+ },
+ }, nil
+ },
+ },
+ registry: &mockRegistry{
+ ParseLogFn: func(log coreTypes.Log) (generated.AbigenLog, error) {
+ if log.BlockNumber == 1 {
+ return &iregistry21.IKeeperRegistryMasterUpkeepTriggerConfigSet{
+ Id: core.GenUpkeepID(types.LogTrigger, "abc").BigInt(),
+ TriggerConfig: []byte{1, 2, 3},
+ }, nil
+ }
+ return &iregistry21.IKeeperRegistryMasterUpkeepUnpaused{
+ Id: core.GenUpkeepID(types.LogTrigger, "def").BigInt(),
+ }, nil
+ },
+ GetUpkeepTriggerConfigFn: func(opts *bind.CallOpts, upkeepId *big.Int) ([]byte, error) {
+ return nil, nil
+ },
+ },
+ packer: &mockPacker{
+ UnpackLogTriggerConfigFn: func(raw []byte) (automation_utils_2_1.LogTriggerConfig, error) {
+ return automation_utils_2_1.LogTriggerConfig{}, nil
+ },
+ },
+ },
+ {
+ name: "log trigger upkeeps are refreshed in batch without error",
+ ids: func() []*big.Int {
+ res := []*big.Int{}
+ for i := 0; i < logTriggerRefreshBatchSize*3; i++ {
+ res = append(res, core.GenUpkeepID(types.LogTrigger, fmt.Sprintf("%d", i)).BigInt())
+ }
+ return res
+ }(),
+ logEventProvider: &mockLogEventProvider{
+ RefreshActiveUpkeepsFn: func(ids ...*big.Int) ([]*big.Int, error) {
+ assert.Equal(t, logTriggerRefreshBatchSize, len(ids))
+ return ids, nil
+ },
+ RegisterFilterFn: func(opts logprovider.FilterOptions) error {
+ return nil
+ },
+ },
+ poller: &mockLogPoller{
+ IndexedLogsFn: func(eventSig common.Hash, address common.Address, topicIndex int, topicValues []common.Hash, confs int, qopts ...pg.QOpt) ([]logpoller.Log, error) {
+ return []logpoller.Log{
+ {
+ BlockNumber: 2,
+ },
+ {
+ BlockNumber: 1,
+ },
+ }, nil
+ },
+ },
+ registry: &mockRegistry{
+ ParseLogFn: func(log coreTypes.Log) (generated.AbigenLog, error) {
+ if log.BlockNumber == 1 {
+ return &iregistry21.IKeeperRegistryMasterUpkeepTriggerConfigSet{
+ Id: core.GenUpkeepID(types.LogTrigger, "abc").BigInt(),
+ TriggerConfig: []byte{1, 2, 3},
+ }, nil
+ }
+ return &iregistry21.IKeeperRegistryMasterUpkeepUnpaused{
+ Id: core.GenUpkeepID(types.LogTrigger, "def").BigInt(),
+ }, nil
+ },
+ GetUpkeepTriggerConfigFn: func(opts *bind.CallOpts, upkeepId *big.Int) ([]byte, error) {
+ return nil, nil
+ },
+ },
+ packer: &mockPacker{
+ UnpackLogTriggerConfigFn: func(raw []byte) (automation_utils_2_1.LogTriggerConfig, error) {
+ return automation_utils_2_1.LogTriggerConfig{}, nil
+ },
+ },
+ },
+ {
+ name: "log trigger upkeeps are refreshed in batch, with a partial batch without error",
+ ids: func() []*big.Int {
+ res := []*big.Int{}
+ for i := 0; i < logTriggerRefreshBatchSize+3; i++ {
+ res = append(res, core.GenUpkeepID(types.LogTrigger, fmt.Sprintf("%d", i)).BigInt())
+ }
+ return res
+ }(),
+ logEventProvider: &mockLogEventProvider{
+ RefreshActiveUpkeepsFn: func(ids ...*big.Int) ([]*big.Int, error) {
+ if len(ids) != logTriggerRefreshBatchSize {
+ assert.Equal(t, 3, len(ids))
+ }
+ return ids, nil
+ },
+ RegisterFilterFn: func(opts logprovider.FilterOptions) error {
+ return nil
+ },
+ },
+ poller: &mockLogPoller{
+ IndexedLogsFn: func(eventSig common.Hash, address common.Address, topicIndex int, topicValues []common.Hash, confs int, qopts ...pg.QOpt) ([]logpoller.Log, error) {
+ return []logpoller.Log{
+ {
+ BlockNumber: 2,
+ },
+ {
+ BlockNumber: 1,
+ },
+ }, nil
+ },
+ },
+ registry: &mockRegistry{
+ ParseLogFn: func(log coreTypes.Log) (generated.AbigenLog, error) {
+ if log.BlockNumber == 1 {
+ return &iregistry21.IKeeperRegistryMasterUpkeepTriggerConfigSet{
+ Id: core.GenUpkeepID(types.LogTrigger, "abc").BigInt(),
+ TriggerConfig: []byte{1, 2, 3},
+ }, nil
+ }
+ return &iregistry21.IKeeperRegistryMasterUpkeepUnpaused{
+ Id: core.GenUpkeepID(types.LogTrigger, "def").BigInt(),
+ }, nil
+ },
+ GetUpkeepTriggerConfigFn: func(opts *bind.CallOpts, upkeepId *big.Int) ([]byte, error) {
+ return nil, nil
+ },
+ },
+ packer: &mockPacker{
+ UnpackLogTriggerConfigFn: func(raw []byte) (automation_utils_2_1.LogTriggerConfig, error) {
+ return automation_utils_2_1.LogTriggerConfig{}, nil
+ },
+ },
+ },
+ } {
+ t.Run(tc.name, func(t *testing.T) {
+ lggr := logger.TestLogger(t)
+ var hb types3.HeadBroadcaster
+ var lp logpoller.LogPoller
+
+ bs := NewBlockSubscriber(hb, lp, 1000, lggr)
+
+ registry := &EvmRegistry{
+ addr: common.BigToAddress(big.NewInt(1)),
+ poller: tc.poller,
+ logEventProvider: tc.logEventProvider,
+ chLog: make(chan logpoller.Log, 10),
+ bs: bs,
+ registry: tc.registry,
+ packer: tc.packer,
+ lggr: lggr,
+ }
+
+ err := registry.refreshLogTriggerUpkeeps(tc.ids)
+ if tc.expectsErr {
+ assert.Error(t, err)
+ assert.Equal(t, err.Error(), tc.wantErr.Error())
+ } else {
+ assert.NoError(t, err)
+ }
+ })
+ }
+}
+
+type mockLogEventProvider struct {
+ logprovider.LogEventProvider
+ RefreshActiveUpkeepsFn func(ids ...*big.Int) ([]*big.Int, error)
+ RegisterFilterFn func(opts logprovider.FilterOptions) error
+}
+
+func (p *mockLogEventProvider) RefreshActiveUpkeeps(ids ...*big.Int) ([]*big.Int, error) {
+ return p.RefreshActiveUpkeepsFn(ids...)
+}
+
+func (p *mockLogEventProvider) RegisterFilter(ctx context.Context, opts logprovider.FilterOptions) error {
+ return p.RegisterFilterFn(opts)
+}
+
+type mockRegistry struct {
+ Registry
+ GetUpkeepTriggerConfigFn func(opts *bind.CallOpts, upkeepId *big.Int) ([]byte, error)
+ ParseLogFn func(log coreTypes.Log) (generated.AbigenLog, error)
+}
+
+func (r *mockRegistry) ParseLog(log coreTypes.Log) (generated.AbigenLog, error) {
+ return r.ParseLogFn(log)
+}
+
+func (r *mockRegistry) GetUpkeepTriggerConfig(opts *bind.CallOpts, upkeepId *big.Int) ([]byte, error) {
+ return r.GetUpkeepTriggerConfigFn(opts, upkeepId)
+}
+
+type mockPacker struct {
+ encoding.Packer
+ UnpackLogTriggerConfigFn func(raw []byte) (automation_utils_2_1.LogTriggerConfig, error)
+}
+
+func (p *mockPacker) UnpackLogTriggerConfig(raw []byte) (automation_utils_2_1.LogTriggerConfig, error) {
+ return p.UnpackLogTriggerConfigFn(raw)
+}
diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/services.go b/core/services/ocr2/plugins/ocr2keeper/evm21/services.go
index 639b2b6af79..79a9da0c68c 100644
--- a/core/services/ocr2/plugins/ocr2keeper/evm21/services.go
+++ b/core/services/ocr2/plugins/ocr2keeper/evm21/services.go
@@ -10,22 +10,25 @@ import (
ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types"
"github.com/smartcontractkit/ocr2keepers/pkg/v3/plugin"
ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg/v3/types"
+ "github.com/smartcontractkit/sqlx"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/automation_utils_2_1"
- "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/feed_lookup_compatible_interface"
iregistry21 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/i_keeper_registry_master_wrapper_2_1"
+ "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/streams_lookup_compatible_interface"
"github.com/smartcontractkit/chainlink/v2/core/logger"
"github.com/smartcontractkit/chainlink/v2/core/services/ocr2/models"
"github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21/encoding"
"github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider"
+ "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21/transmit"
"github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate"
+ "github.com/smartcontractkit/chainlink/v2/core/services/pg"
)
type AutomationServices interface {
Registry() *EvmRegistry
Encoder() ocr2keepers.Encoder
- TransmitEventProvider() *TransmitEventProvider
+ TransmitEventProvider() *transmit.EventProvider
BlockSubscriber() *BlockSubscriber
PayloadBuilder() ocr2keepers.PayloadBuilder
UpkeepStateStore() upkeepstate.UpkeepStateStore
@@ -35,8 +38,8 @@ type AutomationServices interface {
Keyring() ocr3types.OnchainKeyring[plugin.AutomationReportInfo]
}
-func New(addr common.Address, client evm.Chain, mc *models.MercuryCredentials, keyring ocrtypes.OnchainKeyring, lggr logger.Logger) (AutomationServices, error) {
- feedLookupCompatibleABI, err := abi.JSON(strings.NewReader(feed_lookup_compatible_interface.FeedLookupCompatibleInterfaceABI))
+func New(addr common.Address, client evm.Chain, mc *models.MercuryCredentials, keyring ocrtypes.OnchainKeyring, lggr logger.Logger, db *sqlx.DB, dbCfg pg.QConfig) (AutomationServices, error) {
+ streamsLookupCompatibleABI, err := abi.JSON(strings.NewReader(streams_lookup_compatible_interface.StreamsLookupCompatibleInterfaceABI))
if err != nil {
return nil, fmt.Errorf("%w: %s", ErrABINotParsable, err)
}
@@ -55,33 +58,36 @@ func New(addr common.Address, client evm.Chain, mc *models.MercuryCredentials, k
// lookback blocks for transmit event is hard coded and should provide ample time for logs
// to be detected in most cases
var transmitLookbackBlocks int64 = 250
- transmitter, err := NewTransmitEventProvider(lggr, client.LogPoller(), addr, client.Client(), transmitLookbackBlocks)
+ transmitEventProvider, err := transmit.NewTransmitEventProvider(lggr, client.LogPoller(), addr, client.Client(), transmitLookbackBlocks)
if err != nil {
return nil, err
}
services := new(automationServices)
- services.transmitter = transmitter
+ services.transmitEventProvider = transmitEventProvider
packer := encoding.NewAbiPacker(keeperRegistryABI, utilsABI)
services.encoder = encoding.NewReportEncoder(packer)
- scanner := upkeepstate.NewPerformedEventsScanner(lggr, client.LogPoller(), addr)
- services.upkeepState = upkeepstate.NewUpkeepStateStore(lggr, scanner)
+ finalityDepth := client.Config().EVM().FinalityDepth()
- logProvider, logRecoverer := logprovider.New(lggr, client.LogPoller(), client.Client(), utilsABI, services.upkeepState)
+ orm := upkeepstate.NewORM(client.ID(), db, lggr, dbCfg)
+ scanner := upkeepstate.NewPerformedEventsScanner(lggr, client.LogPoller(), addr, finalityDepth)
+ services.upkeepState = upkeepstate.NewUpkeepStateStore(orm, lggr, scanner)
+
+ logProvider, logRecoverer := logprovider.New(lggr, client.LogPoller(), client.Client(), utilsABI, services.upkeepState, finalityDepth)
services.logProvider = logProvider
services.logRecoverer = logRecoverer
- services.blockSub = NewBlockSubscriber(client.HeadBroadcaster(), client.LogPoller(), lggr)
+ services.blockSub = NewBlockSubscriber(client.HeadBroadcaster(), client.LogPoller(), finalityDepth, lggr)
services.keyring = NewOnchainKeyringV3Wrapper(keyring)
al := NewActiveUpkeepList()
services.payloadBuilder = NewPayloadBuilder(al, logRecoverer, lggr)
- services.reg = NewEvmRegistry(lggr, addr, client, feedLookupCompatibleABI,
+ services.reg = NewEvmRegistry(lggr, addr, client, streamsLookupCompatibleABI,
keeperRegistryABI, registryContract, mc, al, services.logProvider,
- packer, services.blockSub)
+ packer, services.blockSub, finalityDepth)
services.upkeepProvider = NewUpkeepProvider(al, services.blockSub, client.LogPoller())
@@ -89,16 +95,16 @@ func New(addr common.Address, client evm.Chain, mc *models.MercuryCredentials, k
}
type automationServices struct {
- reg *EvmRegistry
- encoder ocr2keepers.Encoder
- transmitter *TransmitEventProvider
- blockSub *BlockSubscriber
- payloadBuilder ocr2keepers.PayloadBuilder
- upkeepState upkeepstate.UpkeepStateStore
- logProvider logprovider.LogEventProvider
- logRecoverer logprovider.LogRecoverer
- upkeepProvider *upkeepProvider
- keyring *onchainKeyringV3Wrapper
+ reg *EvmRegistry
+ encoder ocr2keepers.Encoder
+ transmitEventProvider *transmit.EventProvider
+ blockSub *BlockSubscriber
+ payloadBuilder ocr2keepers.PayloadBuilder
+ upkeepState upkeepstate.UpkeepStateStore
+ logProvider logprovider.LogEventProvider
+ logRecoverer logprovider.LogRecoverer
+ upkeepProvider *upkeepProvider
+ keyring *onchainKeyringV3Wrapper
}
var _ AutomationServices = &automationServices{}
@@ -111,8 +117,8 @@ func (f *automationServices) Encoder() ocr2keepers.Encoder {
return f.encoder
}
-func (f *automationServices) TransmitEventProvider() *TransmitEventProvider {
- return f.transmitter
+func (f *automationServices) TransmitEventProvider() *transmit.EventProvider {
+ return f.transmitEventProvider
}
func (f *automationServices) BlockSubscriber() *BlockSubscriber {
diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/feed_lookup.go b/core/services/ocr2/plugins/ocr2keeper/evm21/streams_lookup.go
similarity index 65%
rename from core/services/ocr2/plugins/ocr2keeper/evm21/feed_lookup.go
rename to core/services/ocr2/plugins/ocr2keeper/evm21/streams_lookup.go
index 9bf0de6c1d1..6c1789de9c4 100644
--- a/core/services/ocr2/plugins/ocr2keeper/evm21/feed_lookup.go
+++ b/core/services/ocr2/plugins/ocr2keeper/evm21/streams_lookup.go
@@ -45,9 +45,7 @@ const (
totalAttempt = 3
)
-type MercuryVersion string
-
-type FeedLookup struct {
+type StreamsLookup struct {
feedParamKey string
feeds []string
timeParamKey string
@@ -68,10 +66,10 @@ type MercuryV03Response struct {
}
type MercuryV03Report struct {
- FeedID string `json:"feedID"` // feed id in hex
- ValidFromTimestamp string `json:"validFromTimestamp"`
- ObservationsTimestamp string `json:"observationsTimestamp"`
- FullReport string `json:"fullReport"` // the actual mercury report of this feed, can be sent to verifier
+ FeedID string `json:"feedID"` // feed id in hex encoded
+ ValidFromTimestamp uint32 `json:"validFromTimestamp"`
+ ObservationsTimestamp uint32 `json:"observationsTimestamp"`
+ FullReport string `json:"fullReport"` // the actual hex encoded mercury report of this feed, can be sent to verifier
}
type MercuryData struct {
@@ -82,32 +80,36 @@ type MercuryData struct {
State encoding.PipelineExecutionState
}
-// UpkeepPrivilegeConfig represents the administrative offchain config for each upkeep. It can be set by s_upkeepManager
+// UpkeepPrivilegeConfig represents the administrative offchain config for each upkeep. It can be set by s_upkeepPrivilegeManager
// role on the registry. Upkeeps allowed to use Mercury server will have this set to true.
type UpkeepPrivilegeConfig struct {
MercuryEnabled bool `json:"mercuryEnabled"`
}
-// feedLookup looks through check upkeep results looking for any that need off chain lookup
-func (r *EvmRegistry) feedLookup(ctx context.Context, checkResults []ocr2keepers.CheckResult) []ocr2keepers.CheckResult {
- lggr := r.lggr.With("where", "FeedLookup")
- lookups := map[int]*FeedLookup{}
+// streamsLookup looks through check upkeep results looking for any that need off chain lookup
+func (r *EvmRegistry) streamsLookup(ctx context.Context, checkResults []ocr2keepers.CheckResult) []ocr2keepers.CheckResult {
+ lggr := r.lggr.With("where", "StreamsLookup")
+ lookups := map[int]*StreamsLookup{}
for i, res := range checkResults {
if res.IneligibilityReason != uint8(encoding.UpkeepFailureReasonTargetCheckReverted) {
- // Feedlookup only works when upkeep target check reverts
+ // Streams Lookup only works when upkeep target check reverts
continue
}
block := big.NewInt(int64(res.Trigger.BlockNumber))
upkeepId := res.UpkeepID
- // Try to decode the revert error into feed lookup format. User upkeeps can revert with any reason, see if they
+ // Try to decode the revert error into streams lookup format. User upkeeps can revert with any reason, see if they
// tried to call mercury
- lggr.Infof("at block %d upkeep %s trying to decodeFeedLookup performData=%s", block, upkeepId, hexutil.Encode(checkResults[i].PerformData))
- l, err := r.decodeFeedLookup(res.PerformData)
+ lggr.Infof("at block %d upkeep %s trying to decodeStreamsLookup performData=%s", block, upkeepId, hexutil.Encode(checkResults[i].PerformData))
+ l, err := r.decodeStreamsLookup(res.PerformData)
if err != nil {
- lggr.Warnf("upkeep %s block %d decodeFeedLookup failed: %v", upkeepId, block, err)
- // Not feed lookup error, nothing to do here
+ lggr.Warnf("at block %d upkeep %s decodeStreamsLookup failed: %v", block, upkeepId, err)
+ // user contract did not revert with StreamsLookup error
+ continue
+ }
+ if r.mercury.cred == nil {
+ lggr.Errorf("at block %d upkeep %s tries to access mercury server but mercury credential is not configured", block, upkeepId)
continue
}
@@ -145,7 +147,7 @@ func (r *EvmRegistry) feedLookup(ctx context.Context, checkResults []ocr2keepers
// the block here is exclusively used to call checkCallback at this block, not to be confused with the block number
// in the revert for mercury v0.2, which is denoted by time in the struct bc starting from v0.3, only timestamp will be supported
l.block = uint64(block.Int64())
- lggr.Infof("at block %d upkeep %s decodeFeedLookup feedKey=%s timeKey=%s feeds=%v time=%s extraData=%s", block, upkeepId, l.feedParamKey, l.timeParamKey, l.feeds, l.time, hexutil.Encode(l.extraData))
+ lggr.Infof("at block %d upkeep %s decodeStreamsLookup feedKey=%s timeKey=%s feeds=%v time=%s extraData=%s", block, upkeepId, l.feedParamKey, l.timeParamKey, l.feeds, l.time, hexutil.Encode(l.extraData))
lookups[i] = l
}
@@ -156,28 +158,29 @@ func (r *EvmRegistry) feedLookup(ctx context.Context, checkResults []ocr2keepers
}
wg.Wait()
- // don't surface error to plugin bc FeedLookup process should be self-contained.
+ // don't surface error to plugin bc StreamsLookup process should be self-contained.
return checkResults
}
-func (r *EvmRegistry) doLookup(ctx context.Context, wg *sync.WaitGroup, lookup *FeedLookup, i int, checkResults []ocr2keepers.CheckResult, lggr logger.Logger) {
+func (r *EvmRegistry) doLookup(ctx context.Context, wg *sync.WaitGroup, lookup *StreamsLookup, i int, checkResults []ocr2keepers.CheckResult, lggr logger.Logger) {
defer wg.Done()
state, reason, values, retryable, err := r.doMercuryRequest(ctx, lookup, lggr)
if err != nil {
- lggr.Errorf("upkeep %s retryable %v doMercuryRequest: %v", lookup.upkeepId, retryable, err)
+ lggr.Errorf("upkeep %s retryable %v doMercuryRequest: %s", lookup.upkeepId, retryable, err.Error())
checkResults[i].Retryable = retryable
checkResults[i].PipelineExecutionState = uint8(state)
checkResults[i].IneligibilityReason = uint8(reason)
return
}
+
for j, v := range values {
- lggr.Infof("checkCallback values[%d]=%s", j, hexutil.Encode(v))
+ lggr.Infof("upkeep %s doMercuryRequest values[%d]: %s", lookup.upkeepId, j, hexutil.Encode(v))
}
state, retryable, mercuryBytes, err := r.checkCallback(ctx, values, lookup)
if err != nil {
- lggr.Errorf("at block %d upkeep %s checkCallback err: %v", lookup.block, lookup.upkeepId, err)
+ lggr.Errorf("at block %d upkeep %s checkCallback err: %s", lookup.block, lookup.upkeepId, err.Error())
checkResults[i].Retryable = retryable
checkResults[i].PipelineExecutionState = uint8(state)
return
@@ -186,7 +189,7 @@ func (r *EvmRegistry) doLookup(ctx context.Context, wg *sync.WaitGroup, lookup *
state, needed, performData, failureReason, _, err := r.packer.UnpackCheckCallbackResult(mercuryBytes)
if err != nil {
- lggr.Errorf("at block %d upkeep %s UnpackCheckCallbackResult err: %v", lookup.block, lookup.upkeepId, err)
+ lggr.Errorf("at block %d upkeep %s UnpackCheckCallbackResult err: %s", lookup.block, lookup.upkeepId, err.Error())
checkResults[i].PipelineExecutionState = uint8(state)
return
}
@@ -217,34 +220,56 @@ func (r *EvmRegistry) allowedToUseMercury(opts *bind.CallOpts, upkeepId *big.Int
return encoding.NoPipelineError, encoding.UpkeepFailureReasonNone, false, allowed.(bool), nil
}
- cfg, err := r.registry.GetUpkeepPrivilegeConfig(opts, upkeepId)
+ payload, err := r.packer.PackGetUpkeepPrivilegeConfig(upkeepId)
+ if err != nil {
+ // pack error, no retryable
+ r.lggr.Warnf("failed to pack getUpkeepPrivilegeConfig data for upkeepId %s: %s", upkeepId, err)
+
+ return encoding.PackUnpackDecodeFailed, encoding.UpkeepFailureReasonNone, false, false, fmt.Errorf("failed to pack upkeepId: %w", err)
+ }
+
+ var resultBytes hexutil.Bytes
+ args := map[string]interface{}{
+ "to": r.addr.Hex(),
+ "data": hexutil.Bytes(payload),
+ }
+
+ // call checkCallback function at the block which OCR3 has agreed upon
+ err = r.client.CallContext(opts.Context, &resultBytes, "eth_call", args, hexutil.EncodeBig(opts.BlockNumber))
if err != nil {
return encoding.RpcFlakyFailure, encoding.UpkeepFailureReasonNone, true, false, fmt.Errorf("failed to get upkeep privilege config: %v", err)
}
+
+ cfg, err := r.packer.UnpackGetUpkeepPrivilegeConfig(resultBytes)
+ if err != nil {
+ return encoding.PackUnpackDecodeFailed, encoding.UpkeepFailureReasonNone, false, false, fmt.Errorf("failed to get upkeep privilege config: %v", err)
+ }
+
if len(cfg) == 0 {
r.mercury.allowListCache.Set(upkeepId.String(), false, cache.DefaultExpiration)
return encoding.NoPipelineError, encoding.UpkeepFailureReasonMercuryAccessNotAllowed, false, false, fmt.Errorf("upkeep privilege config is empty")
}
- var a UpkeepPrivilegeConfig
- err = json.Unmarshal(cfg, &a)
- if err != nil {
+ var privilegeConfig UpkeepPrivilegeConfig
+ if err := json.Unmarshal(cfg, &privilegeConfig); err != nil {
return encoding.MercuryUnmarshalError, encoding.UpkeepFailureReasonNone, false, false, fmt.Errorf("failed to unmarshal privilege config: %v", err)
}
- r.mercury.allowListCache.Set(upkeepId.String(), a.MercuryEnabled, cache.DefaultExpiration)
- return encoding.NoPipelineError, encoding.UpkeepFailureReasonNone, false, a.MercuryEnabled, nil
+
+ r.mercury.allowListCache.Set(upkeepId.String(), privilegeConfig.MercuryEnabled, cache.DefaultExpiration)
+
+ return encoding.NoPipelineError, encoding.UpkeepFailureReasonNone, false, privilegeConfig.MercuryEnabled, nil
}
-// decodeFeedLookup decodes the revert error FeedLookup(string feedParamKey, string[] feeds, string feedParamKey, uint256 time, byte[] extraData)
-func (r *EvmRegistry) decodeFeedLookup(data []byte) (*FeedLookup, error) {
- e := r.mercury.abi.Errors["FeedLookup"]
+// decodeStreamsLookup decodes the revert error StreamsLookup(string feedParamKey, string[] feeds, string feedParamKey, uint256 time, byte[] extraData)
+func (r *EvmRegistry) decodeStreamsLookup(data []byte) (*StreamsLookup, error) {
+ e := r.mercury.abi.Errors["StreamsLookup"]
unpack, err := e.Unpack(data)
if err != nil {
return nil, fmt.Errorf("unpack error: %w", err)
}
errorParameters := unpack.([]interface{})
- return &FeedLookup{
+ return &StreamsLookup{
feedParamKey: *abi.ConvertType(errorParameters[0], new(string)).(*string),
feeds: *abi.ConvertType(errorParameters[1], new([]string)).(*[]string),
timeParamKey: *abi.ConvertType(errorParameters[2], new(string)).(*string),
@@ -253,7 +278,7 @@ func (r *EvmRegistry) decodeFeedLookup(data []byte) (*FeedLookup, error) {
}, nil
}
-func (r *EvmRegistry) checkCallback(ctx context.Context, values [][]byte, lookup *FeedLookup) (encoding.PipelineExecutionState, bool, hexutil.Bytes, error) {
+func (r *EvmRegistry) checkCallback(ctx context.Context, values [][]byte, lookup *StreamsLookup) (encoding.PipelineExecutionState, bool, hexutil.Bytes, error) {
payload, err := r.abi.Pack("checkCallback", lookup.upkeepId, values, lookup.extraData)
if err != nil {
return encoding.PackUnpackDecodeFailed, false, nil, err
@@ -274,30 +299,30 @@ func (r *EvmRegistry) checkCallback(ctx context.Context, values [][]byte, lookup
}
// doMercuryRequest sends requests to Mercury API to retrieve mercury data.
-func (r *EvmRegistry) doMercuryRequest(ctx context.Context, ml *FeedLookup, lggr logger.Logger) (encoding.PipelineExecutionState, encoding.UpkeepFailureReason, [][]byte, bool, error) {
+func (r *EvmRegistry) doMercuryRequest(ctx context.Context, sl *StreamsLookup, lggr logger.Logger) (encoding.PipelineExecutionState, encoding.UpkeepFailureReason, [][]byte, bool, error) {
var isMercuryV03 bool
- resultLen := len(ml.feeds)
+ resultLen := len(sl.feeds)
ch := make(chan MercuryData, resultLen)
- if len(ml.feeds) == 0 {
- return encoding.NoPipelineError, encoding.UpkeepFailureReasonInvalidRevertDataInput, [][]byte{}, false, fmt.Errorf("invalid revert data input: feed param key %s, time param key %s, feeds %s", ml.feedParamKey, ml.timeParamKey, ml.feeds)
+ if len(sl.feeds) == 0 {
+ return encoding.NoPipelineError, encoding.UpkeepFailureReasonInvalidRevertDataInput, [][]byte{}, false, fmt.Errorf("invalid revert data input: feed param key %s, time param key %s, feeds %s", sl.feedParamKey, sl.timeParamKey, sl.feeds)
}
- if ml.feedParamKey == feedIdHex && ml.timeParamKey == blockNumber {
+ if sl.feedParamKey == feedIdHex && sl.timeParamKey == blockNumber {
// only mercury v0.2
- for i := range ml.feeds {
- go r.singleFeedRequest(ctx, ch, i, ml, lggr)
+ for i := range sl.feeds {
+ go r.singleFeedRequest(ctx, ch, i, sl, lggr)
}
- } else if ml.feedParamKey == feedIDs && ml.timeParamKey == timestamp {
+ } else if sl.feedParamKey == feedIDs && sl.timeParamKey == timestamp {
// only mercury v0.3
resultLen = 1
isMercuryV03 = true
ch = make(chan MercuryData, resultLen)
- go r.multiFeedsRequest(ctx, ch, ml, lggr)
+ go r.multiFeedsRequest(ctx, ch, sl, lggr)
} else {
- return encoding.NoPipelineError, encoding.UpkeepFailureReasonInvalidRevertDataInput, [][]byte{}, false, fmt.Errorf("invalid revert data input: feed param key %s, time param key %s, feeds %s", ml.feedParamKey, ml.timeParamKey, ml.feeds)
+ return encoding.NoPipelineError, encoding.UpkeepFailureReasonInvalidRevertDataInput, [][]byte{}, false, fmt.Errorf("invalid revert data input: feed param key %s, time param key %s, feeds %s", sl.feedParamKey, sl.timeParamKey, sl.feeds)
}
var reqErr error
- results := make([][]byte, len(ml.feeds))
+ results := make([][]byte, len(sl.feeds))
retryable := true
allSuccess := true
// in v0.2, use the last execution error as the state, if no execution errors, state will be no error
@@ -319,20 +344,19 @@ func (r *EvmRegistry) doMercuryRequest(ctx context.Context, ml *FeedLookup, lggr
results[m.Index] = m.Bytes[0]
}
}
- lggr.Debugf("upkeep %s retryable %s reqErr %w", ml.upkeepId.String(), retryable && !allSuccess, reqErr)
// only retry when not all successful AND none are not retryable
return state, encoding.UpkeepFailureReasonNone, results, retryable && !allSuccess, reqErr
}
// singleFeedRequest sends a v0.2 Mercury request for a single feed report.
-func (r *EvmRegistry) singleFeedRequest(ctx context.Context, ch chan<- MercuryData, index int, ml *FeedLookup, lggr logger.Logger) {
+func (r *EvmRegistry) singleFeedRequest(ctx context.Context, ch chan<- MercuryData, index int, sl *StreamsLookup, lggr logger.Logger) {
q := url.Values{
- ml.feedParamKey: {ml.feeds[index]},
- ml.timeParamKey: {ml.time.String()},
+ sl.feedParamKey: {sl.feeds[index]},
+ sl.timeParamKey: {sl.time.String()},
}
- mercuryURL := r.mercury.cred.URL
+ mercuryURL := r.mercury.cred.LegacyURL
reqUrl := fmt.Sprintf("%s%s%s", mercuryURL, mercuryPathV02, q.Encode())
- lggr.Debugf("request URL: %s", reqUrl)
+ lggr.Debugf("request URL for upkeep %s feed %s: %s", sl.upkeepId.String(), sl.feeds[index], reqUrl)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, reqUrl, nil)
if err != nil {
@@ -356,7 +380,7 @@ func (r *EvmRegistry) singleFeedRequest(ctx context.Context, ch chan<- MercuryDa
retryable = false
resp, err1 := r.hc.Do(req)
if err1 != nil {
- lggr.Warnf("at block %s upkeep %s GET request fails for feed %s: %v", ml.time.String(), ml.upkeepId.String(), ml.feeds[index], err1)
+ lggr.Warnf("at block %s upkeep %s GET request fails for feed %s: %v", sl.time.String(), sl.upkeepId.String(), sl.feeds[index], err1)
retryable = true
state = encoding.MercuryFlakyFailure
return err1
@@ -376,27 +400,29 @@ func (r *EvmRegistry) singleFeedRequest(ctx context.Context, ch chan<- MercuryDa
}
if resp.StatusCode == http.StatusNotFound || resp.StatusCode == http.StatusInternalServerError {
- lggr.Warnf("at block %s upkeep %s received status code %d for feed %s", ml.time.String(), ml.upkeepId.String(), resp.StatusCode, ml.feeds[index])
+ lggr.Warnf("at block %s upkeep %s received status code %d for feed %s", sl.time.String(), sl.upkeepId.String(), resp.StatusCode, sl.feeds[index])
retryable = true
state = encoding.MercuryFlakyFailure
return errors.New(strconv.FormatInt(int64(resp.StatusCode), 10))
} else if resp.StatusCode != http.StatusOK {
retryable = false
state = encoding.InvalidMercuryRequest
- return fmt.Errorf("at block %s upkeep %s received status code %d for feed %s", ml.time.String(), ml.upkeepId.String(), resp.StatusCode, ml.feeds[index])
+ return fmt.Errorf("at block %s upkeep %s received status code %d for feed %s", sl.time.String(), sl.upkeepId.String(), resp.StatusCode, sl.feeds[index])
}
+ lggr.Debugf("at block %s upkeep %s received status code %d from mercury v0.2 with BODY=%s", sl.time.String(), sl.upkeepId.String(), resp.StatusCode, hexutil.Encode(body))
+
var m MercuryV02Response
err1 = json.Unmarshal(body, &m)
if err1 != nil {
- lggr.Warnf("at block %s upkeep %s failed to unmarshal body to MercuryV02Response for feed %s: %v", ml.time.String(), ml.upkeepId.String(), ml.feeds[index], err1)
+ lggr.Warnf("at block %s upkeep %s failed to unmarshal body to MercuryV02Response for feed %s: %v", sl.time.String(), sl.upkeepId.String(), sl.feeds[index], err1)
retryable = false
state = encoding.MercuryUnmarshalError
return err1
}
blobBytes, err1 := hexutil.Decode(m.ChainlinkBlob)
if err1 != nil {
- lggr.Warnf("at block %s upkeep %s failed to decode chainlinkBlob %s for feed %s: %v", ml.time.String(), ml.upkeepId.String(), m.ChainlinkBlob, ml.feeds[index], err1)
+ lggr.Warnf("at block %s upkeep %s failed to decode chainlinkBlob %s for feed %s: %v", sl.time.String(), sl.upkeepId.String(), m.ChainlinkBlob, sl.feeds[index], err1)
retryable = false
state = encoding.InvalidMercuryResponse
return err1
@@ -423,7 +449,7 @@ func (r *EvmRegistry) singleFeedRequest(ctx context.Context, ch chan<- MercuryDa
Index: index,
Bytes: [][]byte{},
Retryable: retryable,
- Error: retryErr,
+ Error: fmt.Errorf("failed to request feed for %s: %w", sl.feeds[index], retryErr),
State: state,
}
ch <- md
@@ -431,14 +457,15 @@ func (r *EvmRegistry) singleFeedRequest(ctx context.Context, ch chan<- MercuryDa
}
// multiFeedsRequest sends a Mercury v0.3 request for a multi-feed report
-func (r *EvmRegistry) multiFeedsRequest(ctx context.Context, ch chan<- MercuryData, ml *FeedLookup, lggr logger.Logger) {
- q := url.Values{
- feedIDs: {strings.Join(ml.feeds, ",")},
- timestamp: {ml.time.String()},
- }
-
- reqUrl := fmt.Sprintf("%s%s%s", r.mercury.cred.URL, mercuryBatchPathV03, q.Encode())
- lggr.Debugf("request URL: %s", reqUrl)
+func (r *EvmRegistry) multiFeedsRequest(ctx context.Context, ch chan<- MercuryData, sl *StreamsLookup, lggr logger.Logger) {
+ // this won't work bc q.Encode() will encode commas as '%2C' but the server is strictly expecting a comma separated list
+ //q := url.Values{
+ // feedIDs: {strings.Join(sl.feeds, ",")},
+ // timestamp: {sl.time.String()},
+ //}
+ params := fmt.Sprintf("%s=%s&%s=%s", feedIDs, strings.Join(sl.feeds, ","), timestamp, sl.time.String())
+ reqUrl := fmt.Sprintf("%s%s%s", r.mercury.cred.URL, mercuryBatchPathV03, params)
+ lggr.Debugf("request URL for upkeep %s userId %s: %s", sl.upkeepId.String(), r.mercury.cred.Username, reqUrl)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, reqUrl, nil)
if err != nil {
@@ -447,7 +474,7 @@ func (r *EvmRegistry) multiFeedsRequest(ctx context.Context, ch chan<- MercuryDa
}
ts := time.Now().UTC().UnixMilli()
- signature := r.generateHMAC(http.MethodGet, mercuryBatchPathV03+q.Encode(), []byte{}, r.mercury.cred.Username, r.mercury.cred.Password, ts)
+ signature := r.generateHMAC(http.MethodGet, mercuryBatchPathV03+params, []byte{}, r.mercury.cred.Username, r.mercury.cred.Password, ts)
req.Header.Set(headerContentType, applicationJson)
// username here is often referred to as user id
req.Header.Set(headerAuthorization, r.mercury.cred.Username)
@@ -455,7 +482,7 @@ func (r *EvmRegistry) multiFeedsRequest(ctx context.Context, ch chan<- MercuryDa
req.Header.Set(headerSignature, signature)
// mercury will inspect authorization headers above to make sure this user (in automation's context, this node) is eligible to access mercury
// and if it has an automation role. it will then look at this upkeep id to check if it has access to all the requested feeds.
- req.Header.Set(headerUpkeepId, ml.upkeepId.String())
+ req.Header.Set(headerUpkeepId, sl.upkeepId.String())
// in the case of multiple retries here, use the last attempt's data
state := encoding.NoPipelineError
@@ -466,7 +493,7 @@ func (r *EvmRegistry) multiFeedsRequest(ctx context.Context, ch chan<- MercuryDa
retryable = false
resp, err1 := r.hc.Do(req)
if err1 != nil {
- lggr.Warnf("at block %s upkeep %s GET request fails from mercury v0.3: %v", ml.time.String(), ml.upkeepId.String(), err1)
+ lggr.Warnf("at timestamp %s upkeep %s GET request fails from mercury v0.3: %v", sl.time.String(), sl.upkeepId.String(), err1)
retryable = true
state = encoding.MercuryFlakyFailure
return err1
@@ -485,41 +512,57 @@ func (r *EvmRegistry) multiFeedsRequest(ctx context.Context, ch chan<- MercuryDa
return err1
}
- if resp.StatusCode == http.StatusNotFound || resp.StatusCode == http.StatusInternalServerError {
- lggr.Warnf("at block %s upkeep %s received status code %d from mercury v0.3", ml.time.String(), ml.upkeepId.String(), resp.StatusCode)
+ lggr.Infof("at timestamp %s upkeep %s received status code %d from mercury v0.3", sl.time.String(), sl.upkeepId.String(), resp.StatusCode)
+ if resp.StatusCode == http.StatusUnauthorized {
+ retryable = false
+ state = encoding.UpkeepNotAuthorized
+ return fmt.Errorf("at timestamp %s upkeep %s received status code %d from mercury v0.3, most likely this is caused by unauthorized upkeep", sl.time.String(), sl.upkeepId.String(), resp.StatusCode)
+ } else if resp.StatusCode == http.StatusBadRequest {
+ 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 invalid format of timestamp", sl.time.String(), sl.upkeepId.String(), resp.StatusCode)
+ } else if resp.StatusCode == http.StatusInternalServerError {
retryable = true
state = encoding.MercuryFlakyFailure
- return errors.New(strconv.FormatInt(int64(resp.StatusCode), 10))
+ return fmt.Errorf("%d", http.StatusInternalServerError)
+ } 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
state = encoding.InvalidMercuryRequest
- return fmt.Errorf("at block %s upkeep %s received status code %d from mercury v0.3", ml.time.String(), ml.upkeepId.String(), resp.StatusCode)
+ return fmt.Errorf("at timestamp %s upkeep %s received status code %d from mercury v0.3", sl.time.String(), sl.upkeepId.String(), resp.StatusCode)
}
+ lggr.Debugf("at block %s upkeep %s received status code %d from mercury v0.3 with BODY=%s", sl.time.String(), sl.upkeepId.String(), resp.StatusCode, hexutil.Encode(body))
+
var response MercuryV03Response
err1 = json.Unmarshal(body, &response)
if err1 != nil {
- lggr.Warnf("at block %s upkeep %s failed to unmarshal body to MercuryV03Response from mercury v0.3: %v", ml.time.String(), ml.upkeepId.String(), err1)
+ lggr.Warnf("at timestamp %s upkeep %s failed to unmarshal body to MercuryV03Response from mercury v0.3: %v", sl.time.String(), sl.upkeepId.String(), err1)
retryable = false
state = encoding.MercuryUnmarshalError
return err1
}
- if len(response.Reports) != len(ml.feeds) {
- // this should never happen. if this upkeep does not have permission for any feeds it requests, or if certain feeds are
- // missing in mercury server, the mercury server v0.3 should respond with 400s, rather than returning partial results
- retryable = false
- state = encoding.InvalidMercuryResponse
- return fmt.Errorf("at block %s upkeep %s requested %d feeds but received %d reports from mercury v0.3", ml.time.String(), ml.upkeepId.String(), len(ml.feeds), len(response.Reports))
+ // in v0.3, if some feeds are not available, the server will only return available feeds, but we need to make sure ALL feeds are retrieved before calling user contract
+ // 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
- var b []byte
for _, rsp := range response.Reports {
- b, err1 = hexutil.Decode(rsp.FullReport)
- if err1 != nil {
- lggr.Warnf("upkeep %s block %s failed to decode fullReport %s from mercury v0.3: %v", ml.upkeepId.String(), ml.time.String(), rsp.FullReport, err1)
+ 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 err1
+ return err
}
reportBytes = append(reportBytes, b)
}
diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/feed_lookup_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/streams_lookup_test.go
similarity index 57%
rename from core/services/ocr2/plugins/ocr2keeper/evm21/feed_lookup_test.go
rename to core/services/ocr2/plugins/ocr2keeper/evm21/streams_lookup_test.go
index a1d7d221b27..f59cec18c1e 100644
--- a/core/services/ocr2/plugins/ocr2keeper/evm21/feed_lookup_test.go
+++ b/core/services/ocr2/plugins/ocr2keeper/evm21/streams_lookup_test.go
@@ -12,6 +12,7 @@ import (
"testing"
"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/common/hexutil"
"github.com/patrickmn/go-cache"
@@ -27,8 +28,8 @@ import (
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/gethwrappers/generated/automation_utils_2_1"
- "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/feed_lookup_compatible_interface"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/i_keeper_registry_master_wrapper_2_1"
+ "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/streams_lookup_compatible_interface"
"github.com/smartcontractkit/chainlink/v2/core/logger"
"github.com/smartcontractkit/chainlink/v2/core/services/ocr2/models"
)
@@ -41,10 +42,10 @@ func setupEVMRegistry(t *testing.T) *EvmRegistry {
require.Nil(t, err, "need registry abi")
utilsABI, err := abi.JSON(strings.NewReader(automation_utils_2_1.AutomationUtilsABI))
require.Nil(t, err, "need utils abi")
- feedLookupCompatibleABI, err := abi.JSON(strings.NewReader(feed_lookup_compatible_interface.FeedLookupCompatibleInterfaceABI))
+ streamsLookupCompatibleABI, err := abi.JSON(strings.NewReader(streams_lookup_compatible_interface.StreamsLookupCompatibleInterfaceABI))
require.Nil(t, err, "need mercury abi")
var logPoller logpoller.LogPoller
- mockRegistry := mocks.NewRegistry(t)
+ mockReg := mocks.NewRegistry(t)
mockHttpClient := mocks.NewHttpClient(t)
client := evmClientMocks.NewClient(t)
@@ -54,7 +55,7 @@ func setupEVMRegistry(t *testing.T) *EvmRegistry {
addr: addr,
client: client,
logProcessed: make(map[string]bool),
- registry: mockRegistry,
+ registry: mockReg,
abi: keeperRegistryABI,
active: NewActiveUpkeepList(),
packer: encoding.NewAbiPacker(keeperRegistryABI, utilsABI),
@@ -62,11 +63,12 @@ func setupEVMRegistry(t *testing.T) *EvmRegistry {
chLog: make(chan logpoller.Log, 1000),
mercury: &MercuryConfig{
cred: &models.MercuryCredentials{
- URL: "https://google.com",
- Username: "FakeClientID",
- Password: "FakeClientKey",
+ LegacyURL: "https://google.old.com",
+ URL: "https://google.com",
+ Username: "FakeClientID",
+ Password: "FakeClientKey",
},
- abi: feedLookupCompatibleABI,
+ abi: streamsLookupCompatibleABI,
allowListCache: cache.New(defaultAllowListExpiration, allowListCleanupInterval),
},
hc: mockHttpClient,
@@ -74,15 +76,16 @@ func setupEVMRegistry(t *testing.T) *EvmRegistry {
return r
}
-func TestEvmRegistry_FeedLookup(t *testing.T) {
+func TestEvmRegistry_StreamsLookup(t *testing.T) {
upkeepId, ok := new(big.Int).SetString("71022726777042968814359024671382968091267501884371696415772139504780367423725", 10)
var upkeepIdentifier [32]byte
copy(upkeepIdentifier[:], upkeepId.Bytes())
assert.True(t, ok, t.Name())
+ blockNum := ocr2keepers.BlockNumber(37974374)
tests := []struct {
name string
input []ocr2keepers.CheckResult
- blob string
+ blobs map[string]string
callbackResp []byte
expectedResults []ocr2keepers.CheckResult
callbackNeeded bool
@@ -97,32 +100,34 @@ func TestEvmRegistry_FeedLookup(t *testing.T) {
name: "success - happy path no cache",
input: []ocr2keepers.CheckResult{
{
- PerformData: []byte{125, 221, 147, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 141, 110, 193, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 102, 101, 101, 100, 73, 100, 72, 101, 120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 48, 120, 52, 53, 53, 52, 52, 56, 50, 100, 53, 53, 53, 51, 52, 52, 50, 100, 52, 49, 53, 50, 52, 50, 52, 57, 53, 52, 53, 50, 53, 53, 52, 100, 50, 100, 53, 52, 52, 53, 53, 51, 53, 52, 52, 101, 52, 53, 53, 52, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 98, 108, 111, 99, 107, 78, 117, 109, 98, 101, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ PerformData: hexutil.MustDecode("0xf055e4a200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000000000000000000000000000000024371660000000000000000000000000000000000000000000000000000000000000280000000000000000000000000000000000000000000000000000000000000000966656564496448657800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000423078343535343438326435353533343432643431353234323439353435323535346432643534343535333534346534353534303030303030303030303030303030300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000042307834323534343332643535353334343264343135323432343935343532353534643264353434353533353434653435353430303030303030303030303030303030000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b626c6f636b4e756d62657200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000064000000000000000000000000"),
UpkeepID: upkeepIdentifier,
Trigger: ocr2keepers.Trigger{
- BlockNumber: 26046145,
+ BlockNumber: blockNum,
},
IneligibilityReason: uint8(encoding.UpkeepFailureReasonTargetCheckReverted),
},
},
- blob: "0x00066dfcd1ed2d95b18c948dbc5bd64c687afe93e4ca7d663ddec14c20090ad80000000000000000000000000000000000000000000000000000000000159761000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000002200000000000000000000000000000000000000000000000000000000000000280000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001204554482d5553442d415242495452554d2d544553544e4554000000000000000000000000000000000000000000000000000000000000000000000000648a1fbb000000000000000000000000000000000000000000000000000000274421041500000000000000000000000000000000000000000000000000000027437c6ecd0000000000000000000000000000000000000000000000000000002744c5995d00000000000000000000000000000000000000000000000000000000018d6ec108936dfe39c48715572a51ac868129958f937fb95ef5abdf73a239cf86a4fee700000000000000000000000000000000000000000000000000000000018d6ec100000000000000000000000000000000000000000000000000000000648a1fbb00000000000000000000000000000000000000000000000000000000000000028a26e557ee2feb91ccb116f3ab4eb1469afe5c3b012538cb151dbe3fbceaf6f117b24ac2a82cff25b286ae0a9b903dc6badaa16f6e67bf0983461b008574e30a00000000000000000000000000000000000000000000000000000000000000020db5c5924481061b98df59caefd9c4c1e72657c4976bf7c7568730fbdaf828080bff6b1edea2c8fed5e8bbac5574aa94cf809d898f5055cb1db14a16f1493726",
+ blobs: map[string]string{
+ "0x4554482d5553442d415242495452554d2d544553544e45540000000000000000": "0x00066dfcd1ed2d95b18c948dbc5bd64c687afe93e4ca7d663ddec14c20090ad80000000000000000000000000000000000000000000000000000000004555638000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000002200000000000000000000000000000000000000000000000000000000000000280010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001204554482d5553442d415242495452554d2d544553544e455400000000000000000000000000000000000000000000000000000000000000000000000064f0d4a0000000000000000000000000000000000000000000000000000000269ecbb83b000000000000000000000000000000000000000000000000000000269e4a4e14000000000000000000000000000000000000000000000000000000269f4d0edb000000000000000000000000000000000000000000000000000000000243716664b42d20423a47fb13ad3098b49b37f667548e6745fff958b663afe25a845f6100000000000000000000000000000000000000000000000000000000024371660000000000000000000000000000000000000000000000000000000064f0d4a00000000000000000000000000000000000000000000000000000000000000002381e91cffa9502c20de1ddcee350db3f715a5ab449448e3184a5b03c682356c6e2115f20663b3731e373cf33465a96da26f2876debb548f281e62e48f64c374200000000000000000000000000000000000000000000000000000000000000027db99e34135098d4e0bb9ae143ec9cd72fd63150c6d0cc5b38f4aa1aa42408377e8fe8e5ac489c9b7f62ff5aa7b05d2e892e7dee4cac631097247969b3b03fa3",
+ "0x4254432d5553442d415242495452554d2d544553544e45540000000000000000": "0x0006da4a86c4933dd4a87b21dd2871aea29f706bcde43c70039355ac5b664fb5000000000000000000000000000000000000000000000000000000000454d118000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000002200000000000000000000000000000000000000000000000000000000000000280000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001204254432d5553442d415242495452554d2d544553544e455400000000000000000000000000000000000000000000000000000000000000000000000064f0d4a0000000000000000000000000000000000000000000000000000002645f00877a000000000000000000000000000000000000000000000000000002645e1e1010000000000000000000000000000000000000000000000000000002645fe2fee4000000000000000000000000000000000000000000000000000000000243716664b42d20423a47fb13ad3098b49b37f667548e6745fff958b663afe25a845f6100000000000000000000000000000000000000000000000000000000024371660000000000000000000000000000000000000000000000000000000064f0d4a00000000000000000000000000000000000000000000000000000000000000002a0373c0bce7393673f819eb9681cac2773c2d718ce933eb858252195b17a9c832d7b0bee173c02c3c25fb65912b8b13b9302ede8423bab3544cb7a8928d5eb3600000000000000000000000000000000000000000000000000000000000000027d7b79d7646383a5dbf51edf14d53bd3ad0a9f3ca8affab3165e89d3ddce9cb17b58e892fafe4ecb24d2fde07c6a756029e752a5114c33c173df4e7d309adb4d",
+ },
cachedAdminCfg: false,
- extraData: []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100},
+ extraData: hexutil.MustDecode("0x0000000000000000000000000000000000000064"),
callbackNeeded: true,
- checkCallbackResp: hexutil.MustDecode("0x000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000428200000000000000000000000000000000000000000000000000000000000003c0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000003800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000002e000066dfcd1ed2d95b18c948dbc5bd64c687afe93e4ca7d663ddec14c20090ad80000000000000000000000000000000000000000000000000000000000159761000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000002200000000000000000000000000000000000000000000000000000000000000280000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001204554482d5553442d415242495452554d2d544553544e4554000000000000000000000000000000000000000000000000000000000000000000000000648a1fbb000000000000000000000000000000000000000000000000000000274421041500000000000000000000000000000000000000000000000000000027437c6ecd0000000000000000000000000000000000000000000000000000002744c5995d00000000000000000000000000000000000000000000000000000000018d6ec108936dfe39c48715572a51ac868129958f937fb95ef5abdf73a239cf86a4fee700000000000000000000000000000000000000000000000000000000018d6ec100000000000000000000000000000000000000000000000000000000648a1fbb00000000000000000000000000000000000000000000000000000000000000028a26e557ee2feb91ccb116f3ab4eb1469afe5c3b012538cb151dbe3fbceaf6f117b24ac2a82cff25b286ae0a9b903dc6badaa16f6e67bf0983461b008574e30a00000000000000000000000000000000000000000000000000000000000000020db5c5924481061b98df59caefd9c4c1e72657c4976bf7c7568730fbdaf828080bff6b1edea2c8fed5e8bbac5574aa94cf809d898f5055cb1db14a16f14937260000000000000000000000000000000000000000000000000000000000000008786f657a5a362c01000000000000000000000000000000000000000000000000"),
- values: [][]byte{{0, 6, 109, 252, 209, 237, 45, 149, 177, 140, 148, 141, 188, 91, 214, 76, 104, 122, 254, 147, 228, 202, 125, 102, 61, 222, 193, 76, 32, 9, 10, 216, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 151, 97, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 128, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 32, 69, 84, 72, 45, 85, 83, 68, 45, 65, 82, 66, 73, 84, 82, 85, 77, 45, 84, 69, 83, 84, 78, 69, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100, 138, 31, 187, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39, 68, 33, 4, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39, 67, 124, 110, 205, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39, 68, 197, 153, 93, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 141, 110, 193, 8, 147, 109, 254, 57, 196, 135, 21, 87, 42, 81, 172, 134, 129, 41, 149, 143, 147, 127, 185, 94, 245, 171, 223, 115, 162, 57, 207, 134, 164, 254, 231, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 141, 110, 193, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100, 138, 31, 187, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 138, 38, 229, 87, 238, 47, 235, 145, 204, 177, 22, 243, 171, 78, 177, 70, 154, 254, 92, 59, 1, 37, 56, 203, 21, 29, 190, 63, 188, 234, 246, 241, 23, 178, 74, 194, 168, 44, 255, 37, 178, 134, 174, 10, 155, 144, 61, 198, 186, 218, 161, 111, 110, 103, 191, 9, 131, 70, 27, 0, 133, 116, 227, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 13, 181, 197, 146, 68, 129, 6, 27, 152, 223, 89, 202, 239, 217, 196, 193, 231, 38, 87, 196, 151, 107, 247, 199, 86, 135, 48, 251, 218, 248, 40, 8, 11, 255, 107, 30, 222, 162, 200, 254, 213, 232, 187, 172, 85, 116, 170, 148, 207, 128, 157, 137, 143, 80, 85, 203, 29, 177, 74, 22, 241, 73, 55, 38}},
+ checkCallbackResp: hexutil.MustDecode("0x00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063a400000000000000000000000000000000000000000000000000000000000006e0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000006a000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000034000000000000000000000000000000000000000000000000000000000000002e000066dfcd1ed2d95b18c948dbc5bd64c687afe93e4ca7d663ddec14c20090ad80000000000000000000000000000000000000000000000000000000004555638000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000002200000000000000000000000000000000000000000000000000000000000000280010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001204554482d5553442d415242495452554d2d544553544e455400000000000000000000000000000000000000000000000000000000000000000000000064f0d4a0000000000000000000000000000000000000000000000000000000269ecbb83b000000000000000000000000000000000000000000000000000000269e4a4e14000000000000000000000000000000000000000000000000000000269f4d0edb000000000000000000000000000000000000000000000000000000000243716664b42d20423a47fb13ad3098b49b37f667548e6745fff958b663afe25a845f6100000000000000000000000000000000000000000000000000000000024371660000000000000000000000000000000000000000000000000000000064f0d4a00000000000000000000000000000000000000000000000000000000000000002381e91cffa9502c20de1ddcee350db3f715a5ab449448e3184a5b03c682356c6e2115f20663b3731e373cf33465a96da26f2876debb548f281e62e48f64c374200000000000000000000000000000000000000000000000000000000000000027db99e34135098d4e0bb9ae143ec9cd72fd63150c6d0cc5b38f4aa1aa42408377e8fe8e5ac489c9b7f62ff5aa7b05d2e892e7dee4cac631097247969b3b03fa300000000000000000000000000000000000000000000000000000000000002e00006da4a86c4933dd4a87b21dd2871aea29f706bcde43c70039355ac5b664fb5000000000000000000000000000000000000000000000000000000000454d118000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000002200000000000000000000000000000000000000000000000000000000000000280000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001204254432d5553442d415242495452554d2d544553544e455400000000000000000000000000000000000000000000000000000000000000000000000064f0d4a0000000000000000000000000000000000000000000000000000002645f00877a000000000000000000000000000000000000000000000000000002645e1e1010000000000000000000000000000000000000000000000000000002645fe2fee4000000000000000000000000000000000000000000000000000000000243716664b42d20423a47fb13ad3098b49b37f667548e6745fff958b663afe25a845f6100000000000000000000000000000000000000000000000000000000024371660000000000000000000000000000000000000000000000000000000064f0d4a00000000000000000000000000000000000000000000000000000000000000002a0373c0bce7393673f819eb9681cac2773c2d718ce933eb858252195b17a9c832d7b0bee173c02c3c25fb65912b8b13b9302ede8423bab3544cb7a8928d5eb3600000000000000000000000000000000000000000000000000000000000000027d7b79d7646383a5dbf51edf14d53bd3ad0a9f3ca8affab3165e89d3ddce9cb17b58e892fafe4ecb24d2fde07c6a756029e752a5114c33c173df4e7d309adb4d00000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000064000000000000000000000000"),
+ values: [][]byte{hexutil.MustDecode("0x00066dfcd1ed2d95b18c948dbc5bd64c687afe93e4ca7d663ddec14c20090ad80000000000000000000000000000000000000000000000000000000004555638000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000002200000000000000000000000000000000000000000000000000000000000000280010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001204554482d5553442d415242495452554d2d544553544e455400000000000000000000000000000000000000000000000000000000000000000000000064f0d4a0000000000000000000000000000000000000000000000000000000269ecbb83b000000000000000000000000000000000000000000000000000000269e4a4e14000000000000000000000000000000000000000000000000000000269f4d0edb000000000000000000000000000000000000000000000000000000000243716664b42d20423a47fb13ad3098b49b37f667548e6745fff958b663afe25a845f6100000000000000000000000000000000000000000000000000000000024371660000000000000000000000000000000000000000000000000000000064f0d4a00000000000000000000000000000000000000000000000000000000000000002381e91cffa9502c20de1ddcee350db3f715a5ab449448e3184a5b03c682356c6e2115f20663b3731e373cf33465a96da26f2876debb548f281e62e48f64c374200000000000000000000000000000000000000000000000000000000000000027db99e34135098d4e0bb9ae143ec9cd72fd63150c6d0cc5b38f4aa1aa42408377e8fe8e5ac489c9b7f62ff5aa7b05d2e892e7dee4cac631097247969b3b03fa3"), hexutil.MustDecode("0x0006da4a86c4933dd4a87b21dd2871aea29f706bcde43c70039355ac5b664fb5000000000000000000000000000000000000000000000000000000000454d118000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000002200000000000000000000000000000000000000000000000000000000000000280000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001204254432d5553442d415242495452554d2d544553544e455400000000000000000000000000000000000000000000000000000000000000000000000064f0d4a0000000000000000000000000000000000000000000000000000002645f00877a000000000000000000000000000000000000000000000000000002645e1e1010000000000000000000000000000000000000000000000000000002645fe2fee4000000000000000000000000000000000000000000000000000000000243716664b42d20423a47fb13ad3098b49b37f667548e6745fff958b663afe25a845f6100000000000000000000000000000000000000000000000000000000024371660000000000000000000000000000000000000000000000000000000064f0d4a00000000000000000000000000000000000000000000000000000000000000002a0373c0bce7393673f819eb9681cac2773c2d718ce933eb858252195b17a9c832d7b0bee173c02c3c25fb65912b8b13b9302ede8423bab3544cb7a8928d5eb3600000000000000000000000000000000000000000000000000000000000000027d7b79d7646383a5dbf51edf14d53bd3ad0a9f3ca8affab3165e89d3ddce9cb17b58e892fafe4ecb24d2fde07c6a756029e752a5114c33c173df4e7d309adb4d")},
expectedResults: []ocr2keepers.CheckResult{
{
Eligible: true,
- PerformData: []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 224, 0, 6, 109, 252, 209, 237, 45, 149, 177, 140, 148, 141, 188, 91, 214, 76, 104, 122, 254, 147, 228, 202, 125, 102, 61, 222, 193, 76, 32, 9, 10, 216, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 151, 97, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 128, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 32, 69, 84, 72, 45, 85, 83, 68, 45, 65, 82, 66, 73, 84, 82, 85, 77, 45, 84, 69, 83, 84, 78, 69, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100, 138, 31, 187, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39, 68, 33, 4, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39, 67, 124, 110, 205, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39, 68, 197, 153, 93, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 141, 110, 193, 8, 147, 109, 254, 57, 196, 135, 21, 87, 42, 81, 172, 134, 129, 41, 149, 143, 147, 127, 185, 94, 245, 171, 223, 115, 162, 57, 207, 134, 164, 254, 231, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 141, 110, 193, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100, 138, 31, 187, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 138, 38, 229, 87, 238, 47, 235, 145, 204, 177, 22, 243, 171, 78, 177, 70, 154, 254, 92, 59, 1, 37, 56, 203, 21, 29, 190, 63, 188, 234, 246, 241, 23, 178, 74, 194, 168, 44, 255, 37, 178, 134, 174, 10, 155, 144, 61, 198, 186, 218, 161, 111, 110, 103, 191, 9, 131, 70, 27, 0, 133, 116, 227, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 13, 181, 197, 146, 68, 129, 6, 27, 152, 223, 89, 202, 239, 217, 196, 193, 231, 38, 87, 196, 151, 107, 247, 199, 86, 135, 48, 251, 218, 248, 40, 8, 11, 255, 107, 30, 222, 162, 200, 254, 213, 232, 187, 172, 85, 116, 170, 148, 207, 128, 157, 137, 143, 80, 85, 203, 29, 177, 74, 22, 241, 73, 55, 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 120, 111, 101, 122, 90, 54, 44, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ PerformData: hexutil.MustDecode("0x000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000006a000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000034000000000000000000000000000000000000000000000000000000000000002e000066dfcd1ed2d95b18c948dbc5bd64c687afe93e4ca7d663ddec14c20090ad80000000000000000000000000000000000000000000000000000000004555638000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000002200000000000000000000000000000000000000000000000000000000000000280010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001204554482d5553442d415242495452554d2d544553544e455400000000000000000000000000000000000000000000000000000000000000000000000064f0d4a0000000000000000000000000000000000000000000000000000000269ecbb83b000000000000000000000000000000000000000000000000000000269e4a4e14000000000000000000000000000000000000000000000000000000269f4d0edb000000000000000000000000000000000000000000000000000000000243716664b42d20423a47fb13ad3098b49b37f667548e6745fff958b663afe25a845f6100000000000000000000000000000000000000000000000000000000024371660000000000000000000000000000000000000000000000000000000064f0d4a00000000000000000000000000000000000000000000000000000000000000002381e91cffa9502c20de1ddcee350db3f715a5ab449448e3184a5b03c682356c6e2115f20663b3731e373cf33465a96da26f2876debb548f281e62e48f64c374200000000000000000000000000000000000000000000000000000000000000027db99e34135098d4e0bb9ae143ec9cd72fd63150c6d0cc5b38f4aa1aa42408377e8fe8e5ac489c9b7f62ff5aa7b05d2e892e7dee4cac631097247969b3b03fa300000000000000000000000000000000000000000000000000000000000002e00006da4a86c4933dd4a87b21dd2871aea29f706bcde43c70039355ac5b664fb5000000000000000000000000000000000000000000000000000000000454d118000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000002200000000000000000000000000000000000000000000000000000000000000280000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001204254432d5553442d415242495452554d2d544553544e455400000000000000000000000000000000000000000000000000000000000000000000000064f0d4a0000000000000000000000000000000000000000000000000000002645f00877a000000000000000000000000000000000000000000000000000002645e1e1010000000000000000000000000000000000000000000000000000002645fe2fee4000000000000000000000000000000000000000000000000000000000243716664b42d20423a47fb13ad3098b49b37f667548e6745fff958b663afe25a845f6100000000000000000000000000000000000000000000000000000000024371660000000000000000000000000000000000000000000000000000000064f0d4a00000000000000000000000000000000000000000000000000000000000000002a0373c0bce7393673f819eb9681cac2773c2d718ce933eb858252195b17a9c832d7b0bee173c02c3c25fb65912b8b13b9302ede8423bab3544cb7a8928d5eb3600000000000000000000000000000000000000000000000000000000000000027d7b79d7646383a5dbf51edf14d53bd3ad0a9f3ca8affab3165e89d3ddce9cb17b58e892fafe4ecb24d2fde07c6a756029e752a5114c33c173df4e7d309adb4d00000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000064000000000000000000000000"),
UpkeepID: upkeepIdentifier,
Trigger: ocr2keepers.Trigger{
- BlockNumber: 26046145,
+ BlockNumber: blockNum,
},
IneligibilityReason: uint8(encoding.UpkeepFailureReasonNone),
},
},
- hasError: false,
hasPermission: true,
},
{
@@ -180,26 +185,55 @@ func TestEvmRegistry_FeedLookup(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
r := setupEVMRegistry(t)
+ client := new(evmClientMocks.Client)
+ r.client = client
if !tt.cachedAdminCfg && !tt.hasError {
- mockRegistry := mocks.NewRegistry(t)
cfg := UpkeepPrivilegeConfig{MercuryEnabled: tt.hasPermission}
- b, err := json.Marshal(cfg)
- assert.Nil(t, err)
- mockRegistry.On("GetUpkeepPrivilegeConfig", mock.Anything, upkeepId).Return(b, nil)
- r.registry = mockRegistry
+ bCfg, err := json.Marshal(cfg)
+ require.Nil(t, err)
+
+ bContractCfg, err := r.abi.Methods["getUpkeepPrivilegeConfig"].Outputs.PackValues([]interface{}{bCfg})
+ require.Nil(t, err)
+
+ payload, err := r.abi.Pack("getUpkeepPrivilegeConfig", upkeepId)
+ require.Nil(t, err)
+
+ args := map[string]interface{}{
+ "to": r.addr.Hex(),
+ "data": hexutil.Bytes(payload),
+ }
+
+ client.On("CallContext", mock.Anything, mock.AnythingOfType("*hexutil.Bytes"), "eth_call", args, mock.AnythingOfType("string")).Return(nil).
+ Run(func(args mock.Arguments) {
+ b := args.Get(1).(*hexutil.Bytes)
+ *b = bContractCfg
+ }).Once()
}
- if tt.blob != "" {
+ if len(tt.blobs) > 0 {
hc := mocks.NewHttpClient(t)
- mr := MercuryV02Response{ChainlinkBlob: tt.blob}
- b, err := json.Marshal(mr)
+ mr1 := MercuryV02Response{ChainlinkBlob: tt.blobs["0x4554482d5553442d415242495452554d2d544553544e45540000000000000000"]}
+ b1, err := json.Marshal(mr1)
assert.Nil(t, err)
- resp := &http.Response{
+ resp1 := &http.Response{
StatusCode: http.StatusOK,
- Body: io.NopCloser(bytes.NewReader(b)),
+ Body: io.NopCloser(bytes.NewReader(b1)),
}
- hc.On("Do", mock.Anything).Return(resp, nil).Once()
+ mr2 := MercuryV02Response{ChainlinkBlob: tt.blobs["0x4254432d5553442d415242495452554d2d544553544e45540000000000000000"]}
+ b2, err := json.Marshal(mr2)
+ assert.Nil(t, err)
+ resp2 := &http.Response{
+ StatusCode: http.StatusOK,
+ Body: io.NopCloser(bytes.NewReader(b2)),
+ }
+ hc.On("Do", mock.MatchedBy(func(req *http.Request) bool {
+ return strings.Contains(req.URL.String(), "0x4254432d5553442d415242495452554d2d544553544e45540000000000000000")
+ })).Return(resp2, nil).Once()
+
+ hc.On("Do", mock.MatchedBy(func(req *http.Request) bool {
+ return strings.Contains(req.URL.String(), "0x4554482d5553442d415242495452554d2d544553544e45540000000000000000")
+ })).Return(resp1, nil).Once()
r.hc = hc
}
@@ -210,37 +244,35 @@ func TestEvmRegistry_FeedLookup(t *testing.T) {
"to": r.addr.Hex(),
"data": hexutil.Bytes(payload),
}
- client := new(evmClientMocks.Client)
- client.On("CallContext", mock.Anything, mock.AnythingOfType("*hexutil.Bytes"), "eth_call", args, hexutil.EncodeUint64(uint64(26046145))).Return(nil).
+ client.On("CallContext", mock.Anything, mock.AnythingOfType("*hexutil.Bytes"), "eth_call", args, hexutil.EncodeUint64(uint64(blockNum))).Return(nil).
Run(func(args mock.Arguments) {
b := args.Get(1).(*hexutil.Bytes)
*b = tt.checkCallbackResp
}).Once()
- r.client = client
}
- got := r.feedLookup(context.Background(), tt.input)
+ got := r.streamsLookup(context.Background(), tt.input)
assert.Equal(t, tt.expectedResults, got, tt.name)
})
}
}
-func TestEvmRegistry_DecodeFeedLookup(t *testing.T) {
+func TestEvmRegistry_DecodeStreamsLookup(t *testing.T) {
tests := []struct {
name string
data []byte
- expected *FeedLookup
+ expected *StreamsLookup
state encoding.PipelineExecutionState
err error
}{
{
- name: "success - decode to feed lookup",
- data: []byte{125, 221, 147, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 138, 215, 253, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 102, 101, 101, 100, 73, 100, 72, 101, 120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 48, 120, 52, 53, 53, 52, 52, 56, 50, 100, 53, 53, 53, 51, 52, 52, 50, 100, 52, 49, 53, 50, 52, 50, 52, 57, 53, 52, 53, 50, 53, 53, 52, 100, 50, 100, 53, 52, 52, 53, 53, 51, 53, 52, 52, 101, 52, 53, 53, 52, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 48, 120, 52, 50, 53, 52, 52, 51, 50, 100, 53, 53, 53, 51, 52, 52, 50, 100, 52, 49, 53, 50, 52, 50, 52, 57, 53, 52, 53, 50, 53, 53, 52, 100, 50, 100, 53, 52, 52, 53, 53, 51, 53, 52, 52, 101, 52, 53, 53, 52, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 98, 108, 111, 99, 107, 78, 117, 109, 98, 101, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- expected: &FeedLookup{
+ name: "success - decode to streams lookup",
+ data: hexutil.MustDecode("0xf055e4a200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000000000000000000000000000002435eb50000000000000000000000000000000000000000000000000000000000000280000000000000000000000000000000000000000000000000000000000000000966656564496448657800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000423078343535343438326435353533343432643431353234323439353435323535346432643534343535333534346534353534303030303030303030303030303030300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000042307834323534343332643535353334343264343135323432343935343532353534643264353434353533353434653435353430303030303030303030303030303030000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b626c6f636b4e756d62657200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000064000000000000000000000000"),
+ expected: &StreamsLookup{
feedParamKey: feedIdHex,
feeds: []string{"0x4554482d5553442d415242495452554d2d544553544e45540000000000000000", "0x4254432d5553442d415242495452554d2d544553544e45540000000000000000"},
timeParamKey: blockNumber,
- time: big.NewInt(25876477),
+ time: big.NewInt(37969589),
extraData: []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100},
},
},
@@ -254,7 +286,7 @@ func TestEvmRegistry_DecodeFeedLookup(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
r := setupEVMRegistry(t)
- fl, err := r.decodeFeedLookup(tt.data)
+ fl, err := r.decodeStreamsLookup(tt.data)
assert.Equal(t, tt.expected, fl)
if tt.err != nil {
assert.Equal(t, tt.err.Error(), err.Error())
@@ -320,24 +352,59 @@ func TestEvmRegistry_AllowedToUseMercury(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
r := setupEVMRegistry(t)
+ client := new(evmClientMocks.Client)
+ r.client = client
+
if tt.cached {
r.mercury.allowListCache.Set(upkeepId.String(), tt.allowed, cache.DefaultExpiration)
} else {
if tt.err != nil {
- mockRegistry := mocks.NewRegistry(t)
- mockRegistry.On("GetUpkeepPrivilegeConfig", mock.Anything, upkeepId).Return(tt.config, tt.ethCallErr)
- r.registry = mockRegistry
+ bContractCfg, err := r.abi.Methods["getUpkeepPrivilegeConfig"].Outputs.PackValues([]interface{}{tt.config})
+ require.Nil(t, err)
+
+ payload, err := r.abi.Pack("getUpkeepPrivilegeConfig", upkeepId)
+ require.Nil(t, err)
+
+ args := map[string]interface{}{
+ "to": r.addr.Hex(),
+ "data": hexutil.Bytes(payload),
+ }
+
+ client.On("CallContext", mock.Anything, mock.AnythingOfType("*hexutil.Bytes"), "eth_call", args, mock.AnythingOfType("string")).
+ Return(tt.ethCallErr).
+ Run(func(args mock.Arguments) {
+ b := args.Get(1).(*hexutil.Bytes)
+ *b = bContractCfg
+ }).Once()
} else {
- mockRegistry := mocks.NewRegistry(t)
cfg := UpkeepPrivilegeConfig{MercuryEnabled: tt.allowed}
- b, err := json.Marshal(cfg)
- assert.Nil(t, err)
- mockRegistry.On("GetUpkeepPrivilegeConfig", mock.Anything, upkeepId).Return(b, nil)
- r.registry = mockRegistry
+ bCfg, err := json.Marshal(cfg)
+ require.Nil(t, err)
+
+ bContractCfg, err := r.abi.Methods["getUpkeepPrivilegeConfig"].Outputs.PackValues([]interface{}{bCfg})
+ require.Nil(t, err)
+
+ payload, err := r.abi.Pack("getUpkeepPrivilegeConfig", upkeepId)
+ require.Nil(t, err)
+
+ args := map[string]interface{}{
+ "to": r.addr.Hex(),
+ "data": hexutil.Bytes(payload),
+ }
+
+ client.On("CallContext", mock.Anything, mock.AnythingOfType("*hexutil.Bytes"), "eth_call", args, mock.AnythingOfType("string")).Return(nil).
+ Run(func(args mock.Arguments) {
+ b := args.Get(1).(*hexutil.Bytes)
+ *b = bContractCfg
+ }).Once()
}
}
- state, reason, retryable, allowed, err := r.allowedToUseMercury(nil, upkeepId)
+ opts := &bind.CallOpts{
+ BlockNumber: big.NewInt(10),
+ }
+
+ state, reason, retryable, allowed, err := r.allowedToUseMercury(opts, upkeepId)
assert.Equal(t, tt.err, err)
assert.Equal(t, tt.allowed, allowed)
assert.Equal(t, tt.state, state)
@@ -348,12 +415,11 @@ func TestEvmRegistry_AllowedToUseMercury(t *testing.T) {
}
func TestEvmRegistry_DoMercuryRequest(t *testing.T) {
- upkeepId := big.NewInt(0)
- upkeepId.SetString("88786950015966611018675766524283132478093844178961698330929478019253453382042", 10)
+ upkeepId, _ := new(big.Int).SetString("88786950015966611018675766524283132478093844178961698330929478019253453382042", 10)
tests := []struct {
name string
- lookup *FeedLookup
+ lookup *StreamsLookup
mockHttpStatusCode int
mockChainlinkBlobs []string
expectedValues [][]byte
@@ -364,7 +430,7 @@ func TestEvmRegistry_DoMercuryRequest(t *testing.T) {
}{
{
name: "success",
- lookup: &FeedLookup{
+ lookup: &StreamsLookup{
feedParamKey: feedIdHex,
feeds: []string{"0x4554482d5553442d415242495452554d2d544553544e45540000000000000000"},
timeParamKey: blockNumber,
@@ -380,7 +446,7 @@ func TestEvmRegistry_DoMercuryRequest(t *testing.T) {
},
{
name: "failure - retryable",
- lookup: &FeedLookup{
+ lookup: &StreamsLookup{
feedParamKey: feedIdHex,
feeds: []string{"0x4554482d5553442d415242495452554d2d544553544e45540000000000000000"},
timeParamKey: blockNumber,
@@ -392,12 +458,12 @@ func TestEvmRegistry_DoMercuryRequest(t *testing.T) {
mockChainlinkBlobs: []string{"0x00066dfcd1ed2d95b18c948dbc5bd64c687afe93e4ca7d663ddec14c20090ad80000000000000000000000000000000000000000000000000000000000081401000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000002200000000000000000000000000000000000000000000000000000000000000280000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001204554482d5553442d415242495452554d2d544553544e455400000000000000000000000000000000000000000000000000000000000000000000000064891c98000000000000000000000000000000000000000000000000000000289ad8d367000000000000000000000000000000000000000000000000000000289acf0b38000000000000000000000000000000000000000000000000000000289b3da40000000000000000000000000000000000000000000000000000000000018ae7ce74d9fa252a8983976eab600dc7590c778d04813430841bc6e765c34cd81a168d00000000000000000000000000000000000000000000000000000000018ae7cb0000000000000000000000000000000000000000000000000000000064891c98000000000000000000000000000000000000000000000000000000000000000260412b94e525ca6cedc9f544fd86f77606d52fe731a5d069dbe836a8bfc0fb8c911963b0ae7a14971f3b4621bffb802ef0605392b9a6c89c7fab1df8633a5ade00000000000000000000000000000000000000000000000000000000000000024500c2f521f83fba5efc2bf3effaaedde43d0a4adff785c1213b712a3aed0d8157642a84324db0cf9695ebd27708d4608eb0337e0dd87b0e43f0fa70c700d911"},
expectedValues: [][]byte{nil},
expectedRetryable: true,
- expectedError: errors.New("All attempts fail:\n#1: 500\n#2: 500\n#3: 500"),
+ expectedError: errors.New("failed to request feed for 0x4554482d5553442d415242495452554d2d544553544e45540000000000000000: All attempts fail:\n#1: 500\n#2: 500\n#3: 500"),
state: encoding.MercuryFlakyFailure,
},
{
name: "failure - not retryable",
- lookup: &FeedLookup{
+ lookup: &StreamsLookup{
feedParamKey: feedIdHex,
feeds: []string{"0x4554482d5553442d415242495452554d2d544553544e45540000000000000000"},
timeParamKey: blockNumber,
@@ -409,12 +475,12 @@ func TestEvmRegistry_DoMercuryRequest(t *testing.T) {
mockChainlinkBlobs: []string{"0x00066dfcd1ed2d95b18c948dbc5bd64c687afe93e4ca7d663ddec14c20090ad80000000000000000000000000000000000000000000000000000000000081401000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000002200000000000000000000000000000000000000000000000000000000000000280000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001204554482d5553442d415242495452554d2d544553544e455400000000000000000000000000000000000000000000000000000000000000000000000064891c98000000000000000000000000000000000000000000000000000000289ad8d367000000000000000000000000000000000000000000000000000000289acf0b38000000000000000000000000000000000000000000000000000000289b3da40000000000000000000000000000000000000000000000000000000000018ae7ce74d9fa252a8983976eab600dc7590c778d04813430841bc6e765c34cd81a168d00000000000000000000000000000000000000000000000000000000018ae7cb0000000000000000000000000000000000000000000000000000000064891c98000000000000000000000000000000000000000000000000000000000000000260412b94e525ca6cedc9f544fd86f77606d52fe731a5d069dbe836a8bfc0fb8c911963b0ae7a14971f3b4621bffb802ef0605392b9a6c89c7fab1df8633a5ade00000000000000000000000000000000000000000000000000000000000000024500c2f521f83fba5efc2bf3effaaedde43d0a4adff785c1213b712a3aed0d8157642a84324db0cf9695ebd27708d4608eb0337e0dd87b0e43f0fa70c700d911"},
expectedValues: [][]byte{nil},
expectedRetryable: false,
- expectedError: errors.New("All attempts fail:\n#1: at block 25880526 upkeep 88786950015966611018675766524283132478093844178961698330929478019253453382042 received status code 502 for feed 0x4554482d5553442d415242495452554d2d544553544e45540000000000000000"),
+ expectedError: errors.New("failed to request feed for 0x4554482d5553442d415242495452554d2d544553544e45540000000000000000: All attempts fail:\n#1: at block 25880526 upkeep 88786950015966611018675766524283132478093844178961698330929478019253453382042 received status code 502 for feed 0x4554482d5553442d415242495452554d2d544553544e45540000000000000000"),
state: encoding.InvalidMercuryRequest,
},
{
name: "failure - no feeds",
- lookup: &FeedLookup{
+ lookup: &StreamsLookup{
feedParamKey: feedIdHex,
feeds: []string{},
timeParamKey: blockNumber,
@@ -427,7 +493,7 @@ func TestEvmRegistry_DoMercuryRequest(t *testing.T) {
},
{
name: "failure - invalid revert data",
- lookup: &FeedLookup{
+ lookup: &StreamsLookup{
feedParamKey: feedIDs,
feeds: []string{},
timeParamKey: blockNumber,
@@ -479,7 +545,7 @@ func TestEvmRegistry_SingleFeedRequest(t *testing.T) {
tests := []struct {
name string
index int
- lookup *FeedLookup
+ lookup *StreamsLookup
blob string
statusCode int
lastStatusCode int
@@ -490,7 +556,7 @@ func TestEvmRegistry_SingleFeedRequest(t *testing.T) {
{
name: "success - mercury responds in the first try",
index: 0,
- lookup: &FeedLookup{
+ lookup: &StreamsLookup{
feedParamKey: feedIdHex,
feeds: []string{"0x4554482d5553442d415242495452554d2d544553544e45540000000000000000"},
timeParamKey: blockNumber,
@@ -502,7 +568,7 @@ func TestEvmRegistry_SingleFeedRequest(t *testing.T) {
{
name: "success - retry for 404",
index: 0,
- lookup: &FeedLookup{
+ lookup: &StreamsLookup{
feedParamKey: feedIdHex,
feeds: []string{"0x4554482d5553442d415242495452554d2d544553544e45540000000000000000"},
timeParamKey: blockNumber,
@@ -517,7 +583,7 @@ func TestEvmRegistry_SingleFeedRequest(t *testing.T) {
{
name: "success - retry for 500",
index: 0,
- lookup: &FeedLookup{
+ lookup: &StreamsLookup{
feedParamKey: feedIdHex,
feeds: []string{"0x4554482d5553442d415242495452554d2d544553544e45540000000000000000"},
timeParamKey: blockNumber,
@@ -532,7 +598,7 @@ func TestEvmRegistry_SingleFeedRequest(t *testing.T) {
{
name: "failure - returns retryable",
index: 0,
- lookup: &FeedLookup{
+ lookup: &StreamsLookup{
feedParamKey: feedIdHex,
feeds: []string{"0x4554482d5553442d415242495452554d2d544553544e45540000000000000000"},
timeParamKey: blockNumber,
@@ -543,12 +609,12 @@ func TestEvmRegistry_SingleFeedRequest(t *testing.T) {
retryNumber: totalAttempt,
statusCode: http.StatusNotFound,
retryable: true,
- errorMessage: "All attempts fail:\n#1: 404\n#2: 404\n#3: 404",
+ errorMessage: "failed to request feed for 0x4554482d5553442d415242495452554d2d544553544e45540000000000000000: All attempts fail:\n#1: 404\n#2: 404\n#3: 404",
},
{
name: "failure - returns retryable and then non-retryable",
index: 0,
- lookup: &FeedLookup{
+ lookup: &StreamsLookup{
feedParamKey: feedIdHex,
feeds: []string{"0x4554482d5553442d415242495452554d2d544553544e45540000000000000000"},
timeParamKey: blockNumber,
@@ -559,12 +625,12 @@ func TestEvmRegistry_SingleFeedRequest(t *testing.T) {
retryNumber: 1,
statusCode: http.StatusNotFound,
lastStatusCode: http.StatusBadGateway,
- errorMessage: "All attempts fail:\n#1: 404\n#2: at block 123456 upkeep 123456789 received status code 502 for feed 0x4554482d5553442d415242495452554d2d544553544e45540000000000000000",
+ errorMessage: "failed to request feed for 0x4554482d5553442d415242495452554d2d544553544e45540000000000000000: All attempts fail:\n#1: 404\n#2: at block 123456 upkeep 123456789 received status code 502 for feed 0x4554482d5553442d415242495452554d2d544553544e45540000000000000000",
},
{
name: "failure - returns not retryable",
index: 0,
- lookup: &FeedLookup{
+ lookup: &StreamsLookup{
feedParamKey: feedIdHex,
feeds: []string{"0x4554482d5553442d415242495452554d2d544553544e45540000000000000000"},
timeParamKey: blockNumber,
@@ -573,7 +639,7 @@ func TestEvmRegistry_SingleFeedRequest(t *testing.T) {
},
blob: "0xab2123dc",
statusCode: http.StatusBadGateway,
- errorMessage: "All attempts fail:\n#1: at block 123456 upkeep 123456789 received status code 502 for feed 0x4554482d5553442d415242495452554d2d544553544e45540000000000000000",
+ errorMessage: "failed to request feed for 0x4554482d5553442d415242495452554d2d544553544e45540000000000000000: All attempts fail:\n#1: at block 123456 upkeep 123456789 received status code 502 for feed 0x4554482d5553442d415242495452554d2d544553544e45540000000000000000",
},
}
@@ -644,35 +710,36 @@ func TestEvmRegistry_MultiFeedRequest(t *testing.T) {
upkeepId := big.NewInt(123456789)
tests := []struct {
name string
- lookup *FeedLookup
+ lookup *StreamsLookup
statusCode int
lastStatusCode int
retryNumber int
retryable bool
errorMessage string
- response MercuryV03Response
+ firstResponse *MercuryV03Response
+ response *MercuryV03Response
}{
{
name: "success - mercury responds in the first try",
- lookup: &FeedLookup{
+ lookup: &StreamsLookup{
feedParamKey: feedIDs,
feeds: []string{"0x4554482d5553442d415242495452554d2d544553544e45540000000000000000", "0x4254432d5553442d415242495452554d2d544553544e45540000000000000000"},
timeParamKey: timestamp,
time: big.NewInt(123456),
upkeepId: upkeepId,
},
- response: MercuryV03Response{
+ response: &MercuryV03Response{
Reports: []MercuryV03Report{
{
FeedID: "0x4554482d5553442d415242495452554d2d544553544e45540000000000000000",
- ValidFromTimestamp: "123456",
- ObservationsTimestamp: "123456",
+ ValidFromTimestamp: 123456,
+ ObservationsTimestamp: 123456,
FullReport: "0xab2123dc00000012",
},
{
FeedID: "0x4254432d5553442d415242495452554d2d544553544e45540000000000000000",
- ValidFromTimestamp: "123458",
- ObservationsTimestamp: "123458",
+ ValidFromTimestamp: 123458,
+ ObservationsTimestamp: 123458,
FullReport: "0xab2123dc00000016",
},
},
@@ -680,66 +747,66 @@ func TestEvmRegistry_MultiFeedRequest(t *testing.T) {
statusCode: http.StatusOK,
},
{
- name: "success - retry for 404",
- lookup: &FeedLookup{
+ name: "success - retry for 500",
+ lookup: &StreamsLookup{
feedParamKey: feedIDs,
feeds: []string{"0x4554482d5553442d415242495452554d2d544553544e45540000000000000000", "0x4254432d5553442d415242495452554d2d544553544e45540000000000000000"},
timeParamKey: timestamp,
time: big.NewInt(123456),
upkeepId: upkeepId,
},
- retryNumber: 1,
- statusCode: http.StatusNotFound,
+ retryNumber: 2,
+ statusCode: http.StatusInternalServerError,
lastStatusCode: http.StatusOK,
- response: MercuryV03Response{
+ response: &MercuryV03Response{
Reports: []MercuryV03Report{
{
FeedID: "0x4554482d5553442d415242495452554d2d544553544e45540000000000000000",
- ValidFromTimestamp: "123456",
- ObservationsTimestamp: "123456",
+ ValidFromTimestamp: 123456,
+ ObservationsTimestamp: 123456,
FullReport: "0xab2123dc00000012",
},
{
FeedID: "0x4254432d5553442d415242495452554d2d544553544e45540000000000000000",
- ValidFromTimestamp: "123458",
- ObservationsTimestamp: "123458",
- FullReport: "0xab2123dc00000012",
+ ValidFromTimestamp: 123458,
+ ObservationsTimestamp: 123458,
+ FullReport: "0xab2123dc00000019",
},
},
},
},
{
- name: "success - retry for 500",
- lookup: &FeedLookup{
+ name: "failure - fail to decode reportBlob",
+ lookup: &StreamsLookup{
feedParamKey: feedIDs,
feeds: []string{"0x4554482d5553442d415242495452554d2d544553544e45540000000000000000", "0x4254432d5553442d415242495452554d2d544553544e45540000000000000000"},
timeParamKey: timestamp,
time: big.NewInt(123456),
upkeepId: upkeepId,
},
- retryNumber: 2,
- statusCode: http.StatusInternalServerError,
- lastStatusCode: http.StatusOK,
- response: MercuryV03Response{
+ response: &MercuryV03Response{
Reports: []MercuryV03Report{
{
FeedID: "0x4554482d5553442d415242495452554d2d544553544e45540000000000000000",
- ValidFromTimestamp: "123456",
- ObservationsTimestamp: "123456",
- FullReport: "0xab2123dc00000012",
+ ValidFromTimestamp: 123456,
+ ObservationsTimestamp: 123456,
+ FullReport: "qerwiu", // invalid hex blob
},
{
FeedID: "0x4254432d5553442d415242495452554d2d544553544e45540000000000000000",
- ValidFromTimestamp: "123458",
- ObservationsTimestamp: "123458",
- FullReport: "0xab2123dc00000019",
+ 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: &FeedLookup{
+ lookup: &StreamsLookup{
feedParamKey: feedIDs,
feeds: []string{"0x4554482d5553442d415242495452554d2d544553544e45540000000000000000", "0x4254432d5553442d415242495452554d2d544553544e45540000000000000000"},
timeParamKey: timestamp,
@@ -747,13 +814,13 @@ func TestEvmRegistry_MultiFeedRequest(t *testing.T) {
upkeepId: upkeepId,
},
retryNumber: totalAttempt,
- statusCode: http.StatusNotFound,
+ statusCode: http.StatusInternalServerError,
retryable: true,
- errorMessage: "All attempts fail:\n#1: 404\n#2: 404\n#3: 404",
+ errorMessage: "All attempts fail:\n#1: 500\n#2: 500\n#3: 500",
},
{
name: "failure - returns retryable and then non-retryable",
- lookup: &FeedLookup{
+ lookup: &StreamsLookup{
feedParamKey: feedIDs,
feeds: []string{"0x4554482d5553442d415242495452554d2d544553544e45540000000000000000", "0x4254432d5553442d415242495452554d2d544553544e45540000000000000000"},
timeParamKey: timestamp,
@@ -761,13 +828,25 @@ func TestEvmRegistry_MultiFeedRequest(t *testing.T) {
upkeepId: upkeepId,
},
retryNumber: 1,
- statusCode: http.StatusNotFound,
- lastStatusCode: http.StatusBadGateway,
- errorMessage: "All attempts fail:\n#1: 404\n#2: at block 123456 upkeep 123456789 received status code 502 from mercury v0.3",
+ statusCode: http.StatusInternalServerError,
+ lastStatusCode: http.StatusUnauthorized,
+ errorMessage: "All attempts fail:\n#1: 500\n#2: at timestamp 123456 upkeep 123456789 received status code 401 from mercury v0.3, most likely this is caused by unauthorized upkeep",
},
{
- name: "failure - returns not retryable",
- lookup: &FeedLookup{
+ name: "failure - returns status code 420 not retryable",
+ lookup: &StreamsLookup{
+ feedParamKey: feedIDs,
+ feeds: []string{"0x4554482d5553442d415242495452554d2d544553544e45540000000000000000"},
+ timeParamKey: timestamp,
+ time: big.NewInt(123456),
+ upkeepId: upkeepId,
+ },
+ statusCode: 420,
+ errorMessage: "All attempts fail:\n#1: at timestamp 123456 upkeep 123456789 received status code 420 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",
+ },
+ {
+ name: "failure - returns status code 502 not retryable",
+ lookup: &StreamsLookup{
feedParamKey: feedIDs,
feeds: []string{"0x4554482d5553442d415242495452554d2d544553544e45540000000000000000"},
timeParamKey: timestamp,
@@ -775,29 +854,45 @@ func TestEvmRegistry_MultiFeedRequest(t *testing.T) {
upkeepId: upkeepId,
},
statusCode: http.StatusBadGateway,
- errorMessage: "All attempts fail:\n#1: at block 123456 upkeep 123456789 received status code 502 from mercury v0.3",
+ errorMessage: "All attempts fail:\n#1: at timestamp 123456 upkeep 123456789 received status code 502 from mercury v0.3",
},
{
- name: "failure - reports length does not match feeds length",
- lookup: &FeedLookup{
+ name: "success - retry when reports length does not match feeds length",
+ lookup: &StreamsLookup{
feedParamKey: feedIDs,
feeds: []string{"0x4554482d5553442d415242495452554d2d544553544e45540000000000000000", "0x4254432d5553442d415242495452554d2d544553544e45540000000000000000"},
timeParamKey: timestamp,
time: big.NewInt(123456),
upkeepId: upkeepId,
},
- response: MercuryV03Response{
+ firstResponse: &MercuryV03Response{
Reports: []MercuryV03Report{
{
FeedID: "0x4554482d5553442d415242495452554d2d544553544e45540000000000000000",
- ValidFromTimestamp: "123456",
- ObservationsTimestamp: "123456",
+ ValidFromTimestamp: 123456,
+ ObservationsTimestamp: 123456,
FullReport: "0xab2123dc00000012",
},
},
},
- statusCode: http.StatusOK,
- errorMessage: "All attempts fail:\n#1: at block 123456 upkeep 123456789 requested 2 feeds but received 1 reports from mercury v0.3",
+ response: &MercuryV03Response{
+ Reports: []MercuryV03Report{
+ {
+ FeedID: "0x4554482d5553442d415242495452554d2d544553544e45540000000000000000",
+ ValidFromTimestamp: 123456,
+ ObservationsTimestamp: 123456,
+ FullReport: "0xab2123dc00000012",
+ },
+ {
+ FeedID: "0x4254432d5553442d415242495452554d2d544553544e45540000000000000000",
+ ValidFromTimestamp: 123458,
+ ObservationsTimestamp: 123458,
+ FullReport: "0xab2123dc00000019",
+ },
+ },
+ },
+ retryNumber: 1,
+ statusCode: http.StatusOK,
},
}
@@ -815,17 +910,33 @@ func TestEvmRegistry_MultiFeedRequest(t *testing.T) {
}
hc.On("Do", mock.Anything).Return(resp, nil).Once()
} else if tt.retryNumber < totalAttempt {
- retryResp := &http.Response{
- StatusCode: tt.statusCode,
- Body: io.NopCloser(bytes.NewReader(b)),
- }
- hc.On("Do", mock.Anything).Return(retryResp, nil).Times(tt.retryNumber)
+ if tt.firstResponse != nil && tt.response != nil {
+ b0, err := json.Marshal(tt.firstResponse)
+ assert.Nil(t, err)
+ resp0 := &http.Response{
+ StatusCode: tt.statusCode,
+ Body: io.NopCloser(bytes.NewReader(b0)),
+ }
+ b1, err := json.Marshal(tt.response)
+ assert.Nil(t, err)
+ resp1 := &http.Response{
+ StatusCode: tt.statusCode,
+ Body: io.NopCloser(bytes.NewReader(b1)),
+ }
+ hc.On("Do", mock.Anything).Return(resp0, nil).Once().On("Do", mock.Anything).Return(resp1, nil).Once()
+ } else {
+ retryResp := &http.Response{
+ StatusCode: tt.statusCode,
+ Body: io.NopCloser(bytes.NewReader(b)),
+ }
+ hc.On("Do", mock.Anything).Return(retryResp, nil).Times(tt.retryNumber)
- resp := &http.Response{
- StatusCode: tt.lastStatusCode,
- Body: io.NopCloser(bytes.NewReader(b)),
+ resp := &http.Response{
+ StatusCode: tt.lastStatusCode,
+ Body: io.NopCloser(bytes.NewReader(b)),
+ }
+ hc.On("Do", mock.Anything).Return(resp, nil).Once()
}
- hc.On("Do", mock.Anything).Return(resp, nil).Once()
} else {
resp := &http.Response{
StatusCode: tt.statusCode,
@@ -847,11 +958,9 @@ func TestEvmRegistry_MultiFeedRequest(t *testing.T) {
} else {
assert.Nil(t, m.Error)
var reports [][]byte
- var report []byte
for _, rsp := range tt.response.Reports {
- report, err = hexutil.Decode(rsp.FullReport)
- assert.Nil(t, err)
- reports = append(reports, report)
+ b, _ := hexutil.Decode(rsp.FullReport)
+ reports = append(reports, b)
}
assert.Equal(t, reports, m.Bytes)
}
@@ -866,7 +975,7 @@ func TestEvmRegistry_CheckCallback(t *testing.T) {
values := [][]byte{bs}
tests := []struct {
name string
- lookup *FeedLookup
+ lookup *StreamsLookup
values [][]byte
statusCode int
@@ -882,7 +991,7 @@ func TestEvmRegistry_CheckCallback(t *testing.T) {
}{
{
name: "success - empty extra data",
- lookup: &FeedLookup{
+ lookup: &StreamsLookup{
feedParamKey: feedIdHex,
feeds: []string{"ETD-USD", "BTC-ETH"},
timeParamKey: blockNumber,
@@ -900,7 +1009,7 @@ func TestEvmRegistry_CheckCallback(t *testing.T) {
},
{
name: "success - with extra data",
- lookup: &FeedLookup{
+ lookup: &StreamsLookup{
feedParamKey: feedIdHex,
feeds: []string{"0x4554482d5553442d415242495452554d2d544553544e45540000000000000000", "0x4254432d5553442d415242495452554d2d544553544e45540000000000000000"},
timeParamKey: blockNumber,
@@ -919,7 +1028,7 @@ func TestEvmRegistry_CheckCallback(t *testing.T) {
},
{
name: "failure - bad response",
- lookup: &FeedLookup{
+ lookup: &StreamsLookup{
feedParamKey: feedIdHex,
feeds: []string{"ETD-USD", "BTC-ETH"},
timeParamKey: blockNumber,
diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/transmit/cache.go b/core/services/ocr2/plugins/ocr2keeper/evm21/transmit/cache.go
new file mode 100644
index 00000000000..5e0dadbdc4f
--- /dev/null
+++ b/core/services/ocr2/plugins/ocr2keeper/evm21/transmit/cache.go
@@ -0,0 +1,72 @@
+package transmit
+
+import (
+ "sync"
+
+ ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg/v3/types"
+)
+
+// transmitEventCache holds a ring buffer of the last visited blocks (transmit block),
+// and their corresponding logs (by log id).
+// Using a ring buffer allows us to keep a cache of the last N blocks,
+// without having to iterate over the entire buffer to clean it up.
+type transmitEventCache struct {
+ lock sync.RWMutex
+ buffer []cacheBlock
+
+ cap int64
+}
+
+func newTransmitEventCache(cap int64) transmitEventCache {
+ return transmitEventCache{
+ buffer: make([]cacheBlock, cap),
+ cap: cap,
+ }
+}
+
+func (c *transmitEventCache) get(block ocr2keepers.BlockNumber, logID string) (ocr2keepers.TransmitEvent, bool) {
+ c.lock.RLock()
+ defer c.lock.RUnlock()
+
+ i := int64(block) % int64(c.cap)
+ b := c.buffer[i]
+ if b.block != block {
+ return ocr2keepers.TransmitEvent{}, false
+ }
+ if len(b.records) == 0 {
+ return ocr2keepers.TransmitEvent{}, false
+ }
+ e, ok := b.records[logID]
+
+ return e, ok
+}
+
+func (c *transmitEventCache) add(logID string, e ocr2keepers.TransmitEvent) {
+ c.lock.Lock()
+ defer c.lock.Unlock()
+
+ i := int64(e.TransmitBlock) % int64(c.cap)
+ b := c.buffer[i]
+ isBlockEmpty := len(b.records) == 0
+ isNewBlock := b.block < e.TransmitBlock
+ if isBlockEmpty || isNewBlock {
+ b = newCacheBlock(e.TransmitBlock)
+ } else if b.block > e.TransmitBlock {
+ // old log
+ return
+ }
+ b.records[logID] = e
+ c.buffer[i] = b
+}
+
+type cacheBlock struct {
+ block ocr2keepers.BlockNumber
+ records map[string]ocr2keepers.TransmitEvent
+}
+
+func newCacheBlock(block ocr2keepers.BlockNumber) cacheBlock {
+ return cacheBlock{
+ block: block,
+ records: make(map[string]ocr2keepers.TransmitEvent),
+ }
+}
diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/transmit/cache_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/transmit/cache_test.go
new file mode 100644
index 00000000000..55d245c168f
--- /dev/null
+++ b/core/services/ocr2/plugins/ocr2keeper/evm21/transmit/cache_test.go
@@ -0,0 +1,101 @@
+package transmit
+
+import (
+ "testing"
+
+ ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg/v3/types"
+ "github.com/stretchr/testify/require"
+)
+
+func TestTransmitEventCache_Sanity(t *testing.T) {
+ tests := []struct {
+ name string
+ cap int64
+ logIDsToAdd []string
+ eventsToAdd []ocr2keepers.TransmitEvent
+ toGet []string
+ blocksToGet []int64
+ expected map[string]ocr2keepers.TransmitEvent
+ }{
+ {
+ "empty cache",
+ 10,
+ []string{},
+ []ocr2keepers.TransmitEvent{},
+ []string{"1"},
+ []int64{1},
+ map[string]ocr2keepers.TransmitEvent{},
+ },
+ {
+ "happy path",
+ 10,
+ []string{"3", "2", "4", "1"},
+ []ocr2keepers.TransmitEvent{
+ {WorkID: "3", TransmitBlock: 3},
+ {WorkID: "2", TransmitBlock: 2},
+ {WorkID: "4", TransmitBlock: 4},
+ {WorkID: "1", TransmitBlock: 1},
+ },
+ []string{"1", "3"},
+ []int64{1, 3},
+ map[string]ocr2keepers.TransmitEvent{
+ "1": {WorkID: "1", TransmitBlock: 1},
+ "3": {WorkID: "3", TransmitBlock: 3},
+ },
+ },
+ {
+ "different blocks",
+ 10,
+ []string{"3", "1", "2", "4"},
+ []ocr2keepers.TransmitEvent{
+ {WorkID: "3", TransmitBlock: 3},
+ {WorkID: "1", TransmitBlock: 1},
+ {WorkID: "2", TransmitBlock: 2},
+ {WorkID: "4", TransmitBlock: 4},
+ },
+ []string{"1", "3"},
+ []int64{9, 9},
+ map[string]ocr2keepers.TransmitEvent{},
+ },
+ {
+ "overflow",
+ 3,
+ []string{"4", "1", "3", "2", "5"},
+ []ocr2keepers.TransmitEvent{
+ {WorkID: "4", TransmitBlock: 4},
+ {WorkID: "1", TransmitBlock: 1},
+ {WorkID: "3", TransmitBlock: 3},
+ {WorkID: "2", TransmitBlock: 2},
+ {WorkID: "5", TransmitBlock: 5},
+ },
+ []string{"1", "4", "2", "3", "5"},
+ []int64{1, 4, 2, 3, 5},
+ map[string]ocr2keepers.TransmitEvent{
+ "3": {WorkID: "3", TransmitBlock: 3},
+ "4": {WorkID: "4", TransmitBlock: 4},
+ "5": {WorkID: "5", TransmitBlock: 5},
+ },
+ },
+ }
+
+ for _, tc := range tests {
+ t.Run(tc.name, func(t *testing.T) {
+ c := newTransmitEventCache(tc.cap)
+ require.Equal(t, len(tc.eventsToAdd), len(tc.logIDsToAdd))
+ for i, e := range tc.eventsToAdd {
+ c.add(tc.logIDsToAdd[i], e)
+ }
+ require.Equal(t, len(tc.toGet), len(tc.blocksToGet))
+ for i, logID := range tc.toGet {
+ e, exist := c.get(ocr2keepers.BlockNumber(tc.blocksToGet[i]), logID)
+ expected, ok := tc.expected[logID]
+ if !ok {
+ require.False(t, exist, "expected not to find logID %s", logID)
+ continue
+ }
+ require.True(t, exist, "expected to find logID %s", logID)
+ require.Equal(t, expected.WorkID, e.WorkID)
+ }
+ })
+ }
+}
diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/transmit/encoding.go b/core/services/ocr2/plugins/ocr2keeper/evm21/transmit/encoding.go
new file mode 100644
index 00000000000..ec709d04bd8
--- /dev/null
+++ b/core/services/ocr2/plugins/ocr2keeper/evm21/transmit/encoding.go
@@ -0,0 +1,112 @@
+package transmit
+
+import (
+ "fmt"
+ "math/big"
+
+ ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg/v3/types"
+
+ "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller"
+ iregistry21 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/i_keeper_registry_master_wrapper_2_1"
+)
+
+// defaultLogParser parses logs from the registry contract
+func defaultLogParser(registry *iregistry21.IKeeperRegistryMaster, log logpoller.Log) (transmitEventLog, error) {
+ rawLog := log.ToGethLog()
+ abilog, err := registry.ParseLog(rawLog)
+ if err != nil {
+ return transmitEventLog{}, fmt.Errorf("%w: failed to parse log", err)
+ }
+
+ switch l := abilog.(type) {
+ case *iregistry21.IKeeperRegistryMasterUpkeepPerformed:
+ if l == nil {
+ break
+ }
+ return transmitEventLog{
+ Log: log,
+ Performed: l,
+ }, nil
+ case *iregistry21.IKeeperRegistryMasterReorgedUpkeepReport:
+ if l == nil {
+ break
+ }
+ return transmitEventLog{
+ Log: log,
+ Reorged: l,
+ }, nil
+ case *iregistry21.IKeeperRegistryMasterStaleUpkeepReport:
+ if l == nil {
+ break
+ }
+ return transmitEventLog{
+ Log: log,
+ Stale: l,
+ }, nil
+ case *iregistry21.IKeeperRegistryMasterInsufficientFundsUpkeepReport:
+ if l == nil {
+ break
+ }
+ return transmitEventLog{
+ Log: log,
+ InsufficientFunds: l,
+ }, nil
+ default:
+ return transmitEventLog{}, fmt.Errorf("unknown log type: %v", l)
+ }
+ return transmitEventLog{}, fmt.Errorf("log with bad structure")
+}
+
+// transmitEventLog is a wrapper around logpoller.Log and the parsed log
+type transmitEventLog struct {
+ logpoller.Log
+ Performed *iregistry21.IKeeperRegistryMasterUpkeepPerformed
+ Stale *iregistry21.IKeeperRegistryMasterStaleUpkeepReport
+ Reorged *iregistry21.IKeeperRegistryMasterReorgedUpkeepReport
+ InsufficientFunds *iregistry21.IKeeperRegistryMasterInsufficientFundsUpkeepReport
+}
+
+func (l transmitEventLog) Id() *big.Int {
+ switch {
+ case l.Performed != nil:
+ return l.Performed.Id
+ case l.Stale != nil:
+ return l.Stale.Id
+ case l.Reorged != nil:
+ return l.Reorged.Id
+ case l.InsufficientFunds != nil:
+ return l.InsufficientFunds.Id
+ default:
+ return nil
+ }
+}
+
+func (l transmitEventLog) Trigger() []byte {
+ switch {
+ case l.Performed != nil:
+ return l.Performed.Trigger
+ case l.Stale != nil:
+ return l.Stale.Trigger
+ case l.Reorged != nil:
+ return l.Reorged.Trigger
+ case l.InsufficientFunds != nil:
+ return l.InsufficientFunds.Trigger
+ default:
+ return []byte{}
+ }
+}
+
+func (l transmitEventLog) TransmitEventType() ocr2keepers.TransmitEventType {
+ switch {
+ case l.Performed != nil:
+ return ocr2keepers.PerformEvent
+ case l.Stale != nil:
+ return ocr2keepers.StaleReportEvent
+ case l.Reorged != nil:
+ return ocr2keepers.ReorgReportEvent
+ case l.InsufficientFunds != nil:
+ return ocr2keepers.InsufficientFundsReportEvent
+ default:
+ return ocr2keepers.UnknownEvent
+ }
+}
diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/transmit/encoding_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/transmit/encoding_test.go
new file mode 100644
index 00000000000..f081f82f2a2
--- /dev/null
+++ b/core/services/ocr2/plugins/ocr2keeper/evm21/transmit/encoding_test.go
@@ -0,0 +1,100 @@
+package transmit
+
+import (
+ "testing"
+
+ "github.com/ethereum/go-ethereum/common"
+ ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg/v3/types"
+ "github.com/stretchr/testify/require"
+
+ "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller"
+ iregistry21 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/i_keeper_registry_master_wrapper_2_1"
+ "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21/core"
+)
+
+func TestTransmitEventLog(t *testing.T) {
+ uid := core.GenUpkeepID(ocr2keepers.ConditionTrigger, "111")
+
+ tests := []struct {
+ name string
+ log transmitEventLog
+ etype ocr2keepers.TransmitEventType
+ }{
+ {
+ "performed",
+ transmitEventLog{
+ Log: logpoller.Log{
+ BlockNumber: 1,
+ BlockHash: common.HexToHash("0x010203040"),
+ },
+ Performed: &iregistry21.IKeeperRegistryMasterUpkeepPerformed{
+ Id: uid.BigInt(),
+ Trigger: []byte{1, 2, 3, 4, 5, 6, 7, 8},
+ },
+ },
+ ocr2keepers.PerformEvent,
+ },
+ {
+ "stale",
+ transmitEventLog{
+ Log: logpoller.Log{
+ BlockNumber: 1,
+ BlockHash: common.HexToHash("0x010203040"),
+ },
+ Stale: &iregistry21.IKeeperRegistryMasterStaleUpkeepReport{
+ Id: uid.BigInt(),
+ Trigger: []byte{1, 2, 3, 4, 5, 6, 7, 8},
+ },
+ },
+ ocr2keepers.StaleReportEvent,
+ },
+ {
+ "insufficient funds",
+ transmitEventLog{
+ Log: logpoller.Log{
+ BlockNumber: 1,
+ BlockHash: common.HexToHash("0x010203040"),
+ },
+ InsufficientFunds: &iregistry21.IKeeperRegistryMasterInsufficientFundsUpkeepReport{
+ Id: uid.BigInt(),
+ Trigger: []byte{1, 2, 3, 4, 5, 6, 7, 8},
+ },
+ },
+ ocr2keepers.InsufficientFundsReportEvent,
+ },
+ {
+ "reorged",
+ transmitEventLog{
+ Log: logpoller.Log{
+ BlockNumber: 1,
+ BlockHash: common.HexToHash("0x010203040"),
+ },
+ Reorged: &iregistry21.IKeeperRegistryMasterReorgedUpkeepReport{
+ Id: uid.BigInt(),
+ Trigger: []byte{1, 2, 3, 4, 5, 6, 7, 8},
+ },
+ },
+ ocr2keepers.ReorgReportEvent,
+ },
+ {
+ "empty",
+ transmitEventLog{
+ Log: logpoller.Log{
+ BlockNumber: 1,
+ BlockHash: common.HexToHash("0x010203040"),
+ },
+ },
+ ocr2keepers.UnknownEvent,
+ },
+ }
+
+ for _, tc := range tests {
+ t.Run(tc.name, func(t *testing.T) {
+ if tc.log.Id() != nil {
+ require.Equal(t, uid.BigInt().Int64(), tc.log.Id().Int64())
+ require.Equal(t, []byte{0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8}, tc.log.Trigger())
+ }
+ require.Equal(t, tc.etype, tc.log.TransmitEventType())
+ })
+ }
+}
diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/transmit/event_provider.go b/core/services/ocr2/plugins/ocr2keeper/evm21/transmit/event_provider.go
new file mode 100644
index 00000000000..b0ae2a7bf63
--- /dev/null
+++ b/core/services/ocr2/plugins/ocr2keeper/evm21/transmit/event_provider.go
@@ -0,0 +1,225 @@
+package transmit
+
+import (
+ "context"
+ "encoding/hex"
+ "fmt"
+ "sync"
+
+ "github.com/ethereum/go-ethereum/common"
+ ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg/v3/types"
+
+ evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client"
+ "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller"
+ iregistry21 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/i_keeper_registry_master_wrapper_2_1"
+ "github.com/smartcontractkit/chainlink/v2/core/logger"
+ "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21/core"
+ "github.com/smartcontractkit/chainlink/v2/core/services/pg"
+ "github.com/smartcontractkit/chainlink/v2/core/utils"
+)
+
+var _ ocr2keepers.TransmitEventProvider = &EventProvider{}
+
+type logParser func(registry *iregistry21.IKeeperRegistryMaster, log logpoller.Log) (transmitEventLog, error)
+
+type EventProvider struct {
+ sync utils.StartStopOnce
+ mu sync.RWMutex
+ runState int
+ runError error
+
+ logger logger.Logger
+ logPoller logpoller.LogPoller
+ registry *iregistry21.IKeeperRegistryMaster
+ client evmclient.Client
+
+ registryAddress common.Address
+ lookbackBlocks int64
+
+ parseLog logParser
+ cache transmitEventCache
+}
+
+func EventProviderFilterName(addr common.Address) string {
+ return logpoller.FilterName("KeepersRegistry TransmitEventProvider", addr)
+}
+
+func NewTransmitEventProvider(
+ logger logger.Logger,
+ logPoller logpoller.LogPoller,
+ registryAddress common.Address,
+ client evmclient.Client,
+ lookbackBlocks int64,
+) (*EventProvider, error) {
+ var err error
+
+ contract, err := iregistry21.NewIKeeperRegistryMaster(registryAddress, client)
+ if err != nil {
+ return nil, err
+ }
+ err = logPoller.RegisterFilter(logpoller.Filter{
+ Name: EventProviderFilterName(contract.Address()),
+ EventSigs: []common.Hash{
+ // These are the events that are emitted when a node transmits a report
+ iregistry21.IKeeperRegistryMasterUpkeepPerformed{}.Topic(), // Happy path: report performed the upkeep
+ iregistry21.IKeeperRegistryMasterReorgedUpkeepReport{}.Topic(), // Report checkBlockNumber was reorged
+ iregistry21.IKeeperRegistryMasterInsufficientFundsUpkeepReport{}.Topic(), // Upkeep didn't have sufficient funds when report reached chain, perform was aborted early
+ // Report was too old when it reached the chain. For conditionals upkeep was already performed on a higher block than checkBlockNum
+ // for logs upkeep was already performed for the particular log
+ iregistry21.IKeeperRegistryMasterStaleUpkeepReport{}.Topic(),
+ },
+ Addresses: []common.Address{registryAddress},
+ })
+ if err != nil {
+ return nil, err
+ }
+
+ return &EventProvider{
+ logger: logger,
+ logPoller: logPoller,
+ registryAddress: registryAddress,
+ lookbackBlocks: lookbackBlocks,
+ registry: contract,
+ client: client,
+ parseLog: defaultLogParser,
+ cache: newTransmitEventCache(lookbackBlocks),
+ }, nil
+}
+
+func (c *EventProvider) Name() string {
+ return c.logger.Name()
+}
+
+func (c *EventProvider) Start(_ context.Context) error {
+ return c.sync.StartOnce("AutomationTransmitEventProvider", func() error {
+ c.mu.Lock()
+ defer c.mu.Unlock()
+
+ c.runState = 1
+ return nil
+ })
+}
+
+func (c *EventProvider) Close() error {
+ return c.sync.StopOnce("AutomationRegistry", func() error {
+ c.mu.Lock()
+ defer c.mu.Unlock()
+
+ c.runState = 0
+ c.runError = nil
+ return nil
+ })
+}
+
+func (c *EventProvider) Ready() error {
+ c.mu.RLock()
+ defer c.mu.RUnlock()
+
+ if c.runState == 1 {
+ return nil
+ }
+ return c.sync.Ready()
+}
+
+func (c *EventProvider) HealthReport() map[string]error {
+ c.mu.RLock()
+ defer c.mu.RUnlock()
+
+ if c.runState > 1 {
+ c.sync.SvcErrBuffer.Append(fmt.Errorf("failed run state: %w", c.runError))
+ }
+ return map[string]error{c.Name(): c.sync.Healthy()}
+}
+
+func (c *EventProvider) GetLatestEvents(ctx context.Context) ([]ocr2keepers.TransmitEvent, error) {
+ end, err := c.logPoller.LatestBlock(pg.WithParentCtx(ctx))
+ if err != nil {
+ return nil, fmt.Errorf("%w: failed to get latest block from log poller", err)
+ }
+
+ // always check the last lookback number of blocks and rebroadcast
+ // this allows the plugin to make decisions based on event confirmations
+ logs, err := c.logPoller.LogsWithSigs(
+ end-c.lookbackBlocks,
+ end,
+ []common.Hash{
+ iregistry21.IKeeperRegistryMasterUpkeepPerformed{}.Topic(),
+ iregistry21.IKeeperRegistryMasterStaleUpkeepReport{}.Topic(),
+ iregistry21.IKeeperRegistryMasterReorgedUpkeepReport{}.Topic(),
+ iregistry21.IKeeperRegistryMasterInsufficientFundsUpkeepReport{}.Topic(),
+ },
+ c.registryAddress,
+ pg.WithParentCtx(ctx),
+ )
+ if err != nil {
+ return nil, fmt.Errorf("%w: failed to collect logs from log poller", err)
+ }
+
+ return c.processLogs(end, logs...)
+}
+
+// processLogs will parse the unseen logs and return the corresponding transmit events.
+func (c *EventProvider) processLogs(latestBlock int64, logs ...logpoller.Log) ([]ocr2keepers.TransmitEvent, error) {
+ var vals []ocr2keepers.TransmitEvent
+
+ for _, log := range logs {
+ k := c.logKey(log)
+
+ transmitEvent, ok := c.cache.get(ocr2keepers.BlockNumber(log.BlockNumber), k)
+ if !ok {
+ l, err := c.parseLog(c.registry, log)
+ if err != nil {
+ c.logger.Debugw("failed to parse log", "err", err)
+ continue
+ }
+ id := l.Id()
+ upkeepId := &ocr2keepers.UpkeepIdentifier{}
+ ok := upkeepId.FromBigInt(id)
+ if !ok {
+ return nil, core.ErrInvalidUpkeepID
+ }
+ triggerW, err := core.UnpackTrigger(id, l.Trigger())
+ if err != nil {
+ return nil, fmt.Errorf("%w: failed to unpack trigger", err)
+ }
+ trigger := ocr2keepers.NewTrigger(
+ ocr2keepers.BlockNumber(triggerW.BlockNum),
+ triggerW.BlockHash,
+ )
+ switch core.GetUpkeepType(*upkeepId) {
+ case ocr2keepers.LogTrigger:
+ trigger.LogTriggerExtension = &ocr2keepers.LogTriggerExtension{}
+ trigger.LogTriggerExtension.TxHash = triggerW.TxHash
+ trigger.LogTriggerExtension.Index = triggerW.LogIndex
+ trigger.LogTriggerExtension.BlockHash = triggerW.LogBlockHash
+ default:
+ }
+ workID := core.UpkeepWorkID(*upkeepId, trigger)
+ transmitEvent = ocr2keepers.TransmitEvent{
+ Type: l.TransmitEventType(),
+ TransmitBlock: ocr2keepers.BlockNumber(l.BlockNumber),
+ TransactionHash: l.TxHash,
+ WorkID: workID,
+ UpkeepID: *upkeepId,
+ CheckBlock: trigger.BlockNumber,
+ }
+ c.cache.add(k, transmitEvent)
+ }
+
+ transmitEvent.Confirmations = latestBlock - int64(transmitEvent.TransmitBlock)
+
+ vals = append(vals, transmitEvent)
+ }
+
+ return vals, nil
+}
+
+func (c *EventProvider) logKey(log logpoller.Log) string {
+ logExt := ocr2keepers.LogTriggerExtension{
+ TxHash: log.TxHash,
+ Index: uint32(log.LogIndex),
+ BlockHash: log.BlockHash,
+ }
+ logId := logExt.LogIdentifier()
+ return hex.EncodeToString(logId)
+}
diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/transmit_event_provider_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/transmit/event_provider_test.go
similarity index 52%
rename from core/services/ocr2/plugins/ocr2keeper/evm21/transmit_event_provider_test.go
rename to core/services/ocr2/plugins/ocr2keeper/evm21/transmit/event_provider_test.go
index de619c24df1..72f3b63088d 100644
--- a/core/services/ocr2/plugins/ocr2keeper/evm21/transmit_event_provider_test.go
+++ b/core/services/ocr2/plugins/ocr2keeper/evm21/transmit/event_provider_test.go
@@ -1,4 +1,4 @@
-package evm
+package transmit
import (
"context"
@@ -13,6 +13,7 @@ import (
"github.com/stretchr/testify/require"
"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"
iregistry21 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/i_keeper_registry_master_wrapper_2_1"
@@ -20,15 +21,15 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21/core"
)
-func TestTransmitEventProvider(t *testing.T) {
+func TestTransmitEventProvider_Sanity(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
- mp := new(mocks.LogPoller)
+ lp := new(mocks.LogPoller)
- mp.On("RegisterFilter", mock.Anything).Return(nil)
+ lp.On("RegisterFilter", mock.Anything).Return(nil)
- provider, err := NewTransmitEventProvider(logger.TestLogger(t), mp, common.HexToAddress("0x"), client.NewNullClient(big.NewInt(1), logger.TestLogger(t)), 32)
+ provider, err := NewTransmitEventProvider(logger.TestLogger(t), lp, common.HexToAddress("0x"), client.NewNullClient(big.NewInt(1), logger.TestLogger(t)), 32)
require.NoError(t, err)
require.NotNil(t, provider)
@@ -57,7 +58,6 @@ func TestTransmitEventProvider(t *testing.T) {
errored bool
resultsLen int
}{
- // TODO: add more tests
{
"empty logs",
100,
@@ -89,8 +89,8 @@ func TestTransmitEventProvider(t *testing.T) {
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
- mp.On("LatestBlock", mock.Anything).Return(tc.latestBlock, nil)
- mp.On("LogsWithSigs", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(tc.logs, nil)
+ lp.On("LatestBlock", mock.Anything).Return(tc.latestBlock, nil)
+ lp.On("LogsWithSigs", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(tc.logs, nil)
res, err := provider.GetLatestEvents(ctx)
require.Equal(t, tc.errored, err != nil)
@@ -99,15 +99,22 @@ func TestTransmitEventProvider(t *testing.T) {
}
}
-func TestTransmitEventProvider_ConvertToTransmitEvents(t *testing.T) {
- provider := &TransmitEventProvider{}
+func TestTransmitEventProvider_ProcessLogs(t *testing.T) {
+ lp := new(mocks.LogPoller)
+ lp.On("RegisterFilter", mock.Anything).Return(nil)
+ client := evmClientMocks.NewClient(t)
+
+ provider, err := NewTransmitEventProvider(logger.TestLogger(t), lp, common.HexToAddress("0x"), client, 250)
+ require.NoError(t, err)
+
id := core.GenUpkeepID(ocr2keepers.LogTrigger, "1111111111111111")
+
tests := []struct {
- name string
- performed []transmitEventLog
- latestBlock int64
- want []ocr2keepers.TransmitEvent
- errored bool
+ name string
+ parsedPerformed []transmitEventLog
+ latestBlock int64
+ want []ocr2keepers.TransmitEvent
+ errored bool
}{
{
"happy flow",
@@ -120,7 +127,7 @@ func TestTransmitEventProvider_ConvertToTransmitEvents(t *testing.T) {
Performed: &iregistry21.IKeeperRegistryMasterUpkeepPerformed{
Id: id.BigInt(),
Trigger: func() []byte {
- b, _ := hexutil.Decode("0x0000000000000000000000000000000000000000000000000000000001111111000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000001111111")
+ b, _ := hexutil.Decode("0x0000000000000000000000000000000000000000000000000000000001111abc0000000000000000000000000000000000000000000000000000000001111111000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000001111111")
return b
}(),
},
@@ -131,7 +138,7 @@ func TestTransmitEventProvider_ConvertToTransmitEvents(t *testing.T) {
{
Type: ocr2keepers.PerformEvent,
UpkeepID: id,
- CheckBlock: ocr2keepers.BlockNumber(1), // empty for log triggers
+ CheckBlock: ocr2keepers.BlockNumber(1),
},
},
false,
@@ -143,105 +150,79 @@ func TestTransmitEventProvider_ConvertToTransmitEvents(t *testing.T) {
[]ocr2keepers.TransmitEvent{},
false,
},
- }
-
- for _, tc := range tests {
- t.Run(tc.name, func(t *testing.T) {
- results, err := provider.convertToTransmitEvents(tc.performed, tc.latestBlock)
- require.Equal(t, tc.errored, err != nil)
- require.Len(t, results, len(tc.want))
- for i, res := range results {
- require.Equal(t, tc.want[i].Type, res.Type)
- require.Equal(t, tc.want[i].UpkeepID, res.UpkeepID)
- require.Equal(t, tc.want[i].CheckBlock, res.CheckBlock)
- }
- })
- }
-}
-
-func TestTransmitEventLog(t *testing.T) {
- uid := core.GenUpkeepID(ocr2keepers.ConditionTrigger, "111")
-
- tests := []struct {
- name string
- log transmitEventLog
- etype ocr2keepers.TransmitEventType
- }{
- {
- "performed",
- transmitEventLog{
- Log: logpoller.Log{
- BlockNumber: 1,
- BlockHash: common.HexToHash("0x010203040"),
- },
- Performed: &iregistry21.IKeeperRegistryMasterUpkeepPerformed{
- Id: uid.BigInt(),
- Trigger: []byte{1, 2, 3, 4, 5, 6, 7, 8},
- },
- },
- ocr2keepers.PerformEvent,
- },
- {
- "stale",
- transmitEventLog{
- Log: logpoller.Log{
- BlockNumber: 1,
- BlockHash: common.HexToHash("0x010203040"),
- },
- Stale: &iregistry21.IKeeperRegistryMasterStaleUpkeepReport{
- Id: uid.BigInt(),
- Trigger: []byte{1, 2, 3, 4, 5, 6, 7, 8},
- },
- },
- ocr2keepers.StaleReportEvent,
- },
{
- "insufficient funds",
- transmitEventLog{
- Log: logpoller.Log{
- BlockNumber: 1,
- BlockHash: common.HexToHash("0x010203040"),
+ "same log twice", // shouldn't happen in practice as log poller should not return duplicate logs
+ []transmitEventLog{
+ {
+ Log: logpoller.Log{
+ BlockNumber: 1,
+ BlockHash: common.HexToHash("0x0102030405060708010203040506070801020304050607080102030405060708"),
+ },
+ Performed: &iregistry21.IKeeperRegistryMasterUpkeepPerformed{
+ Id: id.BigInt(),
+ Trigger: func() []byte {
+ b, _ := hexutil.Decode("0x0000000000000000000000000000000000000000000000000000000001111abc0000000000000000000000000000000000000000000000000000000001111111000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000001111111")
+ return b
+ }(),
+ },
},
- InsufficientFunds: &iregistry21.IKeeperRegistryMasterInsufficientFundsUpkeepReport{
- Id: uid.BigInt(),
- Trigger: []byte{1, 2, 3, 4, 5, 6, 7, 8},
+ {
+ Log: logpoller.Log{
+ BlockNumber: 1,
+ BlockHash: common.HexToHash("0x0102030405060708010203040506070801020304050607080102030405060708"),
+ },
+ Performed: &iregistry21.IKeeperRegistryMasterUpkeepPerformed{
+ Id: id.BigInt(),
+ Trigger: func() []byte {
+ b, _ := hexutil.Decode("0x0000000000000000000000000000000000000000000000000000000001111abc0000000000000000000000000000000000000000000000000000000001111111000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000001111111")
+ return b
+ }(),
+ },
},
},
- ocr2keepers.InsufficientFundsReportEvent,
- },
- {
- "reorged",
- transmitEventLog{
- Log: logpoller.Log{
- BlockNumber: 1,
- BlockHash: common.HexToHash("0x010203040"),
- },
- Reorged: &iregistry21.IKeeperRegistryMasterReorgedUpkeepReport{
- Id: uid.BigInt(),
- Trigger: []byte{1, 2, 3, 4, 5, 6, 7, 8},
+ 1,
+ []ocr2keepers.TransmitEvent{
+ {
+ Type: ocr2keepers.PerformEvent,
+ UpkeepID: id,
+ CheckBlock: ocr2keepers.BlockNumber(1),
},
- },
- ocr2keepers.ReorgReportEvent,
- },
- {
- "empty",
- transmitEventLog{
- Log: logpoller.Log{
- BlockNumber: 1,
- BlockHash: common.HexToHash("0x010203040"),
+ {
+ Type: ocr2keepers.PerformEvent,
+ UpkeepID: id,
+ CheckBlock: ocr2keepers.BlockNumber(1),
},
},
- ocr2keepers.UnknownEvent,
+ false,
},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
- if tc.log.Id() != nil {
- require.Equal(t, uid.BigInt().Int64(), tc.log.Id().Int64())
- require.Equal(t, []byte{0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8}, tc.log.Trigger())
+ parseResults := make(map[string]transmitEventLog, len(tc.parsedPerformed))
+ performedLogs := make([]logpoller.Log, len(tc.parsedPerformed))
+ for i, l := range tc.parsedPerformed {
+ performedLogs[i] = l.Log
+ if _, ok := parseResults[provider.logKey(l.Log)]; ok {
+ continue
+ }
+ parseResults[provider.logKey(l.Log)] = l
+ }
+ provider.mu.Lock()
+ provider.cache = newTransmitEventCache(provider.cache.cap)
+ provider.parseLog = func(registry *iregistry21.IKeeperRegistryMaster, log logpoller.Log) (transmitEventLog, error) {
+ return parseResults[provider.logKey(log)], nil
+ }
+ provider.mu.Unlock()
+
+ results, err := provider.processLogs(tc.latestBlock, performedLogs...)
+ require.Equal(t, tc.errored, err != nil)
+ require.Len(t, results, len(tc.want))
+ for i, res := range results {
+ require.Equal(t, tc.want[i].Type, res.Type)
+ require.Equal(t, tc.want[i].UpkeepID, res.UpkeepID)
+ require.Equal(t, tc.want[i].CheckBlock, res.CheckBlock)
}
- require.Equal(t, tc.etype, tc.log.TransmitEventType())
})
}
}
diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/transmit_event_provider.go b/core/services/ocr2/plugins/ocr2keeper/evm21/transmit_event_provider.go
deleted file mode 100644
index 3b87277ee54..00000000000
--- a/core/services/ocr2/plugins/ocr2keeper/evm21/transmit_event_provider.go
+++ /dev/null
@@ -1,302 +0,0 @@
-package evm
-
-import (
- "context"
- "fmt"
- "math/big"
- "sync"
-
- "github.com/ethereum/go-ethereum/common"
- ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg/v3/types"
-
- evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client"
- "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller"
- iregistry21 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/i_keeper_registry_master_wrapper_2_1"
- "github.com/smartcontractkit/chainlink/v2/core/logger"
- "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21/core"
- "github.com/smartcontractkit/chainlink/v2/core/services/pg"
- "github.com/smartcontractkit/chainlink/v2/core/utils"
-)
-
-var _ ocr2keepers.TransmitEventProvider = &TransmitEventProvider{}
-
-type TransmitEventProvider struct {
- sync utils.StartStopOnce
- mu sync.RWMutex
- runState int
- runError error
-
- logger logger.Logger
- logPoller logpoller.LogPoller
- registryAddress common.Address
- lookbackBlocks int64
- registry *iregistry21.IKeeperRegistryMaster
- client evmclient.Client
-}
-
-func TransmitEventProviderFilterName(addr common.Address) string {
- return logpoller.FilterName("KeepersRegistry TransmitEventProvider", addr)
-}
-
-func NewTransmitEventProvider(
- logger logger.Logger,
- logPoller logpoller.LogPoller,
- registryAddress common.Address,
- client evmclient.Client,
- lookbackBlocks int64,
-) (*TransmitEventProvider, error) {
- var err error
-
- contract, err := iregistry21.NewIKeeperRegistryMaster(registryAddress, client)
- if err != nil {
- return nil, err
- }
- err = logPoller.RegisterFilter(logpoller.Filter{
- Name: TransmitEventProviderFilterName(contract.Address()),
- EventSigs: []common.Hash{
- // These are the events that are emitted when a node transmits a report
- iregistry21.IKeeperRegistryMasterUpkeepPerformed{}.Topic(), // Happy path: report performed the upkeep
- iregistry21.IKeeperRegistryMasterReorgedUpkeepReport{}.Topic(), // Report checkBlockNumber was reorged
- iregistry21.IKeeperRegistryMasterInsufficientFundsUpkeepReport{}.Topic(), // Upkeep didn't have sufficient funds when report reached chain, perform was aborted early
- // Report was too old when it reached the chain. For conditionals upkeep was already performed on a higher block than checkBlockNum
- // for logs upkeep was already performed for the particular log
- iregistry21.IKeeperRegistryMasterStaleUpkeepReport{}.Topic(),
- },
- Addresses: []common.Address{registryAddress},
- })
- if err != nil {
- return nil, err
- }
-
- return &TransmitEventProvider{
- logger: logger,
- logPoller: logPoller,
- registryAddress: registryAddress,
- lookbackBlocks: lookbackBlocks,
- registry: contract,
- client: client,
- }, nil
-}
-
-func (c *TransmitEventProvider) Name() string {
- return c.logger.Name()
-}
-
-func (c *TransmitEventProvider) Start(ctx context.Context) error {
- return c.sync.StartOnce("AutomationTransmitEventProvider", func() error {
- c.mu.Lock()
- defer c.mu.Unlock()
-
- c.runState = 1
- return nil
- })
-}
-
-func (c *TransmitEventProvider) Close() error {
- return c.sync.StopOnce("AutomationRegistry", func() error {
- c.mu.Lock()
- defer c.mu.Unlock()
-
- c.runState = 0
- c.runError = nil
- return nil
- })
-}
-
-func (c *TransmitEventProvider) Ready() error {
- c.mu.RLock()
- defer c.mu.RUnlock()
-
- if c.runState == 1 {
- return nil
- }
- return c.sync.Ready()
-}
-
-func (c *TransmitEventProvider) HealthReport() map[string]error {
- c.mu.RLock()
- defer c.mu.RUnlock()
-
- if c.runState > 1 {
- c.sync.SvcErrBuffer.Append(fmt.Errorf("failed run state: %w", c.runError))
- }
- return map[string]error{c.Name(): c.sync.Healthy()}
-}
-
-func (c *TransmitEventProvider) GetLatestEvents(ctx context.Context) ([]ocr2keepers.TransmitEvent, error) {
- end, err := c.logPoller.LatestBlock(pg.WithParentCtx(ctx))
- if err != nil {
- return nil, fmt.Errorf("%w: failed to get latest block from log poller", err)
- }
-
- // always check the last lookback number of blocks and rebroadcast
- // this allows the plugin to make decisions based on event confirmations
- logs, err := c.logPoller.LogsWithSigs(
- end-c.lookbackBlocks,
- end,
- []common.Hash{
- iregistry21.IKeeperRegistryMasterUpkeepPerformed{}.Topic(),
- iregistry21.IKeeperRegistryMasterStaleUpkeepReport{}.Topic(),
- iregistry21.IKeeperRegistryMasterReorgedUpkeepReport{}.Topic(),
- iregistry21.IKeeperRegistryMasterInsufficientFundsUpkeepReport{}.Topic(),
- },
- c.registryAddress,
- pg.WithParentCtx(ctx),
- )
- if err != nil {
- return nil, fmt.Errorf("%w: failed to collect logs from log poller", err)
- }
-
- parsed, err := c.parseLogs(logs)
- if err != nil {
- return nil, fmt.Errorf("%w: failed to parse logs", err)
- }
-
- return c.convertToTransmitEvents(parsed, end)
-}
-
-func (c *TransmitEventProvider) parseLogs(logs []logpoller.Log) ([]transmitEventLog, error) {
- results := []transmitEventLog{}
-
- for _, log := range logs {
- rawLog := log.ToGethLog()
- abilog, err := c.registry.ParseLog(rawLog)
- if err != nil {
- return nil, fmt.Errorf("%w: failed to parse log", err)
- }
-
- switch l := abilog.(type) {
- case *iregistry21.IKeeperRegistryMasterUpkeepPerformed:
- if l == nil {
- continue
- }
- results = append(results, transmitEventLog{
- Log: log,
- Performed: l,
- })
- case *iregistry21.IKeeperRegistryMasterReorgedUpkeepReport:
- if l == nil {
- continue
- }
- results = append(results, transmitEventLog{
- Log: log,
- Reorged: l,
- })
- case *iregistry21.IKeeperRegistryMasterStaleUpkeepReport:
- if l == nil {
- continue
- }
- results = append(results, transmitEventLog{
- Log: log,
- Stale: l,
- })
- case *iregistry21.IKeeperRegistryMasterInsufficientFundsUpkeepReport:
- if l == nil {
- continue
- }
- results = append(results, transmitEventLog{
- Log: log,
- InsufficientFunds: l,
- })
- default:
- c.logger.Debugw("skipping unknown log type", "l", l)
- continue
- }
- }
-
- return results, nil
-}
-
-func (c *TransmitEventProvider) convertToTransmitEvents(logs []transmitEventLog, latestBlock int64) ([]ocr2keepers.TransmitEvent, error) {
- vals := []ocr2keepers.TransmitEvent{}
-
- for _, l := range logs {
- id := l.Id()
- upkeepId := &ocr2keepers.UpkeepIdentifier{}
- ok := upkeepId.FromBigInt(id)
- if !ok {
- return nil, core.ErrInvalidUpkeepID
- }
- triggerW, err := core.UnpackTrigger(id, l.Trigger())
- if err != nil {
- return nil, fmt.Errorf("%w: failed to unpack trigger", err)
- }
- trigger := ocr2keepers.NewTrigger(
- ocr2keepers.BlockNumber(triggerW.BlockNum),
- triggerW.BlockHash,
- )
- switch core.GetUpkeepType(*upkeepId) {
- case ocr2keepers.LogTrigger:
- trigger.LogTriggerExtension = &ocr2keepers.LogTriggerExtension{}
- trigger.LogTriggerExtension.TxHash = triggerW.TxHash
- trigger.LogTriggerExtension.Index = triggerW.LogIndex
- default:
- }
- workID := core.UpkeepWorkID(*upkeepId, trigger)
- vals = append(vals, ocr2keepers.TransmitEvent{
- Type: l.TransmitEventType(),
- TransmitBlock: ocr2keepers.BlockNumber(l.BlockNumber),
- Confirmations: latestBlock - l.BlockNumber,
- TransactionHash: l.TxHash,
- WorkID: workID,
- UpkeepID: *upkeepId,
- CheckBlock: trigger.BlockNumber,
- })
- }
-
- return vals, nil
-}
-
-// transmitEventLog is a wrapper around logpoller.Log and the parsed log
-type transmitEventLog struct {
- logpoller.Log
- Performed *iregistry21.IKeeperRegistryMasterUpkeepPerformed
- Stale *iregistry21.IKeeperRegistryMasterStaleUpkeepReport
- Reorged *iregistry21.IKeeperRegistryMasterReorgedUpkeepReport
- InsufficientFunds *iregistry21.IKeeperRegistryMasterInsufficientFundsUpkeepReport
-}
-
-func (l transmitEventLog) Id() *big.Int {
- switch {
- case l.Performed != nil:
- return l.Performed.Id
- case l.Stale != nil:
- return l.Stale.Id
- case l.Reorged != nil:
- return l.Reorged.Id
- case l.InsufficientFunds != nil:
- return l.InsufficientFunds.Id
- default:
- return nil
- }
-}
-
-func (l transmitEventLog) Trigger() []byte {
- switch {
- case l.Performed != nil:
- return l.Performed.Trigger
- case l.Stale != nil:
- return l.Stale.Trigger
- case l.Reorged != nil:
- return l.Reorged.Trigger
- case l.InsufficientFunds != nil:
- return l.InsufficientFunds.Trigger
- default:
- return []byte{}
- }
-}
-
-func (l transmitEventLog) TransmitEventType() ocr2keepers.TransmitEventType {
- switch {
- case l.Performed != nil:
- return ocr2keepers.PerformEvent
- case l.Stale != nil:
- return ocr2keepers.StaleReportEvent
- case l.Reorged != nil:
- return ocr2keepers.ReorgReportEvent
- case l.InsufficientFunds != nil:
- return ocr2keepers.InsufficientFundsReportEvent
- default:
- return ocr2keepers.UnknownEvent
- }
-}
diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/upkeep_provider.go b/core/services/ocr2/plugins/ocr2keeper/evm21/upkeep_provider.go
index 8e08008eca4..5cb60d5dc1d 100644
--- a/core/services/ocr2/plugins/ocr2keeper/evm21/upkeep_provider.go
+++ b/core/services/ocr2/plugins/ocr2keeper/evm21/upkeep_provider.go
@@ -26,7 +26,7 @@ func NewUpkeepProvider(activeUpkeeps ActiveUpkeepList, bs *BlockSubscriber, lp l
}
}
-func (p *upkeepProvider) GetActiveUpkeeps(ctx context.Context) ([]ocr2keepers.UpkeepPayload, error) {
+func (p *upkeepProvider) GetActiveUpkeeps(_ context.Context) ([]ocr2keepers.UpkeepPayload, error) {
latestBlock := p.bs.latestBlock.Load()
if latestBlock == nil {
return nil, fmt.Errorf("no latest block found when fetching active upkeeps")
@@ -35,7 +35,7 @@ func (p *upkeepProvider) GetActiveUpkeeps(ctx context.Context) ([]ocr2keepers.Up
for _, uid := range p.activeUpkeeps.View(ocr2keepers.ConditionTrigger) {
payload, err := core.NewUpkeepPayload(
uid,
- ocr2keepers.NewTrigger(ocr2keepers.BlockNumber(latestBlock.Number), latestBlock.Hash),
+ ocr2keepers.NewTrigger(latestBlock.Number, latestBlock.Hash),
nil,
)
if err != nil {
diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate/orm.go b/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate/orm.go
new file mode 100644
index 00000000000..5db2f8bd0f3
--- /dev/null
+++ b/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate/orm.go
@@ -0,0 +1,95 @@
+package upkeepstate
+
+import (
+ "math/big"
+ "time"
+
+ "github.com/lib/pq"
+ "github.com/smartcontractkit/sqlx"
+
+ "github.com/smartcontractkit/chainlink/v2/core/logger"
+ "github.com/smartcontractkit/chainlink/v2/core/services/pg"
+ "github.com/smartcontractkit/chainlink/v2/core/utils"
+)
+
+type orm struct {
+ chainID *utils.Big
+ q pg.Q
+}
+
+type persistedStateRecord struct {
+ UpkeepID *utils.Big
+ WorkID string
+ CompletionState uint8
+ BlockNumber int64
+ IneligibilityReason uint8
+ InsertedAt time.Time
+}
+
+// NewORM creates an ORM scoped to chainID.
+func NewORM(chainID *big.Int, db *sqlx.DB, lggr logger.Logger, cfg pg.QConfig) *orm {
+ return &orm{
+ chainID: utils.NewBig(chainID),
+ q: pg.NewQ(db, lggr.Named("ORM"), cfg),
+ }
+}
+
+// BatchInsertRecords is idempotent and sets upkeep state values in db
+func (o *orm) BatchInsertRecords(state []persistedStateRecord, qopts ...pg.QOpt) error {
+ q := o.q.WithOpts(qopts...)
+
+ if len(state) == 0 {
+ return nil
+ }
+
+ type row struct {
+ EvmChainId *utils.Big
+ WorkId string
+ CompletionState uint8
+ BlockNumber int64
+ InsertedAt time.Time
+ UpkeepId *utils.Big
+ IneligibilityReason uint8
+ }
+
+ var rows []row
+ for _, record := range state {
+ rows = append(rows, row{
+ EvmChainId: o.chainID,
+ WorkId: record.WorkID,
+ CompletionState: record.CompletionState,
+ BlockNumber: record.BlockNumber,
+ InsertedAt: record.InsertedAt,
+ UpkeepId: record.UpkeepID,
+ IneligibilityReason: record.IneligibilityReason,
+ })
+ }
+
+ return q.ExecQNamed(`INSERT INTO evm.upkeep_states
+(evm_chain_id, work_id, completion_state, block_number, inserted_at, upkeep_id, ineligibility_reason) VALUES
+(:evm_chain_id, :work_id, :completion_state, :block_number, :inserted_at, :upkeep_id, :ineligibility_reason) ON CONFLICT (evm_chain_id, work_id) DO NOTHING`, rows)
+}
+
+// SelectStatesByWorkIDs searches the data store for stored states for the
+// provided work ids and configured chain id
+func (o *orm) SelectStatesByWorkIDs(workIDs []string, qopts ...pg.QOpt) (states []persistedStateRecord, err error) {
+ q := o.q.WithOpts(qopts...)
+
+ err = q.Select(&states, `SELECT upkeep_id, work_id, completion_state, block_number, ineligibility_reason, inserted_at
+ FROM evm.upkeep_states
+ WHERE work_id = ANY($1) AND evm_chain_id = $2::NUMERIC`, pq.Array(workIDs), o.chainID)
+
+ if err != nil {
+ return nil, err
+ }
+
+ return states, err
+}
+
+// DeleteExpired prunes stored states older than to the provided time
+func (o *orm) DeleteExpired(expired time.Time, qopts ...pg.QOpt) error {
+ q := o.q.WithOpts(qopts...)
+ _, err := q.Exec(`DELETE FROM evm.upkeep_states WHERE inserted_at <= $1 AND evm_chain_id::NUMERIC = $2`, expired, o.chainID)
+
+ return err
+}
diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate/orm_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate/orm_test.go
new file mode 100644
index 00000000000..54ca7285dd0
--- /dev/null
+++ b/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate/orm_test.go
@@ -0,0 +1,52 @@
+package upkeepstate
+
+import (
+ "math/big"
+ "testing"
+ "time"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+ "go.uber.org/zap/zapcore"
+
+ "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/utils"
+)
+
+func TestInsertSelectDelete(t *testing.T) {
+ lggr, _ := logger.TestLoggerObserved(t, zapcore.ErrorLevel)
+ chainID := testutils.FixtureChainID
+ db := pgtest.NewSqlxDB(t)
+ orm := NewORM(chainID, db, lggr, pgtest.NewQConfig(true))
+
+ inserted := []persistedStateRecord{
+ {
+ UpkeepID: utils.NewBig(big.NewInt(2)),
+ WorkID: "0x1",
+ CompletionState: 100,
+ BlockNumber: 2,
+ IneligibilityReason: 2,
+ InsertedAt: time.Now(),
+ },
+ }
+
+ err := orm.BatchInsertRecords(inserted)
+
+ require.NoError(t, err, "no error expected from insert")
+
+ states, err := orm.SelectStatesByWorkIDs([]string{"0x1"})
+
+ require.NoError(t, err, "no error expected from select")
+ require.Len(t, states, 1, "records return should equal records inserted")
+
+ err = orm.DeleteExpired(time.Now())
+
+ assert.NoError(t, err, "no error expected from delete")
+
+ states, err = orm.SelectStatesByWorkIDs([]string{"0x1"})
+
+ require.NoError(t, err, "no error expected from select")
+ require.Len(t, states, 0, "records return should be empty since records were deleted")
+}
diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate/scanner.go b/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate/scanner.go
index 9a0684850ec..9ce9a10ac73 100644
--- a/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate/scanner.go
+++ b/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate/scanner.go
@@ -11,11 +11,18 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller"
iregistry21 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/i_keeper_registry_master_wrapper_2_1"
"github.com/smartcontractkit/chainlink/v2/core/logger"
+ "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider"
"github.com/smartcontractkit/chainlink/v2/core/services/pg"
)
+var (
+ _ PerformedLogsScanner = &performedEventsScanner{}
+
+ workIDsBatchSize = 25
+)
+
type PerformedLogsScanner interface {
- WorkIDsInRange(ctx context.Context, start, end int64) ([]string, error)
+ ScanWorkIDs(ctx context.Context, workIDs ...string) ([]string, error)
Start(context.Context) error
io.Closer
@@ -25,17 +32,21 @@ type performedEventsScanner struct {
lggr logger.Logger
poller logpoller.LogPoller
registryAddress common.Address
+
+ finalityDepth uint32
}
func NewPerformedEventsScanner(
lggr logger.Logger,
poller logpoller.LogPoller,
registryAddress common.Address,
+ finalityDepth uint32,
) *performedEventsScanner {
return &performedEventsScanner{
- lggr: lggr,
+ lggr: lggr.Named("EventsScanner"),
poller: poller,
registryAddress: registryAddress,
+ finalityDepth: finalityDepth,
}
}
@@ -47,26 +58,32 @@ func (s *performedEventsScanner) Start(_ context.Context) error {
iregistry21.IKeeperRegistryMasterDedupKeyAdded{}.Topic(),
},
Addresses: []common.Address{s.registryAddress},
+ Retention: logprovider.LogRetention,
})
}
-// implements io.Closer, does nothing upon close
+// Close implements io.Closer and does nothing
func (s *performedEventsScanner) Close() error {
return nil
}
-func (s *performedEventsScanner) WorkIDsInRange(ctx context.Context, start, end int64) ([]string, error) {
- logs, err := s.poller.LogsWithSigs(
- start,
- end,
- []common.Hash{
- iregistry21.IKeeperRegistryMasterDedupKeyAdded{}.Topic(),
- },
- s.registryAddress,
- pg.WithParentCtx(ctx),
- )
- if err != nil {
- return nil, fmt.Errorf("error fetching logs: %w", err)
+func (s *performedEventsScanner) ScanWorkIDs(ctx context.Context, workID ...string) ([]string, error) {
+ var ids []common.Hash
+ for _, id := range workID {
+ ids = append(ids, common.HexToHash(id))
+ }
+ logs := make([]logpoller.Log, 0)
+ for i := 0; i < len(ids); i += workIDsBatchSize {
+ end := i + workIDsBatchSize
+ if end > len(ids) {
+ end = len(ids)
+ }
+ batch := ids[i:end]
+ batchLogs, err := s.poller.IndexedLogs(iregistry21.IKeeperRegistryMasterDedupKeyAdded{}.Topic(), s.registryAddress, 1, batch, int(s.finalityDepth), pg.WithParentCtx(ctx))
+ if err != nil {
+ return nil, fmt.Errorf("error fetching logs: %w", err)
+ }
+ logs = append(logs, batchLogs...)
}
return s.logsToWorkIDs(logs), nil
diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate/scanner_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate/scanner_test.go
index f066fe0aa43..9442a5f5d7a 100644
--- a/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate/scanner_test.go
+++ b/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate/scanner_test.go
@@ -2,6 +2,7 @@ package upkeepstate
import (
"fmt"
+ "sort"
"testing"
"github.com/ethereum/go-ethereum/common"
@@ -22,13 +23,15 @@ func TestPerformedEventsScanner(t *testing.T) {
tests := []struct {
name string
+ workIDs []string
pollerResults []logpoller.Log
scannerResults []string
pollerErr error
errored bool
}{
{
- "no logs",
+ "empty",
+ []string{},
[]logpoller.Log{},
[]string{},
nil,
@@ -36,6 +39,7 @@ func TestPerformedEventsScanner(t *testing.T) {
},
{
"log poller error",
+ []string{"111"},
[]logpoller.Log{},
[]string{},
fmt.Errorf("test-error"),
@@ -43,6 +47,7 @@ func TestPerformedEventsScanner(t *testing.T) {
},
{
"one result",
+ []string{"290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563"},
[]logpoller.Log{
{
BlockNumber: 1,
@@ -59,6 +64,7 @@ func TestPerformedEventsScanner(t *testing.T) {
},
{
"missing workID",
+ []string{"290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563"},
[]logpoller.Log{
{
BlockNumber: 1,
@@ -79,7 +85,7 @@ func TestPerformedEventsScanner(t *testing.T) {
mp := new(mocks.LogPoller)
mp.On("RegisterFilter", mock.Anything).Return(nil)
mp.On("UnregisterFilter", mock.Anything, mock.Anything).Return(nil)
- scanner := NewPerformedEventsScanner(lggr, mp, registryAddr)
+ scanner := NewPerformedEventsScanner(lggr, mp, registryAddr, 100)
go func() {
_ = scanner.Start(ctx)
@@ -88,9 +94,9 @@ func TestPerformedEventsScanner(t *testing.T) {
_ = scanner.Close()
}()
- mp.On("LogsWithSigs", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(tc.pollerResults, tc.pollerErr)
+ mp.On("IndexedLogs", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(tc.pollerResults, tc.pollerErr)
- results, err := scanner.WorkIDsInRange(ctx, 0, 100)
+ results, err := scanner.ScanWorkIDs(ctx, tc.workIDs...)
if tc.errored {
require.Error(t, err)
return
@@ -105,19 +111,55 @@ func TestPerformedEventsScanner(t *testing.T) {
}
}
-func TestPerformedEventsScanner_LogPollerErrors(t *testing.T) {
+func TestPerformedEventsScanner_Batch(t *testing.T) {
ctx := testutils.Context(t)
registryAddr := common.HexToAddress("0x12345")
lggr := logger.TestLogger(t)
+ lp := new(mocks.LogPoller)
+ scanner := NewPerformedEventsScanner(lggr, lp, registryAddr, 100)
+
+ lp.On("IndexedLogs", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return([]logpoller.Log{
+ {
+ BlockNumber: 1,
+ Address: registryAddr,
+ Topics: convertTopics([]common.Hash{
+ iregistry21.IKeeperRegistryMasterDedupKeyAdded{}.Topic(),
+ common.HexToHash("0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563"),
+ }),
+ },
+ }, nil).Times(1)
+ lp.On("IndexedLogs", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return([]logpoller.Log{
+ {
+ BlockNumber: 3,
+ Address: registryAddr,
+ Topics: convertTopics([]common.Hash{
+ iregistry21.IKeeperRegistryMasterDedupKeyAdded{}.Topic(),
+ common.HexToHash("0x331decd9548b62a8d603457658386fc84ba6bc95888008f6362f93160ef3b663"),
+ }),
+ },
+ }, nil).Times(1)
+
+ origWorkIDsBatchSize := workIDsBatchSize
+ workIDsBatchSize = 8
+ defer func() {
+ workIDsBatchSize = origWorkIDsBatchSize
+ }()
- mp := new(mocks.LogPoller)
- scanner := NewPerformedEventsScanner(lggr, mp, registryAddr)
+ ids, err := scanner.ScanWorkIDs(ctx,
+ "290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563",
+ "1111", "2222", "3333", "4444", "5555", "6666", "7777", "8888", "9999",
+ "331decd9548b62a8d603457658386fc84ba6bc95888008f6362f93160ef3b663",
+ )
- mp.On("LogsWithSigs", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil, fmt.Errorf("test error"))
+ require.NoError(t, err)
+ require.Equal(t, 2, len(ids))
+ sort.Slice(ids, func(i, j int) bool {
+ return ids[i] < ids[j]
+ })
+ require.Equal(t, "290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563", ids[0])
+ require.Equal(t, "331decd9548b62a8d603457658386fc84ba6bc95888008f6362f93160ef3b663", ids[1])
- workIDs, err := scanner.WorkIDsInRange(ctx, 0, 100)
- require.Error(t, err)
- require.Nil(t, workIDs)
+ lp.AssertExpectations(t)
}
func convertTopics(topics []common.Hash) [][]byte {
diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate/store.go b/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate/store.go
index 13fb749d222..34bd6822d69 100644
--- a/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate/store.go
+++ b/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate/store.go
@@ -4,6 +4,7 @@ import (
"context"
"fmt"
"io"
+ "math/big"
"sync"
"time"
@@ -11,15 +12,27 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/logger"
"github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21/core"
+ "github.com/smartcontractkit/chainlink/v2/core/services/pg"
+ "github.com/smartcontractkit/chainlink/v2/core/utils"
)
-var (
+const (
+ UpkeepStateStoreServiceName = "UpkeepStateStore"
// CacheExpiration is the amount of time that we keep a record in the cache.
CacheExpiration = 24 * time.Hour
// GCInterval is the amount of time between cache cleanups.
GCInterval = 2 * time.Hour
+ // flushCadence is the amount of time between flushes to the DB.
+ flushCadence = 30 * time.Second
+ concurrentBatchCalls = 10
)
+type ORM interface {
+ BatchInsertRecords([]persistedStateRecord, ...pg.QOpt) error
+ SelectStatesByWorkIDs([]string, ...pg.QOpt) ([]persistedStateRecord, error)
+ DeleteExpired(time.Time, ...pg.QOpt) error
+}
+
// UpkeepStateStore is the interface for managing upkeeps final state in a local store.
type UpkeepStateStore interface {
ocr2keepers.UpkeepStateUpdater
@@ -29,7 +42,9 @@ type UpkeepStateStore interface {
}
var (
- _ UpkeepStateStore = &upkeepStateStore{}
+ _ UpkeepStateStore = &upkeepStateStore{}
+ newTickerFn = time.NewTicker
+ batchSize = 1000
)
// upkeepStateRecord is a record that we save in a local cache.
@@ -43,93 +58,135 @@ type upkeepStateRecord struct {
// upkeepStateStore implements UpkeepStateStore.
// It stores the state of ineligible upkeeps in a local, in-memory cache.
// In addition, performed events are fetched by the scanner on demand.
-// TODO: Add DB persistence
type upkeepStateStore struct {
- lggr logger.Logger
+ utils.StartStopOnce
+ threadCtrl utils.ThreadControl
+
+ orm ORM
+ lggr logger.Logger
+ scanner PerformedLogsScanner
- cancel context.CancelFunc
+ retention time.Duration
+ cleanCadence time.Duration
mu sync.RWMutex
cache map[string]*upkeepStateRecord
- scanner PerformedLogsScanner
+ pendingRecords []persistedStateRecord
+ sem chan struct{}
+ batchSize int
}
// NewUpkeepStateStore creates a new state store
-func NewUpkeepStateStore(lggr logger.Logger, scanner PerformedLogsScanner) *upkeepStateStore {
+func NewUpkeepStateStore(orm ORM, lggr logger.Logger, scanner PerformedLogsScanner) *upkeepStateStore {
return &upkeepStateStore{
- lggr: lggr.Named("upkeepStateStore"),
- cache: map[string]*upkeepStateRecord{},
- scanner: scanner,
+ orm: orm,
+ lggr: lggr.Named(UpkeepStateStoreServiceName),
+ cache: map[string]*upkeepStateRecord{},
+ scanner: scanner,
+ retention: CacheExpiration,
+ cleanCadence: GCInterval,
+ threadCtrl: utils.NewThreadControl(),
+ pendingRecords: []persistedStateRecord{},
+ sem: make(chan struct{}, concurrentBatchCalls),
+ batchSize: batchSize,
}
}
// Start starts the upkeep state store.
-// it does background cleanup of the cache.
-func (u *upkeepStateStore) Start(context.Context) error {
- u.mu.Lock()
- if u.cancel != nil {
- u.mu.Unlock()
- return fmt.Errorf("already started")
- }
- ctx, cancel := context.WithCancel(context.Background())
- u.cancel = cancel
- u.mu.Unlock()
-
- if err := u.scanner.Start(ctx); err != nil {
- return fmt.Errorf("failed to start scanner")
- }
+// it does background cleanup of the cache every GCInterval,
+// and flush records to DB every flushCadence.
+func (u *upkeepStateStore) Start(pctx context.Context) error {
+ return u.StartOnce(UpkeepStateStoreServiceName, func() error {
+ if err := u.scanner.Start(pctx); err != nil {
+ return fmt.Errorf("failed to start scanner")
+ }
- u.lggr.Debug("Starting upkeep state store")
+ u.lggr.Debug("Starting upkeep state store")
- {
- go func(ctx context.Context) {
- ticker := time.NewTicker(GCInterval)
+ u.threadCtrl.Go(func(ctx context.Context) {
+ ticker := time.NewTicker(utils.WithJitter(u.cleanCadence))
defer ticker.Stop()
+ flushTicker := newTickerFn(utils.WithJitter(flushCadence))
+ defer flushTicker.Stop()
+
for {
select {
case <-ticker.C:
- u.cleanup()
+ if err := u.cleanup(ctx); err != nil {
+ u.lggr.Errorw("unable to clean old state values", "err", err)
+ }
+ ticker.Reset(utils.WithJitter(u.cleanCadence))
+ case <-flushTicker.C:
+ u.flush(ctx)
+ flushTicker.Reset(utils.WithJitter(flushCadence))
case <-ctx.Done():
-
+ u.flush(ctx)
+ return
}
}
- }(ctx)
- }
-
- return nil
+ })
+ return nil
+ })
}
-func (u *upkeepStateStore) Close() error {
+func (u *upkeepStateStore) flush(ctx context.Context) {
u.mu.Lock()
- defer u.mu.Unlock()
+ cloneRecords := make([]persistedStateRecord, len(u.pendingRecords))
+ copy(cloneRecords, u.pendingRecords)
+ u.pendingRecords = []persistedStateRecord{}
+ u.mu.Unlock()
- if cancel := u.cancel; cancel != nil {
- u.cancel = nil
- cancel()
- } else {
- return fmt.Errorf("already stopped")
- }
- if err := u.scanner.Close(); err != nil {
- return fmt.Errorf("failed to start scanner")
+ for i := 0; i < len(cloneRecords); i += u.batchSize {
+ end := i + u.batchSize
+ if end > len(cloneRecords) {
+ end = len(cloneRecords)
+ }
+
+ batch := cloneRecords[i:end]
+
+ u.sem <- struct{}{}
+
+ go func() {
+ if err := u.orm.BatchInsertRecords(batch, pg.WithParentCtx(ctx)); err != nil {
+ u.lggr.Errorw("error inserting records", "err", err)
+ }
+ <-u.sem
+ }()
}
+}
- return nil
+// Close stops the service of pruning stale data; implements io.Closer
+func (u *upkeepStateStore) Close() error {
+ return u.StopOnce(UpkeepStateStoreServiceName, func() error {
+ u.threadCtrl.Close()
+ return nil
+ })
+}
+
+func (u *upkeepStateStore) HealthReport() map[string]error {
+ return map[string]error{UpkeepStateStoreServiceName: u.Healthy()}
}
// SelectByWorkIDs returns the current state of the upkeep for the provided ids.
// If an id is not found, the state is returned as StateUnknown.
-// We first check the cache, and if any ids are missing, we fetch them from the scanner.
-func (u *upkeepStateStore) SelectByWorkIDsInRange(ctx context.Context, start, end int64, workIDs ...string) ([]ocr2keepers.UpkeepState, error) {
- states, ok := u.selectFromCache(workIDs...)
- if ok {
+// We first check the cache, and if any ids are missing, we fetch them from the scanner and DB.
+func (u *upkeepStateStore) SelectByWorkIDs(ctx context.Context, workIDs ...string) ([]ocr2keepers.UpkeepState, error) {
+ states, missing := u.selectFromCache(workIDs...)
+ if len(missing) == 0 {
// all ids were found in the cache
return states, nil
}
- if err := u.fetchPerformed(ctx, start, end); err != nil {
+ if err := u.fetchPerformed(ctx, missing...); err != nil {
+ return nil, err
+ }
+ if err := u.fetchFromDB(ctx, missing...); err != nil {
return nil, err
}
+
+ // at this point all values should be in the cache. if values are missing
+ // their state is indicated as unknown
states, _ = u.selectFromCache(workIDs...)
return states, nil
@@ -138,20 +195,18 @@ func (u *upkeepStateStore) SelectByWorkIDsInRange(ctx context.Context, start, en
// SetUpkeepState updates the state of the upkeep.
// Currently we only store the state if the upkeep is ineligible.
// Performed events will be fetched on demand.
-func (u *upkeepStateStore) SetUpkeepState(_ context.Context, result ocr2keepers.CheckResult, _ ocr2keepers.UpkeepState) error {
+func (u *upkeepStateStore) SetUpkeepState(ctx context.Context, result ocr2keepers.CheckResult, _ ocr2keepers.UpkeepState) error {
if result.Eligible {
return nil
}
- u.upsertStateRecord(result.WorkID, ocr2keepers.Ineligible)
-
- return nil
+ return u.upsertStateRecord(ctx, result.WorkID, ocr2keepers.Ineligible, uint64(result.Trigger.BlockNumber), result.UpkeepID.BigInt(), result.IneligibilityReason)
}
// upsertStateRecord inserts or updates a record for the provided
// check result. If an item already exists in the data store, the state and
// block are updated.
-func (u *upkeepStateStore) upsertStateRecord(workID string, s ocr2keepers.UpkeepState) {
+func (u *upkeepStateStore) upsertStateRecord(ctx context.Context, workID string, s ocr2keepers.UpkeepState, b uint64, upkeepID *big.Int, reason uint8) error {
u.mu.Lock()
defer u.mu.Unlock()
@@ -162,18 +217,33 @@ func (u *upkeepStateStore) upsertStateRecord(workID string, s ocr2keepers.Upkeep
addedAt: time.Now(),
}
}
+
record.state = s
u.cache[workID] = record
+
+ u.pendingRecords = append(u.pendingRecords, persistedStateRecord{
+ UpkeepID: utils.NewBig(upkeepID),
+ WorkID: record.workID,
+ CompletionState: uint8(record.state),
+ IneligibilityReason: reason,
+ InsertedAt: record.addedAt,
+ })
+
+ return nil
}
// fetchPerformed fetches all performed logs from the scanner to populate the cache.
-func (u *upkeepStateStore) fetchPerformed(ctx context.Context, start, end int64, workIDs ...string) error {
- performed, err := u.scanner.WorkIDsInRange(ctx, start, end)
+func (u *upkeepStateStore) fetchPerformed(ctx context.Context, workIDs ...string) error {
+ performed, err := u.scanner.ScanWorkIDs(ctx, workIDs...)
if err != nil {
return err
}
+ if len(performed) > 0 {
+ u.lggr.Debugw("Fetched performed logs", "performed", len(performed))
+ }
+
u.mu.Lock()
defer u.mu.Unlock()
@@ -184,6 +254,7 @@ func (u *upkeepStateStore) fetchPerformed(ctx context.Context, start, end int64,
state: ocr2keepers.Performed,
addedAt: time.Now(),
}
+
u.cache[workID] = s
}
}
@@ -191,35 +262,62 @@ func (u *upkeepStateStore) fetchPerformed(ctx context.Context, start, end int64,
return nil
}
+// fetchFromDB fetches all upkeeps indicated as ineligible from the db to
+// populate the cache.
+func (u *upkeepStateStore) fetchFromDB(ctx context.Context, workIDs ...string) error {
+ states, err := u.orm.SelectStatesByWorkIDs(workIDs, pg.WithParentCtx(ctx))
+ if err != nil {
+ return err
+ }
+
+ u.mu.Lock()
+ defer u.mu.Unlock()
+
+ for _, state := range states {
+ if _, ok := u.cache[state.WorkID]; !ok {
+ u.cache[state.WorkID] = &upkeepStateRecord{
+ workID: state.WorkID,
+ state: ocr2keepers.UpkeepState(state.CompletionState),
+ addedAt: state.InsertedAt,
+ }
+ }
+ }
+
+ return nil
+}
+
// selectFromCache returns all saved state values for the provided ids,
// returning stateNotFound for any ids that are not found.
// the second return value is true if all ids were found in the cache.
-func (u *upkeepStateStore) selectFromCache(workIDs ...string) ([]ocr2keepers.UpkeepState, bool) {
+func (u *upkeepStateStore) selectFromCache(workIDs ...string) ([]ocr2keepers.UpkeepState, []string) {
u.mu.RLock()
defer u.mu.RUnlock()
- var hasMisses bool
+ var missing []string
states := make([]ocr2keepers.UpkeepState, len(workIDs))
for i, workID := range workIDs {
if state, ok := u.cache[workID]; ok {
states[i] = state.state
} else {
- hasMisses = true
- states[i] = ocr2keepers.UnknownState
+ missing = append(missing, workID)
}
}
- return states, !hasMisses
+ return states, missing
}
// cleanup removes any records that are older than the TTL from both cache and DB.
-func (u *upkeepStateStore) cleanup() {
+func (u *upkeepStateStore) cleanup(ctx context.Context) error {
u.cleanCache()
- u.cleanDB()
+
+ return u.cleanDB(ctx)
}
// cleanDB cleans up records in the DB that are older than the TTL.
-func (u *upkeepStateStore) cleanDB() {
+func (u *upkeepStateStore) cleanDB(ctx context.Context) error {
+ tm := time.Now().Add(-1 * u.retention)
+
+ return u.orm.DeleteExpired(tm, pg.WithParentCtx(ctx), pg.WithLongQueryTimeout())
}
// cleanupCache removes any records from the cache that are older than the TTL.
@@ -228,7 +326,7 @@ func (u *upkeepStateStore) cleanCache() {
defer u.mu.Unlock()
for id, state := range u.cache {
- if time.Since(state.addedAt) > CacheExpiration {
+ if time.Since(state.addedAt) > u.retention {
delete(u.cache, id)
}
}
diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate/store_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate/store_test.go
index 853b0c317ce..49851b584e8 100644
--- a/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate/store_test.go
+++ b/core/services/ocr2/plugins/ocr2keeper/evm21/upkeepstate/store_test.go
@@ -11,9 +11,12 @@ import (
ocr2keepers "github.com/smartcontractkit/ocr2keepers/pkg/v3/types"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
+ "go.uber.org/zap/zapcore"
"github.com/smartcontractkit/chainlink/v2/core/internal/testutils"
+ "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest"
"github.com/smartcontractkit/chainlink/v2/core/logger"
+ "github.com/smartcontractkit/chainlink/v2/core/services/pg"
)
func TestUpkeepStateStore(t *testing.T) {
@@ -23,6 +26,8 @@ func TestUpkeepStateStore(t *testing.T) {
workIDsSelect []string
workIDsFromScanner []string
errScanner error
+ recordsFromDB []persistedStateRecord
+ errDB error
expected []ocr2keepers.UpkeepState
errored bool
}{
@@ -74,6 +79,34 @@ func TestUpkeepStateStore(t *testing.T) {
ocr2keepers.Performed,
},
},
+ {
+ name: "fetch results from db",
+ inserts: []ocr2keepers.CheckResult{
+ {
+ UpkeepID: createUpkeepIDForTest(1),
+ WorkID: "0x1",
+ Eligible: false,
+ Trigger: ocr2keepers.Trigger{
+ BlockNumber: ocr2keepers.BlockNumber(1),
+ },
+ },
+ },
+ workIDsSelect: []string{"0x1", "0x2", "0x3"},
+ workIDsFromScanner: []string{"0x2", "0x222"},
+ recordsFromDB: []persistedStateRecord{
+ {
+ WorkID: "0x3",
+ CompletionState: 2,
+ BlockNumber: 2,
+ InsertedAt: time.Now(),
+ },
+ },
+ expected: []ocr2keepers.UpkeepState{
+ ocr2keepers.Ineligible,
+ ocr2keepers.Performed,
+ ocr2keepers.Ineligible,
+ },
+ },
{
name: "unknown states",
inserts: []ocr2keepers.CheckResult{
@@ -109,22 +142,45 @@ func TestUpkeepStateStore(t *testing.T) {
errScanner: fmt.Errorf("test error"),
errored: true,
},
+ {
+ name: "db error",
+ inserts: []ocr2keepers.CheckResult{
+ {
+ UpkeepID: createUpkeepIDForTest(1),
+ WorkID: "0x1",
+ Eligible: false,
+ Trigger: ocr2keepers.Trigger{
+ BlockNumber: ocr2keepers.BlockNumber(1),
+ },
+ },
+ },
+ workIDsSelect: []string{"0x1", "0x2"},
+ workIDsFromScanner: []string{"0x2", "0x222"},
+ errDB: fmt.Errorf("test error"),
+ errored: true,
+ },
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
ctx := testutils.Context(t)
+ lggr := logger.TestLogger(t)
scanner := &mockScanner{}
scanner.addWorkID(tc.workIDsFromScanner...)
scanner.setErr(tc.errScanner)
- store := NewUpkeepStateStore(logger.TestLogger(t), scanner)
+
+ orm := &mockORM{}
+ orm.addRecords(tc.recordsFromDB...)
+ orm.setErr(tc.errDB)
+
+ store := NewUpkeepStateStore(orm, lggr, scanner)
for _, insert := range tc.inserts {
assert.NoError(t, store.SetUpkeepState(ctx, insert, ocr2keepers.Performed))
}
- states, err := store.SelectByWorkIDsInRange(ctx, 1, 100, tc.workIDsSelect...)
+ states, err := store.SelectByWorkIDs(ctx, tc.workIDsSelect...)
if tc.errored {
assert.Error(t, err)
return
@@ -139,9 +195,241 @@ func TestUpkeepStateStore(t *testing.T) {
}
}
+func TestUpkeepStateStore_SetSelectIntegration(t *testing.T) {
+ if testing.Short() {
+ t.Skip("database required for upkeep state store integration test")
+ }
+
+ makeTestResult := func(id int64, workID string, eligible bool, block uint64) ocr2keepers.CheckResult {
+ uid := &ocr2keepers.UpkeepIdentifier{}
+ _ = uid.FromBigInt(big.NewInt(id))
+
+ return ocr2keepers.CheckResult{
+ UpkeepID: *uid,
+ WorkID: workID,
+ Eligible: eligible,
+ Trigger: ocr2keepers.Trigger{
+ BlockNumber: ocr2keepers.BlockNumber(block),
+ },
+ }
+ }
+
+ type storedValue struct {
+ result ocr2keepers.CheckResult
+ state ocr2keepers.UpkeepState
+ }
+
+ tests := []struct {
+ name string
+ flushSize int
+ expectedWrites int
+ queryIDs []string
+ storedValues []storedValue
+ expected []ocr2keepers.UpkeepState
+ }{
+ {
+ name: "querying non-stored workIDs on db with values returns unknown state results",
+ queryIDs: []string{"0x1", "0x2", "0x3", "0x4"},
+ flushSize: 10,
+ expectedWrites: 1,
+ storedValues: []storedValue{
+ {result: makeTestResult(1, "0x11", false, 1), state: ocr2keepers.Performed},
+ {result: makeTestResult(2, "0x22", false, 1), state: ocr2keepers.Performed},
+ {result: makeTestResult(3, "0x33", false, 1), state: ocr2keepers.Performed},
+ {result: makeTestResult(4, "0x44", false, 1), state: ocr2keepers.Performed},
+ },
+ expected: []ocr2keepers.UpkeepState{
+ ocr2keepers.UnknownState,
+ ocr2keepers.UnknownState,
+ ocr2keepers.UnknownState,
+ ocr2keepers.UnknownState,
+ },
+ },
+ {
+ name: "storing eligible values is a noop",
+ queryIDs: []string{"0x1", "0x2", "0x3", "0x4"},
+ flushSize: 4,
+ expectedWrites: 1,
+ storedValues: []storedValue{
+ {result: makeTestResult(9, "0x1", false, 1), state: ocr2keepers.Ineligible},
+ {result: makeTestResult(10, "0x2", false, 1), state: ocr2keepers.Ineligible},
+ {result: makeTestResult(11, "0x3", false, 1), state: ocr2keepers.Ineligible},
+ {result: makeTestResult(12, "0x4", true, 1), state: ocr2keepers.Performed}, // gets inserted
+ },
+ expected: []ocr2keepers.UpkeepState{
+ ocr2keepers.Ineligible,
+ ocr2keepers.Ineligible,
+ ocr2keepers.Ineligible,
+ ocr2keepers.UnknownState,
+ },
+ },
+ {
+ name: "provided state on setupkeepstate is currently ignored for eligible check results",
+ queryIDs: []string{"0x1", "0x2"},
+ flushSize: 1,
+ expectedWrites: 1,
+ storedValues: []storedValue{
+ {result: makeTestResult(13, "0x1", true, 1), state: ocr2keepers.Ineligible},
+ {result: makeTestResult(14, "0x2", false, 1), state: ocr2keepers.Performed}, // gets inserted
+ },
+ expected: []ocr2keepers.UpkeepState{
+ ocr2keepers.UnknownState,
+ ocr2keepers.Ineligible,
+ },
+ },
+ {
+ name: "provided state outside the flush batch isn't registered in the db",
+ queryIDs: []string{"0x1", "0x2", "0x3", "0x4", "0x5", "0x6", "0x7", "0x8"},
+ flushSize: 3,
+ expectedWrites: 2,
+ storedValues: []storedValue{
+ {result: makeTestResult(13, "0x1", true, 1), state: ocr2keepers.Ineligible},
+ {result: makeTestResult(14, "0x2", false, 1), state: ocr2keepers.Performed}, // gets inserted
+ {result: makeTestResult(15, "0x3", true, 1), state: ocr2keepers.Ineligible},
+ {result: makeTestResult(16, "0x4", false, 1), state: ocr2keepers.Performed}, // gets inserted
+ {result: makeTestResult(17, "0x5", true, 1), state: ocr2keepers.Ineligible},
+ {result: makeTestResult(18, "0x6", false, 1), state: ocr2keepers.Performed}, // gets inserted
+ {result: makeTestResult(19, "0x7", true, 1), state: ocr2keepers.Ineligible},
+ {result: makeTestResult(20, "0x8", false, 1), state: ocr2keepers.Performed}, // gets inserted
+ },
+ expected: []ocr2keepers.UpkeepState{
+ ocr2keepers.UnknownState,
+ ocr2keepers.Ineligible,
+ ocr2keepers.UnknownState,
+ ocr2keepers.Ineligible,
+ ocr2keepers.UnknownState,
+ ocr2keepers.Ineligible,
+ ocr2keepers.UnknownState,
+ ocr2keepers.Ineligible,
+ },
+ },
+ }
+
+ for _, test := range tests {
+ t.Run(test.name, func(t *testing.T) {
+ ctx := testutils.Context(t)
+
+ tickerCh := make(chan time.Time)
+
+ oldNewTickerFn := newTickerFn
+ oldFlushSize := batchSize
+ newTickerFn = func(d time.Duration) *time.Ticker {
+ t := time.NewTicker(d)
+ t.C = tickerCh
+ return t
+ }
+ batchSize = test.flushSize
+ defer func() {
+ newTickerFn = oldNewTickerFn
+ batchSize = oldFlushSize
+ }()
+
+ lggr, observedLogs := logger.TestLoggerObserved(t, zapcore.ErrorLevel)
+ chainID := testutils.FixtureChainID
+ db := pgtest.NewSqlxDB(t)
+ realORM := NewORM(chainID, db, lggr, pgtest.NewQConfig(true))
+ insertFinished := make(chan struct{}, 1)
+ orm := &wrappedORM{
+ BatchInsertRecordsFn: func(records []persistedStateRecord, opt ...pg.QOpt) error {
+ err := realORM.BatchInsertRecords(records, opt...)
+ insertFinished <- struct{}{}
+ return err
+ },
+ SelectStatesByWorkIDsFn: func(strings []string, opt ...pg.QOpt) ([]persistedStateRecord, error) {
+ return realORM.SelectStatesByWorkIDs(strings, opt...)
+ },
+ DeleteExpiredFn: func(t time.Time, opt ...pg.QOpt) error {
+ return realORM.DeleteExpired(t, opt...)
+ },
+ }
+ scanner := &mockScanner{}
+ store := NewUpkeepStateStore(orm, lggr, scanner)
+
+ require.NoError(t, store.Start(ctx))
+
+ t.Cleanup(func() {
+ t.Log("cleaning up database")
+
+ if _, err := db.Exec(`DELETE FROM evm.upkeep_states`); err != nil {
+ t.Logf("error in cleanup: %s", err)
+ }
+ })
+
+ for _, insert := range test.storedValues {
+ require.NoError(t, store.SetUpkeepState(context.Background(), insert.result, insert.state), "storing states should not produce an error")
+ }
+
+ tickerCh <- time.Now()
+
+ // if this test inserts data, wait for the insert to complete before proceeding
+ for i := 0; i < test.expectedWrites; i++ {
+ <-insertFinished
+ }
+
+ // empty the cache before doing selects to force a db lookup
+ store.cache = make(map[string]*upkeepStateRecord)
+
+ states, err := store.SelectByWorkIDs(ctx, test.queryIDs...)
+
+ require.NoError(t, err, "no error expected from selecting states")
+
+ assert.Equal(t, test.expected, states, "upkeep state values should match expected")
+
+ observedLogs.TakeAll()
+
+ require.Equal(t, 0, observedLogs.Len())
+
+ require.NoError(t, store.Close())
+ })
+ }
+}
+
+func TestUpkeepStateStore_emptyDB(t *testing.T) {
+ t.Run("querying non-stored workIDs on empty db returns unknown state results", func(t *testing.T) {
+ lggr, observedLogs := logger.TestLoggerObserved(t, zapcore.ErrorLevel)
+ chainID := testutils.FixtureChainID
+ db := pgtest.NewSqlxDB(t)
+ realORM := NewORM(chainID, db, lggr, pgtest.NewQConfig(true))
+ insertFinished := make(chan struct{}, 1)
+ orm := &wrappedORM{
+ BatchInsertRecordsFn: func(records []persistedStateRecord, opt ...pg.QOpt) error {
+ err := realORM.BatchInsertRecords(records, opt...)
+ insertFinished <- struct{}{}
+ return err
+ },
+ SelectStatesByWorkIDsFn: func(strings []string, opt ...pg.QOpt) ([]persistedStateRecord, error) {
+ return realORM.SelectStatesByWorkIDs(strings, opt...)
+ },
+ DeleteExpiredFn: func(t time.Time, opt ...pg.QOpt) error {
+ return realORM.DeleteExpired(t, opt...)
+ },
+ }
+ scanner := &mockScanner{}
+ store := NewUpkeepStateStore(orm, lggr, scanner)
+
+ states, err := store.SelectByWorkIDs(context.Background(), []string{"0x1", "0x2", "0x3", "0x4"}...)
+ assert.NoError(t, err)
+ assert.Equal(t, []ocr2keepers.UpkeepState{
+ ocr2keepers.UnknownState,
+ ocr2keepers.UnknownState,
+ ocr2keepers.UnknownState,
+ ocr2keepers.UnknownState,
+ }, states)
+
+ observedLogs.TakeAll()
+
+ require.Equal(t, 0, observedLogs.Len())
+ })
+}
+
func TestUpkeepStateStore_Upsert(t *testing.T) {
+ db := pgtest.NewSqlxDB(t)
ctx := testutils.Context(t)
- store := NewUpkeepStateStore(logger.TestLogger(t), &mockScanner{})
+ lggr := logger.TestLogger(t)
+ chainID := testutils.FixtureChainID
+ orm := NewORM(chainID, db, lggr, pgtest.NewQConfig(true))
+
+ store := NewUpkeepStateStore(orm, lggr, &mockScanner{})
res := ocr2keepers.CheckResult{
UpkeepID: createUpkeepIDForTest(1),
@@ -164,6 +452,49 @@ func TestUpkeepStateStore_Upsert(t *testing.T) {
require.True(t, now.After(addedAt))
}
+func TestUpkeepStateStore_Service(t *testing.T) {
+ orm := &mockORM{
+ onDelete: func(tm time.Time) {
+
+ },
+ }
+ scanner := &mockScanner{}
+
+ store := NewUpkeepStateStore(orm, logger.TestLogger(t), scanner)
+
+ store.retention = 500 * time.Millisecond
+ store.cleanCadence = 100 * time.Millisecond
+
+ assert.NoError(t, store.Start(context.Background()), "no error from starting service")
+
+ // add a value to set up the test
+ require.NoError(t, store.SetUpkeepState(context.Background(), ocr2keepers.CheckResult{
+ Eligible: false,
+ WorkID: "0x2",
+ Trigger: ocr2keepers.Trigger{
+ BlockNumber: ocr2keepers.BlockNumber(1),
+ },
+ }, ocr2keepers.Ineligible))
+
+ // allow one cycle of cleaning the cache
+ time.Sleep(110 * time.Millisecond)
+
+ // select from store to ensure values still exist
+ values, err := store.SelectByWorkIDs(context.Background(), "0x2")
+ require.NoError(t, err, "no error from selecting states")
+ require.Equal(t, []ocr2keepers.UpkeepState{ocr2keepers.Ineligible}, values, "selected values should match expected")
+
+ // wait longer than cache timeout
+ time.Sleep(700 * time.Millisecond)
+
+ // select from store to ensure cached values were removed
+ values, err = store.SelectByWorkIDs(context.Background(), "0x2")
+ require.NoError(t, err, "no error from selecting states")
+ require.Equal(t, []ocr2keepers.UpkeepState{ocr2keepers.UnknownState}, values, "selected values should match expected")
+
+ assert.NoError(t, store.Close(), "no error from closing service")
+}
+
func createUpkeepIDForTest(v int64) ocr2keepers.UpkeepIdentifier {
uid := &ocr2keepers.UpkeepIdentifier{}
_ = uid.FromBigInt(big.NewInt(v))
@@ -191,7 +522,7 @@ func (s *mockScanner) setErr(err error) {
s.err = err
}
-func (s *mockScanner) WorkIDsInRange(ctx context.Context, start, end int64) ([]string, error) {
+func (s *mockScanner) ScanWorkIDs(context.Context, ...string) ([]string, error) {
s.lock.Lock()
defer s.lock.Unlock()
@@ -207,3 +538,67 @@ func (s *mockScanner) Start(context.Context) error {
func (s *mockScanner) Close() error {
return nil
}
+
+type mockORM struct {
+ lock sync.Mutex
+ records []persistedStateRecord
+ lastPruneDepth time.Time
+ onDelete func(tm time.Time)
+ err error
+}
+
+func (_m *mockORM) addRecords(records ...persistedStateRecord) {
+ _m.lock.Lock()
+ defer _m.lock.Unlock()
+
+ _m.records = append(_m.records, records...)
+}
+
+func (_m *mockORM) setErr(err error) {
+ _m.lock.Lock()
+ defer _m.lock.Unlock()
+
+ _m.err = err
+}
+
+func (_m *mockORM) BatchInsertRecords(state []persistedStateRecord, _ ...pg.QOpt) error {
+ return nil
+}
+
+func (_m *mockORM) SelectStatesByWorkIDs(workIDs []string, _ ...pg.QOpt) ([]persistedStateRecord, error) {
+ _m.lock.Lock()
+ defer _m.lock.Unlock()
+
+ res := _m.records[:]
+ _m.records = nil
+
+ return res, _m.err
+}
+
+func (_m *mockORM) DeleteExpired(tm time.Time, _ ...pg.QOpt) error {
+ _m.lock.Lock()
+ defer _m.lock.Unlock()
+
+ _m.lastPruneDepth = tm
+ _m.onDelete(tm)
+
+ return _m.err
+}
+
+type wrappedORM struct {
+ BatchInsertRecordsFn func([]persistedStateRecord, ...pg.QOpt) error
+ SelectStatesByWorkIDsFn func([]string, ...pg.QOpt) ([]persistedStateRecord, error)
+ DeleteExpiredFn func(time.Time, ...pg.QOpt) error
+}
+
+func (o *wrappedORM) BatchInsertRecords(r []persistedStateRecord, q ...pg.QOpt) error {
+ return o.BatchInsertRecordsFn(r, q...)
+}
+
+func (o *wrappedORM) SelectStatesByWorkIDs(ids []string, q ...pg.QOpt) ([]persistedStateRecord, error) {
+ return o.SelectStatesByWorkIDsFn(ids, q...)
+}
+
+func (o *wrappedORM) DeleteExpired(t time.Time, q ...pg.QOpt) error {
+ return o.DeleteExpiredFn(t, q...)
+}
diff --git a/core/services/ocr2/plugins/ocr2keeper/integration_21_test.go b/core/services/ocr2/plugins/ocr2keeper/integration_21_test.go
index 91e422ce949..e864b0d7e2f 100644
--- a/core/services/ocr2/plugins/ocr2keeper/integration_21_test.go
+++ b/core/services/ocr2/plugins/ocr2keeper/integration_21_test.go
@@ -7,6 +7,7 @@ import (
"encoding/json"
"fmt"
"math/big"
+ "net/http"
"strings"
"sync"
"testing"
@@ -29,15 +30,18 @@ import (
"github.com/stretchr/testify/require"
"github.com/umbracle/ethgo/abi"
+ relaytypes "github.com/smartcontractkit/chainlink-relay/pkg/types"
"github.com/smartcontractkit/chainlink/v2/core/assets"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller"
automationForwarderLogic "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/automation_forwarder_logic"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/basic_upkeep_contract"
+ "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/dummy_protocol_wrapper"
iregistry21 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/i_keeper_registry_master_wrapper_2_1"
registrylogica21 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_registry_logic_a_wrapper_2_1"
registrylogicb21 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_registry_logic_b_wrapper_2_1"
registry21 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_registry_wrapper_2_1"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/link_token_interface"
+ "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/log_triggered_streams_lookup_wrapper"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/log_upkeep_counter_wrapper"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/mock_v3_aggregator_contract"
"github.com/smartcontractkit/chainlink/v2/core/internal/cltest"
@@ -46,6 +50,7 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/services/job"
"github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ethkey"
"github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper"
+ evm21 "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21"
"github.com/smartcontractkit/chainlink/v2/core/services/pipeline"
"github.com/smartcontractkit/chainlink/v2/core/services/relay/evm"
)
@@ -57,7 +62,7 @@ func TestFilterNamesFromSpec21(t *testing.T) {
address := common.HexToAddress(hexutil.Encode(b))
spec := &job.OCR2OracleSpec{
- PluginType: job.OCR2Keeper,
+ PluginType: relaytypes.OCR2Keeper,
ContractID: address.String(), // valid contract addr
}
@@ -69,7 +74,7 @@ func TestFilterNamesFromSpec21(t *testing.T) {
assert.Equal(t, logpoller.FilterName("KeeperRegistry Events", address), names[1])
spec = &job.OCR2OracleSpec{
- PluginType: job.OCR2Keeper,
+ PluginType: relaytypes.OCR2Keeper,
ContractID: "0x5431", // invalid contract addr
}
_, err = ocr2keeper.FilterNamesFromSpec21(spec)
@@ -109,7 +114,7 @@ func TestIntegration_KeeperPluginConditionalUpkeep(t *testing.T) {
require.NoError(t, err)
registry := deployKeeper21Registry(t, steve, backend, linkAddr, linkFeedAddr, gasFeedAddr)
- nodes := setupNodes(t, nodeKeys, registry, backend, steve)
+ nodes, _ := setupNodes(t, nodeKeys, registry, backend, steve)
<-time.After(time.Second * 5)
@@ -165,7 +170,6 @@ func TestIntegration_KeeperPluginConditionalUpkeep(t *testing.T) {
}
func TestIntegration_KeeperPluginLogUpkeep(t *testing.T) {
- t.Skip() // TODO: fix test (fails in CI)
g := gomega.NewWithT(t)
// setup blockchain
@@ -195,13 +199,9 @@ func TestIntegration_KeeperPluginLogUpkeep(t *testing.T) {
require.NoError(t, err)
linkFeedAddr, _, _, err := mock_v3_aggregator_contract.DeployMockV3AggregatorContract(steve, backend, 18, big.NewInt(2000000000000000000))
require.NoError(t, err)
- registry := deployKeeper21Registry(t, steve, backend, linkAddr, linkFeedAddr, gasFeedAddr)
-
- nodes := setupNodes(t, nodeKeys, registry, backend, steve)
- // wait for nodes to start
- // TODO: find a better way to do this
- <-time.After(time.Second * 10)
+ registry := deployKeeper21Registry(t, steve, backend, linkAddr, linkFeedAddr, gasFeedAddr)
+ nodes, _ := setupNodes(t, nodeKeys, registry, backend, steve)
upkeeps := 1
_, err = linkToken.Transfer(sergey, carrol.From, big.NewInt(0).Mul(oneHunEth, big.NewInt(int64(upkeeps+1))))
@@ -216,26 +216,23 @@ func TestIntegration_KeeperPluginLogUpkeep(t *testing.T) {
backend.Commit()
- emits := 10
+ emits := 1
go emitEvents(testutils.Context(t), t, emits, contracts, carrol, func() {
backend.Commit()
- time.Sleep(3 * time.Second)
})
listener, done := listenPerformed(t, backend, registry, ids, int64(1))
g.Eventually(listener, testutils.WaitTimeout(t), cltest.DBPollingInterval).Should(gomega.BeTrue())
done()
- runs := checkPipelineRuns(t, nodes, 1*len(nodes)) // TODO: TBD
+ runs := checkPipelineRuns(t, nodes, 1)
t.Run("recover logs", func(t *testing.T) {
- t.Skip() // TODO: fix test (fails in CI)
addr, contract := addrs[0], contracts[0]
upkeepID := registerUpkeep(t, registry, addr, carrol, steve, backend)
backend.Commit()
t.Logf("Registered new upkeep %s for address %s", upkeepID.String(), addr.String())
- // blockBeforeEmits := backend.Blockchain().CurrentBlock().Number.Uint64()
// Emit 100 logs in a burst
emits := 100
i := 0
@@ -252,18 +249,132 @@ func TestIntegration_KeeperPluginLogUpkeep(t *testing.T) {
backend.Commit()
time.Sleep(time.Millisecond * 10)
}
- t.Logf("Mined %d blocks", dummyBlocks)
+ t.Logf("Mined %d blocks, waiting for logs to be recovered", dummyBlocks)
- // listener, done := listenPerformed(t, backend, registry, []*big.Int{upkeepID}, int64(blockBeforeEmits))
- // defer done()
- // g.Eventually(listener, testutils.WaitTimeout(t), cltest.DBPollingInterval).Should(gomega.BeTrue())
-
- expectedPostRecover := runs + emits // TODO: TBD
+ expectedPostRecover := runs + emits
waitPipelineRuns(t, nodes, expectedPostRecover, testutils.WaitTimeout(t), cltest.DBPollingInterval)
})
}
+func TestIntegration_KeeperPluginLogUpkeep_Retry(t *testing.T) {
+ g := gomega.NewWithT(t)
+
+ // setup blockchain
+ linkOwner := testutils.MustNewSimTransactor(t) // owns all the link
+ registryOwner := testutils.MustNewSimTransactor(t) // registry owner
+ upkeepOwner := testutils.MustNewSimTransactor(t) // upkeep owner
+ genesisData := core.GenesisAlloc{
+ linkOwner.From: {Balance: assets.Ether(10000).ToInt()},
+ registryOwner.From: {Balance: assets.Ether(10000).ToInt()},
+ upkeepOwner.From: {Balance: assets.Ether(10000).ToInt()},
+ }
+
+ // Generate 5 keys for nodes (1 bootstrap + 4 ocr nodes) and fund them with ether
+ var nodeKeys [5]ethkey.KeyV2
+ for i := int64(0); i < 5; i++ {
+ nodeKeys[i] = cltest.MustGenerateRandomKey(t)
+ genesisData[nodeKeys[i].Address] = core.GenesisAccount{Balance: assets.Ether(1000).ToInt()}
+ }
+
+ backend := cltest.NewSimulatedBackend(t, genesisData, uint32(ethconfig.Defaults.Miner.GasCeil))
+ stopMining := cltest.Mine(backend, 3*time.Second) // Should be greater than deltaRound since we cannot access old blocks on simulated blockchain
+ defer stopMining()
+
+ // Deploy registry
+ linkAddr, _, linkToken, err := link_token_interface.DeployLinkToken(linkOwner, backend)
+ require.NoError(t, err)
+
+ gasFeedAddr, _, _, err := mock_v3_aggregator_contract.DeployMockV3AggregatorContract(registryOwner, backend, 18, big.NewInt(60000000000))
+ require.NoError(t, err)
+
+ linkFeedAddr, _, _, err := mock_v3_aggregator_contract.DeployMockV3AggregatorContract(registryOwner, backend, 18, big.NewInt(2000000000000000000))
+ require.NoError(t, err)
+
+ registry := deployKeeper21Registry(t, registryOwner, backend, linkAddr, linkFeedAddr, gasFeedAddr)
+
+ nodes, mercuryServer := setupNodes(t, nodeKeys, registry, backend, registryOwner)
+
+ const upkeepCount = 10
+ const mercuryFailCount = upkeepCount * 3 * 2
+
+ // testing with the mercury server involves mocking responses. currently,
+ // there is not a way to connect a mercury call to an upkeep id (though we
+ // could add custom headers) so the test must be fairly basic and just
+ // count calls before switching to successes
+ var (
+ mu sync.Mutex
+ count int
+ )
+
+ mercuryServer.RegisterHandler(func(w http.ResponseWriter, r *http.Request) {
+ mu.Lock()
+ defer mu.Unlock()
+
+ count++
+
+ _ = r.ParseForm()
+
+ t.Logf("MercuryHTTPServe:RequestURI: %s", r.RequestURI)
+
+ for key, value := range r.Form {
+ t.Logf("MercuryHTTPServe:FormValue: key: %s; value: %s;", key, value)
+ }
+
+ // the streams lookup retries against the remote server 3 times before
+ // returning a result as retryable.
+ // the simulation here should force the streams lookup process to return
+ // retryable 2 times.
+ // the total count of failures should be (upkeepCount * 3 * tryCount)
+ if count <= mercuryFailCount {
+ w.WriteHeader(http.StatusNotFound)
+
+ return
+ }
+
+ // start sending success messages
+ output := `{"chainlinkBlob":"0x0001c38d71fed6c320b90e84b6f559459814d068e2a1700adc931ca9717d4fe70000000000000000000000000000000000000000000000000000000001a80b52b4bf1233f9cb71144a253a1791b202113c4ab4a92fa1b176d684b4959666ff8200000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001004254432d5553442d415242495452554d2d544553544e4554000000000000000000000000000000000000000000000000000000000000000000000000645570be000000000000000000000000000000000000000000000000000002af2b818dc5000000000000000000000000000000000000000000000000000002af2426faf3000000000000000000000000000000000000000000000000000002af32dc209700000000000000000000000000000000000000000000000000000000012130f8df0a9745bb6ad5e2df605e158ba8ad8a33ef8a0acf9851f0f01668a3a3f2b68600000000000000000000000000000000000000000000000000000000012130f60000000000000000000000000000000000000000000000000000000000000002c4a7958dce105089cf5edb68dad7dcfe8618d7784eb397f97d5a5fade78c11a58275aebda478968e545f7e3657aba9dcbe8d44605e4c6fde3e24edd5e22c94270000000000000000000000000000000000000000000000000000000000000002459c12d33986018a8959566d145225f0c4a4e61a9a3f50361ccff397899314f0018162cf10cd89897635a0bb62a822355bd199d09f4abe76e4d05261bb44733d"}`
+
+ w.WriteHeader(http.StatusOK)
+ _, _ = w.Write([]byte(output))
+ })
+
+ defer mercuryServer.Stop()
+
+ _, err = linkToken.Transfer(linkOwner, upkeepOwner.From, big.NewInt(0).Mul(oneHunEth, big.NewInt(int64(upkeepCount+1))))
+ require.NoError(t, err)
+
+ backend.Commit()
+
+ feeds, err := newFeedLookupUpkeepController(backend, registryOwner)
+ require.NoError(t, err, "no error expected from creating a feed lookup controller")
+
+ // deploy multiple upkeeps that listen to a log emitter and need to be
+ // performed for each log event
+ _ = feeds.DeployUpkeeps(t, backend, upkeepOwner, upkeepCount)
+ _ = feeds.RegisterAndFund(t, registry, registryOwner, backend, linkToken)
+ _ = feeds.EnableMercury(t, backend, registry, registryOwner)
+ _ = feeds.VerifyEnv(t, backend, registry, registryOwner)
+
+ // start emitting events in a separate go-routine
+ // feed lookup relies on a single contract event log to perform multiple
+ // listener contracts
+ go func() {
+ // only 1 event is necessary to make all 10 upkeeps eligible
+ _ = feeds.EmitEvents(t, backend, 1, func() {
+ // pause per emit for expected block production time
+ time.Sleep(3 * time.Second)
+ })
+ }()
+
+ listener, done := listenPerformed(t, backend, registry, feeds.UpkeepsIds(), int64(1))
+ g.Eventually(listener, testutils.WaitTimeout(t)-(5*time.Second), cltest.DBPollingInterval).Should(gomega.BeTrue())
+
+ done()
+
+ _ = checkPipelineRuns(t, nodes, 1*len(nodes)) // TODO: TBD
+}
+
func waitPipelineRuns(t *testing.T, nodes []Node, n int, timeout, interval time.Duration) {
ctx, cancel := context.WithTimeout(testutils.Context(t), timeout)
defer cancel()
@@ -321,29 +432,37 @@ func listenPerformed(t *testing.T, backend *backends.SimulatedBackend, registry
cache := &sync.Map{}
ctx, cancel := context.WithCancel(testutils.Context(t))
start := startBlock
+
go func() {
for ctx.Err() == nil {
bl := backend.Blockchain().CurrentBlock().Number.Uint64()
+
sc := make([]bool, len(ids))
for i := range sc {
sc[i] = true
}
+
iter, err := registry.FilterUpkeepPerformed(&bind.FilterOpts{
Start: uint64(start),
End: &bl,
Context: ctx,
}, ids, sc)
+
if ctx.Err() != nil {
return
}
+
require.NoError(t, err)
+
for iter.Next() {
if iter.Event != nil {
t.Logf("[automation-ocr3 | EvmRegistry] upkeep performed event emitted for id %s", iter.Event.Id.String())
cache.Store(iter.Event.Id.String(), true)
}
}
+
require.NoError(t, iter.Close())
+
time.Sleep(time.Second)
}
}()
@@ -351,11 +470,14 @@ func listenPerformed(t *testing.T, backend *backends.SimulatedBackend, registry
return mapListener(cache, 0), cancel
}
-func setupNodes(t *testing.T, nodeKeys [5]ethkey.KeyV2, registry *iregistry21.IKeeperRegistryMaster, backend *backends.SimulatedBackend, usr *bind.TransactOpts) []Node {
+func setupNodes(t *testing.T, nodeKeys [5]ethkey.KeyV2, registry *iregistry21.IKeeperRegistryMaster, backend *backends.SimulatedBackend, usr *bind.TransactOpts) ([]Node, *SimulatedMercuryServer) {
lggr := logger.TestLogger(t)
+ mServer := NewSimulatedMercuryServer()
+ mServer.Start()
+
// Setup bootstrap + oracle nodes
bootstrapNodePort := int64(19599)
- appBootstrap, bootstrapPeerID, bootstrapTransmitter, bootstrapKb := setupNode(t, bootstrapNodePort, "bootstrap_keeper_ocr", nodeKeys[0], backend, nil)
+ appBootstrap, bootstrapPeerID, bootstrapTransmitter, bootstrapKb := setupNode(t, bootstrapNodePort, "bootstrap_keeper_ocr", nodeKeys[0], backend, nil, mServer)
bootstrapNode := Node{
appBootstrap, bootstrapTransmitter, bootstrapKb,
}
@@ -368,7 +490,7 @@ func setupNodes(t *testing.T, nodeKeys [5]ethkey.KeyV2, registry *iregistry21.IK
app, peerID, transmitter, kb := setupNode(t, bootstrapNodePort+i+1, fmt.Sprintf("oracle_keeper%d", i), nodeKeys[i+1], backend, []commontypes.BootstrapperLocator{
// Supply the bootstrap IP and port as a V2 peer address
{PeerID: bootstrapPeerID, Addrs: []string{fmt.Sprintf("127.0.0.1:%d", bootstrapNodePort)}},
- })
+ }, mServer)
nodes = append(nodes, Node{
app, transmitter, kb,
@@ -441,7 +563,7 @@ func setupNodes(t *testing.T, nodeKeys [5]ethkey.KeyV2, registry *iregistry21.IK
"fallbackLinkPrice": big.NewInt(2000000000000000000),
"transcoder": testutils.NewAddress(),
"registrars": []common.Address{testutils.NewAddress()},
- "upkeepPrivilegeManager": testutils.NewAddress(),
+ "upkeepPrivilegeManager": usr.From,
}, configType)
require.NoError(t, err)
rawCfg, err := json.Marshal(config.OffchainConfig{
@@ -499,7 +621,7 @@ func setupNodes(t *testing.T, nodeKeys [5]ethkey.KeyV2, registry *iregistry21.IK
require.NoError(t, err)
backend.Commit()
- return nodes
+ return nodes, mServer
}
func deployUpkeeps(t *testing.T, backend *backends.SimulatedBackend, carrol, steve *bind.TransactOpts, linkToken *link_token_interface.LinkToken, registry *iregistry21.IKeeperRegistryMaster, n int) ([]*big.Int, []common.Address, []*log_upkeep_counter_wrapper.LogUpkeepCounter) {
@@ -602,3 +724,297 @@ func getUpkeepIdFromTx21(t *testing.T, registry *iregistry21.IKeeperRegistryMast
require.NoError(t, err)
return parsedLog.Id
}
+
+// ------- below this line could be added to a test helpers package
+type registerAndFundFunc func(*testing.T, common.Address, *bind.TransactOpts, uint8, []byte) *big.Int
+
+func registerAndFund(
+ registry *iregistry21.IKeeperRegistryMaster,
+ registryOwner *bind.TransactOpts,
+ backend *backends.SimulatedBackend,
+ linkToken *link_token_interface.LinkToken,
+) registerAndFundFunc {
+ return func(t *testing.T, upkeepAddr common.Address, upkeepOwner *bind.TransactOpts, trigger uint8, config []byte) *big.Int {
+ // register the upkeep on the host registry contract
+ registrationTx, err := registry.RegisterUpkeep(
+ registryOwner,
+ upkeepAddr,
+ 2_500_000,
+ upkeepOwner.From,
+ trigger,
+ []byte{},
+ config,
+ []byte{},
+ )
+ require.NoError(t, err)
+
+ backend.Commit()
+
+ receipt, err := backend.TransactionReceipt(testutils.Context(t), registrationTx.Hash())
+ require.NoError(t, err)
+
+ parsedLog, err := registry.ParseUpkeepRegistered(*receipt.Logs[0])
+ require.NoError(t, err)
+
+ upkeepID := parsedLog.Id
+
+ // Fund the upkeep
+ _, err = linkToken.Approve(upkeepOwner, registry.Address(), oneHunEth)
+ require.NoError(t, err)
+
+ _, err = registry.AddFunds(upkeepOwner, upkeepID, oneHunEth)
+ require.NoError(t, err)
+
+ backend.Commit()
+
+ return upkeepID
+ }
+}
+
+type feedLookupUpkeepController struct {
+ // address for dummy protocol
+ logSrcAddr common.Address
+ // dummy protocol is a log event source
+ protocol *dummy_protocol_wrapper.DummyProtocol
+ protocolOwner *bind.TransactOpts
+ // log trigger listener contracts react to logs produced from protocol
+ count int
+ upkeepIds []*big.Int
+ addresses []common.Address
+ contracts []*log_triggered_streams_lookup_wrapper.LogTriggeredStreamsLookup
+ contractsOwner *bind.TransactOpts
+}
+
+func newFeedLookupUpkeepController(
+ backend *backends.SimulatedBackend,
+ protocolOwner *bind.TransactOpts,
+) (*feedLookupUpkeepController, error) {
+ addr, _, contract, err := dummy_protocol_wrapper.DeployDummyProtocol(protocolOwner, backend)
+ if err != nil {
+ return nil, err
+ }
+
+ backend.Commit()
+
+ return &feedLookupUpkeepController{
+ logSrcAddr: addr,
+ protocol: contract,
+ protocolOwner: protocolOwner,
+ }, nil
+}
+
+func (c *feedLookupUpkeepController) DeployUpkeeps(
+ t *testing.T,
+ backend *backends.SimulatedBackend,
+ owner *bind.TransactOpts,
+ count int,
+) error {
+ addresses := make([]common.Address, count)
+ contracts := make([]*log_triggered_streams_lookup_wrapper.LogTriggeredStreamsLookup, count)
+
+ // deploy n upkeep contracts
+ for x := 0; x < count; x++ {
+ addr, _, contract, err := log_triggered_streams_lookup_wrapper.DeployLogTriggeredStreamsLookup(
+ owner,
+ backend,
+ false,
+ false,
+ )
+
+ if err != nil {
+ require.NoError(t, err, "test dependent on contract deployment")
+
+ return err
+ }
+
+ addresses[x] = addr
+ contracts[x] = contract
+ }
+
+ backend.Commit()
+
+ c.count = count
+ c.addresses = addresses
+ c.contracts = contracts
+ c.contractsOwner = owner
+
+ return nil
+}
+
+func (c *feedLookupUpkeepController) RegisterAndFund(
+ t *testing.T,
+ registry *iregistry21.IKeeperRegistryMaster,
+ registryOwner *bind.TransactOpts,
+ backend *backends.SimulatedBackend,
+ linkToken *link_token_interface.LinkToken,
+) error {
+ ids := make([]*big.Int, len(c.contracts))
+
+ t.Logf("address: %s", c.logSrcAddr.Hex())
+
+ logTriggerConfigType := abi.MustNewType("tuple(address contractAddress, uint8 filterSelector, bytes32 topic0, bytes32 topic1, bytes32 topic2, bytes32 topic3)")
+ config, err := abi.Encode(map[string]interface{}{
+ "contractAddress": c.logSrcAddr,
+ "filterSelector": 0, // no indexed topics filtered
+ "topic0": "0xd1ffe9e45581c11d7d9f2ed5f75217cd4be9f8b7eee6af0f6d03f46de53956cd", // LimitOrderExecuted event for dummy protocol
+ "topic1": "0x",
+ "topic2": "0x",
+ "topic3": "0x",
+ }, logTriggerConfigType)
+
+ require.NoError(t, err)
+
+ registerFunc := registerAndFund(registry, registryOwner, backend, linkToken)
+
+ for x := range c.contracts {
+ ids[x] = registerFunc(t, c.addresses[x], c.contractsOwner, 1, config)
+ }
+
+ c.upkeepIds = ids
+
+ return nil
+}
+
+func (c *feedLookupUpkeepController) EnableMercury(
+ t *testing.T,
+ backend *backends.SimulatedBackend,
+ registry *iregistry21.IKeeperRegistryMaster,
+ registryOwner *bind.TransactOpts,
+) error {
+ adminBytes, _ := json.Marshal(evm21.UpkeepPrivilegeConfig{
+ MercuryEnabled: true,
+ })
+
+ for _, id := range c.upkeepIds {
+ if _, err := registry.SetUpkeepPrivilegeConfig(registryOwner, id, adminBytes); err != nil {
+ require.NoError(t, err)
+
+ return err
+ }
+
+ callOpts := &bind.CallOpts{
+ Pending: true,
+ From: registryOwner.From,
+ Context: context.Background(),
+ }
+
+ bts, err := registry.GetUpkeepPrivilegeConfig(callOpts, id)
+ if err != nil {
+ require.NoError(t, err)
+
+ return err
+ }
+
+ var checkBytes evm21.UpkeepPrivilegeConfig
+ if err := json.Unmarshal(bts, &checkBytes); err != nil {
+ require.NoError(t, err)
+
+ return err
+ }
+
+ require.True(t, checkBytes.MercuryEnabled)
+ }
+
+ bl, _ := backend.BlockByHash(testutils.Context(t), backend.Commit())
+ t.Logf("block number after mercury enabled: %d", bl.NumberU64())
+
+ return nil
+}
+
+func (c *feedLookupUpkeepController) VerifyEnv(
+ t *testing.T,
+ backend *backends.SimulatedBackend,
+ registry *iregistry21.IKeeperRegistryMaster,
+ registryOwner *bind.TransactOpts,
+) error {
+ t.Log("verifying number of active upkeeps")
+
+ ids, err := registry.GetActiveUpkeepIDs(&bind.CallOpts{
+ Context: testutils.Context(t),
+ From: registryOwner.From,
+ }, big.NewInt(0), big.NewInt(100))
+
+ require.NoError(t, err)
+ require.Len(t, ids, c.count, "active upkeep ids does not match count")
+ require.Len(t, ids, len(c.upkeepIds))
+
+ t.Log("verifying total number of contracts")
+ require.Len(t, c.contracts, len(c.upkeepIds), "one contract for each upkeep id expected")
+
+ // call individual contracts to see that they revert
+ for _, contract := range c.contracts {
+ _, err := contract.CheckLog(c.contractsOwner, log_triggered_streams_lookup_wrapper.Log{
+ Index: big.NewInt(0),
+ Timestamp: big.NewInt(123),
+ TxHash: common.HexToHash("0x1"),
+ BlockNumber: big.NewInt(0),
+ BlockHash: common.HexToHash("0x14"),
+ Source: common.HexToAddress("0x2"),
+ Topics: [][32]byte{
+ common.HexToHash("0xd1ffe9e45581c11d7d9f2ed5f75217cd4be9f8b7eee6af0f6d03f46de53956cd"), // matches executedSig and should result in a feedlookup revert
+ common.HexToHash("0x"),
+ common.HexToHash("0x"),
+ common.HexToHash("0x"),
+ },
+ Data: []byte{},
+ }, []byte("0x"))
+
+ require.Error(t, err, "check log contract call should revert: %s", err)
+ }
+
+ return nil
+}
+
+func (c *feedLookupUpkeepController) EmitEvents(
+ t *testing.T,
+ backend *backends.SimulatedBackend,
+ count int,
+ afterEmit func(),
+) error {
+ ctx := testutils.Context(t)
+
+ for i := 0; i < count && ctx.Err() == nil; i++ {
+ _, err := c.protocol.ExecuteLimitOrder(c.protocolOwner, big.NewInt(1000), big.NewInt(10000), c.logSrcAddr)
+ require.NoError(t, err, "no error expected from limit order exec")
+
+ if err != nil {
+ return err
+ }
+
+ backend.Commit()
+
+ // verify event was emitted
+ block, _ := backend.BlockByHash(context.Background(), backend.Commit())
+ t.Logf("block number after emit event: %d", block.NumberU64())
+
+ iter, _ := c.protocol.FilterLimitOrderExecuted(
+ &bind.FilterOpts{
+ Context: testutils.Context(t),
+ Start: block.NumberU64() - 1,
+ },
+ []*big.Int{big.NewInt(1000)},
+ []*big.Int{big.NewInt(10000)},
+ []common.Address{c.logSrcAddr},
+ )
+
+ var eventEmitted bool
+ for iter.Next() {
+ if iter.Event != nil {
+ eventEmitted = true
+ }
+ }
+
+ require.True(t, eventEmitted, "event expected on backend")
+ if !eventEmitted {
+ return fmt.Errorf("event was not emitted")
+ }
+
+ afterEmit()
+ }
+
+ return nil
+}
+
+func (c *feedLookupUpkeepController) UpkeepsIds() []*big.Int {
+ return c.upkeepIds
+}
diff --git a/core/services/ocr2/plugins/ocr2keeper/integration_test.go b/core/services/ocr2/plugins/ocr2keeper/integration_test.go
index 8b7e92c40fe..eea9c1574cf 100644
--- a/core/services/ocr2/plugins/ocr2keeper/integration_test.go
+++ b/core/services/ocr2/plugins/ocr2keeper/integration_test.go
@@ -7,7 +7,10 @@ import (
"encoding/json"
"fmt"
"math/big"
+ "net/http"
+ "net/http/httptest"
"strings"
+ "sync"
"testing"
"time"
@@ -56,6 +59,8 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/services/relay/evm"
"github.com/smartcontractkit/chainlink/v2/core/store/models"
"github.com/smartcontractkit/chainlink/v2/core/utils"
+
+ relaytypes "github.com/smartcontractkit/chainlink-relay/pkg/types"
)
const (
@@ -108,11 +113,12 @@ func setupNode(
nodeKey ethkey.KeyV2,
backend *backends.SimulatedBackend,
p2pV2Bootstrappers []commontypes.BootstrapperLocator,
+ mercury MercuryEndpoint,
) (chainlink.Application, string, common.Address, ocr2key.KeyBundle) {
p2pKey, err := p2pkey.NewV2()
require.NoError(t, err)
p2paddresses := []string{fmt.Sprintf("127.0.0.1:%d", port)}
- config, _ := heavyweight.FullTestDBV2(t, fmt.Sprintf("%s%d", dbName, port), func(c *chainlink.Config, s *chainlink.Secrets) {
+ cfg, _ := heavyweight.FullTestDBV2(t, fmt.Sprintf("%s%d", dbName, port), func(c *chainlink.Config, s *chainlink.Secrets) {
c.Feature.LogPoller = ptr(true)
c.OCR.Enabled = ptr(false)
@@ -133,14 +139,15 @@ func setupNode(
c.EVM[0].GasEstimator.Mode = ptr("FixedPrice")
s.Mercury.Credentials = map[string]toml.MercuryCredentials{
MercuryCredName: {
- URL: models.MustSecretURL("https://mercury.chain.link"),
- Username: models.NewSecret("username1"),
- Password: models.NewSecret("password1"),
+ LegacyURL: models.MustSecretURL(mercury.URL()),
+ URL: models.MustSecretURL(mercury.URL()),
+ Username: models.NewSecret(mercury.Username()),
+ Password: models.NewSecret(mercury.Password()),
},
}
})
- app := cltest.NewApplicationWithConfigV2AndKeyOnSimulatedBlockchain(t, config, backend, nodeKey, p2pKey)
+ app := cltest.NewApplicationWithConfigV2AndKeyOnSimulatedBlockchain(t, cfg, backend, nodeKey, p2pKey)
kb, err := app.GetKeyStore().OCR2().Create(chaintype.EVM)
require.NoError(t, err)
@@ -162,16 +169,16 @@ type Node struct {
func (node *Node) AddJob(t *testing.T, spec string) {
c := node.App.GetConfig()
- job, err := validate.ValidatedOracleSpecToml(c.OCR2(), c.Insecure(), spec)
+ jb, err := validate.ValidatedOracleSpecToml(c.OCR2(), c.Insecure(), spec)
require.NoError(t, err)
- err = node.App.AddJobV2(context.Background(), &job)
+ err = node.App.AddJobV2(context.Background(), &jb)
require.NoError(t, err)
}
func (node *Node) AddBootstrapJob(t *testing.T, spec string) {
- job, err := ocrbootstrap.ValidatedBootstrapSpecToml(spec)
+ jb, err := ocrbootstrap.ValidatedBootstrapSpecToml(spec)
require.NoError(t, err)
- err = node.App.AddJobV2(context.Background(), &job)
+ err = node.App.AddJobV2(context.Background(), &jb)
require.NoError(t, err)
}
@@ -232,7 +239,7 @@ func TestIntegration_KeeperPluginBasic(t *testing.T) {
// Setup bootstrap + oracle nodes
bootstrapNodePort := int64(19599)
- appBootstrap, bootstrapPeerID, bootstrapTransmitter, bootstrapKb := setupNode(t, bootstrapNodePort, "bootstrap_keeper_ocr", nodeKeys[0], backend, nil)
+ appBootstrap, bootstrapPeerID, bootstrapTransmitter, bootstrapKb := setupNode(t, bootstrapNodePort, "bootstrap_keeper_ocr", nodeKeys[0], backend, nil, NewSimulatedMercuryServer())
bootstrapNode := Node{
appBootstrap, bootstrapTransmitter, bootstrapKb,
}
@@ -245,7 +252,7 @@ func TestIntegration_KeeperPluginBasic(t *testing.T) {
app, peerID, transmitter, kb := setupNode(t, bootstrapNodePort+i+1, fmt.Sprintf("oracle_keeper%d", i), nodeKeys[i+1], backend, []commontypes.BootstrapperLocator{
// Supply the bootstrap IP and port as a V2 peer address
{PeerID: bootstrapPeerID, Addrs: []string{fmt.Sprintf("127.0.0.1:%d", bootstrapNodePort)}},
- })
+ }, NewSimulatedMercuryServer())
nodes = append(nodes, Node{
app, transmitter, kb,
@@ -492,7 +499,7 @@ func TestIntegration_KeeperPluginForwarderEnabled(t *testing.T) {
effectiveTransmitters := make([]common.Address, 0)
// Setup bootstrap + oracle nodes
bootstrapNodePort := int64(19599)
- appBootstrap, bootstrapPeerID, bootstrapTransmitter, bootstrapKb := setupNode(t, bootstrapNodePort, "bootstrap_keeper_ocr", nodeKeys[0], backend, nil)
+ appBootstrap, bootstrapPeerID, bootstrapTransmitter, bootstrapKb := setupNode(t, bootstrapNodePort, "bootstrap_keeper_ocr", nodeKeys[0], backend, nil, NewSimulatedMercuryServer())
bootstrapNode := Node{
appBootstrap, bootstrapTransmitter, bootstrapKb,
@@ -506,7 +513,7 @@ func TestIntegration_KeeperPluginForwarderEnabled(t *testing.T) {
app, peerID, transmitter, kb := setupNode(t, bootstrapNodePort+i+1, fmt.Sprintf("oracle_keeper%d", i), nodeKeys[i+1], backend, []commontypes.BootstrapperLocator{
// Supply the bootstrap IP and port as a V2 peer address
{PeerID: bootstrapPeerID, Addrs: []string{fmt.Sprintf("127.0.0.1:%d", bootstrapNodePort)}},
- })
+ }, NewSimulatedMercuryServer())
nodeForwarder := setupForwarderForNode(t, app, sergey, backend, transmitter, linkAddr)
effectiveTransmitters = append(effectiveTransmitters, nodeForwarder)
@@ -705,7 +712,7 @@ func TestFilterNamesFromSpec20(t *testing.T) {
address := common.HexToAddress(hexutil.Encode(b))
spec := &job.OCR2OracleSpec{
- PluginType: job.OCR2Keeper,
+ PluginType: relaytypes.OCR2Keeper,
ContractID: address.String(), // valid contract addr
}
@@ -717,9 +724,78 @@ func TestFilterNamesFromSpec20(t *testing.T) {
assert.Equal(t, logpoller.FilterName("EvmRegistry - Upkeep events for", address), names[1])
spec = &job.OCR2OracleSpec{
- PluginType: job.OCR2Keeper,
+ PluginType: relaytypes.OCR2Keeper,
ContractID: "0x5431", // invalid contract addr
}
_, err = ocr2keeper.FilterNamesFromSpec20(spec)
require.ErrorContains(t, err, "not a valid EIP55 formatted address")
}
+
+// ------- below this line could be added to a test helpers package
+type MercuryEndpoint interface {
+ URL() string
+ Username() string
+ Password() string
+ CallCount() int
+ RegisterHandler(http.HandlerFunc)
+}
+
+type SimulatedMercuryServer struct {
+ server *httptest.Server
+ handler http.HandlerFunc
+
+ mu sync.RWMutex
+ callCount int
+}
+
+func NewSimulatedMercuryServer() *SimulatedMercuryServer {
+ srv := &SimulatedMercuryServer{
+ handler: func(w http.ResponseWriter, r *http.Request) {
+ w.WriteHeader(http.StatusNotFound)
+ },
+ }
+
+ srv.server = httptest.NewUnstartedServer(srv)
+
+ return srv
+}
+
+func (ms *SimulatedMercuryServer) URL() string {
+ return ms.server.URL
+}
+
+func (ms *SimulatedMercuryServer) Username() string {
+ return "username1"
+}
+
+func (ms *SimulatedMercuryServer) Password() string {
+ return "password1"
+}
+
+func (ms *SimulatedMercuryServer) CallCount() int {
+ ms.mu.RLock()
+ defer ms.mu.RUnlock()
+
+ return ms.callCount
+}
+
+func (ms *SimulatedMercuryServer) RegisterHandler(h http.HandlerFunc) {
+ ms.handler = h
+}
+
+func (ms *SimulatedMercuryServer) Start() {
+ ms.server.Start()
+}
+
+func (ms *SimulatedMercuryServer) Stop() {
+ ms.server.Close()
+}
+
+func (ms *SimulatedMercuryServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+ ms.mu.Lock()
+ defer ms.mu.Unlock()
+
+ ms.callCount++
+
+ ms.handler.ServeHTTP(w, r)
+}
diff --git a/core/services/ocr2/plugins/ocr2keeper/util.go b/core/services/ocr2/plugins/ocr2keeper/util.go
index 5934ed45df2..132afd0d29d 100644
--- a/core/services/ocr2/plugins/ocr2keeper/util.go
+++ b/core/services/ocr2/plugins/ocr2keeper/util.go
@@ -21,6 +21,8 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/services/ocr2/models"
kevm20 "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm20"
kevm21 "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21"
+ kevm21transmit "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21/transmit"
+ "github.com/smartcontractkit/chainlink/v2/core/services/pg"
"github.com/smartcontractkit/chainlink/v2/core/services/pipeline"
evmrelay "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm"
)
@@ -113,6 +115,7 @@ func EVMDependencies21(
pr pipeline.Runner,
mc *models.MercuryCredentials,
keyring ocrtypes.OnchainKeyring,
+ dbCfg pg.QConfig,
) (evmrelay.OCR2KeeperProvider, kevm21.AutomationServices, error) {
var err error
var keeperProvider evmrelay.OCR2KeeperProvider
@@ -124,7 +127,7 @@ func EVMDependencies21(
}
rAddr := ethkey.MustEIP55Address(oSpec.ContractID).Address()
- services, err := kevm21.New(rAddr, chain, mc, keyring, lggr)
+ services, err := kevm21.New(rAddr, chain, mc, keyring, lggr, db, dbCfg)
if err != nil {
return nil, nil, err
}
@@ -137,5 +140,5 @@ func FilterNamesFromSpec21(spec *job.OCR2OracleSpec) (names []string, err error)
if err != nil {
return nil, err
}
- return []string{kevm21.TransmitEventProviderFilterName(addr.Address()), kevm21.RegistryUpkeepFilterName(addr.Address())}, err
+ return []string{kevm21transmit.EventProviderFilterName(addr.Address()), kevm21.RegistryUpkeepFilterName(addr.Address())}, err
}
diff --git a/core/services/ocr2/plugins/ocr2vrf/coordinator/coordinator_test.go b/core/services/ocr2/plugins/ocr2vrf/coordinator/coordinator_test.go
index 5a32644d0ee..1222ab7b2a4 100644
--- a/core/services/ocr2/plugins/ocr2vrf/coordinator/coordinator_test.go
+++ b/core/services/ocr2/plugins/ocr2vrf/coordinator/coordinator_test.go
@@ -25,6 +25,7 @@ import (
"github.com/smartcontractkit/ocr2vrf/ocr2vrf"
ocr2vrftypes "github.com/smartcontractkit/ocr2vrf/types"
+ relaytypes "github.com/smartcontractkit/chainlink-relay/pkg/types"
evmclimocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client/mocks"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller"
lp_mocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller/mocks"
@@ -1761,7 +1762,7 @@ func TestFilterNamesFromSpec(t *testing.T) {
spec := &job.OCR2OracleSpec{
ContractID: beaconAddress.String(),
- PluginType: job.OCR2VRF,
+ PluginType: relaytypes.OCR2VRF,
PluginConfig: job.JSONConfig{
"VRFCoordinatorAddress": coordinatorAddress.String(),
"DKGContractAddress": dkgAddress.String(),
@@ -1775,7 +1776,7 @@ func TestFilterNamesFromSpec(t *testing.T) {
assert.Equal(t, logpoller.FilterName("VRF Coordinator", beaconAddress, coordinatorAddress, dkgAddress), names[0])
spec = &job.OCR2OracleSpec{
- PluginType: job.OCR2VRF,
+ PluginType: relaytypes.OCR2VRF,
ContractID: beaconAddress.String(),
PluginConfig: nil, // missing coordinator & dkg addresses
}
diff --git a/core/services/ocr2/plugins/ocr2vrf/internal/ocr2vrf_integration_test.go b/core/services/ocr2/plugins/ocr2vrf/internal/ocr2vrf_integration_test.go
index 0ca6fb383c6..c6a4552683a 100644
--- a/core/services/ocr2/plugins/ocr2vrf/internal/ocr2vrf_integration_test.go
+++ b/core/services/ocr2/plugins/ocr2vrf/internal/ocr2vrf_integration_test.go
@@ -8,7 +8,6 @@ import (
"fmt"
"math/big"
"net"
- "os"
"testing"
"time"
@@ -323,16 +322,12 @@ func setupNodeOCR2(
}
func TestIntegration_OCR2VRF_ForwarderFlow(t *testing.T) {
- if os.Getenv("CI") == "" && os.Getenv("VRF_LOCAL_TESTING") == "" {
- t.Skip("Skipping test locally.")
- }
+ t.Skip()
runOCR2VRFTest(t, true)
}
func TestIntegration_OCR2VRF(t *testing.T) {
- if os.Getenv("CI") == "" && os.Getenv("VRF_LOCAL_TESTING") == "" {
- t.Skip("Skipping test locally.")
- }
+ t.Skip()
runOCR2VRFTest(t, false)
}
@@ -431,8 +426,8 @@ func runOCR2VRFTest(t *testing.T, useForwarders bool) {
err = bootstrapNode.app.Start(testutils.Context(t))
require.NoError(t, err)
- chainSet := bootstrapNode.app.GetRelayers().LegacyEVMChains()
- require.NotNil(t, chainSet)
+ evmChains := bootstrapNode.app.GetRelayers().LegacyEVMChains()
+ require.NotNil(t, evmChains)
bootstrapJobSpec := fmt.Sprintf(`
type = "bootstrap"
name = "bootstrap"
diff --git a/core/services/ocr2/plugins/s4/messages_test.go b/core/services/ocr2/plugins/s4/messages_test.go
index 78fcabf9899..55c65eec8df 100644
--- a/core/services/ocr2/plugins/s4/messages_test.go
+++ b/core/services/ocr2/plugins/s4/messages_test.go
@@ -1,14 +1,16 @@
package s4_test
import (
+ "crypto/ecdsa"
"testing"
"time"
+ "github.com/ethereum/go-ethereum/common"
+
"github.com/smartcontractkit/chainlink/v2/core/internal/testutils"
"github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/s4"
s4_svc "github.com/smartcontractkit/chainlink/v2/core/services/s4"
- "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
@@ -55,6 +57,32 @@ func Test_MarshalUnmarshalQuery(t *testing.T) {
require.Equal(t, addressRange, ar)
}
+func signRow(t *testing.T, row *s4.Row, address common.Address, pk *ecdsa.PrivateKey) {
+ t.Helper()
+
+ env := &s4_svc.Envelope{
+ Address: address.Bytes(),
+ SlotID: uint(row.Slotid),
+ Version: row.Version,
+ Expiration: row.Expiration,
+ Payload: row.Payload,
+ }
+ sig, err := env.Sign(pk)
+ require.NoError(t, err)
+ row.Signature = sig
+}
+
+func marshalUnmarshal(t *testing.T, row *s4.Row) *s4.Row {
+ t.Helper()
+
+ data, err := s4.MarshalRows([]*s4.Row{row})
+ require.NoError(t, err)
+ rows, err := s4.UnmarshalRows(data)
+ require.NoError(t, err)
+ require.Len(t, rows, 1)
+ return rows[0]
+}
+
func Test_VerifySignature(t *testing.T) {
t.Parallel()
@@ -71,20 +99,24 @@ func Test_VerifySignature(t *testing.T) {
for addr[0] != 0 {
pk, addr = testutils.NewPrivateKeyAndAddress(t)
}
- rows := generateTestRows(t, 1, time.Minute)
- rows[0].Address = addr.Big().Bytes()
- env := &s4_svc.Envelope{
- Address: addr.Bytes(),
- SlotID: uint(rows[0].Slotid),
- Version: rows[0].Version,
- Expiration: rows[0].Expiration,
- Payload: rows[0].Payload,
- }
- sig, err := env.Sign(pk)
- assert.NoError(t, err)
- rows[0].Signature = sig
+ row := generateTestRows(t, 1, time.Minute)[0]
+ row.Address = addr.Big().Bytes()
+ signRow(t, row, addr, pk)
- err = rows[0].VerifySignature()
- require.NoError(t, err)
+ require.NoError(t, row.VerifySignature())
+ sameRow := marshalUnmarshal(t, row)
+ require.NoError(t, sameRow.VerifySignature())
+ })
+
+ t.Run("empty payload", func(t *testing.T) {
+ pk, addr := testutils.NewPrivateKeyAndAddress(t)
+ row := generateTestRows(t, 1, time.Minute)[0]
+ row.Payload = []byte{}
+ row.Address = addr.Big().Bytes()
+ signRow(t, row, addr, pk)
+
+ require.NoError(t, row.VerifySignature())
+ sameRow := marshalUnmarshal(t, row)
+ require.NoError(t, sameRow.VerifySignature())
})
}
diff --git a/core/services/ocr2/plugins/s4/plugin.go b/core/services/ocr2/plugins/s4/plugin.go
index 23041b3b91e..7e4b91be97e 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
diff --git a/core/services/ocr2/plugins/s4/plugin_test.go b/core/services/ocr2/plugins/s4/plugin_test.go
index 0d37103936f..b85ba053122 100644
--- a/core/services/ocr2/plugins/s4/plugin_test.go
+++ b/core/services/ocr2/plugins/s4/plugin_test.go
@@ -345,7 +345,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 +355,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 +384,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 +476,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 b051e94dfe8..442fcffe8b4 100644
--- a/core/services/ocr2/plugins/threshold/decryption_queue.go
+++ b/core/services/ocr2/plugins/threshold/decryption_queue.go
@@ -56,7 +56,7 @@ func NewDecryptionQueue(maxQueueLength int, maxCiphertextBytes int, maxCiphertex
make(map[string]pendingRequest),
make(map[string]completedRequest),
sync.RWMutex{},
- lggr.Named("decryptionQueue"),
+ lggr.Named("DecryptionQueue"),
}
return &dq
}
@@ -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
}
@@ -171,7 +171,11 @@ func (dq *decryptionQueue) GetRequests(requestCountLimit int, totalBytesLimit in
dq.pendingRequestQueue = removeMultipleIndices(dq.pendingRequestQueue, indicesToRemove)
- dq.lggr.Debugf("returning first %d of %d total requests awaiting decryption", len(requests), len(dq.pendingRequestQueue))
+ if len(dq.pendingRequestQueue) > 0 {
+ dq.lggr.Debugf("returning first %d of %d total requests awaiting decryption", len(requests), len(dq.pendingRequestQueue))
+ } else {
+ dq.lggr.Debug("no requests awaiting decryption")
+ }
return requests
}
@@ -194,7 +198,7 @@ func (dq *decryptionQueue) GetCiphertext(ciphertextId decryptionPlugin.Ciphertex
req, ok := dq.pendingRequests[string(ciphertextId)]
if !ok {
- return nil, fmt.Errorf("ciphertextID %s not found", ciphertextId)
+ return nil, decryptionPlugin.ErrNotFound
}
return req.ciphertext, nil
@@ -228,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/plugins/threshold/decryption_queue_test.go b/core/services/ocr2/plugins/threshold/decryption_queue_test.go
index dbe6e779ea6..bf7deb6bbbe 100644
--- a/core/services/ocr2/plugins/threshold/decryption_queue_test.go
+++ b/core/services/ocr2/plugins/threshold/decryption_queue_test.go
@@ -2,6 +2,7 @@ package threshold
import (
"context"
+ "errors"
"reflect"
"testing"
"time"
@@ -200,7 +201,7 @@ func Test_decryptionQueue_GetCiphertext_CiphertextNotFound(t *testing.T) {
dq := NewDecryptionQueue(3, 1000, 64, testutils.WaitTimeout(t), lggr)
_, err := dq.GetCiphertext([]byte{0xa5})
- assert.Equal(t, err.Error(), "ciphertextID 0xa5 not found")
+ assert.True(t, errors.Is(err, decryptionPlugin.ErrNotFound))
}
func Test_decryptionQueue_Decrypt_DecryptCalledAfterReadyResult(t *testing.T) {
diff --git a/core/services/ocr2/testhelpers/onchain_config.go b/core/services/ocr2/testhelpers/onchain_config.go
new file mode 100644
index 00000000000..ec7e619b936
--- /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/ocr2/validate/config.go b/core/services/ocr2/validate/config.go
index 20c23d95d6c..11f225e968a 100644
--- a/core/services/ocr2/validate/config.go
+++ b/core/services/ocr2/validate/config.go
@@ -66,7 +66,7 @@ func ToLocalConfig(ocr2Config OCR2Config, insConf InsecureConfig, spec job.OCR2O
}
var (
- minOCR2MaxDurationQuery = 20 * time.Millisecond
+ minOCR2MaxDurationQuery = 100 * time.Millisecond
minOCR2MaxDurationQueryErr error
minOCR2MaxDurationQueryOnce sync.Once
)
diff --git a/core/services/ocr2/validate/validate.go b/core/services/ocr2/validate/validate.go
index ca1ab60deb9..cde1a1f9276 100644
--- a/core/services/ocr2/validate/validate.go
+++ b/core/services/ocr2/validate/validate.go
@@ -12,6 +12,7 @@ import (
libocr2 "github.com/smartcontractkit/libocr/offchainreporting2plus"
+ "github.com/smartcontractkit/chainlink-relay/pkg/types"
"github.com/smartcontractkit/chainlink/v2/core/services/job"
dkgconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/dkg/config"
mercuryconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/mercury/config"
@@ -98,20 +99,20 @@ func validateSpec(tree *toml.Tree, spec job.Job) error {
}
switch spec.OCR2OracleSpec.PluginType {
- case job.Median:
+ case types.Median:
if spec.Pipeline.Source == "" {
return errors.New("no pipeline specified")
}
- case job.DKG:
+ case types.DKG:
return validateDKGSpec(spec.OCR2OracleSpec.PluginConfig)
- case job.OCR2VRF:
+ case types.OCR2VRF:
return validateOCR2VRFSpec(spec.OCR2OracleSpec.PluginConfig)
- case job.OCR2Keeper:
+ case types.OCR2Keeper:
return validateOCR2KeeperSpec(spec.OCR2OracleSpec.PluginConfig)
- case job.OCR2Functions:
+ case types.Functions:
// TODO validator for DR-OCR spec: https://app.shortcut.com/chainlinklabs/story/54054/ocr-plugin-for-directrequest-ocr
return nil
- case job.Mercury:
+ case types.Mercury:
return validateOCR2MercurySpec(spec.OCR2OracleSpec.PluginConfig, *spec.OCR2OracleSpec.FeedID)
case "":
return errors.New("no plugin specified")
diff --git a/core/services/ocrbootstrap/delegate.go b/core/services/ocrbootstrap/delegate.go
index b39f9eec6ec..9f9efca68e2 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,
}
@@ -118,14 +118,15 @@ func (d *Delegate) ServicesForSpec(jobSpec job.Job, qopts ...pg.QOpt) (services
if routerFields.ContractVersion != 1 || routerFields.ContractUpdateCheckFrequencySec == 0 {
return nil, errors.New("invalid router contract config")
}
- configProvider, err = relayer.NewFunctionsProvider(
+ 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,
+ ProviderType: string(types.Functions),
},
types.PluginArgs{
PluginConfig: spec.RelayConfig.Bytes(), // contains all necessary fields for config provider
@@ -133,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(),
@@ -165,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 4ea7cb7a9a9..ed832e45fcf 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 f40637cd999..51a004f1f05 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 bc7d67c2f9d..3aa3aff876e 100644
--- a/core/services/ocrcommon/run_saver.go
+++ b/core/services/ocrcommon/run_saver.go
@@ -12,13 +12,19 @@ type RunResultSaver struct {
utils.StartStopOnce
maxSuccessfulRuns uint64
- runResults <-chan pipeline.Run
+ runResults <-chan *pipeline.Run
pipelineRunner pipeline.Runner
done chan struct{}
logger logger.Logger
}
-func NewResultRunSaver(runResults <-chan pipeline.Run, pipelineRunner pipeline.Runner, done chan struct{},
+func (r *RunResultSaver) HealthReport() map[string]error {
+ return map[string]error{r.Name(): r.Healthy()}
+}
+
+func (r *RunResultSaver) Name() string { return r.logger.Name() }
+
+func NewResultRunSaver(runResults <-chan *pipeline.Run, pipelineRunner pipeline.Runner, done chan struct{},
logger logger.Logger, maxSuccessfulRuns uint64,
) *RunResultSaver {
return &RunResultSaver{
@@ -26,7 +32,7 @@ func NewResultRunSaver(runResults <-chan pipeline.Run, pipelineRunner pipeline.R
runResults: runResults,
pipelineRunner: pipelineRunner,
done: done,
- logger: logger,
+ logger: logger.Named("RunResultSaver"),
}
}
@@ -45,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:
@@ -67,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 0f24f93e97d..7d20a7a202e 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/transmitter_pipeline.go b/core/services/ocrcommon/transmitter_pipeline.go
index 23b672a5e32..e62f745a941 100644
--- a/core/services/ocrcommon/transmitter_pipeline.go
+++ b/core/services/ocrcommon/transmitter_pipeline.go
@@ -81,12 +81,12 @@ 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")
}
if run.State != pipeline.RunStatusCompleted {
- return fmt.Errorf("unexpected pipeline run state: %s", run.State)
+ return fmt.Errorf("unexpected pipeline run state: %s with fatal errors %w", run.State, run.FatalErrors.ToError())
}
return nil
diff --git a/core/services/pg/channels.go b/core/services/pg/channels.go
index 7b0b768bdab..736cd407962 100644
--- a/core/services/pg/channels.go
+++ b/core/services/pg/channels.go
@@ -1,8 +1,8 @@
package pg
-// Postgres channel to listen for new eth_txes
+// Postgres channel to listen for new evm.txes
const (
- ChannelInsertOnTx = "insert_on_eth_txes"
+ ChannelInsertOnTx = "evm.insert_on_txes"
ChannelInsertOnCosmosMsg = "insert_on_cosmos_msg"
- ChannelInsertOnEVMLogs = "insert_on_evm_logs"
+ ChannelInsertOnEVMLogs = "evm.insert_on_logs"
)
diff --git a/core/services/pipeline/mocks/runner.go b/core/services/pipeline/mocks/runner.go
index a43498c100e..e2cc70378e5 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/orm_test.go b/core/services/pipeline/orm_test.go
index 0863226e647..4c03ce16ef8 100644
--- a/core/services/pipeline/orm_test.go
+++ b/core/services/pipeline/orm_test.go
@@ -522,8 +522,7 @@ func Test_GetUnfinishedRuns_Keepers(t *testing.T) {
bridgeORM := bridges.NewORM(db, lggr, config.Database())
relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()})
- legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
- require.NoError(t, err)
+ legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
jorm := job.NewORM(db, legacyChains, porm, bridgeORM, keyStore, lggr, config.Database())
defer func() { assert.NoError(t, jorm.Close()) }()
@@ -548,7 +547,7 @@ func Test_GetUnfinishedRuns_Keepers(t *testing.T) {
MaxTaskDuration: models.Interval(1 * time.Minute),
}
- err = jorm.CreateJob(&keeperJob)
+ err := jorm.CreateJob(&keeperJob)
require.NoError(t, err)
require.Equal(t, job.Keeper, keeperJob.Type)
@@ -625,8 +624,7 @@ func Test_GetUnfinishedRuns_DirectRequest(t *testing.T) {
bridgeORM := bridges.NewORM(db, lggr, config.Database())
relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: config, KeyStore: keyStore.Eth()})
- legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
- require.NoError(t, err)
+ legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
jorm := job.NewORM(db, legacyChains, porm, bridgeORM, keyStore, lggr, config.Database())
defer func() { assert.NoError(t, jorm.Close()) }()
@@ -650,7 +648,7 @@ func Test_GetUnfinishedRuns_DirectRequest(t *testing.T) {
MaxTaskDuration: models.Interval(1 * time.Minute),
}
- err = jorm.CreateJob(&drJob)
+ err := jorm.CreateJob(&drJob)
require.NoError(t, err)
require.Equal(t, job.DirectRequest, drJob.Type)
diff --git a/core/services/pipeline/runner.go b/core/services/pipeline/runner.go
index 7a755e8fe11..3366a177ba8 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 1b13289289e..22b70829ba5 100644
--- a/core/services/pipeline/runner_test.go
+++ b/core/services/pipeline/runner_test.go
@@ -44,8 +44,7 @@ func newRunner(t testing.TB, db *sqlx.DB, bridgeORM bridges.ORM, cfg chainlink.G
lggr := logger.TestLogger(t)
ethKeyStore := cltest.NewKeyStore(t, db, cfg.Database()).Eth()
relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: cfg, KeyStore: ethKeyStore})
- legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
- require.NoError(t, err)
+ legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
orm := mocks.NewORM(t)
q := pg.NewQ(db, lggr, cfg.Database())
@@ -482,8 +481,7 @@ func Test_PipelineRunner_HandleFaultsPersistRun(t *testing.T) {
cfg := configtest.NewTestGeneralConfig(t)
ethKeyStore := cltest.NewKeyStore(t, db, cfg.Database()).Eth()
relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: cfg, KeyStore: ethKeyStore})
- legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
- require.NoError(t, err)
+ legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
lggr := logger.TestLogger(t)
r := pipeline.NewRunner(orm, btORM, cfg.JobPipeline(), cfg.WebServer(), legacyChains, ethKeyStore, nil, lggr, nil, nil)
@@ -637,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
@@ -646,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
@@ -659,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)
@@ -775,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 bbb9ee80b9b..1d7da59da9d 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.estimategas.go b/core/services/pipeline/task.estimategas.go
index 967fb7ca034..88c6f6facc3 100644
--- a/core/services/pipeline/task.estimategas.go
+++ b/core/services/pipeline/task.estimategas.go
@@ -47,12 +47,20 @@ func (t *EstimateGasLimitTask) Type() TaskType {
return TaskTypeEstimateGasLimit
}
+func (t *EstimateGasLimitTask) getEvmChainID() string {
+ if t.EVMChainID == "" {
+ t.EVMChainID = "$(jobSpec.evmChainID)"
+ }
+ return t.EVMChainID
+}
+
func (t *EstimateGasLimitTask) Run(ctx context.Context, lggr logger.Logger, vars Vars, inputs []Result) (result Result, runInfo RunInfo) {
var (
fromAddr AddressParam
toAddr AddressParam
data BytesParam
multiplier DecimalParam
+ chainID StringParam
)
err := multierr.Combine(
errors.Wrap(ResolveParam(&fromAddr, From(VarExpr(t.From, vars), utils.ZeroAddress)), "from"),
@@ -60,14 +68,15 @@ func (t *EstimateGasLimitTask) Run(ctx context.Context, lggr logger.Logger, vars
errors.Wrap(ResolveParam(&data, From(VarExpr(t.Data, vars), NonemptyString(t.Data))), "data"),
// Default to 1, i.e. exactly what estimateGas suggests
errors.Wrap(ResolveParam(&multiplier, From(VarExpr(t.Multiplier, vars), NonemptyString(t.Multiplier), decimal.New(1, 0))), "multiplier"),
+ errors.Wrap(ResolveParam(&chainID, From(VarExpr(t.getEvmChainID(), vars), NonemptyString(t.getEvmChainID()), "")), "evmChainID"),
)
if err != nil {
return Result{Error: err}, runInfo
}
- chain, err := t.legacyChains.Get(t.EVMChainID)
+ chain, err := t.legacyChains.Get(string(chainID))
if err != nil {
- err = fmt.Errorf("%w: %s: %w", ErrInvalidEVMChainID, t.EVMChainID, err)
+ err = fmt.Errorf("%w: %s: %w", ErrInvalidEVMChainID, chainID, err)
return Result{Error: err}, runInfo
}
diff --git a/core/services/pipeline/task.eth_call.go b/core/services/pipeline/task.eth_call.go
index f3c76d404d4..e877e1e90f4 100644
--- a/core/services/pipeline/task.eth_call.go
+++ b/core/services/pipeline/task.eth_call.go
@@ -55,6 +55,13 @@ func (t *ETHCallTask) Type() TaskType {
return TaskTypeETHCall
}
+func (t *ETHCallTask) getEvmChainID() string {
+ if t.EVMChainID == "" {
+ t.EVMChainID = "$(jobSpec.evmChainID)"
+ }
+ return t.EVMChainID
+}
+
func (t *ETHCallTask) Run(ctx context.Context, lggr logger.Logger, vars Vars, inputs []Result) (result Result, runInfo RunInfo) {
_, err := CheckInputs(inputs, -1, -1, 0)
if err != nil {
@@ -80,7 +87,7 @@ func (t *ETHCallTask) Run(ctx context.Context, lggr logger.Logger, vars Vars, in
errors.Wrap(ResolveParam(&gasPrice, From(VarExpr(t.GasPrice, vars), t.GasPrice)), "gasPrice"),
errors.Wrap(ResolveParam(&gasTipCap, From(VarExpr(t.GasTipCap, vars), t.GasTipCap)), "gasTipCap"),
errors.Wrap(ResolveParam(&gasFeeCap, From(VarExpr(t.GasFeeCap, vars), t.GasFeeCap)), "gasFeeCap"),
- errors.Wrap(ResolveParam(&chainID, From(VarExpr(t.EVMChainID, vars), NonemptyString(t.EVMChainID), "")), "evmChainID"),
+ errors.Wrap(ResolveParam(&chainID, From(VarExpr(t.getEvmChainID(), vars), NonemptyString(t.getEvmChainID()), "")), "evmChainID"),
errors.Wrap(ResolveParam(&gasUnlimited, From(VarExpr(t.GasUnlimited, vars), NonemptyString(t.GasUnlimited), false)), "gasUnlimited"),
)
if err != nil {
diff --git a/core/services/pipeline/task.eth_call_test.go b/core/services/pipeline/task.eth_call_test.go
index 8d7f128a0d4..77a10681fb4 100644
--- a/core/services/pipeline/task.eth_call_test.go
+++ b/core/services/pipeline/task.eth_call_test.go
@@ -56,7 +56,7 @@ func TestETHCallTask(t *testing.T) {
"0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF",
"",
"$(foo)",
- "",
+ "0",
"",
nil,
pipeline.NewVarsFrom(map[string]interface{}{
@@ -76,7 +76,7 @@ func TestETHCallTask(t *testing.T) {
"0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF",
"",
"$(foo)",
- "",
+ "0",
"$(gasLimit)",
nil,
pipeline.NewVarsFrom(map[string]interface{}{
@@ -97,7 +97,7 @@ func TestETHCallTask(t *testing.T) {
"0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF",
"",
"$(foo)",
- "",
+ "0",
"",
&specGasLimit,
pipeline.NewVarsFrom(map[string]interface{}{
@@ -117,7 +117,7 @@ func TestETHCallTask(t *testing.T) {
"0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF",
"0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF",
"$(foo)",
- "",
+ "0",
"",
nil,
pipeline.NewVarsFrom(map[string]interface{}{
@@ -138,7 +138,7 @@ func TestETHCallTask(t *testing.T) {
"0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF",
"0xThisAintGonnaWork",
"$(foo)",
- "",
+ "0",
"",
nil,
pipeline.NewVarsFrom(map[string]interface{}{
@@ -153,7 +153,7 @@ func TestETHCallTask(t *testing.T) {
"0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbee",
"",
"$(foo)",
- "",
+ "0",
"",
nil,
pipeline.NewVarsFrom(map[string]interface{}{
@@ -168,7 +168,7 @@ func TestETHCallTask(t *testing.T) {
"0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF",
"",
"$(foo)",
- "",
+ "0",
"",
nil,
pipeline.NewVarsFrom(map[string]interface{}{
@@ -183,7 +183,7 @@ func TestETHCallTask(t *testing.T) {
"0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF",
"",
"$(foo)",
- "",
+ "0",
"",
nil,
pipeline.NewVarsFrom(map[string]interface{}{
@@ -198,7 +198,7 @@ func TestETHCallTask(t *testing.T) {
"0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF",
"",
"$(foo)",
- "",
+ "0",
"",
nil,
pipeline.NewVarsFrom(map[string]interface{}{
@@ -258,11 +258,9 @@ func TestETHCallTask(t *testing.T) {
db := pgtest.NewSqlxDB(t)
var legacyChains evm.LegacyChainContainer
- var err error
if test.expectedErrorCause != nil || test.expectedErrorContains != "" {
exts := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: cfg, TxManager: txManager, KeyStore: keyStore})
- legacyChains, err = evmrelay.NewLegacyChainsFromRelayerExtenders(exts)
- require.NoError(t, err)
+ legacyChains = evmrelay.NewLegacyChainsFromRelayerExtenders(exts)
} else {
legacyChains = cltest.NewLegacyChainsWithMockChain(t, ethClient, cfg)
}
diff --git a/core/services/pipeline/task.eth_tx.go b/core/services/pipeline/task.eth_tx.go
index 8761732e4f0..d5d29240652 100644
--- a/core/services/pipeline/task.eth_tx.go
+++ b/core/services/pipeline/task.eth_tx.go
@@ -56,9 +56,16 @@ func (t *ETHTxTask) Type() TaskType {
return TaskTypeETHTx
}
+func (t *ETHTxTask) getEvmChainID() string {
+ if t.EVMChainID == "" {
+ t.EVMChainID = "$(jobSpec.evmChainID)"
+ }
+ return t.EVMChainID
+}
+
func (t *ETHTxTask) Run(_ context.Context, lggr logger.Logger, vars Vars, inputs []Result) (result Result, runInfo RunInfo) {
var chainID StringParam
- err := errors.Wrap(ResolveParam(&chainID, From(VarExpr(t.EVMChainID, vars), NonemptyString(t.EVMChainID), "")), "evmChainID")
+ err := errors.Wrap(ResolveParam(&chainID, From(VarExpr(t.getEvmChainID(), vars), NonemptyString(t.getEvmChainID()), "")), "evmChainID")
if err != nil {
return Result{Error: err}, runInfo
}
diff --git a/core/services/pipeline/task.eth_tx_test.go b/core/services/pipeline/task.eth_tx_test.go
index 83f855c9982..a280e6f2720 100644
--- a/core/services/pipeline/task.eth_tx_test.go
+++ b/core/services/pipeline/task.eth_tx_test.go
@@ -65,7 +65,7 @@ func TestETHTxTask(t *testing.T) {
"12345",
`{ "jobID": 321, "requestID": "0x5198616554d738d9485d1a7cf53b2f33e09c3bbc8fe9ac0020bd672cd2bc15d2", "requestTxHash": "0xc524fafafcaec40652b1f84fca09c231185437d008d195fccf2f51e64b7062f8" }`,
`0`,
- "",
+ "0",
`{"CheckerType": "vrf_v2", "VRFCoordinatorAddress": "0x2E396ecbc8223Ebc16EC45136228AE5EDB649943"}`,
nil,
false,
@@ -107,7 +107,7 @@ func TestETHTxTask(t *testing.T) {
"$(gasLimit)",
`{ "jobID": $(jobID), "requestID": $(requestID), "requestTxHash": $(requestTxHash) }`,
`0`,
- "",
+ "0",
"",
nil,
false,
@@ -150,7 +150,7 @@ func TestETHTxTask(t *testing.T) {
"$(gasLimit)",
`{ "jobID": $(jobID), "requestID": $(requestID), "requestTxHash": $(requestTxHash) }`,
"$(minConfirmations)",
- "",
+ "0",
"",
nil,
false,
@@ -182,7 +182,7 @@ func TestETHTxTask(t *testing.T) {
"$(gasLimit)",
`$(requestData)`,
`0`,
- "",
+ "0",
"",
nil,
false,
@@ -227,7 +227,7 @@ func TestETHTxTask(t *testing.T) {
"$(gasLimit)",
`$(requestData)`,
`0`,
- "",
+ "0",
"",
nil,
false,
@@ -272,7 +272,7 @@ func TestETHTxTask(t *testing.T) {
"12345",
`{}`,
`0`,
- "",
+ "0",
"",
nil,
false,
@@ -302,7 +302,7 @@ func TestETHTxTask(t *testing.T) {
"",
`{ "jobID": 321, "requestID": "0x5198616554d738d9485d1a7cf53b2f33e09c3bbc8fe9ac0020bd672cd2bc15d2", "requestTxHash": "0xc524fafafcaec40652b1f84fca09c231185437d008d195fccf2f51e64b7062f8" }`,
`0`,
- "",
+ "0",
"",
nil, // spec does not override gas limit
false,
@@ -336,7 +336,7 @@ func TestETHTxTask(t *testing.T) {
"",
`{ "jobID": 321, "requestID": "0x5198616554d738d9485d1a7cf53b2f33e09c3bbc8fe9ac0020bd672cd2bc15d2", "requestTxHash": "0xc524fafafcaec40652b1f84fca09c231185437d008d195fccf2f51e64b7062f8" }`,
`0`,
- "",
+ "0",
"",
&specGasLimit,
false,
@@ -370,7 +370,7 @@ func TestETHTxTask(t *testing.T) {
"$(gasLimit)",
`$(requestData)`,
`0`,
- "",
+ "0",
"",
nil,
false,
@@ -400,7 +400,7 @@ func TestETHTxTask(t *testing.T) {
"12345",
`{ "jobID": 321, "requestID": "0x5198616554d738d9485d1a7cf53b2f33e09c3bbc8fe9ac0020bd672cd2bc15d2", "requestTxHash": "0xc524fafafcaec40652b1f84fca09c231185437d008d195fccf2f51e64b7062f8" }`,
`0`,
- "",
+ "0",
"",
nil,
false,
@@ -435,7 +435,7 @@ func TestETHTxTask(t *testing.T) {
"12345",
`{ "jobID": 321, "requestID": "0x5198616554d738d9485d1a7cf53b2f33e09c3bbc8fe9ac0020bd672cd2bc15d2", "requestTxHash": "0xc524fafafcaec40652b1f84fca09c231185437d008d195fccf2f51e64b7062f8", "foo": "bar" }`,
`0`,
- "",
+ "0",
"",
nil,
false,
@@ -452,7 +452,7 @@ func TestETHTxTask(t *testing.T) {
"12345",
`{ "jobID": "asdf", "requestID": 123, "requestTxHash": true }`,
`0`,
- "",
+ "0",
"",
nil,
false,
@@ -469,7 +469,7 @@ func TestETHTxTask(t *testing.T) {
"12345",
`{ "jobID": 321, "requestID": "0x5198616554d738d9485d1a7cf53b2f33e09c3bbc8fe9ac0020bd672cd2bc15d2", "requestTxHash": "0xc524fafafcaec40652b1f84fca09c231185437d008d195fccf2f51e64b7062f8" }`,
`0`,
- "",
+ "0",
"",
nil,
false,
@@ -486,7 +486,7 @@ func TestETHTxTask(t *testing.T) {
"12345",
`{ "jobID": 321, "requestID": "0x5198616554d738d9485d1a7cf53b2f33e09c3bbc8fe9ac0020bd672cd2bc15d2", "requestTxHash": "0xc524fafafcaec40652b1f84fca09c231185437d008d195fccf2f51e64b7062f8" }`,
`0`,
- "",
+ "0",
"",
nil,
false,
@@ -503,7 +503,7 @@ func TestETHTxTask(t *testing.T) {
"12345",
`{ "jobID": 321, "requestID": "0x5198616554d738d9485d1a7cf53b2f33e09c3bbc8fe9ac0020bd672cd2bc15d2", "requestTxHash": "0xc524fafafcaec40652b1f84fca09c231185437d008d195fccf2f51e64b7062f8" }`,
`3`,
- "",
+ "0",
"",
nil,
false,
@@ -575,8 +575,7 @@ func TestETHTxTask(t *testing.T) {
relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: cfg,
TxManager: txManager, KeyStore: keyStore})
- legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
- require.NoError(t, err)
+ legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
test.setupClientMocks(keyStore, txManager)
task.HelperSetDependencies(legacyChains, keyStore, test.specGasLimit, pipeline.DirectRequestJobType)
diff --git a/core/services/pipeline/task.vrfv2plus.go b/core/services/pipeline/task.vrfv2plus.go
index c998a48d740..a596bfa3092 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/promreporter/prom_reporter.go b/core/services/promreporter/prom_reporter.go
index 508e424c3b0..c0b48b46e3a 100644
--- a/core/services/promreporter/prom_reporter.go
+++ b/core/services/promreporter/prom_reporter.go
@@ -176,7 +176,7 @@ func (pr *promReporter) reportHeadMetrics(ctx context.Context, head *evmtypes.He
func (pr *promReporter) reportPendingEthTxes(ctx context.Context, evmChainID *big.Int) (err error) {
var unconfirmed int64
- if err := pr.db.QueryRowContext(ctx, `SELECT count(*) FROM eth_txes WHERE state = 'unconfirmed' AND evm_chain_id = $1`, evmChainID.String()).Scan(&unconfirmed); err != nil {
+ if err := pr.db.QueryRowContext(ctx, `SELECT count(*) FROM evm.txes WHERE state = 'unconfirmed' AND evm_chain_id = $1`, evmChainID.String()).Scan(&unconfirmed); err != nil {
return errors.Wrap(err, "failed to query for unconfirmed eth_tx count")
}
pr.backend.SetUnconfirmedTransactions(evmChainID, unconfirmed)
@@ -186,7 +186,7 @@ func (pr *promReporter) reportPendingEthTxes(ctx context.Context, evmChainID *bi
func (pr *promReporter) reportMaxUnconfirmedAge(ctx context.Context, evmChainID *big.Int) (err error) {
var broadcastAt null.Time
now := time.Now()
- if err := pr.db.QueryRowContext(ctx, `SELECT min(initial_broadcast_at) FROM eth_txes WHERE state = 'unconfirmed' AND evm_chain_id = $1`, evmChainID.String()).Scan(&broadcastAt); err != nil {
+ if err := pr.db.QueryRowContext(ctx, `SELECT min(initial_broadcast_at) FROM evm.txes WHERE state = 'unconfirmed' AND evm_chain_id = $1`, evmChainID.String()).Scan(&broadcastAt); err != nil {
return errors.Wrap(err, "failed to query for unconfirmed eth_tx count")
}
var seconds float64
@@ -201,11 +201,11 @@ func (pr *promReporter) reportMaxUnconfirmedAge(ctx context.Context, evmChainID
func (pr *promReporter) reportMaxUnconfirmedBlocks(ctx context.Context, head *evmtypes.Head) (err error) {
var earliestUnconfirmedTxBlock null.Int
err = pr.db.QueryRowContext(ctx, `
-SELECT MIN(broadcast_before_block_num) FROM eth_tx_attempts
-JOIN eth_txes ON eth_txes.id = eth_tx_attempts.eth_tx_id
-WHERE eth_txes.state = 'unconfirmed'
+SELECT MIN(broadcast_before_block_num) FROM evm.tx_attempts
+JOIN evm.txes ON evm.txes.id = evm.tx_attempts.eth_tx_id
+WHERE evm.txes.state = 'unconfirmed'
AND evm_chain_id = $1
-AND eth_txes.state = 'unconfirmed'`, head.EVMChainID.String()).Scan(&earliestUnconfirmedTxBlock)
+AND evm.txes.state = 'unconfirmed'`, head.EVMChainID.String()).Scan(&earliestUnconfirmedTxBlock)
if err != nil {
return errors.Wrap(err, "failed to query for min broadcast_before_block_num")
}
diff --git a/core/services/promreporter/prom_reporter_test.go b/core/services/promreporter/prom_reporter_test.go
index 62fbef64ea9..9629045cb0b 100644
--- a/core/services/promreporter/prom_reporter_test.go
+++ b/core/services/promreporter/prom_reporter_test.go
@@ -54,7 +54,7 @@ func Test_PromReporter_OnNewLongestChain(t *testing.T) {
require.Eventually(t, func() bool { return subscribeCalls.Load() >= 1 }, 12*time.Second, 100*time.Millisecond)
})
- t.Run("with unconfirmed eth_txes", func(t *testing.T) {
+ t.Run("with unconfirmed evm.txes", func(t *testing.T) {
db := pgtest.NewSqlxDB(t)
cfg := configtest.NewGeneralConfig(t, nil)
txStore := cltest.NewTestTxStore(t, db, cfg.Database())
@@ -82,7 +82,7 @@ func Test_PromReporter_OnNewLongestChain(t *testing.T) {
etx := cltest.MustInsertUnconfirmedEthTxWithBroadcastLegacyAttempt(t, txStore, 0, fromAddress)
cltest.MustInsertUnconfirmedEthTxWithBroadcastLegacyAttempt(t, txStore, 1, fromAddress)
cltest.MustInsertUnconfirmedEthTxWithBroadcastLegacyAttempt(t, txStore, 2, fromAddress)
- require.NoError(t, utils.JustError(db.Exec(`UPDATE eth_tx_attempts SET broadcast_before_block_num = 7 WHERE eth_tx_id = $1`, etx.ID)))
+ require.NoError(t, utils.JustError(db.Exec(`UPDATE evm.tx_attempts SET broadcast_before_block_num = 7 WHERE eth_tx_id = $1`, etx.ID)))
head := newHead()
reporter.OnNewLongestChain(testutils.Context(t), &head)
diff --git a/core/services/relay/evm/config_poller.go b/core/services/relay/evm/config_poller.go
index aada1242303..504155bf1e8 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,10 +183,17 @@ 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 {
+ 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 {
return ocrtypes.ContractConfig{}, err
@@ -157,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 724c303210b..73c16a19596 100644
--- a/core/services/relay/evm/config_poller_test.go
+++ b/core/services/relay/evm/config_poller_test.go
@@ -1,109 +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() })
- logPoller, err := NewConfigPoller(lggr, lp, ocrAddress)
- require.NoError(t, err)
- // Should have no config to begin with.
- _, config, err := logPoller.LatestConfigDetails(testutils.Context(t))
- require.NoError(t, err)
- require.Equal(t, ocrtypes2.ConfigDigest{}, config)
- // 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 = logPoller.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 := logPoller.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 {
@@ -113,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
@@ -137,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)
@@ -155,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/contract_transmitter.go b/core/services/relay/evm/contract_transmitter.go
index d4a2c6204ca..470b5bae076 100644
--- a/core/services/relay/evm/contract_transmitter.go
+++ b/core/services/relay/evm/contract_transmitter.go
@@ -93,6 +93,9 @@ func (oc *contractTransmitter) Transmit(ctx context.Context, reportCtx ocrtypes.
var rs [][32]byte
var ss [][32]byte
var vs [32]byte
+ if len(signatures) > 32 {
+ return errors.New("too many signatures, maximum is 32")
+ }
for i, as := range signatures {
r, s, v, err := evmutil.SplitSignature(as.Signature)
if err != nil {
@@ -138,6 +141,9 @@ func parseTransmitted(log []byte) ([32]byte, uint32, error) {
if err != nil {
return [32]byte{}, 0, err
}
+ if len(transmitted) < 2 {
+ return [32]byte{}, 0, errors.New("transmitted event log has too few arguments")
+ }
configDigest := *abi.ConvertType(transmitted[0], new([32]byte)).(*[32]byte)
epoch := *abi.ConvertType(transmitted[1], new(uint32)).(*uint32)
return configDigest, epoch, err
diff --git a/core/services/relay/evm/evm.go b/core/services/relay/evm/evm.go
index 86cb1cf433e..6ae2052c408 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"
@@ -35,6 +36,7 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/services/pipeline"
"github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/functions"
"github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury"
+ mercuryutils "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/utils"
reportcodecv1 "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/v1/reportcodec"
reportcodecv2 "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/v2/reportcodec"
reportcodecv3 "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/v3/reportcodec"
@@ -60,16 +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.Named("Relayer"),
- ks: ks,
- mercuryPool: wsrpc.NewPool(lggr.Named("Mercury.WSRPCPool")),
- eventBroadcaster: eventBroadcaster,
- pgCfg: cfg,
- }
+ lggr: lggr,
+ ks: opts.CSAETHKeystore,
+ mercuryPool: wsrpc.NewPool(lggr),
+ eventBroadcaster: opts.EventBroadcaster,
+ pgCfg: opts.QConfig,
+ }, nil
}
func (r *Relayer) Name() string {
@@ -105,41 +140,54 @@ 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)
if relayConfig.ChainID.String() != r.chain.ID().String() {
return nil, fmt.Errorf("internal error: chain id in spec does not match this relayer's chain: have %s expected %s", relayConfig.ChainID.String(), r.chain.ID().String())
}
configWatcher, err := newConfigProvider(r.lggr, r.chain, relayOpts, r.eventBroadcaster)
if err != nil {
- return nil, errors.WithStack(err)
+ return nil, pkgerrors.WithStack(err)
}
- // FIXME: We actually know the version here since it's in the feed ID, can
- // we use generics to avoid passing three of this?
- // https://smartcontract-it.atlassian.net/browse/MERC-1414
- reportCodecV1 := reportcodecv1.NewReportCodec(*relayConfig.FeedID, r.lggr.Named("ReportCodecV1"))
- reportCodecV2 := reportcodecv2.NewReportCodec(*relayConfig.FeedID, r.lggr.Named("ReportCodecV2"))
- reportCodecV3 := reportcodecv3.NewReportCodec(*relayConfig.FeedID, r.lggr.Named("ReportCodecV3"))
-
if !relayConfig.EffectiveTransmitterID.Valid {
- return nil, errors.New("EffectiveTransmitterID must be specified")
+ 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())
if err != nil {
return nil, err
}
- transmitter := mercury.NewTransmitter(r.lggr, configWatcher.ContractConfigTracker(), client, privKey.PublicKey, *relayConfig.FeedID, r.db, r.pgCfg)
+
+ // FIXME: We actually know the version here since it's in the feed ID, can
+ // we use generics to avoid passing three of this?
+ // https://smartcontract-it.atlassian.net/browse/MERC-1414
+ reportCodecV1 := reportcodecv1.NewReportCodec(*relayConfig.FeedID, r.lggr.Named("ReportCodecV1"))
+ reportCodecV2 := reportcodecv2.NewReportCodec(*relayConfig.FeedID, r.lggr.Named("ReportCodecV2"))
+ reportCodecV3 := reportcodecv3.NewReportCodec(*relayConfig.FeedID, r.lggr.Named("ReportCodecV3"))
+
+ var transmitterCodec mercury.TransmitterReportDecoder
+ switch feedID.Version() {
+ case 1:
+ transmitterCodec = reportCodecV1
+ case 2:
+ transmitterCodec = reportCodecV2
+ case 3:
+ transmitterCodec = reportCodecV3
+ default:
+ return nil, fmt.Errorf("invalid feed version %d", feedID.Version())
+ }
+ transmitter := mercury.NewTransmitter(r.lggr, configWatcher.ContractConfigTracker(), client, privKey.PublicKey, rargs.JobID, *relayConfig.FeedID, r.db, r.pgCfg, transmitterCodec)
return NewMercuryProvider(configWatcher, transmitter, reportCodecV1, reportCodecV2, reportCodecV3, r.lggr), nil
}
@@ -175,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 {
@@ -274,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
@@ -292,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 {
@@ -309,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) (*contractTransmitter, error) {
@@ -328,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))
}
@@ -375,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(
@@ -396,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)
@@ -454,11 +506,8 @@ func (r *Relayer) NewMedianProvider(rargs relaytypes.RelayArgs, pargs relaytypes
return nil, err
}
- var contractTransmitter ContractTransmitter
- var reportCodec median.ReportCodec
-
- reportCodec = evmreportcodec.ReportCodec{}
- contractTransmitter, err = newContractTransmitter(r.lggr, rargs, pargs.TransmitterID, configWatcher, r.ks.Eth())
+ reportCodec := evmreportcodec.ReportCodec{}
+ contractTransmitter, err := newContractTransmitter(r.lggr, rargs, pargs.TransmitterID, configWatcher, r.ks.Eth())
if err != nil {
return nil, err
}
diff --git a/core/services/relay/evm/evm_test.go b/core/services/relay/evm/evm_test.go
new file mode 100644
index 00000000000..df7cd8eb818
--- /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.go b/core/services/relay/evm/functions/config_poller.go
index 4feff842ce3..f068f13cc77 100644
--- a/core/services/relay/evm/functions/config_poller.go
+++ b/core/services/relay/evm/functions/config_poller.go
@@ -162,6 +162,9 @@ func (cp *configPoller) LatestConfig(ctx context.Context, changedInBlock uint64)
if err != nil {
return ocrtypes.ContractConfig{}, err
}
+ if len(lgs) == 0 {
+ return ocrtypes.ContractConfig{}, errors.New("no logs found")
+ }
latestConfigSet, err := configFromLog(lgs[len(lgs)-1].Data, cp.pluginType)
if err != nil {
return ocrtypes.ContractConfig{}, err
diff --git a/core/services/relay/evm/functions/config_poller_test.go b/core/services/relay/evm/functions/config_poller_test.go
index b6de78b49df..d6573ef3544 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"
@@ -89,6 +90,8 @@ func runTest(t *testing.T, pluginType functions.FunctionsPluginType, expectedDig
_, 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)
pluginConfig := &functionsConfig.ReportingPluginConfigWrapper{
Config: &functionsConfig.ReportingPluginConfig{
@@ -168,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
@@ -184,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/contract_transmitter.go b/core/services/relay/evm/functions/contract_transmitter.go
index ecbe3c49f96..648cbcc2606 100644
--- a/core/services/relay/evm/functions/contract_transmitter.go
+++ b/core/services/relay/evm/functions/contract_transmitter.go
@@ -1,8 +1,10 @@
package functions
import (
+ "bytes"
"context"
"database/sql"
+ "encoding/hex"
"fmt"
"math/big"
"sync/atomic"
@@ -99,6 +101,9 @@ func (oc *contractTransmitter) Transmit(ctx context.Context, reportCtx ocrtypes.
var rs [][32]byte
var ss [][32]byte
var vs [32]byte
+ if len(signatures) > 32 {
+ return errors.New("too many signatures, maximum is 32")
+ }
for i, as := range signatures {
r, s, v, err := evmutil.SplitSignature(as.Signature)
if err != nil {
@@ -134,9 +139,20 @@ func (oc *contractTransmitter) Transmit(ctx context.Context, reportCtx ocrtypes.
if len(requests[0].CoordinatorContract) != common.AddressLength {
return fmt.Errorf("FunctionsContractTransmitter: incorrect length of CoordinatorContract field: %d", len(requests[0].CoordinatorContract))
}
- // NOTE: this is incorrect if batch contains requests destined for different contracts (unlikely)
- // it will be fixed when we get rid of batching
destinationContract.SetBytes(requests[0].CoordinatorContract)
+ if destinationContract == (common.Address{}) {
+ return errors.New("FunctionsContractTransmitter: destination coordinator contract is zero")
+ }
+ // Sanity check - every report should contain requests with the same coordinator contract.
+ for _, req := range requests[1:] {
+ if !bytes.Equal(req.CoordinatorContract, destinationContract.Bytes()) {
+ oc.lggr.Errorw("FunctionsContractTransmitter: non-uniform coordinator addresses in a batch - still sending to a single destination",
+ "requestID", hex.EncodeToString(req.RequestID),
+ "destinationContract", destinationContract,
+ "requestCoordinator", hex.EncodeToString(req.CoordinatorContract),
+ )
+ }
+ }
oc.lggr.Debugw("FunctionsContractTransmitter: ready", "nRequests", len(requests), "coordinatorContract", destinationContract.Hex())
} else {
return fmt.Errorf("unsupported contract version: %d", oc.contractVersion)
@@ -169,6 +185,9 @@ func parseTransmitted(log []byte) ([32]byte, uint32, error) {
if err != nil {
return [32]byte{}, 0, err
}
+ if len(transmitted) < 2 {
+ return [32]byte{}, 0, errors.New("transmitted event log has too few arguments")
+ }
configDigest := *abi.ConvertType(transmitted[0], new([32]byte)).(*[32]byte)
epoch := *abi.ConvertType(transmitted[1], new(uint32)).(*uint32)
return configDigest, epoch, err
diff --git a/core/services/relay/evm/functions/contract_transmitter_test.go b/core/services/relay/evm/functions/contract_transmitter_test.go
index fb4a071de2a..6b227bcdd50 100644
--- a/core/services/relay/evm/functions/contract_transmitter_test.go
+++ b/core/services/relay/evm/functions/contract_transmitter_test.go
@@ -116,6 +116,55 @@ func TestContractTransmitter_Transmit_V1(t *testing.T) {
reportBytes, err := codec.EncodeReport(processedRequests)
require.NoError(t, err)
+ // success
require.NoError(t, ot.Transmit(testutils.Context(t), ocrtypes.ReportContext{}, reportBytes, []ocrtypes.AttributedOnchainSignature{}))
require.Equal(t, coordinatorAddress, ocrTransmitter.toAddress)
+
+ // failure on too many signatures
+ signatures := []ocrtypes.AttributedOnchainSignature{}
+ for i := 0; i < 33; i++ {
+ signatures = append(signatures, ocrtypes.AttributedOnchainSignature{})
+ }
+ require.Error(t, ot.Transmit(testutils.Context(t), ocrtypes.ReportContext{}, reportBytes, signatures))
+}
+
+func TestContractTransmitter_Transmit_V1_CoordinatorMismatch(t *testing.T) {
+ t.Parallel()
+
+ contractVersion := uint32(1)
+ configuredDestAddress, coordinatorAddress1, coordinatorAddress2 := testutils.NewAddress(), testutils.NewAddress(), testutils.NewAddress()
+ lggr := logger.TestLogger(t)
+ c := evmclimocks.NewClient(t)
+ lp := lpmocks.NewLogPoller(t)
+ contractABI, _ := abi.JSON(strings.NewReader(ocr2aggregator.OCR2AggregatorABI))
+ lp.On("RegisterFilter", mock.Anything).Return(nil)
+
+ ocrTransmitter := mockTransmitter{}
+ ot, err := functions.NewFunctionsContractTransmitter(c, contractABI, &ocrTransmitter, lp, lggr, func(b []byte) (*txmgr.TxMeta, error) {
+ return &txmgr.TxMeta{}, nil
+ }, contractVersion)
+ require.NoError(t, err)
+ require.NoError(t, ot.UpdateRoutes(configuredDestAddress, configuredDestAddress))
+
+ reqId1, err := hex.DecodeString("110102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f")
+ require.NoError(t, err)
+ reqId2, err := hex.DecodeString("220102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f")
+ require.NoError(t, err)
+ processedRequests := []*encoding.ProcessedRequest{
+ {
+ RequestID: reqId1,
+ CoordinatorContract: coordinatorAddress1.Bytes(),
+ },
+ {
+ RequestID: reqId2,
+ CoordinatorContract: coordinatorAddress2.Bytes(),
+ },
+ }
+ codec, err := encoding.NewReportCodec(contractVersion)
+ require.NoError(t, err)
+ reportBytes, err := codec.EncodeReport(processedRequests)
+ require.NoError(t, err)
+
+ require.NoError(t, ot.Transmit(testutils.Context(t), ocrtypes.ReportContext{}, reportBytes, []ocrtypes.AttributedOnchainSignature{}))
+ require.Equal(t, coordinatorAddress1, ocrTransmitter.toAddress)
}
diff --git a/core/services/relay/evm/functions/logpoller_wrapper.go b/core/services/relay/evm/functions/logpoller_wrapper.go
index eae1970da93..db2c7fd68ce 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/loop_impl.go b/core/services/relay/evm/loop_impl.go
index 02a9194b380..8142721ed16 100644
--- a/core/services/relay/evm/loop_impl.go
+++ b/core/services/relay/evm/loop_impl.go
@@ -2,6 +2,7 @@ package evm
import (
"github.com/smartcontractkit/chainlink-relay/pkg/loop"
+
"github.com/smartcontractkit/chainlink/v2/core/chains/evm"
"github.com/smartcontractkit/chainlink/v2/core/services/relay"
)
@@ -10,7 +11,6 @@ import (
type LoopRelayAdapter interface {
loop.Relayer
Chain() evm.Chain
- Default() bool
}
type LoopRelayer struct {
loop.Relayer
@@ -19,8 +19,8 @@ type LoopRelayer struct {
var _ loop.Relayer = &LoopRelayer{}
-func NewLoopRelayAdapter(r *Relayer, cs EVMChainRelayerExtender) *LoopRelayer {
- ra := relay.NewRelayerAdapter(r, cs)
+func NewLoopRelayServerAdapter(r *Relayer, cs EVMChainRelayerExtender) *LoopRelayer {
+ ra := relay.NewRelayerServerAdapter(r, cs)
return &LoopRelayer{
Relayer: ra,
ext: cs,
@@ -30,7 +30,3 @@ func NewLoopRelayAdapter(r *Relayer, cs EVMChainRelayerExtender) *LoopRelayer {
func (la *LoopRelayer) Chain() evm.Chain {
return la.ext.Chain()
}
-
-func (la *LoopRelayer) Default() bool {
- return la.ext.Default()
-}
diff --git a/core/services/relay/evm/mercury/helpers_test.go b/core/services/relay/evm/mercury/helpers_test.go
index 4a7b8f70d75..4e3587b5de6 100644
--- a/core/services/relay/evm/mercury/helpers_test.go
+++ b/core/services/relay/evm/mercury/helpers_test.go
@@ -175,7 +175,7 @@ func SetupTH(t *testing.T, feedID common.Hash) TestHarness {
require.NoError(t, lp.Start(ctx))
t.Cleanup(func() { lp.Close() })
- eventBroadcaster.On("Subscribe", "insert_on_evm_logs", "").Return(subscription, nil)
+ eventBroadcaster.On("Subscribe", "evm.insert_on_logs", "").Return(subscription, nil)
configPoller, err := NewConfigPoller(lggr, lp, verifierAddress, feedID, eventBroadcaster)
require.NoError(t, err)
diff --git a/core/services/relay/evm/mercury/mocks/pipeline.go b/core/services/relay/evm/mercury/mocks/pipeline.go
index 317404e4409..f553ba98509 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/orm.go b/core/services/relay/evm/mercury/orm.go
index 49a5f250e14..dd7d7b33e74 100644
--- a/core/services/relay/evm/mercury/orm.go
+++ b/core/services/relay/evm/mercury/orm.go
@@ -21,7 +21,7 @@ import (
)
type ORM interface {
- InsertTransmitRequest(req *pb.TransmitRequest, reportCtx ocrtypes.ReportContext, qopts ...pg.QOpt) error
+ InsertTransmitRequest(req *pb.TransmitRequest, jobID int32, reportCtx ocrtypes.ReportContext, qopts ...pg.QOpt) error
DeleteTransmitRequests(reqs []*pb.TransmitRequest, qopts ...pg.QOpt) error
GetTransmitRequests(qopts ...pg.QOpt) ([]*Transmission, error)
PruneTransmitRequests(maxSize int, qopts ...pg.QOpt) error
@@ -48,7 +48,7 @@ func NewORM(db *sqlx.DB, lggr logger.Logger, cfg pg.QConfig) ORM {
}
// InsertTransmitRequest inserts one transmit request if the payload does not exist already.
-func (o *orm) InsertTransmitRequest(req *pb.TransmitRequest, reportCtx ocrtypes.ReportContext, qopts ...pg.QOpt) error {
+func (o *orm) InsertTransmitRequest(req *pb.TransmitRequest, jobID int32, reportCtx ocrtypes.ReportContext, qopts ...pg.QOpt) error {
q := o.q.WithOpts(qopts...)
var wg sync.WaitGroup
wg.Add(2)
@@ -57,10 +57,10 @@ func (o *orm) InsertTransmitRequest(req *pb.TransmitRequest, reportCtx ocrtypes.
go func() {
defer wg.Done()
err1 = q.ExecQ(`
- INSERT INTO mercury_transmit_requests (payload, payload_hash, config_digest, epoch, round, extra_hash)
- VALUES ($1, $2, $3, $4, $5, $6)
+ INSERT INTO mercury_transmit_requests (payload, payload_hash, config_digest, epoch, round, extra_hash, job_id)
+ VALUES ($1, $2, $3, $4, $5, $6, $7)
ON CONFLICT (payload_hash) DO NOTHING
- `, req.Payload, hashPayload(req.Payload), reportCtx.ConfigDigest[:], reportCtx.Epoch, reportCtx.Round, reportCtx.ExtraHash[:])
+ `, req.Payload, hashPayload(req.Payload), reportCtx.ConfigDigest[:], reportCtx.Epoch, reportCtx.Round, reportCtx.ExtraHash[:], jobID)
}()
feedID, err := FeedIDFromReport(req.Payload)
@@ -70,12 +70,12 @@ func (o *orm) InsertTransmitRequest(req *pb.TransmitRequest, reportCtx ocrtypes.
go func() {
defer wg.Done()
err2 = q.ExecQ(`
- INSERT INTO feed_latest_reports (feed_id, report, epoch, round, updated_at)
- VALUES ($1, $2, $3, $4, NOW())
+ INSERT INTO feed_latest_reports (feed_id, report, epoch, round, updated_at, job_id)
+ VALUES ($1, $2, $3, $4, NOW(), $5)
ON CONFLICT (feed_id) DO UPDATE
SET feed_id=$1, report=$2, epoch=$3, round=$4, updated_at=NOW()
WHERE excluded.epoch > feed_latest_reports.epoch OR (excluded.epoch = feed_latest_reports.epoch AND excluded.round > feed_latest_reports.round)
- `, feedID[:], req.Payload, reportCtx.Epoch, reportCtx.Round)
+ `, feedID[:], req.Payload, reportCtx.Epoch, reportCtx.Round, jobID)
}()
wg.Wait()
return errors.Join(err1, err2)
diff --git a/core/services/relay/evm/mercury/orm_test.go b/core/services/relay/evm/mercury/orm_test.go
index 39db450442f..a6a72327677 100644
--- a/core/services/relay/evm/mercury/orm_test.go
+++ b/core/services/relay/evm/mercury/orm_test.go
@@ -15,6 +15,10 @@ import (
func TestORM(t *testing.T) {
db := pgtest.NewSqlxDB(t)
+
+ var jobID int32 // foreign key constraints disabled so can leave as 0
+ pgtest.MustExec(t, db, `SET CONSTRAINTS mercury_transmit_requests_job_id_fkey DEFERRED`)
+ pgtest.MustExec(t, db, `SET CONSTRAINTS feed_latest_reports_job_id_fkey DEFERRED`)
lggr := logger.TestLogger(t)
orm := NewORM(db, lggr, pgtest.NewQConfig(true))
feedID := sampleFeedID
@@ -37,11 +41,11 @@ func TestORM(t *testing.T) {
assert.Nil(t, l)
// Test insert and get requests.
- err = orm.InsertTransmitRequest(&pb.TransmitRequest{Payload: reports[0]}, reportContexts[0])
+ err = orm.InsertTransmitRequest(&pb.TransmitRequest{Payload: reports[0]}, jobID, reportContexts[0])
require.NoError(t, err)
- err = orm.InsertTransmitRequest(&pb.TransmitRequest{Payload: reports[1]}, reportContexts[1])
+ err = orm.InsertTransmitRequest(&pb.TransmitRequest{Payload: reports[1]}, jobID, reportContexts[1])
require.NoError(t, err)
- err = orm.InsertTransmitRequest(&pb.TransmitRequest{Payload: reports[2]}, reportContexts[2])
+ err = orm.InsertTransmitRequest(&pb.TransmitRequest{Payload: reports[2]}, jobID, reportContexts[2])
require.NoError(t, err)
transmissions, err := orm.GetTransmitRequests()
@@ -99,7 +103,7 @@ func TestORM(t *testing.T) {
require.Empty(t, transmissions)
// More inserts.
- err = orm.InsertTransmitRequest(&pb.TransmitRequest{Payload: reports[3]}, reportContexts[3])
+ err = orm.InsertTransmitRequest(&pb.TransmitRequest{Payload: reports[3]}, jobID, reportContexts[3])
require.NoError(t, err)
transmissions, err = orm.GetTransmitRequests()
@@ -109,9 +113,9 @@ func TestORM(t *testing.T) {
})
// Duplicate requests are ignored.
- err = orm.InsertTransmitRequest(&pb.TransmitRequest{Payload: reports[3]}, reportContexts[3])
+ err = orm.InsertTransmitRequest(&pb.TransmitRequest{Payload: reports[3]}, jobID, reportContexts[3])
require.NoError(t, err)
- err = orm.InsertTransmitRequest(&pb.TransmitRequest{Payload: reports[3]}, reportContexts[3])
+ err = orm.InsertTransmitRequest(&pb.TransmitRequest{Payload: reports[3]}, jobID, reportContexts[3])
require.NoError(t, err)
transmissions, err = orm.GetTransmitRequests()
@@ -127,6 +131,10 @@ func TestORM(t *testing.T) {
func TestORM_PruneTransmitRequests(t *testing.T) {
db := pgtest.NewSqlxDB(t)
+ var jobID int32 // foreign key constraints disabled so can leave as 0
+ pgtest.MustExec(t, db, `SET CONSTRAINTS mercury_transmit_requests_job_id_fkey DEFERRED`)
+ pgtest.MustExec(t, db, `SET CONSTRAINTS feed_latest_reports_job_id_fkey DEFERRED`)
+
lggr := logger.TestLogger(t)
orm := NewORM(db, lggr, pgtest.NewQConfig(true))
@@ -143,9 +151,9 @@ func TestORM_PruneTransmitRequests(t *testing.T) {
}
}
- err := orm.InsertTransmitRequest(&pb.TransmitRequest{Payload: reports[0]}, makeReportContext(1, 1))
+ err := orm.InsertTransmitRequest(&pb.TransmitRequest{Payload: reports[0]}, jobID, makeReportContext(1, 1))
require.NoError(t, err)
- err = orm.InsertTransmitRequest(&pb.TransmitRequest{Payload: reports[1]}, makeReportContext(1, 2))
+ err = orm.InsertTransmitRequest(&pb.TransmitRequest{Payload: reports[1]}, jobID, makeReportContext(1, 2))
require.NoError(t, err)
// Max size greater than table size, expect no-op
@@ -170,9 +178,9 @@ func TestORM_PruneTransmitRequests(t *testing.T) {
{Req: &pb.TransmitRequest{Payload: reports[0]}, ReportCtx: makeReportContext(1, 1)},
})
- err = orm.InsertTransmitRequest(&pb.TransmitRequest{Payload: reports[2]}, makeReportContext(2, 1))
+ err = orm.InsertTransmitRequest(&pb.TransmitRequest{Payload: reports[2]}, jobID, makeReportContext(2, 1))
require.NoError(t, err)
- err = orm.InsertTransmitRequest(&pb.TransmitRequest{Payload: reports[3]}, makeReportContext(2, 2))
+ err = orm.InsertTransmitRequest(&pb.TransmitRequest{Payload: reports[3]}, jobID, makeReportContext(2, 2))
require.NoError(t, err)
// Max size is table size + 1, expect the oldest row to be pruned.
@@ -190,6 +198,10 @@ func TestORM_PruneTransmitRequests(t *testing.T) {
func TestORM_InsertTransmitRequest_LatestReport(t *testing.T) {
db := pgtest.NewSqlxDB(t)
+ var jobID int32 // foreign key constraints disabled so can leave as 0
+ pgtest.MustExec(t, db, `SET CONSTRAINTS mercury_transmit_requests_job_id_fkey DEFERRED`)
+ pgtest.MustExec(t, db, `SET CONSTRAINTS feed_latest_reports_job_id_fkey DEFERRED`)
+
lggr := logger.TestLogger(t)
orm := NewORM(db, lggr, pgtest.NewQConfig(true))
feedID := sampleFeedID
@@ -207,7 +219,7 @@ func TestORM_InsertTransmitRequest_LatestReport(t *testing.T) {
}
}
- err := orm.InsertTransmitRequest(&pb.TransmitRequest{Payload: reports[0]}, makeReportContext(
+ err := orm.InsertTransmitRequest(&pb.TransmitRequest{Payload: reports[0]}, jobID, makeReportContext(
0, 0,
))
require.NoError(t, err)
@@ -217,7 +229,7 @@ func TestORM_InsertTransmitRequest_LatestReport(t *testing.T) {
assert.Equal(t, reports[0], l)
t.Run("replaces if epoch and round are larger", func(t *testing.T) {
- err = orm.InsertTransmitRequest(&pb.TransmitRequest{Payload: reports[1]}, makeReportContext(1, 1))
+ err = orm.InsertTransmitRequest(&pb.TransmitRequest{Payload: reports[1]}, jobID, makeReportContext(1, 1))
require.NoError(t, err)
l, err = orm.LatestReport(testutils.Context(t), feedID)
@@ -225,7 +237,7 @@ func TestORM_InsertTransmitRequest_LatestReport(t *testing.T) {
assert.Equal(t, reports[1], l)
})
t.Run("replaces if epoch is the same but round is greater", func(t *testing.T) {
- err = orm.InsertTransmitRequest(&pb.TransmitRequest{Payload: reports[2]}, makeReportContext(1, 2))
+ err = orm.InsertTransmitRequest(&pb.TransmitRequest{Payload: reports[2]}, jobID, makeReportContext(1, 2))
require.NoError(t, err)
l, err = orm.LatestReport(testutils.Context(t), feedID)
@@ -233,7 +245,7 @@ func TestORM_InsertTransmitRequest_LatestReport(t *testing.T) {
assert.Equal(t, reports[2], l)
})
t.Run("replaces if epoch is larger but round is smaller", func(t *testing.T) {
- err = orm.InsertTransmitRequest(&pb.TransmitRequest{Payload: reports[3]}, makeReportContext(2, 1))
+ err = orm.InsertTransmitRequest(&pb.TransmitRequest{Payload: reports[3]}, jobID, makeReportContext(2, 1))
require.NoError(t, err)
l, err = orm.LatestReport(testutils.Context(t), feedID)
@@ -241,7 +253,7 @@ func TestORM_InsertTransmitRequest_LatestReport(t *testing.T) {
assert.Equal(t, reports[3], l)
})
t.Run("does not overwrite if epoch/round is the same", func(t *testing.T) {
- err = orm.InsertTransmitRequest(&pb.TransmitRequest{Payload: reports[0]}, makeReportContext(2, 1))
+ err = orm.InsertTransmitRequest(&pb.TransmitRequest{Payload: reports[0]}, jobID, makeReportContext(2, 1))
require.NoError(t, err)
l, err = orm.LatestReport(testutils.Context(t), feedID)
diff --git a/core/services/relay/evm/mercury/persistence_manager.go b/core/services/relay/evm/mercury/persistence_manager.go
index df170313839..9e8df72a155 100644
--- a/core/services/relay/evm/mercury/persistence_manager.go
+++ b/core/services/relay/evm/mercury/persistence_manager.go
@@ -28,13 +28,23 @@ type PersistenceManager struct {
deleteMu sync.Mutex
deleteQueue []*pb.TransmitRequest
+
+ jobID int32
+
+ maxTransmitQueueSize int
+ flushDeletesFrequency time.Duration
+ pruneFrequency time.Duration
}
-func NewPersistenceManager(lggr logger.Logger, orm ORM) *PersistenceManager {
+func NewPersistenceManager(lggr logger.Logger, orm ORM, jobID int32, maxTransmitQueueSize int, flushDeletesFrequency, pruneFrequency time.Duration) *PersistenceManager {
return &PersistenceManager{
- lggr: lggr.Named("MercuryPersistenceManager"),
- orm: orm,
- stopCh: make(chan struct{}),
+ lggr: lggr.Named("MercuryPersistenceManager"),
+ orm: orm,
+ stopCh: make(chan struct{}),
+ jobID: jobID,
+ maxTransmitQueueSize: maxTransmitQueueSize,
+ flushDeletesFrequency: flushDeletesFrequency,
+ pruneFrequency: pruneFrequency,
}
}
@@ -56,7 +66,7 @@ func (pm *PersistenceManager) Close() error {
}
func (pm *PersistenceManager) Insert(ctx context.Context, req *pb.TransmitRequest, reportCtx ocrtypes.ReportContext) error {
- return pm.orm.InsertTransmitRequest(req, reportCtx, pg.WithParentCtx(ctx))
+ return pm.orm.InsertTransmitRequest(req, pm.jobID, reportCtx, pg.WithParentCtx(ctx))
}
func (pm *PersistenceManager) Delete(ctx context.Context, req *pb.TransmitRequest) error {
@@ -77,18 +87,19 @@ func (pm *PersistenceManager) runFlushDeletesLoop() {
ctx, cancel := pm.stopCh.Ctx(context.Background())
defer cancel()
- ticker := time.NewTicker(utils.WithJitter(flushDeletesFrequency))
+ ticker := time.NewTicker(utils.WithJitter(pm.flushDeletesFrequency))
for {
select {
case <-ctx.Done():
ticker.Stop()
return
case <-ticker.C:
- pm.lggr.Trace("Deleting queued requests from transmit requests table")
queuedReqs := pm.resetDeleteQueue()
if err := pm.orm.DeleteTransmitRequests(queuedReqs, pg.WithParentCtx(ctx)); err != nil {
pm.lggr.Errorw("Failed to delete queued transmit requests", "err", err)
pm.addToDeleteQueue(queuedReqs...)
+ } else {
+ pm.lggr.Debugw("Deleted queued transmit requests")
}
}
}
@@ -100,16 +111,17 @@ func (pm *PersistenceManager) runPruneLoop() {
ctx, cancel := pm.stopCh.Ctx(context.Background())
defer cancel()
- ticker := time.NewTicker(utils.WithJitter(pruneFrequency))
+ ticker := time.NewTicker(utils.WithJitter(pm.pruneFrequency))
for {
select {
case <-ctx.Done():
ticker.Stop()
return
case <-ticker.C:
- pm.lggr.Trace("Pruning transmit requests table")
- if err := pm.orm.PruneTransmitRequests(maxTransmitQueueSize, pg.WithParentCtx(ctx), pg.WithLongQueryTimeout()); err != nil {
+ if err := pm.orm.PruneTransmitRequests(pm.maxTransmitQueueSize, pg.WithParentCtx(ctx), pg.WithLongQueryTimeout()); err != nil {
pm.lggr.Errorw("Failed to prune transmit requests table", "err", err)
+ } else {
+ pm.lggr.Debugw("Pruned transmit requests table")
}
}
}
diff --git a/core/services/relay/evm/mercury/persistence_manager_test.go b/core/services/relay/evm/mercury/persistence_manager_test.go
index 5ad1efedf1b..97628ed9c2b 100644
--- a/core/services/relay/evm/mercury/persistence_manager_test.go
+++ b/core/services/relay/evm/mercury/persistence_manager_test.go
@@ -7,22 +7,28 @@ import (
ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types"
"github.com/stretchr/testify/require"
+ "go.uber.org/zap/zapcore"
+ "go.uber.org/zap/zaptest/observer"
+ "github.com/smartcontractkit/chainlink/v2/core/internal/testutils"
"github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest"
"github.com/smartcontractkit/chainlink/v2/core/logger"
"github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/wsrpc/pb"
)
-func bootstrapPersistenceManager(t *testing.T) *PersistenceManager {
+func bootstrapPersistenceManager(t *testing.T) (*PersistenceManager, *observer.ObservedLogs) {
+ t.Helper()
db := pgtest.NewSqlxDB(t)
- lggr := logger.TestLogger(t)
+ pgtest.MustExec(t, db, `SET CONSTRAINTS mercury_transmit_requests_job_id_fkey DEFERRED`)
+ pgtest.MustExec(t, db, `SET CONSTRAINTS feed_latest_reports_job_id_fkey DEFERRED`)
+ lggr, observedLogs := logger.TestLoggerObserved(t, zapcore.DebugLevel)
orm := NewORM(db, lggr, pgtest.NewQConfig(true))
- return NewPersistenceManager(lggr, orm)
+ return NewPersistenceManager(lggr, orm, 0, 2, 5*time.Millisecond, 5*time.Millisecond), observedLogs
}
func TestPersistenceManager(t *testing.T) {
ctx := context.Background()
- pm := bootstrapPersistenceManager(t)
+ pm, _ := bootstrapPersistenceManager(t)
reports := sampleReports
@@ -50,7 +56,7 @@ func TestPersistenceManager(t *testing.T) {
func TestPersistenceManagerAsyncDelete(t *testing.T) {
ctx := context.Background()
- pm := bootstrapPersistenceManager(t)
+ pm, observedLogs := bootstrapPersistenceManager(t)
reports := sampleReports
@@ -59,13 +65,14 @@ func TestPersistenceManagerAsyncDelete(t *testing.T) {
err = pm.Insert(ctx, &pb.TransmitRequest{Payload: reports[1]}, ocrtypes.ReportContext{})
require.NoError(t, err)
- flushDeletesFrequency = 10 * time.Millisecond
err = pm.Start(ctx)
require.NoError(t, err)
pm.AsyncDelete(&pb.TransmitRequest{Payload: reports[0]})
- time.Sleep(15 * time.Millisecond)
+ // Wait for next poll.
+ observedLogs.TakeAll()
+ testutils.WaitForLogMessage(t, observedLogs, "Deleted queued transmit requests")
transmissions, err := pm.Load(ctx)
require.NoError(t, err)
@@ -90,7 +97,7 @@ func TestPersistenceManagerAsyncDelete(t *testing.T) {
func TestPersistenceManagerPrune(t *testing.T) {
ctx := context.Background()
- pm := bootstrapPersistenceManager(t)
+ pm, observedLogs := bootstrapPersistenceManager(t)
reports := sampleReports
@@ -101,12 +108,12 @@ func TestPersistenceManagerPrune(t *testing.T) {
err = pm.Insert(ctx, &pb.TransmitRequest{Payload: reports[2]}, ocrtypes.ReportContext{ReportTimestamp: ocrtypes.ReportTimestamp{Epoch: 3}})
require.NoError(t, err)
- maxTransmitQueueSize = 2
- pruneFrequency = 10 * time.Millisecond
err = pm.Start(ctx)
require.NoError(t, err)
- time.Sleep(15 * time.Millisecond)
+ // Wait for next poll.
+ observedLogs.TakeAll()
+ testutils.WaitForLogMessage(t, observedLogs, "Pruned transmit requests table")
transmissions, err := pm.Load(ctx)
require.NoError(t, err)
diff --git a/core/services/relay/evm/mercury/queue.go b/core/services/relay/evm/mercury/queue.go
index 743a6553dff..44042c57725 100644
--- a/core/services/relay/evm/mercury/queue.go
+++ b/core/services/relay/evm/mercury/queue.go
@@ -1,13 +1,13 @@
package mercury
import (
- "container/heap"
"context"
"errors"
"fmt"
"sync"
"time"
+ heap "github.com/esote/minmaxheap"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
@@ -59,11 +59,6 @@ type TransmitQueue struct {
type Transmission struct {
Req *pb.TransmitRequest // the payload to transmit
ReportCtx ocrtypes.ReportContext // contains priority information (latest epoch/round wins)
-
- // The index is needed by update and is maintained by the heap.Interface
- // methods
- // It should NOT be set manually
- index int // the index of the item in the heap
}
// maxlen controls how many items will be stored in the queue
@@ -97,13 +92,13 @@ func (tq *TransmitQueue) Push(req *pb.TransmitRequest, reportCtx ocrtypes.Report
if tq.maxlen != 0 && tq.pq.Len() == tq.maxlen {
// evict oldest entry to make room
tq.lggr.Criticalf("Transmit queue is full; dropping oldest transmission (reached max length of %d)", tq.maxlen)
- removed := heap.Remove(tq.pq, tq.pq.Len()-1)
+ removed := heap.PopMax(tq.pq)
if transmission, ok := removed.(*Transmission); ok {
tq.asyncDeleter.AsyncDelete(transmission.Req)
}
}
- heap.Push(tq.pq, &Transmission{req, reportCtx, -1})
+ heap.Push(tq.pq, &Transmission{req, reportCtx})
tq.cond.Signal()
return true
@@ -231,6 +226,10 @@ func (pq priorityQueue) Less(i, j int) bool {
pq[i].ReportCtx.ReportTimestamp.Round > pq[j].ReportCtx.ReportTimestamp.Round
}
+func (pq priorityQueue) Swap(i, j int) {
+ pq[i], pq[j] = pq[j], pq[i]
+}
+
func (pq *priorityQueue) Pop() any {
n := len(*pq)
if n == 0 {
@@ -238,21 +237,11 @@ func (pq *priorityQueue) Pop() any {
}
old := *pq
item := old[n-1]
- old[n-1] = nil // avoid memory leak
- item.index = -1 // for safety
+ old[n-1] = nil // avoid memory leak
*pq = old[0 : n-1]
return item
}
func (pq *priorityQueue) Push(x any) {
- n := len(*pq)
- item := x.(*Transmission)
- item.index = n
- *pq = append(*pq, item)
-}
-
-func (pq priorityQueue) Swap(i, j int) {
- pq[i], pq[j] = pq[j], pq[i]
- pq[i].index = i
- pq[j].index = j
+ *pq = append(*pq, x.(*Transmission))
}
diff --git a/core/services/relay/evm/mercury/queue_test.go b/core/services/relay/evm/mercury/queue_test.go
index 9fa2520147d..de2f64f9fe9 100644
--- a/core/services/relay/evm/mercury/queue_test.go
+++ b/core/services/relay/evm/mercury/queue_test.go
@@ -5,7 +5,6 @@ import (
"testing"
"github.com/stretchr/testify/assert"
- "github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
"go.uber.org/zap/zapcore"
@@ -81,7 +80,7 @@ func Test_Queue(t *testing.T) {
})
t.Run("transmit queue is more than 50% full", func(t *testing.T) {
- transmitQueue.Push(testTransmissions[2].tr, testTransmissions[0].ctx)
+ transmitQueue.Push(testTransmissions[2].tr, testTransmissions[2].ctx)
report := transmitQueue.HealthReport()
assert.Equal(t, report[transmitQueue.Name()].Error(), "transmit priority queue is greater than 50% full (4/7)")
})
@@ -92,21 +91,18 @@ func Test_Queue(t *testing.T) {
})
t.Run("transmit queue is full and evicts the oldest transmission", func(t *testing.T) {
- // There is a bug with queue eviction where the evicted transmission is NOT the oldest.
- // TODO: MERC-1049 Once this bug is fixed, replace the expectation with the one below.
- // deleter.On("AsyncDelete", testTransmissions[0].tr).Once()
- deleter.On("AsyncDelete", mock.Anything).Once()
+ deleter.On("AsyncDelete", testTransmissions[0].tr).Once()
- // add 5 more transmissions to overflow the queue
+ // add 5 more transmissions to overflow the queue by 1
for i := 0; i < 5; i++ {
transmitQueue.Push(testTransmissions[1].tr, testTransmissions[1].ctx)
}
+
// expecting testTransmissions[0] to get evicted and not present in the queue anymore
testutils.WaitForLogMessage(t, observedLogs, "Transmit queue is full; dropping oldest transmission (reached max length of 7)")
for i := 0; i < 7; i++ {
tr := transmitQueue.BlockingPop()
- // TODO: Should be tr.Req instead of tr.
- assert.NotEqual(t, tr, testTransmissions[0].tr)
+ assert.NotEqual(t, tr.Req, testTransmissions[0].tr)
}
})
diff --git a/core/services/relay/evm/mercury/transmitter.go b/core/services/relay/evm/mercury/transmitter.go
index a98d7c28928..199dbfcdf88 100644
--- a/core/services/relay/evm/mercury/transmitter.go
+++ b/core/services/relay/evm/mercury/transmitter.go
@@ -15,19 +15,16 @@ import (
pkgerrors "github.com/pkg/errors"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
- "golang.org/x/exp/maps"
-
"github.com/smartcontractkit/libocr/offchainreporting2plus/chains/evmutil"
ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types"
"github.com/smartcontractkit/sqlx"
+ "golang.org/x/exp/maps"
relaymercury "github.com/smartcontractkit/chainlink-relay/pkg/reportingplugins/mercury"
- mercuryutils "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/utils"
-
"github.com/smartcontractkit/chainlink/v2/core/logger"
"github.com/smartcontractkit/chainlink/v2/core/services"
-
"github.com/smartcontractkit/chainlink/v2/core/services/pg"
+ mercuryutils "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/utils"
"github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/wsrpc"
"github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/wsrpc/pb"
"github.com/smartcontractkit/chainlink/v2/core/utils"
@@ -79,7 +76,11 @@ type ConfigTracker interface {
LatestConfigDetails(ctx context.Context) (changedInBlock uint64, configDigest ocrtypes.ConfigDigest, err error)
}
-var _ Transmitter = &mercuryTransmitter{}
+type TransmitterReportDecoder interface {
+ BenchmarkPriceFromReport(report ocrtypes.Report) (*big.Int, error)
+}
+
+var _ Transmitter = (*mercuryTransmitter)(nil)
type mercuryTransmitter struct {
utils.StartStopOnce
@@ -87,8 +88,10 @@ type mercuryTransmitter struct {
rpcClient wsrpc.Client
cfgTracker ConfigTracker
persistenceManager *PersistenceManager
+ codec TransmitterReportDecoder
feedID mercuryutils.FeedID
+ jobID int32
fromAccount string
stopCh utils.StopChan
@@ -119,16 +122,18 @@ func getPayloadTypes() abi.Arguments {
})
}
-func NewTransmitter(lggr logger.Logger, cfgTracker ConfigTracker, rpcClient wsrpc.Client, fromAccount ed25519.PublicKey, feedID [32]byte, db *sqlx.DB, cfg pg.QConfig) *mercuryTransmitter {
+func NewTransmitter(lggr logger.Logger, cfgTracker ConfigTracker, rpcClient wsrpc.Client, fromAccount ed25519.PublicKey, jobID int32, feedID [32]byte, db *sqlx.DB, cfg pg.QConfig, codec TransmitterReportDecoder) *mercuryTransmitter {
feedIDHex := fmt.Sprintf("0x%x", feedID[:])
- persistenceManager := NewPersistenceManager(lggr, NewORM(db, lggr, cfg))
+ persistenceManager := NewPersistenceManager(lggr, NewORM(db, lggr, cfg), jobID, maxTransmitQueueSize, flushDeletesFrequency, pruneFrequency)
return &mercuryTransmitter{
utils.StartStopOnce{},
lggr.Named("MercuryTransmitter").With("feedID", feedIDHex),
rpcClient,
cfgTracker,
persistenceManager,
+ codec,
feedID,
+ jobID,
fmt.Sprintf("%x", fromAccount),
make(chan (struct{})),
NewTransmitQueue(lggr, feedIDHex, maxTransmitQueueSize, nil, persistenceManager),
@@ -323,18 +328,23 @@ func (mt *mercuryTransmitter) FetchInitialMaxFinalizedBlockNumber(ctx context.Co
func (mt *mercuryTransmitter) LatestPrice(ctx context.Context, feedID [32]byte) (*big.Int, error) {
mt.lggr.Trace("LatestPrice")
- report, err := mt.latestReport(ctx, feedID)
+ fullReport, err := mt.latestReport(ctx, feedID)
if err != nil {
return nil, err
}
- if report == nil {
+ if fullReport == nil {
return nil, nil
}
- price, err := relaymercury.DecodeValueInt192(report.Price)
- if err != nil {
- return nil, pkgerrors.Wrap(err, "failed to decode report.Price as *big.Int")
+ payload := fullReport.Payload
+ m := make(map[string]interface{})
+ if err := PayloadTypes.UnpackIntoMap(m, payload); err != nil {
+ return nil, err
+ }
+ report, is := m["report"].([]byte)
+ if !is {
+ return nil, fmt.Errorf("expected report to be []byte, but it was %T", m["report"])
}
- return price, nil
+ return mt.codec.BenchmarkPriceFromReport(report)
}
// LatestTimestamp will return -1, nil if the feed is missing
diff --git a/core/services/relay/evm/mercury/transmitter_test.go b/core/services/relay/evm/mercury/transmitter_test.go
index f4682d0b32e..6723ffcbcac 100644
--- a/core/services/relay/evm/mercury/transmitter_test.go
+++ b/core/services/relay/evm/mercury/transmitter_test.go
@@ -10,11 +10,12 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
- relaymercury "github.com/smartcontractkit/chainlink-relay/pkg/reportingplugins/mercury"
+ ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types"
"github.com/smartcontractkit/chainlink/v2/core/internal/testutils"
"github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest"
"github.com/smartcontractkit/chainlink/v2/core/logger"
+ mercurytypes "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/types"
mocks "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/wsrpc/mocks"
"github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/wsrpc/pb"
)
@@ -22,6 +23,9 @@ import (
func Test_MercuryTransmitter_Transmit(t *testing.T) {
lggr := logger.TestLogger(t)
db := pgtest.NewSqlxDB(t)
+ var jobID int32
+ pgtest.MustExec(t, db, `SET CONSTRAINTS mercury_transmit_requests_job_id_fkey DEFERRED`)
+ pgtest.MustExec(t, db, `SET CONSTRAINTS feed_latest_reports_job_id_fkey DEFERRED`)
t.Run("v1 report transmission successfully enqueued", func(t *testing.T) {
report := sampleV1Report
@@ -35,7 +39,7 @@ func Test_MercuryTransmitter_Transmit(t *testing.T) {
return out, nil
},
}
- mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, sampleFeedID, db, pgtest.NewQConfig(true))
+ mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, jobID, sampleFeedID, db, pgtest.NewQConfig(true), nil)
err := mt.Transmit(testutils.Context(t), sampleReportContext, report, sampleSigs)
require.NoError(t, err)
@@ -52,7 +56,7 @@ func Test_MercuryTransmitter_Transmit(t *testing.T) {
return out, nil
},
}
- mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, sampleFeedID, db, pgtest.NewQConfig(true))
+ mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, jobID, sampleFeedID, db, pgtest.NewQConfig(true), nil)
err := mt.Transmit(testutils.Context(t), sampleReportContext, report, sampleSigs)
require.NoError(t, err)
@@ -69,7 +73,7 @@ func Test_MercuryTransmitter_Transmit(t *testing.T) {
return out, nil
},
}
- mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, sampleFeedID, db, pgtest.NewQConfig(true))
+ mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, jobID, sampleFeedID, db, pgtest.NewQConfig(true), nil)
err := mt.Transmit(testutils.Context(t), sampleReportContext, report, sampleSigs)
require.NoError(t, err)
@@ -93,7 +97,7 @@ func Test_MercuryTransmitter_LatestTimestamp(t *testing.T) {
return out, nil
},
}
- mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, sampleFeedID, db, pgtest.NewQConfig(true))
+ mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, 0, sampleFeedID, db, pgtest.NewQConfig(true), nil)
ts, err := mt.LatestTimestamp(testutils.Context(t))
require.NoError(t, err)
@@ -108,7 +112,7 @@ func Test_MercuryTransmitter_LatestTimestamp(t *testing.T) {
return out, nil
},
}
- mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, sampleFeedID, db, pgtest.NewQConfig(true))
+ mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, 0, sampleFeedID, db, pgtest.NewQConfig(true), nil)
ts, err := mt.LatestTimestamp(testutils.Context(t))
require.NoError(t, err)
@@ -121,21 +125,33 @@ func Test_MercuryTransmitter_LatestTimestamp(t *testing.T) {
return nil, errors.New("something exploded")
},
}
- mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, sampleFeedID, db, pgtest.NewQConfig(true))
+ mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, 0, sampleFeedID, db, pgtest.NewQConfig(true), nil)
_, err := mt.LatestTimestamp(testutils.Context(t))
require.Error(t, err)
assert.Contains(t, err.Error(), "something exploded")
})
}
+type mockCodec struct {
+ val *big.Int
+ err error
+}
+
+var _ mercurytypes.ReportCodec = &mockCodec{}
+
+func (m *mockCodec) BenchmarkPriceFromReport(_ ocrtypes.Report) (*big.Int, error) {
+ return m.val, m.err
+}
+
func Test_MercuryTransmitter_LatestPrice(t *testing.T) {
t.Parallel()
lggr := logger.TestLogger(t)
db := pgtest.NewSqlxDB(t)
+ codec := new(mockCodec)
+
t.Run("successful query", func(t *testing.T) {
originalPrice := big.NewInt(123456789)
- encodedPrice, _ := relaymercury.EncodeValueInt192(originalPrice)
c := mocks.MockWSRPCClient{
LatestReportF: func(ctx context.Context, in *pb.LatestReportRequest) (out *pb.LatestReportResponse, err error) {
require.NotNil(t, in)
@@ -143,15 +159,30 @@ func Test_MercuryTransmitter_LatestPrice(t *testing.T) {
out = new(pb.LatestReportResponse)
out.Report = new(pb.Report)
out.Report.FeedId = sampleFeedID[:]
- out.Report.Price = encodedPrice
+ out.Report.Payload = buildSamplePayload([]byte("doesn't matter"))
return out, nil
},
}
- mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, sampleFeedID, db, pgtest.NewQConfig(true))
- price, err := mt.LatestPrice(testutils.Context(t), sampleFeedID)
- require.NoError(t, err)
+ mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, 0, sampleFeedID, db, pgtest.NewQConfig(true), codec)
+
+ t.Run("BenchmarkPriceFromReport succeeds", func(t *testing.T) {
+ codec.val = originalPrice
+ codec.err = nil
+
+ price, err := mt.LatestPrice(testutils.Context(t), sampleFeedID)
+ require.NoError(t, err)
+
+ assert.Equal(t, originalPrice, price)
+ })
+ t.Run("BenchmarkPriceFromReport fails", func(t *testing.T) {
+ codec.val = nil
+ codec.err = errors.New("something exploded")
+
+ _, err := mt.LatestPrice(testutils.Context(t), sampleFeedID)
+ require.Error(t, err)
- assert.Equal(t, price, originalPrice)
+ assert.EqualError(t, err, "something exploded")
+ })
})
t.Run("successful query returning nil report (new feed)", func(t *testing.T) {
@@ -162,7 +193,7 @@ func Test_MercuryTransmitter_LatestPrice(t *testing.T) {
return out, nil
},
}
- mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, sampleFeedID, db, pgtest.NewQConfig(true))
+ mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, 0, sampleFeedID, db, pgtest.NewQConfig(true), nil)
price, err := mt.LatestPrice(testutils.Context(t), sampleFeedID)
require.NoError(t, err)
@@ -175,7 +206,7 @@ func Test_MercuryTransmitter_LatestPrice(t *testing.T) {
return nil, errors.New("something exploded")
},
}
- mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, sampleFeedID, db, pgtest.NewQConfig(true))
+ mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, 0, sampleFeedID, db, pgtest.NewQConfig(true), nil)
_, err := mt.LatestPrice(testutils.Context(t), sampleFeedID)
require.Error(t, err)
assert.Contains(t, err.Error(), "something exploded")
@@ -200,7 +231,7 @@ func Test_MercuryTransmitter_FetchInitialMaxFinalizedBlockNumber(t *testing.T) {
return out, nil
},
}
- mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, sampleFeedID, db, pgtest.NewQConfig(true))
+ mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, 0, sampleFeedID, db, pgtest.NewQConfig(true), nil)
bn, err := mt.FetchInitialMaxFinalizedBlockNumber(testutils.Context(t))
require.NoError(t, err)
@@ -215,7 +246,7 @@ func Test_MercuryTransmitter_FetchInitialMaxFinalizedBlockNumber(t *testing.T) {
return out, nil
},
}
- mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, sampleFeedID, db, pgtest.NewQConfig(true))
+ mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, 0, sampleFeedID, db, pgtest.NewQConfig(true), nil)
bn, err := mt.FetchInitialMaxFinalizedBlockNumber(testutils.Context(t))
require.NoError(t, err)
@@ -227,7 +258,7 @@ func Test_MercuryTransmitter_FetchInitialMaxFinalizedBlockNumber(t *testing.T) {
return nil, errors.New("something exploded")
},
}
- mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, sampleFeedID, db, pgtest.NewQConfig(true))
+ mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, 0, sampleFeedID, db, pgtest.NewQConfig(true), nil)
_, err := mt.FetchInitialMaxFinalizedBlockNumber(testutils.Context(t))
require.Error(t, err)
assert.Contains(t, err.Error(), "something exploded")
@@ -244,7 +275,7 @@ func Test_MercuryTransmitter_FetchInitialMaxFinalizedBlockNumber(t *testing.T) {
return out, nil
},
}
- mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, sampleFeedID, db, pgtest.NewQConfig(true))
+ mt := NewTransmitter(lggr, nil, c, sampleClientPubKey, 0, sampleFeedID, db, pgtest.NewQConfig(true), nil)
_, err := mt.FetchInitialMaxFinalizedBlockNumber(testutils.Context(t))
require.Error(t, err)
assert.Contains(t, err.Error(), "latestReport failed; mismatched feed IDs, expected: 0x1c916b4aa7e57ca7b68ae1bf45653f56b656fd3aa335ef7fae696b663f1b8472, got: 0x")
diff --git a/core/services/relay/evm/mercury/types/types.go b/core/services/relay/evm/mercury/types/types.go
index 6affba58169..ca266ca8ccd 100644
--- a/core/services/relay/evm/mercury/types/types.go
+++ b/core/services/relay/evm/mercury/types/types.go
@@ -2,6 +2,11 @@ package types
import (
"context"
+ "math/big"
+
+ "github.com/prometheus/client_golang/prometheus"
+ "github.com/prometheus/client_golang/prometheus/promauto"
+ ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types"
evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client"
httypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker/types"
@@ -17,3 +22,22 @@ type ChainHeadTracker interface {
type DataSourceORM interface {
LatestReport(ctx context.Context, feedID [32]byte, qopts ...pg.QOpt) (report []byte, err error)
}
+
+type ReportCodec interface {
+ BenchmarkPriceFromReport(report ocrtypes.Report) (*big.Int, error)
+}
+
+var (
+ PriceFeedMissingCount = promauto.NewCounterVec(prometheus.CounterOpts{
+ Name: "mercury_price_feed_missing",
+ Help: "Running count of times mercury tried to query a price feed for billing from mercury server, but it was missing",
+ },
+ []string{"queriedFeedID"},
+ )
+ PriceFeedErrorCount = promauto.NewCounterVec(prometheus.CounterOpts{
+ Name: "mercury_price_feed_errors",
+ Help: "Running count of times mercury tried to query a price feed for billing from mercury server, but got an error",
+ },
+ []string{"queriedFeedID"},
+ )
+)
diff --git a/core/services/relay/evm/mercury/utils/feeds.go b/core/services/relay/evm/mercury/utils/feeds.go
index d2fd2106e98..b1a20618ef6 100644
--- a/core/services/relay/evm/mercury/utils/feeds.go
+++ b/core/services/relay/evm/mercury/utils/feeds.go
@@ -6,6 +6,76 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/utils"
)
+var legacyV1FeedIDs = []FeedID{
+ // Arbitrum mainnet (prod)
+ mustHexToFeedID("0xb43dc495134fa357725f93539511c5a4febeadf56e7c29c96566c825094f0b20"),
+ mustHexToFeedID("0xe65b31c6d5b9bdff43a8194dc5b2edc6914ddbc5e9f9e9521f605fc3738fabf5"),
+ mustHexToFeedID("0x30f9926cdef3de98995fb38a100d5c582ae025ebbb8f9a931500596ce080280a"),
+ mustHexToFeedID("0x0f49a4533a64c7f53bfdf5e86d791620d93afdec00cfe1896548397b0f4ec81c"),
+ mustHexToFeedID("0x2cdd4aea8298f5d2e7f8505b91e3313e3aa04376a81f401b4a48c5aab78ee5cf"),
+ mustHexToFeedID("0x5f82d154119f4251d83b2a58bf61c9483c84241053038a2883abf16ed4926433"),
+ mustHexToFeedID("0x74aca63821bf7ead199e924d261d277cbec96d1026ab65267d655c51b4536914"),
+ mustHexToFeedID("0x64ee16b94fdd72d0b3769955445cc82d6804573c22f0f49b67cd02edd07461e7"),
+ mustHexToFeedID("0x95241f154d34539741b19ce4bae815473fd1b2a90ac3b4b023a692f31edfe90e"),
+ mustHexToFeedID("0x297cc1e1ee5fc2f45dff1dd11a46694567904f4dbc596c7cc216d6c688605a1b"),
+ // // Arbitrum mainnet (staging)
+ mustHexToFeedID("0x62ce6a99c4bebb150191d7b72f7a0c0206af00baca480ab007caa4b5bf4bf02a"),
+ mustHexToFeedID("0x984126712e6a8b5b4fe138c49b29483a12e77b5cb3213a0769252380c57480e4"),
+ mustHexToFeedID("0xb74f650d9cae6259ab4212f76abe746600be3a4926947725ed107943915346c1"),
+ mustHexToFeedID("0xa0098c4c06cbab05b2598aecad0cbf49d44780c56d40514e09fd7a9e76a2db00"),
+ mustHexToFeedID("0x2206b467d04656a8a83af43a428d6b66f787162db629f9caed0c12b54a32998e"),
+ mustHexToFeedID("0x55488e61b59ea629df66698c8eea1390f0aedc24942e074a6d565569fb90afde"),
+ mustHexToFeedID("0x98d66aab30d62d044cc55ffccb79ae35151348f40ff06a98c92001ed6ec8e886"),
+ mustHexToFeedID("0x2e768c0eca65d0449ee825b8a921349501339a2487c02146f77611ae01c31a50"),
+ mustHexToFeedID("0xb29931d9fe1e9fc023b4d2f0f1789c8b5e21aabf389f86f9702241a0178345dd"),
+ mustHexToFeedID("0xd8b8cfc1e2dd75116e5792d11810d830ef48843fd44e1633385e81157f8da6b5"),
+ mustHexToFeedID("0x09f8d0caff8cecb7f5e493d4de2ab98b4392f6d07923cd19b2cb524779301b85"),
+ mustHexToFeedID("0xe645924bbf507304dc4bd37f02c8dac73da3b7eb67378de98cfc59f17ba6774a"),
+ // Arbitrum testnet (production)
+ mustHexToFeedID("0x695be66b6a7979f2b3ed33a3d718eabebaf0a881f1f6598b5530875b7e8150ab"),
+ mustHexToFeedID("0x259b566b9d3c64d1e4a8656e2d6fd4c08e19f9fa9637ae76d52e428d07cca8e9"),
+ mustHexToFeedID("0x26c16f2054b7a1d77ae83a0429dace9f3000ba4dbf1690236e8f575742e98f66"),
+ mustHexToFeedID("0x4254432d5553442d415242495452554d2d544553544e45540000000000000000"),
+ mustHexToFeedID("0xbf1febc8c335cb236c1995c1007a928a3f7ae8307a1a20cb31334e6d316c62d1"),
+ mustHexToFeedID("0x4ce52cf28e49f4673198074968aeea280f13b5f897c687eb713bcfc1eeab89ba"),
+ mustHexToFeedID("0xb21d58dccab05dcea22ab780ca010c4bec34e61ce7310e30f4ad0ff8c1621d27"),
+ mustHexToFeedID("0x5ad0d18436dd95672e69903efe95bdfb43a05cb55e8965c5af93db8170c8820c"),
+ mustHexToFeedID("0x4554482d5553442d415242495452554d2d544553544e45540000000000000000"),
+ mustHexToFeedID("0x14e044f932bb959cc2aa8dc1ba110c09224e639aae00264c1ffc2a0830904a3c"),
+ mustHexToFeedID("0x555344432d5553442d415242495452554d2d544553544e455400000000000000"),
+ mustHexToFeedID("0x12be1859ee43f46bab53750915f20855f54e891f88ddd524f26a72d6f4deed1d"),
+ // // Arbitrum testnet (staging)
+ mustHexToFeedID("0x8837f28f5172f18071f164b8540fe8c95162dc0051e31005023fadc1cd9c4b50"),
+ mustHexToFeedID("0xd130b5acd88b47eb7c372611205d5a9ca474829a2719e396ab1eb4f956674e4e"),
+ mustHexToFeedID("0x6d2f5a4b3ba6c1953b4bb636f6ad03aec01b6222274f8ca1e39e53ee12a8cdf3"),
+ mustHexToFeedID("0x6962e629c3a0f5b7e3e9294b0c283c9b20f94f1c89c8ba8c1ee4650738f20fb2"),
+ mustHexToFeedID("0x557b817c6be7392364cef0dd11007c43caea1de78ce42e4f1eadc383e7cb209c"),
+ mustHexToFeedID("0x3250b5dd9491cb11138048d070b8636c35d96fff29671dc68b0723ad41f53433"),
+ mustHexToFeedID("0x3781c2691f6980dc66a72c03a32edb769fe05a9c9cb729cd7e96ecfd89450a0a"),
+ mustHexToFeedID("0xbbbf52c5797cc86d6bd9413d59ec624f07baf5045290ecd5ac6541d5a7ffd234"),
+ mustHexToFeedID("0xf753e1201d54ac94dfd9334c542562ff7e42993419a661261d010af0cbfd4e34"),
+ mustHexToFeedID("0x2489ce4577e814d6794218a13ef3c04cac976f991305400a4c0a1ddcffb90357"),
+ mustHexToFeedID("0xa5b07943b89e2c278fc8a2754e2854316e03cb959f6d323c2d5da218fb6b0ff8"),
+ mustHexToFeedID("0x1c2c0dfac0eb2aae2c05613f0d677daae164cdd406bd3dd6153d743302ce56e8"),
+}
+
+var legacyV1FeedIDM map[FeedID]struct{}
+
+func init() {
+ legacyV1FeedIDM = make(map[FeedID]struct{})
+ for _, feedID := range legacyV1FeedIDs {
+ legacyV1FeedIDM[feedID] = struct{}{}
+ }
+}
+
+func mustHexToFeedID(s string) FeedID {
+ f := new(FeedID)
+ if err := f.UnmarshalText([]byte(s)); err != nil {
+ panic(err)
+ }
+ return *f
+}
+
type FeedVersion uint16
const (
@@ -27,6 +97,9 @@ func (f *FeedID) UnmarshalText(input []byte) error {
}
func (f FeedID) Version() FeedVersion {
+ if _, exists := legacyV1FeedIDM[f]; exists {
+ return REPORT_V1
+ }
return FeedVersion(binary.BigEndian.Uint16(f[:2]))
}
diff --git a/core/services/relay/evm/mercury/utils/feeds_test.go b/core/services/relay/evm/mercury/utils/feeds_test.go
index dddd125a602..37b9b47de76 100644
--- a/core/services/relay/evm/mercury/utils/feeds_test.go
+++ b/core/services/relay/evm/mercury/utils/feeds_test.go
@@ -12,19 +12,26 @@ var (
v3FeedId = (FeedID)([32]uint8{00, 03, 107, 74, 167, 229, 124, 167, 182, 138, 225, 191, 69, 101, 63, 86, 182, 86, 253, 58, 163, 53, 239, 127, 174, 105, 107, 102, 63, 27, 132, 114})
)
-func Test_FeedID(t *testing.T) {
- assert.Equal(t, REPORT_V1, v1FeedId.Version())
- assert.True(t, v1FeedId.IsV1())
- assert.False(t, v1FeedId.IsV2())
- assert.False(t, v1FeedId.IsV3())
+func Test_FeedID_Version(t *testing.T) {
+ t.Run("versioned feed ID", func(t *testing.T) {
+ assert.Equal(t, REPORT_V1, v1FeedId.Version())
+ assert.True(t, v1FeedId.IsV1())
+ assert.False(t, v1FeedId.IsV2())
+ assert.False(t, v1FeedId.IsV3())
- assert.Equal(t, REPORT_V2, v2FeedId.Version())
- assert.False(t, v2FeedId.IsV1())
- assert.True(t, v2FeedId.IsV2())
- assert.False(t, v2FeedId.IsV3())
+ assert.Equal(t, REPORT_V2, v2FeedId.Version())
+ assert.False(t, v2FeedId.IsV1())
+ assert.True(t, v2FeedId.IsV2())
+ assert.False(t, v2FeedId.IsV3())
- assert.Equal(t, REPORT_V3, v3FeedId.Version())
- assert.False(t, v3FeedId.IsV1())
- assert.False(t, v3FeedId.IsV2())
- assert.True(t, v3FeedId.IsV3())
+ assert.Equal(t, REPORT_V3, v3FeedId.Version())
+ assert.False(t, v3FeedId.IsV1())
+ assert.False(t, v3FeedId.IsV2())
+ assert.True(t, v3FeedId.IsV3())
+ })
+ t.Run("legacy special cases", func(t *testing.T) {
+ for _, feedID := range legacyV1FeedIDs {
+ assert.Equal(t, REPORT_V1, feedID.Version())
+ }
+ })
}
diff --git a/core/services/relay/evm/mercury/v1/data_source.go b/core/services/relay/evm/mercury/v1/data_source.go
index ff7a2c0ab7f..5c1f55ddab7 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 b518ee1818d..6e460951301 100644
--- a/core/services/relay/evm/mercury/v1/data_source_test.go
+++ b/core/services/relay/evm/mercury/v1/data_source_test.go
@@ -143,6 +143,16 @@ func TestMercury_Observe(t *testing.T) {
assert.EqualError(t, obs.MaxFinalizedBlockNumber.Err, "something exploded")
assert.Zero(t, obs.MaxFinalizedBlockNumber.Val)
})
+ t.Run("if decoding latest report fails", func(t *testing.T) {
+ orm.report = []byte{1, 2, 3}
+ orm.err = nil
+
+ obs, err := ds.Observe(ctx, repts, true)
+ assert.NoError(t, err)
+
+ assert.EqualError(t, obs.MaxFinalizedBlockNumber.Err, "failed to decode report: abi: cannot marshal in to go type: length insufficient 3 require 32")
+ assert.Zero(t, obs.MaxFinalizedBlockNumber.Val)
+ })
orm.report = nil
orm.err = nil
@@ -298,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/v1/reportcodec/report_codec.go b/core/services/relay/evm/mercury/v1/reportcodec/report_codec.go
index a28186cce9c..fefddd6395b 100644
--- a/core/services/relay/evm/mercury/v1/reportcodec/report_codec.go
+++ b/core/services/relay/evm/mercury/v1/reportcodec/report_codec.go
@@ -4,6 +4,7 @@ import (
"errors"
"fmt"
"math"
+ "math/big"
"github.com/ethereum/go-ethereum/common"
pkgerrors "github.com/pkg/errors"
@@ -89,3 +90,11 @@ func (r *ReportCodec) ValidFromBlockNumFromReport(report ocrtypes.Report) (int64
func (r *ReportCodec) Decode(report ocrtypes.Report) (*reporttypes.Report, error) {
return reporttypes.Decode(report)
}
+
+func (r *ReportCodec) BenchmarkPriceFromReport(report ocrtypes.Report) (*big.Int, error) {
+ decoded, err := r.Decode(report)
+ if err != nil {
+ return nil, err
+ }
+ return decoded.BenchmarkPrice, nil
+}
diff --git a/core/services/relay/evm/mercury/v1/reportcodec/report_codec_test.go b/core/services/relay/evm/mercury/v1/reportcodec/report_codec_test.go
index 6e6a58af4ca..3f4838c3e7c 100644
--- a/core/services/relay/evm/mercury/v1/reportcodec/report_codec_test.go
+++ b/core/services/relay/evm/mercury/v1/reportcodec/report_codec_test.go
@@ -161,3 +161,22 @@ func Test_ReportCodec_ValidFromBlockNumFromReport(t *testing.T) {
assert.Contains(t, err.Error(), "ValidFromBlockNum=18446744073709551615 overflows max int64")
})
}
+
+func Test_ReportCodec_BenchmarkPriceFromReport(t *testing.T) {
+ r := ReportCodec{}
+ feedID := utils.NewHash()
+
+ t.Run("BenchmarkPriceFromReport extracts the benchmark price from valid report", func(t *testing.T) {
+ report := buildSampleReport(42, 999, feedID)
+
+ bp, err := r.BenchmarkPriceFromReport(report)
+ require.NoError(t, err)
+
+ assert.Equal(t, big.NewInt(242), bp)
+ })
+ t.Run("BenchmarkPriceFromReport errors on invalid report", func(t *testing.T) {
+ _, err := r.BenchmarkPriceFromReport([]byte{1, 2, 3})
+ require.Error(t, err)
+ assert.EqualError(t, err, "failed to decode report: abi: cannot marshal in to go type: length insufficient 3 require 32")
+ })
+}
diff --git a/core/services/relay/evm/mercury/v2/data_source.go b/core/services/relay/evm/mercury/v2/data_source.go
index bb9d72e35d9..caeae8d278a 100644
--- a/core/services/relay/evm/mercury/v2/data_source.go
+++ b/core/services/relay/evm/mercury/v2/data_source.go
@@ -17,12 +17,15 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/services/job"
"github.com/smartcontractkit/chainlink/v2/core/services/ocrcommon"
"github.com/smartcontractkit/chainlink/v2/core/services/pipeline"
+ "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/types"
+ mercurytypes "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/types"
mercuryutils "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/utils"
+ "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/v2/reportcodec"
"github.com/smartcontractkit/chainlink/v2/core/utils"
)
type Runner interface {
- ExecuteRun(ctx context.Context, spec pipeline.Spec, vars pipeline.Vars, l logger.Logger) (run pipeline.Run, trrs pipeline.TaskRunResults, err error)
+ ExecuteRun(ctx context.Context, spec pipeline.Spec, vars pipeline.Vars, l logger.Logger) (run *pipeline.Run, trrs pipeline.TaskRunResults, err error)
}
type LatestReportFetcher interface {
@@ -36,7 +39,9 @@ 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
fetcher LatestReportFetcher
linkFeedID mercuryutils.FeedID
@@ -49,8 +54,8 @@ type datasource struct {
var _ relaymercuryv2.DataSource = &datasource{}
-func NewDataSource(pr pipeline.Runner, jb job.Job, spec pipeline.Spec, feedID mercuryutils.FeedID, lggr logger.Logger, rr chan pipeline.Run, enhancedTelemChan chan ocrcommon.EnhancedTelemetryMercuryData, fetcher LatestReportFetcher, linkFeedID, nativeFeedID mercuryutils.FeedID) *datasource {
- return &datasource{pr, jb, spec, feedID, lggr, rr, fetcher, linkFeedID, nativeFeedID, sync.RWMutex{}, enhancedTelemChan}
+func 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}
}
func (ds *datasource) Observe(ctx context.Context, repts ocrtypes.ReportTimestamp, fetchMaxFinalizedTimestamp bool) (obs relaymercuryv2.Observation, err error) {
@@ -61,6 +66,16 @@ func (ds *datasource) Observe(ctx context.Context, repts ocrtypes.ReportTimestam
wg.Add(1)
go func() {
defer wg.Done()
+ latest, dbErr := ds.orm.LatestReport(ctx, ds.feedID)
+ if dbErr != nil {
+ obs.MaxFinalizedTimestamp.Err = dbErr
+ return
+ }
+ if latest != nil {
+ maxFinalizedBlockNumber, decodeErr := ds.codec.ObservationTimestampFromReport(latest)
+ obs.MaxFinalizedTimestamp.Val, obs.MaxFinalizedTimestamp.Err = int64(maxFinalizedBlockNumber), decodeErr
+ return
+ }
obs.MaxFinalizedTimestamp.Val, obs.MaxFinalizedTimestamp.Err = ds.fetcher.LatestTimestamp(ctx)
}()
}
@@ -69,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()
@@ -103,8 +118,12 @@ func (ds *datasource) Observe(ctx context.Context, repts ocrtypes.ReportTimestam
defer wg.Done()
obs.LinkPrice.Val, obs.LinkPrice.Err = ds.fetcher.LatestPrice(ctx, ds.linkFeedID)
if obs.LinkPrice.Val == nil && obs.LinkPrice.Err == nil {
- ds.lggr.Warnw("Mercury server was missing LINK feed, falling back to max int192", "linkFeedID", ds.linkFeedID)
- obs.LinkPrice.Val = relaymercury.MaxInt192
+ mercurytypes.PriceFeedMissingCount.WithLabelValues(ds.linkFeedID.String()).Inc()
+ ds.lggr.Warnw(fmt.Sprintf("Mercury server was missing LINK feed, using sentinel value of %s", relaymercuryv2.MissingPrice), "linkFeedID", ds.linkFeedID)
+ obs.LinkPrice.Val = relaymercuryv2.MissingPrice
+ } else if obs.LinkPrice.Err != nil {
+ mercurytypes.PriceFeedErrorCount.WithLabelValues(ds.linkFeedID.String()).Inc()
+ ds.lggr.Errorw("Mercury server returned error querying LINK price feed", "err", obs.LinkPrice.Err, "linkFeedID", ds.linkFeedID)
}
}()
}
@@ -117,8 +136,12 @@ func (ds *datasource) Observe(ctx context.Context, repts ocrtypes.ReportTimestam
defer wg.Done()
obs.NativePrice.Val, obs.NativePrice.Err = ds.fetcher.LatestPrice(ctx, ds.nativeFeedID)
if obs.NativePrice.Val == nil && obs.NativePrice.Err == nil {
- ds.lggr.Warnw("Mercury server was missing native feed, falling back to max int192", "nativeFeedID", ds.nativeFeedID)
- obs.NativePrice.Val = relaymercury.MaxInt192
+ mercurytypes.PriceFeedMissingCount.WithLabelValues(ds.nativeFeedID.String()).Inc()
+ ds.lggr.Warnw(fmt.Sprintf("Mercury server was missing native feed, using sentinel value of %s", relaymercuryv2.MissingPrice), "nativeFeedID", ds.nativeFeedID)
+ obs.NativePrice.Val = relaymercuryv2.MissingPrice
+ } else if obs.NativePrice.Err != nil {
+ mercurytypes.PriceFeedErrorCount.WithLabelValues(ds.nativeFeedID.String()).Inc()
+ ds.lggr.Errorw("Mercury server returned error querying native price feed", "err", obs.NativePrice.Err, "nativeFeedID", ds.nativeFeedID)
}
}()
}
@@ -195,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,
@@ -206,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/v2/data_source_test.go b/core/services/relay/evm/mercury/v2/data_source_test.go
index 0d5d7b5895f..b66355ac7fb 100644
--- a/core/services/relay/evm/mercury/v2/data_source_test.go
+++ b/core/services/relay/evm/mercury/v2/data_source_test.go
@@ -9,14 +9,17 @@ import (
"github.com/stretchr/testify/assert"
relaymercury "github.com/smartcontractkit/chainlink-relay/pkg/reportingplugins/mercury"
+ relaymercuryv2 "github.com/smartcontractkit/chainlink-relay/pkg/reportingplugins/mercury/v2"
ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types"
"github.com/smartcontractkit/chainlink/v2/core/internal/testutils"
"github.com/smartcontractkit/chainlink/v2/core/logger"
+ "github.com/smartcontractkit/chainlink/v2/core/services/pg"
"github.com/smartcontractkit/chainlink/v2/core/services/pipeline"
mercurymocks "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/mocks"
"github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/utils"
+ reportcodecv2 "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/v2/reportcodec"
)
var _ relaymercury.MercuryServerFetcher = &mockFetcher{}
@@ -51,8 +54,18 @@ func (m *mockFetcher) LatestTimestamp(context.Context) (int64, error) {
return m.ts, m.tsErr
}
+type mockORM struct {
+ report []byte
+ err error
+}
+
+func (m *mockORM) LatestReport(ctx context.Context, feedID [32]byte, qopts ...pg.QOpt) (report []byte, err error) {
+ return m.report, m.err
+}
+
func Test_Datasource(t *testing.T) {
- ds := &datasource{lggr: logger.TestLogger(t)}
+ orm := &mockORM{}
+ ds := &datasource{orm: orm, lggr: logger.TestLogger(t)}
ctx := testutils.Context(t)
repts := ocrtypes.ReportTimestamp{}
@@ -75,6 +88,40 @@ func Test_Datasource(t *testing.T) {
ds.spec = spec
t.Run("when fetchMaxFinalizedTimestamp=true", func(t *testing.T) {
+ t.Run("with latest report in database", func(t *testing.T) {
+ orm.report = buildSampleV2Report()
+ orm.err = nil
+
+ obs, err := ds.Observe(ctx, repts, true)
+ assert.NoError(t, err)
+
+ assert.NoError(t, obs.MaxFinalizedTimestamp.Err)
+ assert.Equal(t, int64(124), obs.MaxFinalizedTimestamp.Val)
+ })
+ t.Run("if querying latest report fails", func(t *testing.T) {
+ orm.report = nil
+ orm.err = errors.New("something exploded")
+
+ obs, err := ds.Observe(ctx, repts, true)
+ assert.NoError(t, err)
+
+ assert.EqualError(t, obs.MaxFinalizedTimestamp.Err, "something exploded")
+ assert.Zero(t, obs.MaxFinalizedTimestamp.Val)
+ })
+ t.Run("if codec fails to decode", func(t *testing.T) {
+ orm.report = []byte{1, 2, 3}
+ orm.err = nil
+
+ obs, err := ds.Observe(ctx, repts, true)
+ assert.NoError(t, err)
+
+ assert.EqualError(t, obs.MaxFinalizedTimestamp.Err, "failed to decode report: abi: cannot marshal in to go type: length insufficient 3 require 32")
+ assert.Zero(t, obs.MaxFinalizedTimestamp.Val)
+ })
+
+ orm.report = nil
+ orm.err = nil
+
t.Run("if LatestTimestamp returns error", func(t *testing.T) {
fetcher.tsErr = errors.New("some error")
@@ -221,11 +268,29 @@ func Test_Datasource(t *testing.T) {
obs, err := ds.Observe(ctx, repts, false)
assert.NoError(t, err)
- assert.Equal(t, obs.LinkPrice.Val, relaymercury.MaxInt192)
+ assert.Equal(t, obs.LinkPrice.Val, relaymercuryv2.MissingPrice)
assert.Nil(t, obs.LinkPrice.Err)
- assert.Equal(t, obs.NativePrice.Val, relaymercury.MaxInt192)
+ assert.Equal(t, obs.NativePrice.Val, relaymercuryv2.MissingPrice)
assert.Nil(t, obs.NativePrice.Err)
})
})
})
}
+
+var sampleFeedID = [32]uint8{28, 145, 107, 74, 167, 229, 124, 167, 182, 138, 225, 191, 69, 101, 63, 86, 182, 86, 253, 58, 163, 53, 239, 127, 174, 105, 107, 102, 63, 27, 132, 114}
+
+func buildSampleV2Report() []byte {
+ feedID := sampleFeedID
+ timestamp := uint32(124)
+ bp := big.NewInt(242)
+ validFromTimestamp := uint32(123)
+ expiresAt := uint32(456)
+ linkFee := big.NewInt(3334455)
+ nativeFee := big.NewInt(556677)
+
+ b, err := reportcodecv2.ReportTypes.Pack(feedID, validFromTimestamp, timestamp, nativeFee, linkFee, expiresAt, bp)
+ if err != nil {
+ panic(err)
+ }
+ return b
+}
diff --git a/core/services/relay/evm/mercury/v2/reportcodec/report_codec.go b/core/services/relay/evm/mercury/v2/reportcodec/report_codec.go
index 60dde81f1cb..0e1dfe9c46f 100644
--- a/core/services/relay/evm/mercury/v2/reportcodec/report_codec.go
+++ b/core/services/relay/evm/mercury/v2/reportcodec/report_codec.go
@@ -67,3 +67,11 @@ func (r *ReportCodec) ObservationTimestampFromReport(report ocrtypes.Report) (ui
func (r *ReportCodec) Decode(report ocrtypes.Report) (*reporttypes.Report, error) {
return reporttypes.Decode(report)
}
+
+func (r *ReportCodec) BenchmarkPriceFromReport(report ocrtypes.Report) (*big.Int, error) {
+ decoded, err := r.Decode(report)
+ if err != nil {
+ return nil, err
+ }
+ return decoded.BenchmarkPrice, nil
+}
diff --git a/core/services/relay/evm/mercury/v2/reportcodec/report_codec_test.go b/core/services/relay/evm/mercury/v2/reportcodec/report_codec_test.go
index c0c931dfe3a..8cf16a5dab4 100644
--- a/core/services/relay/evm/mercury/v2/reportcodec/report_codec_test.go
+++ b/core/services/relay/evm/mercury/v2/reportcodec/report_codec_test.go
@@ -132,3 +132,21 @@ func Test_ReportCodec_ObservationTimestampFromReport(t *testing.T) {
assert.EqualError(t, err, "failed to decode report: abi: cannot marshal in to go type: length insufficient 3 require 32")
})
}
+
+func Test_ReportCodec_BenchmarkPriceFromReport(t *testing.T) {
+ r := ReportCodec{}
+
+ t.Run("BenchmarkPriceFromReport extracts the benchmark price from valid report", func(t *testing.T) {
+ report := buildSampleReport(123)
+
+ bp, err := r.BenchmarkPriceFromReport(report)
+ require.NoError(t, err)
+
+ assert.Equal(t, big.NewInt(242), bp)
+ })
+ t.Run("BenchmarkPriceFromReport errors on invalid report", func(t *testing.T) {
+ _, err := r.BenchmarkPriceFromReport([]byte{1, 2, 3})
+ require.Error(t, err)
+ assert.EqualError(t, err, "failed to decode report: abi: cannot marshal in to go type: length insufficient 3 require 32")
+ })
+}
diff --git a/core/services/relay/evm/mercury/v2/types/types.go b/core/services/relay/evm/mercury/v2/types/types.go
index b09ee66f093..3c1df286d14 100644
--- a/core/services/relay/evm/mercury/v2/types/types.go
+++ b/core/services/relay/evm/mercury/v2/types/types.go
@@ -21,8 +21,8 @@ func GetSchema() abi.Arguments {
{Name: "feedId", Type: mustNewType("bytes32")},
{Name: "validFromTimestamp", Type: mustNewType("uint32")},
{Name: "observationsTimestamp", Type: mustNewType("uint32")},
- {Name: "nativeFee", Type: mustNewType("int192")},
- {Name: "linkFee", Type: mustNewType("int192")},
+ {Name: "nativeFee", Type: mustNewType("uint192")},
+ {Name: "linkFee", Type: mustNewType("uint192")},
{Name: "expiresAt", Type: mustNewType("uint32")},
{Name: "benchmarkPrice", Type: mustNewType("int192")},
})
diff --git a/core/services/relay/evm/mercury/v3/data_source.go b/core/services/relay/evm/mercury/v3/data_source.go
index 46dcf1fecdb..79f6c536efd 100644
--- a/core/services/relay/evm/mercury/v3/data_source.go
+++ b/core/services/relay/evm/mercury/v3/data_source.go
@@ -18,12 +18,15 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/services/job"
"github.com/smartcontractkit/chainlink/v2/core/services/ocrcommon"
"github.com/smartcontractkit/chainlink/v2/core/services/pipeline"
+ "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/types"
+ mercurytypes "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/types"
mercuryutils "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/utils"
+ "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/v3/reportcodec"
"github.com/smartcontractkit/chainlink/v2/core/utils"
)
type Runner interface {
- ExecuteRun(ctx context.Context, spec pipeline.Spec, vars pipeline.Vars, l logger.Logger) (run pipeline.Run, trrs pipeline.TaskRunResults, err error)
+ ExecuteRun(ctx context.Context, spec pipeline.Spec, vars pipeline.Vars, l logger.Logger) (run *pipeline.Run, trrs pipeline.TaskRunResults, err error)
}
type LatestReportFetcher interface {
@@ -37,7 +40,9 @@ 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
fetcher LatestReportFetcher
linkFeedID mercuryutils.FeedID
@@ -50,8 +55,8 @@ type datasource struct {
var _ relaymercuryv3.DataSource = &datasource{}
-func NewDataSource(pr pipeline.Runner, jb job.Job, spec pipeline.Spec, feedID mercuryutils.FeedID, lggr logger.Logger, rr chan pipeline.Run, enhancedTelemChan chan ocrcommon.EnhancedTelemetryMercuryData, fetcher LatestReportFetcher, linkFeedID, nativeFeedID mercuryutils.FeedID) *datasource {
- return &datasource{pr, jb, spec, feedID, lggr, rr, fetcher, linkFeedID, nativeFeedID, sync.RWMutex{}, enhancedTelemChan}
+func 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}
}
func (ds *datasource) Observe(ctx context.Context, repts ocrtypes.ReportTimestamp, fetchMaxFinalizedTimestamp bool) (obs relaymercuryv3.Observation, err error) {
@@ -62,6 +67,16 @@ func (ds *datasource) Observe(ctx context.Context, repts ocrtypes.ReportTimestam
wg.Add(1)
go func() {
defer wg.Done()
+ latest, dbErr := ds.orm.LatestReport(ctx, ds.feedID)
+ if dbErr != nil {
+ obs.MaxFinalizedTimestamp.Err = dbErr
+ return
+ }
+ if latest != nil {
+ maxFinalizedBlockNumber, decodeErr := ds.codec.ObservationTimestampFromReport(latest)
+ obs.MaxFinalizedTimestamp.Val, obs.MaxFinalizedTimestamp.Err = int64(maxFinalizedBlockNumber), decodeErr
+ return
+ }
obs.MaxFinalizedTimestamp.Val, obs.MaxFinalizedTimestamp.Err = ds.fetcher.LatestTimestamp(ctx)
}()
}
@@ -70,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()
@@ -106,8 +121,12 @@ func (ds *datasource) Observe(ctx context.Context, repts ocrtypes.ReportTimestam
defer wg.Done()
obs.LinkPrice.Val, obs.LinkPrice.Err = ds.fetcher.LatestPrice(ctx, ds.linkFeedID)
if obs.LinkPrice.Val == nil && obs.LinkPrice.Err == nil {
- ds.lggr.Warnw("Mercury server was missing LINK feed, falling back to max int192", "linkFeedID", ds.linkFeedID)
- obs.LinkPrice.Val = relaymercury.MaxInt192
+ mercurytypes.PriceFeedMissingCount.WithLabelValues(ds.linkFeedID.String()).Inc()
+ ds.lggr.Warnw(fmt.Sprintf("Mercury server was missing LINK feed, using sentinel value of %s", relaymercuryv3.MissingPrice), "linkFeedID", ds.linkFeedID)
+ obs.LinkPrice.Val = relaymercuryv3.MissingPrice
+ } else if obs.LinkPrice.Err != nil {
+ mercurytypes.PriceFeedErrorCount.WithLabelValues(ds.linkFeedID.String()).Inc()
+ ds.lggr.Errorw("Mercury server returned error querying LINK price feed", "err", obs.LinkPrice.Err, "linkFeedID", ds.linkFeedID)
}
}()
}
@@ -120,8 +139,12 @@ func (ds *datasource) Observe(ctx context.Context, repts ocrtypes.ReportTimestam
defer wg.Done()
obs.NativePrice.Val, obs.NativePrice.Err = ds.fetcher.LatestPrice(ctx, ds.nativeFeedID)
if obs.NativePrice.Val == nil && obs.NativePrice.Err == nil {
- ds.lggr.Warnw("Mercury server was missing native feed, falling back to max int192", "nativeFeedID", ds.nativeFeedID)
- obs.NativePrice.Val = relaymercury.MaxInt192
+ mercurytypes.PriceFeedMissingCount.WithLabelValues(ds.nativeFeedID.String()).Inc()
+ ds.lggr.Warnw(fmt.Sprintf("Mercury server was missing native feed, using sentinel value of %s", relaymercuryv3.MissingPrice), "nativeFeedID", ds.nativeFeedID)
+ obs.NativePrice.Val = relaymercuryv3.MissingPrice
+ } else if obs.NativePrice.Err != nil {
+ mercurytypes.PriceFeedErrorCount.WithLabelValues(ds.nativeFeedID.String()).Inc()
+ ds.lggr.Errorw("Mercury server returned error querying native price feed", "err", obs.NativePrice.Err, "nativeFeedID", ds.nativeFeedID)
}
}()
}
@@ -233,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,
@@ -244,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/mercury/v3/data_source_test.go b/core/services/relay/evm/mercury/v3/data_source_test.go
index 7fc2e90193c..aefc766996e 100644
--- a/core/services/relay/evm/mercury/v3/data_source_test.go
+++ b/core/services/relay/evm/mercury/v3/data_source_test.go
@@ -9,14 +9,17 @@ import (
"github.com/stretchr/testify/assert"
relaymercury "github.com/smartcontractkit/chainlink-relay/pkg/reportingplugins/mercury"
+ relaymercuryv3 "github.com/smartcontractkit/chainlink-relay/pkg/reportingplugins/mercury/v3"
ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types"
"github.com/smartcontractkit/chainlink/v2/core/internal/testutils"
"github.com/smartcontractkit/chainlink/v2/core/logger"
+ "github.com/smartcontractkit/chainlink/v2/core/services/pg"
"github.com/smartcontractkit/chainlink/v2/core/services/pipeline"
mercurymocks "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/mocks"
"github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/utils"
+ reportcodecv3 "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/v3/reportcodec"
)
var _ relaymercury.MercuryServerFetcher = &mockFetcher{}
@@ -51,8 +54,18 @@ func (m *mockFetcher) LatestTimestamp(context.Context) (int64, error) {
return m.ts, m.tsErr
}
+type mockORM struct {
+ report []byte
+ err error
+}
+
+func (m *mockORM) LatestReport(ctx context.Context, feedID [32]byte, qopts ...pg.QOpt) (report []byte, err error) {
+ return m.report, m.err
+}
+
func Test_Datasource(t *testing.T) {
- ds := &datasource{lggr: logger.TestLogger(t)}
+ orm := &mockORM{}
+ ds := &datasource{orm: orm, lggr: logger.TestLogger(t)}
ctx := testutils.Context(t)
repts := ocrtypes.ReportTimestamp{}
@@ -85,6 +98,40 @@ func Test_Datasource(t *testing.T) {
ds.spec = spec
t.Run("when fetchMaxFinalizedTimestamp=true", func(t *testing.T) {
+ t.Run("with latest report in database", func(t *testing.T) {
+ orm.report = buildSampleV3Report()
+ orm.err = nil
+
+ obs, err := ds.Observe(ctx, repts, true)
+ assert.NoError(t, err)
+
+ assert.NoError(t, obs.MaxFinalizedTimestamp.Err)
+ assert.Equal(t, int64(124), obs.MaxFinalizedTimestamp.Val)
+ })
+ t.Run("if querying latest report fails", func(t *testing.T) {
+ orm.report = nil
+ orm.err = errors.New("something exploded")
+
+ obs, err := ds.Observe(ctx, repts, true)
+ assert.NoError(t, err)
+
+ assert.EqualError(t, obs.MaxFinalizedTimestamp.Err, "something exploded")
+ assert.Zero(t, obs.MaxFinalizedTimestamp.Val)
+ })
+ t.Run("if codec fails to decode", func(t *testing.T) {
+ orm.report = []byte{1, 2, 3}
+ orm.err = nil
+
+ obs, err := ds.Observe(ctx, repts, true)
+ assert.NoError(t, err)
+
+ assert.EqualError(t, obs.MaxFinalizedTimestamp.Err, "failed to decode report: abi: cannot marshal in to go type: length insufficient 3 require 32")
+ assert.Zero(t, obs.MaxFinalizedTimestamp.Val)
+ })
+
+ orm.report = nil
+ orm.err = nil
+
t.Run("if LatestTimestamp returns error", func(t *testing.T) {
fetcher.tsErr = errors.New("some error")
@@ -249,11 +296,31 @@ func Test_Datasource(t *testing.T) {
obs, err := ds.Observe(ctx, repts, false)
assert.NoError(t, err)
- assert.Equal(t, obs.LinkPrice.Val, relaymercury.MaxInt192)
+ assert.Equal(t, obs.LinkPrice.Val, relaymercuryv3.MissingPrice)
assert.Nil(t, obs.LinkPrice.Err)
- assert.Equal(t, obs.NativePrice.Val, relaymercury.MaxInt192)
+ assert.Equal(t, obs.NativePrice.Val, relaymercuryv3.MissingPrice)
assert.Nil(t, obs.NativePrice.Err)
})
})
})
}
+
+var sampleFeedID = [32]uint8{28, 145, 107, 74, 167, 229, 124, 167, 182, 138, 225, 191, 69, 101, 63, 86, 182, 86, 253, 58, 163, 53, 239, 127, 174, 105, 107, 102, 63, 27, 132, 114}
+
+func buildSampleV3Report() []byte {
+ feedID := sampleFeedID
+ timestamp := uint32(124)
+ bp := big.NewInt(242)
+ bid := big.NewInt(243)
+ ask := big.NewInt(244)
+ validFromTimestamp := uint32(123)
+ expiresAt := uint32(456)
+ linkFee := big.NewInt(3334455)
+ nativeFee := big.NewInt(556677)
+
+ b, err := reportcodecv3.ReportTypes.Pack(feedID, validFromTimestamp, timestamp, nativeFee, linkFee, expiresAt, bp, bid, ask)
+ if err != nil {
+ panic(err)
+ }
+ return b
+}
diff --git a/core/services/relay/evm/mercury/v3/reportcodec/report_codec.go b/core/services/relay/evm/mercury/v3/reportcodec/report_codec.go
index 66995e74ea7..4c0b3756d7b 100644
--- a/core/services/relay/evm/mercury/v3/reportcodec/report_codec.go
+++ b/core/services/relay/evm/mercury/v3/reportcodec/report_codec.go
@@ -74,3 +74,11 @@ func (r *ReportCodec) ObservationTimestampFromReport(report ocrtypes.Report) (ui
func (r *ReportCodec) Decode(report ocrtypes.Report) (*reporttypes.Report, error) {
return reporttypes.Decode(report)
}
+
+func (r *ReportCodec) BenchmarkPriceFromReport(report ocrtypes.Report) (*big.Int, error) {
+ decoded, err := r.Decode(report)
+ if err != nil {
+ return nil, err
+ }
+ return decoded.BenchmarkPrice, nil
+}
diff --git a/core/services/relay/evm/mercury/v3/reportcodec/report_codec_test.go b/core/services/relay/evm/mercury/v3/reportcodec/report_codec_test.go
index 80cf4c9665b..98b81edb002 100644
--- a/core/services/relay/evm/mercury/v3/reportcodec/report_codec_test.go
+++ b/core/services/relay/evm/mercury/v3/reportcodec/report_codec_test.go
@@ -140,3 +140,21 @@ func Test_ReportCodec_ObservationTimestampFromReport(t *testing.T) {
assert.EqualError(t, err, "failed to decode report: abi: cannot marshal in to go type: length insufficient 3 require 32")
})
}
+
+func Test_ReportCodec_BenchmarkPriceFromReport(t *testing.T) {
+ r := ReportCodec{}
+
+ t.Run("BenchmarkPriceFromReport extracts the benchmark price from valid report", func(t *testing.T) {
+ report := buildSampleReport(123)
+
+ bp, err := r.BenchmarkPriceFromReport(report)
+ require.NoError(t, err)
+
+ assert.Equal(t, big.NewInt(242), bp)
+ })
+ t.Run("BenchmarkPriceFromReport errors on invalid report", func(t *testing.T) {
+ _, err := r.BenchmarkPriceFromReport([]byte{1, 2, 3})
+ require.Error(t, err)
+ assert.EqualError(t, err, "failed to decode report: abi: cannot marshal in to go type: length insufficient 3 require 32")
+ })
+}
diff --git a/core/services/relay/evm/mercury/v3/types/types.go b/core/services/relay/evm/mercury/v3/types/types.go
index 110315942d8..e99f529f857 100644
--- a/core/services/relay/evm/mercury/v3/types/types.go
+++ b/core/services/relay/evm/mercury/v3/types/types.go
@@ -21,8 +21,8 @@ func GetSchema() abi.Arguments {
{Name: "feedId", Type: mustNewType("bytes32")},
{Name: "validFromTimestamp", Type: mustNewType("uint32")},
{Name: "observationsTimestamp", Type: mustNewType("uint32")},
- {Name: "nativeFee", Type: mustNewType("int192")},
- {Name: "linkFee", Type: mustNewType("int192")},
+ {Name: "nativeFee", Type: mustNewType("uint192")},
+ {Name: "linkFee", Type: mustNewType("uint192")},
{Name: "expiresAt", Type: mustNewType("uint32")},
{Name: "benchmarkPrice", Type: mustNewType("int192")},
{Name: "bid", Type: mustNewType("int192")},
diff --git a/core/services/relay/evm/mercury/wsrpc/pool.go b/core/services/relay/evm/mercury/wsrpc/pool.go
index bf6f0335fc9..6630a78437e 100644
--- a/core/services/relay/evm/mercury/wsrpc/pool.go
+++ b/core/services/relay/evm/mercury/wsrpc/pool.go
@@ -127,7 +127,7 @@ type pool struct {
}
func NewPool(lggr logger.Logger) Pool {
- p := newPool(lggr)
+ p := newPool(lggr.Named("Mercury.WSRPCPool"))
p.newClient = NewClient
return p
}
diff --git a/core/services/relay/evm/mercury_provider.go b/core/services/relay/evm/mercury_provider.go
index ee32b8d99be..74072167061 100644
--- a/core/services/relay/evm/mercury_provider.go
+++ b/core/services/relay/evm/mercury_provider.go
@@ -4,13 +4,15 @@ import (
"context"
"errors"
+ "golang.org/x/exp/maps"
+
+ ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types"
+
relaymercury "github.com/smartcontractkit/chainlink-relay/pkg/reportingplugins/mercury"
relaymercuryv1 "github.com/smartcontractkit/chainlink-relay/pkg/reportingplugins/mercury/v1"
relaymercuryv2 "github.com/smartcontractkit/chainlink-relay/pkg/reportingplugins/mercury/v2"
relaymercuryv3 "github.com/smartcontractkit/chainlink-relay/pkg/reportingplugins/mercury/v3"
relaytypes "github.com/smartcontractkit/chainlink-relay/pkg/types"
- ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types"
- "golang.org/x/exp/maps"
"github.com/smartcontractkit/chainlink/v2/core/logger"
"github.com/smartcontractkit/chainlink/v2/core/services"
@@ -96,6 +98,10 @@ func (p *mercuryProvider) ReportCodecV3() relaymercuryv3.ReportCodec {
return p.reportCodecV3
}
-func (p *mercuryProvider) ContractTransmitter() relaymercury.Transmitter {
+func (p *mercuryProvider) ContractTransmitter() ocrtypes.ContractTransmitter {
+ return p.transmitter
+}
+
+func (p *mercuryProvider) MercuryServerFetcher() relaymercury.MercuryServerFetcher {
return p.transmitter
}
diff --git a/core/services/relay/evm/mocks/loop_relay_adapter.go b/core/services/relay/evm/mocks/loop_relay_adapter.go
index b0d9b7cf95e..11150874b9e 100644
--- a/core/services/relay/evm/mocks/loop_relay_adapter.go
+++ b/core/services/relay/evm/mocks/loop_relay_adapter.go
@@ -33,63 +33,6 @@ func (_m *LoopRelayAdapter) Chain() evm.Chain {
return r0
}
-// ChainStatus provides a mock function with given fields: ctx, id
-func (_m *LoopRelayAdapter) ChainStatus(ctx context.Context, id string) (types.ChainStatus, error) {
- ret := _m.Called(ctx, id)
-
- var r0 types.ChainStatus
- var r1 error
- if rf, ok := ret.Get(0).(func(context.Context, string) (types.ChainStatus, error)); ok {
- return rf(ctx, id)
- }
- if rf, ok := ret.Get(0).(func(context.Context, string) types.ChainStatus); ok {
- r0 = rf(ctx, id)
- } else {
- r0 = ret.Get(0).(types.ChainStatus)
- }
-
- if rf, ok := ret.Get(1).(func(context.Context, string) error); ok {
- r1 = rf(ctx, id)
- } else {
- r1 = ret.Error(1)
- }
-
- return r0, r1
-}
-
-// ChainStatuses provides a mock function with given fields: ctx, offset, limit
-func (_m *LoopRelayAdapter) ChainStatuses(ctx context.Context, offset int, limit int) ([]types.ChainStatus, int, error) {
- ret := _m.Called(ctx, offset, limit)
-
- var r0 []types.ChainStatus
- var r1 int
- var r2 error
- if rf, ok := ret.Get(0).(func(context.Context, int, int) ([]types.ChainStatus, int, error)); ok {
- return rf(ctx, offset, limit)
- }
- if rf, ok := ret.Get(0).(func(context.Context, int, int) []types.ChainStatus); ok {
- r0 = rf(ctx, offset, limit)
- } else {
- if ret.Get(0) != nil {
- r0 = ret.Get(0).([]types.ChainStatus)
- }
- }
-
- if rf, ok := ret.Get(1).(func(context.Context, int, int) int); ok {
- r1 = rf(ctx, offset, limit)
- } else {
- r1 = ret.Get(1).(int)
- }
-
- if rf, ok := ret.Get(2).(func(context.Context, int, int) error); ok {
- r2 = rf(ctx, offset, limit)
- } else {
- r2 = ret.Error(2)
- }
-
- return r0, r1, r2
-}
-
// Close provides a mock function with given fields:
func (_m *LoopRelayAdapter) Close() error {
ret := _m.Called()
@@ -104,18 +47,28 @@ func (_m *LoopRelayAdapter) Close() error {
return r0
}
-// Default provides a mock function with given fields:
-func (_m *LoopRelayAdapter) Default() bool {
- ret := _m.Called()
+// GetChainStatus provides a mock function with given fields: ctx
+func (_m *LoopRelayAdapter) GetChainStatus(ctx context.Context) (types.ChainStatus, error) {
+ ret := _m.Called(ctx)
- var r0 bool
- if rf, ok := ret.Get(0).(func() bool); ok {
- r0 = rf()
+ var r0 types.ChainStatus
+ var r1 error
+ if rf, ok := ret.Get(0).(func(context.Context) (types.ChainStatus, error)); ok {
+ return rf(ctx)
+ }
+ if rf, ok := ret.Get(0).(func(context.Context) types.ChainStatus); ok {
+ r0 = rf(ctx)
} else {
- r0 = ret.Get(0).(bool)
+ r0 = ret.Get(0).(types.ChainStatus)
}
- return r0
+ if rf, ok := ret.Get(1).(func(context.Context) error); ok {
+ r1 = rf(ctx)
+ } else {
+ r1 = ret.Error(1)
+ }
+
+ return r0, r1
}
// HealthReport provides a mock function with given fields:
@@ -134,6 +87,46 @@ func (_m *LoopRelayAdapter) HealthReport() map[string]error {
return r0
}
+// ListNodeStatuses provides a mock function with given fields: ctx, pageSize, pageToken
+func (_m *LoopRelayAdapter) ListNodeStatuses(ctx context.Context, pageSize int32, pageToken string) ([]types.NodeStatus, string, int, error) {
+ ret := _m.Called(ctx, pageSize, pageToken)
+
+ var r0 []types.NodeStatus
+ var r1 string
+ var r2 int
+ var r3 error
+ if rf, ok := ret.Get(0).(func(context.Context, int32, string) ([]types.NodeStatus, string, int, error)); ok {
+ return rf(ctx, pageSize, pageToken)
+ }
+ if rf, ok := ret.Get(0).(func(context.Context, int32, string) []types.NodeStatus); ok {
+ r0 = rf(ctx, pageSize, pageToken)
+ } else {
+ if ret.Get(0) != nil {
+ r0 = ret.Get(0).([]types.NodeStatus)
+ }
+ }
+
+ if rf, ok := ret.Get(1).(func(context.Context, int32, string) string); ok {
+ r1 = rf(ctx, pageSize, pageToken)
+ } else {
+ r1 = ret.Get(1).(string)
+ }
+
+ if rf, ok := ret.Get(2).(func(context.Context, int32, string) int); ok {
+ r2 = rf(ctx, pageSize, pageToken)
+ } else {
+ r2 = ret.Get(2).(int)
+ }
+
+ if rf, ok := ret.Get(3).(func(context.Context, int32, string) error); ok {
+ r3 = rf(ctx, pageSize, pageToken)
+ } else {
+ r3 = ret.Error(3)
+ }
+
+ return r0, r1, r2, r3
+}
+
// Name provides a mock function with given fields:
func (_m *LoopRelayAdapter) Name() string {
ret := _m.Called()
@@ -174,46 +167,20 @@ func (_m *LoopRelayAdapter) NewConfigProvider(_a0 context.Context, _a1 types.Rel
return r0, r1
}
-// NewFunctionsProvider provides a mock function with given fields: _a0, _a1, _a2
-func (_m *LoopRelayAdapter) NewFunctionsProvider(_a0 context.Context, _a1 types.RelayArgs, _a2 types.PluginArgs) (types.FunctionsProvider, error) {
- ret := _m.Called(_a0, _a1, _a2)
-
- var r0 types.FunctionsProvider
- var r1 error
- if rf, ok := ret.Get(0).(func(context.Context, types.RelayArgs, types.PluginArgs) (types.FunctionsProvider, error)); ok {
- return rf(_a0, _a1, _a2)
- }
- if rf, ok := ret.Get(0).(func(context.Context, types.RelayArgs, types.PluginArgs) types.FunctionsProvider); ok {
- r0 = rf(_a0, _a1, _a2)
- } else {
- if ret.Get(0) != nil {
- r0 = ret.Get(0).(types.FunctionsProvider)
- }
- }
-
- if rf, ok := ret.Get(1).(func(context.Context, types.RelayArgs, types.PluginArgs) error); ok {
- r1 = rf(_a0, _a1, _a2)
- } else {
- r1 = ret.Error(1)
- }
-
- return r0, r1
-}
-
-// NewMedianProvider provides a mock function with given fields: _a0, _a1, _a2
-func (_m *LoopRelayAdapter) NewMedianProvider(_a0 context.Context, _a1 types.RelayArgs, _a2 types.PluginArgs) (types.MedianProvider, error) {
+// NewPluginProvider provides a mock function with given fields: _a0, _a1, _a2
+func (_m *LoopRelayAdapter) NewPluginProvider(_a0 context.Context, _a1 types.RelayArgs, _a2 types.PluginArgs) (types.PluginProvider, error) {
ret := _m.Called(_a0, _a1, _a2)
- var r0 types.MedianProvider
+ var r0 types.PluginProvider
var r1 error
- if rf, ok := ret.Get(0).(func(context.Context, types.RelayArgs, types.PluginArgs) (types.MedianProvider, error)); ok {
+ if rf, ok := ret.Get(0).(func(context.Context, types.RelayArgs, types.PluginArgs) (types.PluginProvider, error)); ok {
return rf(_a0, _a1, _a2)
}
- if rf, ok := ret.Get(0).(func(context.Context, types.RelayArgs, types.PluginArgs) types.MedianProvider); ok {
+ if rf, ok := ret.Get(0).(func(context.Context, types.RelayArgs, types.PluginArgs) types.PluginProvider); ok {
r0 = rf(_a0, _a1, _a2)
} else {
if ret.Get(0) != nil {
- r0 = ret.Get(0).(types.MedianProvider)
+ r0 = ret.Get(0).(types.PluginProvider)
}
}
@@ -226,72 +193,6 @@ func (_m *LoopRelayAdapter) NewMedianProvider(_a0 context.Context, _a1 types.Rel
return r0, r1
}
-// NewMercuryProvider provides a mock function with given fields: _a0, _a1, _a2
-func (_m *LoopRelayAdapter) NewMercuryProvider(_a0 context.Context, _a1 types.RelayArgs, _a2 types.PluginArgs) (types.MercuryProvider, error) {
- ret := _m.Called(_a0, _a1, _a2)
-
- var r0 types.MercuryProvider
- var r1 error
- if rf, ok := ret.Get(0).(func(context.Context, types.RelayArgs, types.PluginArgs) (types.MercuryProvider, error)); ok {
- return rf(_a0, _a1, _a2)
- }
- if rf, ok := ret.Get(0).(func(context.Context, types.RelayArgs, types.PluginArgs) types.MercuryProvider); ok {
- r0 = rf(_a0, _a1, _a2)
- } else {
- if ret.Get(0) != nil {
- r0 = ret.Get(0).(types.MercuryProvider)
- }
- }
-
- if rf, ok := ret.Get(1).(func(context.Context, types.RelayArgs, types.PluginArgs) error); ok {
- r1 = rf(_a0, _a1, _a2)
- } else {
- r1 = ret.Error(1)
- }
-
- return r0, r1
-}
-
-// NodeStatuses provides a mock function with given fields: ctx, offset, limit, chainIDs
-func (_m *LoopRelayAdapter) NodeStatuses(ctx context.Context, offset int, limit int, chainIDs ...string) ([]types.NodeStatus, int, error) {
- _va := make([]interface{}, len(chainIDs))
- for _i := range chainIDs {
- _va[_i] = chainIDs[_i]
- }
- var _ca []interface{}
- _ca = append(_ca, ctx, offset, limit)
- _ca = append(_ca, _va...)
- ret := _m.Called(_ca...)
-
- var r0 []types.NodeStatus
- var r1 int
- var r2 error
- if rf, ok := ret.Get(0).(func(context.Context, int, int, ...string) ([]types.NodeStatus, int, error)); ok {
- return rf(ctx, offset, limit, chainIDs...)
- }
- if rf, ok := ret.Get(0).(func(context.Context, int, int, ...string) []types.NodeStatus); ok {
- r0 = rf(ctx, offset, limit, chainIDs...)
- } else {
- if ret.Get(0) != nil {
- r0 = ret.Get(0).([]types.NodeStatus)
- }
- }
-
- if rf, ok := ret.Get(1).(func(context.Context, int, int, ...string) int); ok {
- r1 = rf(ctx, offset, limit, chainIDs...)
- } else {
- r1 = ret.Get(1).(int)
- }
-
- if rf, ok := ret.Get(2).(func(context.Context, int, int, ...string) error); ok {
- r2 = rf(ctx, offset, limit, chainIDs...)
- } else {
- r2 = ret.Error(2)
- }
-
- return r0, r1, r2
-}
-
// Ready provides a mock function with given fields:
func (_m *LoopRelayAdapter) Ready() error {
ret := _m.Called()
@@ -306,13 +207,13 @@ func (_m *LoopRelayAdapter) Ready() error {
return r0
}
-// SendTx provides a mock function with given fields: ctx, chainID, from, to, amount, balanceCheck
-func (_m *LoopRelayAdapter) SendTx(ctx context.Context, chainID string, from string, to string, amount *big.Int, balanceCheck bool) error {
- ret := _m.Called(ctx, chainID, from, to, amount, balanceCheck)
+// Start provides a mock function with given fields: _a0
+func (_m *LoopRelayAdapter) Start(_a0 context.Context) error {
+ ret := _m.Called(_a0)
var r0 error
- if rf, ok := ret.Get(0).(func(context.Context, string, string, string, *big.Int, bool) error); ok {
- r0 = rf(ctx, chainID, from, to, amount, balanceCheck)
+ if rf, ok := ret.Get(0).(func(context.Context) error); ok {
+ r0 = rf(_a0)
} else {
r0 = ret.Error(0)
}
@@ -320,13 +221,13 @@ func (_m *LoopRelayAdapter) SendTx(ctx context.Context, chainID string, from str
return r0
}
-// Start provides a mock function with given fields: _a0
-func (_m *LoopRelayAdapter) Start(_a0 context.Context) error {
- ret := _m.Called(_a0)
+// Transact provides a mock function with given fields: ctx, from, to, amount, balanceCheck
+func (_m *LoopRelayAdapter) Transact(ctx context.Context, from string, to string, amount *big.Int, balanceCheck bool) error {
+ ret := _m.Called(ctx, from, to, amount, balanceCheck)
var r0 error
- if rf, ok := ret.Get(0).(func(context.Context) error); ok {
- r0 = rf(_a0)
+ if rf, ok := ret.Get(0).(func(context.Context, string, string, *big.Int, bool) error); ok {
+ r0 = rf(ctx, from, to, amount, balanceCheck)
} else {
r0 = ret.Error(0)
}
diff --git a/core/services/relay/evm/ocr2keeper.go b/core/services/relay/evm/ocr2keeper.go
index c6f4f1ad395..baf98b9b006 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 6e440112e92..14004d0b1aa 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 cab804e5883..ce638d10cf9 100644
--- a/core/services/relay/evm/relayer_extender.go
+++ b/core/services/relay/evm/relayer_extender.go
@@ -4,49 +4,24 @@ import (
"context"
"fmt"
"math/big"
- "sync"
"github.com/pkg/errors"
"go.uber.org/multierr"
- "golang.org/x/exp/maps"
relaytypes "github.com/smartcontractkit/chainlink-relay/pkg/types"
- "github.com/smartcontractkit/chainlink/v2/core/chains"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm"
evmchain "github.com/smartcontractkit/chainlink/v2/core/chains/evm"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/toml"
- evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types"
- "github.com/smartcontractkit/chainlink/v2/core/logger"
- "github.com/smartcontractkit/chainlink/v2/core/services"
"github.com/smartcontractkit/chainlink/v2/core/services/relay"
)
// ErrNoChains indicates that no EVM chains have been started
var ErrNoChains = errors.New("no EVM chains loaded")
-var _ legacyChainSet = &chainSet{}
-
-type legacyChainSet interface {
- services.ServiceCtx
- chains.ChainStatuser
- chains.NodesStatuser
-
- Get(id *big.Int) (evmchain.Chain, error)
-
- Default() (evmchain.Chain, error)
- Chains() []evmchain.Chain
- ChainCount() int
-
- Configs() evmtypes.Configs
-
- SendTx(ctx context.Context, chainID, from, to string, amount *big.Int, balanceCheck bool) error
-}
-
type EVMChainRelayerExtender interface {
relay.RelayerExt
Chain() evmchain.Chain
- Default() bool
}
type EVMChainRelayerExtenderSlicer interface {
@@ -62,24 +37,12 @@ type ChainRelayerExtenders struct {
var _ EVMChainRelayerExtenderSlicer = &ChainRelayerExtenders{}
-func NewLegacyChainsFromRelayerExtenders(exts EVMChainRelayerExtenderSlicer) (*evmchain.LegacyChains, error) {
-
+func NewLegacyChainsFromRelayerExtenders(exts EVMChainRelayerExtenderSlicer) *evmchain.LegacyChains {
m := make(map[string]evmchain.Chain)
- var dflt evmchain.Chain
for _, r := range exts.Slice() {
m[r.Chain().ID().String()] = r.Chain()
- if r.Default() {
- dflt = r.Chain()
- }
- }
- l, err := evmchain.NewLegacyChains(exts.AppConfig(), m)
- if err != nil {
- return nil, err
}
- if dflt != nil {
- l.SetDefault(dflt)
- }
- return l, nil
+ return evmchain.NewLegacyChains(m, exts.AppConfig().EVMConfigs())
}
func newChainRelayerExtsFromSlice(exts []*ChainRelayerExt, appConfig evm.AppConfig) *ChainRelayerExtenders {
@@ -108,330 +71,95 @@ func (c *ChainRelayerExtenders) Len() int {
// implements OneChain
type ChainRelayerExt struct {
chain evmchain.Chain
- // TODO remove this altogether. BFC-2440
- cs *chainSet
- isDefault bool
}
var _ EVMChainRelayerExtender = &ChainRelayerExt{}
-func (s *ChainRelayerExt) Chain() evmchain.Chain {
- return s.chain
-}
-
-func (s *ChainRelayerExt) Default() bool {
- return s.isDefault
-}
-
-var ErrCorruptEVMChain = errors.New("corrupt evm chain")
-
-func (s *ChainRelayerExt) Start(ctx context.Context) error {
- if len(s.cs.chains) > 1 {
- err := fmt.Errorf("%w: internal error more than one chain (%d)", ErrCorruptEVMChain, len(s.cs.chains))
- panic(err)
- }
- return s.cs.Start(ctx)
-}
-
-func (s *ChainRelayerExt) Close() (err error) {
- return s.cs.Close()
-}
-
-func (s *ChainRelayerExt) Name() string {
- // we set each private chainSet logger to contain the chain id
- return s.cs.Name()
-}
-
-func (s *ChainRelayerExt) HealthReport() map[string]error {
- return s.cs.HealthReport()
-}
-
-func (s *ChainRelayerExt) Ready() (err error) {
- return s.cs.Ready()
+func (s *ChainRelayerExt) GetChainStatus(ctx context.Context) (relaytypes.ChainStatus, error) {
+ return s.chain.GetChainStatus(ctx)
}
-var ErrInconsistentChainRelayerExtender = errors.New("inconsistent evm chain relayer extender")
-
-func (s *ChainRelayerExt) ChainStatus(ctx context.Context, id string) (relaytypes.ChainStatus, error) {
- // TODO BCF-2441: update relayer interface
- // we need to implement the interface, but passing id doesn't really make sense because there is only
- // one chain here. check the id here to provide clear error reporting.
- if s.chain.ID().String() != id {
- return relaytypes.ChainStatus{}, fmt.Errorf("%w: given id %q does not match expected id %q", ErrInconsistentChainRelayerExtender, id, s.chain.ID())
- }
- return s.cs.ChainStatus(ctx, id)
+func (s *ChainRelayerExt) ListNodeStatuses(ctx context.Context, pageSize int32, pageToken string) (stats []relaytypes.NodeStatus, nextPageToken string, total int, err error) {
+ return s.chain.ListNodeStatuses(ctx, pageSize, pageToken)
}
-func (s *ChainRelayerExt) ChainStatuses(ctx context.Context, offset, limit int) ([]relaytypes.ChainStatus, int, error) {
- stat, err := s.cs.ChainStatus(ctx, s.chain.ID().String())
- if err != nil {
- return nil, -1, err
- }
- return []relaytypes.ChainStatus{stat}, 1, nil
-
+func (s *ChainRelayerExt) Transact(ctx context.Context, from, to string, amount *big.Int, balanceCheck bool) error {
+ return s.chain.Transact(ctx, from, to, amount, balanceCheck)
}
-func (s *ChainRelayerExt) NodeStatuses(ctx context.Context, offset, limit int, chainIDs ...string) (nodes []relaytypes.NodeStatus, count int, err error) {
- if len(chainIDs) > 1 {
- return nil, -1, fmt.Errorf("single chain chain set only support one chain id. got %v", chainIDs)
- }
- cid := chainIDs[0]
- if cid != s.chain.ID().String() {
- return nil, -1, fmt.Errorf("unknown chain id %s. expected %s", cid, s.chain.ID())
- }
- return s.cs.NodeStatuses(ctx, offset, limit, chainIDs...)
+func (s *ChainRelayerExt) ID() string {
+ return s.chain.ID().String()
}
-func (s *ChainRelayerExt) SendTx(ctx context.Context, chainID, from, to string, amount *big.Int, balanceCheck bool) error {
- return s.cs.SendTx(ctx, chainID, from, to, amount, balanceCheck)
-}
-
-type chainSet struct {
- defaultID *big.Int
- chains map[string]evmchain.Chain
- startedChains []evmchain.Chain
- chainsMu sync.RWMutex
- logger logger.Logger
- opts evmchain.ChainRelayExtenderConfig
-}
-
-func (cll *chainSet) Start(ctx context.Context) error {
- if !cll.opts.AppConfig.EVMEnabled() {
- cll.logger.Warn("EVM is disabled, no EVM-based chains will be started")
- return nil
- }
- if !cll.opts.AppConfig.EVMRPCEnabled() {
- cll.logger.Warn("EVM RPC connections are disabled. Chainlink will not connect to any EVM RPC node.")
- }
- var ms services.MultiStart
- for _, c := range cll.Chains() {
- if err := ms.Start(ctx, c); err != nil {
- return errors.Wrapf(err, "failed to start chain %q", c.ID().String())
- }
- cll.startedChains = append(cll.startedChains, c)
- }
- evmChainIDs := make([]*big.Int, len(cll.startedChains))
- for i, c := range cll.startedChains {
- evmChainIDs[i] = c.ID()
- }
- defChainID := "unspecified"
- if cll.defaultID != nil {
- defChainID = fmt.Sprintf("%q", cll.defaultID.String())
- }
- cll.logger.Infow(fmt.Sprintf("EVM: Started %d/%d chains, default chain ID is %s", len(cll.startedChains), len(cll.Chains()), defChainID), "startedEvmChainIDs", evmChainIDs)
- return nil
-}
-
-func (cll *chainSet) Close() (err error) {
- cll.logger.Debug("EVM: stopping")
- for _, c := range cll.startedChains {
- err = multierr.Combine(err, c.Close())
- }
- return
-}
-
-func (cll *chainSet) Name() string {
- return cll.logger.Name()
-}
-
-func (cll *chainSet) HealthReport() map[string]error {
- report := map[string]error{}
- for _, c := range cll.Chains() {
- maps.Copy(report, c.HealthReport())
- }
- return report
-}
-
-func (cll *chainSet) Ready() (err error) {
- for _, c := range cll.Chains() {
- err = multierr.Combine(err, c.Ready())
- }
- return
-}
-
-func (cll *chainSet) Get(id *big.Int) (evmchain.Chain, error) {
- if id == nil {
- if cll.defaultID == nil {
- cll.logger.Debug("Chain ID not specified, and default is nil")
- return nil, errors.New("chain ID not specified, and default is nil")
- }
- cll.logger.Debugf("Chain ID not specified, using default: %s", cll.defaultID.String())
- return cll.Default()
- }
- return cll.get(id.String())
-}
-
-func (cll *chainSet) get(id string) (evmchain.Chain, error) {
- cll.chainsMu.RLock()
- defer cll.chainsMu.RUnlock()
- c, exists := cll.chains[id]
- if exists {
- return c, nil
- }
- return nil, errors.Wrap(chains.ErrNotFound, fmt.Sprintf("failed to get chain with id %s", id))
-}
-
-func (cll *chainSet) ChainStatus(ctx context.Context, id string) (cfg relaytypes.ChainStatus, err error) {
- var cs []relaytypes.ChainStatus
- cs, _, err = cll.opts.EVMConfigs().Chains(0, -1, id)
- if err != nil {
- return
- }
- l := len(cs)
- if l == 0 {
- err = fmt.Errorf("chain %s: %w", id, chains.ErrNotFound)
- return
- }
- if l > 1 {
- err = fmt.Errorf("multiple chains found: %d", len(cs))
- return
- }
- cfg = cs[0]
- return
-}
-
-func (cll *chainSet) ChainStatuses(ctx context.Context, offset, limit int) ([]relaytypes.ChainStatus, int, error) {
- return cll.opts.EVMConfigs().Chains(offset, limit)
-}
-
-func (cll *chainSet) Default() (evmchain.Chain, error) {
- cll.chainsMu.RLock()
- length := len(cll.chains)
- cll.chainsMu.RUnlock()
- if length == 0 {
- return nil, errors.Wrap(ErrNoChains, "cannot get default EVM chain; no EVM chains are available")
- }
- if cll.defaultID == nil {
- // This is an invariant violation; if any chains are available then a
- // default should _always_ have been set in the constructor
- return nil, errors.New("no default chain ID specified")
- }
-
- return cll.Get(cll.defaultID)
+func (s *ChainRelayerExt) Chain() evmchain.Chain {
+ return s.chain
}
-func (cll *chainSet) Chains() (c []evmchain.Chain) {
- cll.chainsMu.RLock()
- defer cll.chainsMu.RUnlock()
- for _, chain := range cll.chains {
- c = append(c, chain)
- }
- return c
-}
+var ErrCorruptEVMChain = errors.New("corrupt evm chain")
-func (cll *chainSet) ChainCount() int {
- cll.chainsMu.RLock()
- defer cll.chainsMu.RUnlock()
- return len(cll.chains)
+func (s *ChainRelayerExt) Start(ctx context.Context) error {
+ return s.chain.Start(ctx)
}
-func (cll *chainSet) Configs() evmtypes.Configs {
- return cll.opts.EVMConfigs()
+func (s *ChainRelayerExt) Close() (err error) {
+ return s.chain.Close()
}
-func (cll *chainSet) NodeStatuses(ctx context.Context, offset, limit int, chainIDs ...string) (nodes []relaytypes.NodeStatus, count int, err error) {
- nodes, count, err = cll.opts.EVMConfigs().NodeStatusesPaged(offset, limit, chainIDs...)
- if err != nil {
- err = errors.Wrap(err, "GetNodesForChain failed to load nodes from DB")
- return
- }
- for i := range nodes {
- cll.addStateToNode(&nodes[i])
- }
- return
+func (s *ChainRelayerExt) Name() string {
+ return s.chain.Name()
}
-func (cll *chainSet) addStateToNode(n *relaytypes.NodeStatus) {
- cll.chainsMu.RLock()
- chain, exists := cll.chains[n.ChainID]
- cll.chainsMu.RUnlock()
- if !exists {
- // The EVM chain is disabled
- n.State = "Disabled"
- return
- }
- states := chain.Client().NodeStates()
- if states == nil {
- n.State = "Unknown"
- return
- }
- state, exists := states[n.Name]
- if exists {
- n.State = state
- return
- }
- // The node is in the DB and the chain is enabled but it's not running
- n.State = "NotLoaded"
+func (s *ChainRelayerExt) HealthReport() map[string]error {
+ return s.chain.HealthReport()
}
-func (cll *chainSet) SendTx(ctx context.Context, chainID, from, to string, amount *big.Int, balanceCheck bool) error {
- chain, err := cll.get(chainID)
- if err != nil {
- return err
- }
-
- return chain.SendTx(ctx, from, to, amount, balanceCheck)
+func (s *ChainRelayerExt) Ready() (err error) {
+ return s.chain.Ready()
}
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
}
+
+ unique := make(map[string]struct{})
+
evmConfigs := opts.AppConfig.EVMConfigs()
var enabled []*toml.EVMConfig
- for i := range evmConfigs {
+ for i, cfg := range evmConfigs {
+ _, alreadyExists := unique[cfg.ChainID.String()]
+ if alreadyExists {
+ return nil, fmt.Errorf("duplicate chain definition for evm chain id %s", cfg.ChainID.String())
+ }
+ unique[cfg.ChainID.String()] = struct{}{}
if evmConfigs[i].IsEnabled() {
enabled = append(enabled, evmConfigs[i])
}
}
- defaultChainID := opts.AppConfig.DefaultChainID()
- if defaultChainID == nil && len(enabled) >= 1 {
- defaultChainID = enabled[0].ChainID.ToInt()
- if len(enabled) > 1 {
- opts.Logger.Debugf("Multiple chains present, default chain: %s", defaultChainID.String())
- }
- }
-
var result []*ChainRelayerExt
var err error
for i := range enabled {
cid := enabled[i].ChainID.String()
privOpts := evmchain.ChainRelayExtenderConfig{
- Logger: opts.Logger.Named(cid),
- RelayerConfig: opts.RelayerConfig,
- DB: opts.DB,
- KeyStore: opts.KeyStore,
+ Logger: opts.Logger.Named(cid),
+ ChainOpts: opts.ChainOpts,
+ KeyStore: opts.KeyStore,
}
- cll := newChainSet(privOpts)
- cll.logger.Infow(fmt.Sprintf("Loading chain %s", cid), "evmChainID", cid)
+ 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
}
- if _, exists := cll.chains[cid]; exists {
- return nil, errors.Errorf("duplicate chain with ID %s", cid)
- }
- cll.chains[cid] = chain
s := &ChainRelayerExt{
- chain: chain,
- cs: cll,
- isDefault: (cid == defaultChainID.String()),
+ chain: chain,
}
result = append(result, s)
}
- return newChainRelayerExtsFromSlice(result, opts.AppConfig), nil
-}
-
-func newChainSet(opts evmchain.ChainRelayExtenderConfig) *chainSet {
- return &chainSet{
- chains: make(map[string]evmchain.Chain),
- startedChains: make([]evmchain.Chain, 0),
- logger: opts.Logger.Named("ChainSet"),
- opts: opts,
- }
+ // always return because it's accumulating errors
+ return newChainRelayerExtsFromSlice(result, opts.AppConfig), err
}
diff --git a/core/services/relay/evm/relayer_extender_test.go b/core/services/relay/evm/relayer_extender_test.go
index d4cbb1368c2..361a7468f30 100644
--- a/core/services/relay/evm/relayer_extender_test.go
+++ b/core/services/relay/evm/relayer_extender_test.go
@@ -62,28 +62,8 @@ func TestChainRelayExtenders(t *testing.T) {
// test extender methods on single instance
relayExt := relayExtendersInstances[0]
- s, err := relayExt.ChainStatus(testutils.Context(t), "not a chain")
- assert.Error(t, err)
- assert.Empty(t, s)
- // the 0-th extender corresponds to the test fixture default chain
- s, err = relayExt.ChainStatus(testutils.Context(t), cltest.FixtureChainID.String())
+ s, err := relayExt.GetChainStatus(testutils.Context(t))
assert.NotEmpty(t, s)
assert.NoError(t, err)
- stats, cnt, err := relayExt.ChainStatuses(testutils.Context(t), 0, 0)
- assert.NoError(t, err)
- assert.Len(t, stats, 1)
- assert.Equal(t, 1, cnt)
-
- // test error conditions for NodeStatuses
- nstats, cnt, err := relayExt.NodeStatuses(testutils.Context(t), 0, 0, cltest.FixtureChainID.String(), "error, only one chain supported")
- assert.Error(t, err)
- assert.Nil(t, nstats)
- assert.Equal(t, -1, cnt)
-
- nstats, cnt, err = relayExt.NodeStatuses(testutils.Context(t), 0, 0, "not the chain id")
- assert.Error(t, err)
- assert.Nil(t, nstats)
- assert.Equal(t, -1, cnt)
-
}
diff --git a/core/services/relay/evm/types/types.go b/core/services/relay/evm/types/types.go
index 8671082db25..97eddd7d9cf 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 c6d3ab6a900..75ced101b3f 100644
--- a/core/services/relay/relay.go
+++ b/core/services/relay/relay.go
@@ -4,9 +4,7 @@ import (
"context"
"errors"
"fmt"
- "math/big"
"regexp"
- "strconv"
"golang.org/x/exp/maps"
@@ -15,7 +13,8 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/services"
)
-type Network string
+type Network = string
+type ChainID = string
var (
EVM Network = "evm"
@@ -37,29 +36,14 @@ type ID struct {
}
func (i *ID) Name() string {
- return fmt.Sprintf("%s.%s", i.Network, i.ChainID.String())
+ return fmt.Sprintf("%s.%s", i.Network, i.ChainID)
}
func (i *ID) String() string {
return i.Name()
}
-func NewID(n Network, c ChainID) (ID, error) {
- id := ID{Network: n, ChainID: c}
- err := id.validate()
- if err != nil {
- return ID{}, err
- }
- return id, nil
-}
-func (i *ID) validate() error {
- // the only validation is to ensure that EVM chain ids are compatible with int64
- if i.Network == EVM {
- _, err := i.ChainID.Int64()
- if err != nil {
- return fmt.Errorf("RelayIdentifier invalid: EVM relayer must have integer-compatible chain ID: %w", err)
- }
- }
- return nil
+func NewID(n Network, c ChainID) ID {
+ return ID{Network: n, ChainID: c}
}
var idRegex = regexp.MustCompile(
@@ -89,29 +73,10 @@ func (i *ID) UnmarshalString(s string) error {
return nil
}
-type ChainID string
-
-func (c ChainID) String() string {
- return string(c)
-}
-func (c ChainID) Int64() (int64, error) {
- i, err := strconv.Atoi(c.String())
- if err != nil {
- return int64(0), err
- }
- return int64(i), nil
-}
-
-// RelayerExt is a subset of [loop.Relayer] for adapting [types.Relayer], typically with a ChainSet. See [relayerAdapter].
+// RelayerExt is a subset of [loop.Relayer] for adapting [types.Relayer], typically with a Chain. See [relayerAdapter].
type RelayerExt interface {
- services.ServiceCtx
-
- ChainStatus(ctx context.Context, id string) (types.ChainStatus, error)
- ChainStatuses(ctx context.Context, offset, limit int) ([]types.ChainStatus, int, error)
-
- NodeStatuses(ctx context.Context, offset, limit int, chainIDs ...string) (nodes []types.NodeStatus, count int, err error)
-
- SendTx(ctx context.Context, chainID, from, to string, amount *big.Int, balanceCheck bool) error
+ types.ChainService
+ ID() string
}
var _ loop.Relayer = (*relayerAdapter)(nil)
@@ -123,6 +88,8 @@ type relayerAdapter struct {
}
// NewRelayerAdapter returns a [loop.Relayer] adapted from a [types.Relayer] and [RelayerExt].
+// Unlike NewRelayerServerAdapter which is used to adapt non-LOOPP relayers, this is used to adapt
+// LOOPP-based relayer which are then server over GRPC (by the relayerServer).
func NewRelayerAdapter(r types.Relayer, e RelayerExt) loop.Relayer {
return &relayerAdapter{Relayer: r, RelayerExt: e}
}
@@ -143,6 +110,10 @@ func (r *relayerAdapter) NewFunctionsProvider(ctx context.Context, rargs types.R
return r.Relayer.NewFunctionsProvider(rargs, pargs)
}
+func (r *relayerAdapter) NewPluginProvider(ctx context.Context, rargs types.RelayArgs, pargs types.PluginArgs) (types.PluginProvider, error) {
+ return nil, fmt.Errorf("unexpected call to NewPluginProvider: did you forget to wrap relayerAdapter in a relayerServerAdapter?")
+}
+
func (r *relayerAdapter) Start(ctx context.Context) error {
var ms services.MultiStart
return ms.Start(ctx, r.RelayerExt, r.Relayer)
@@ -162,7 +133,60 @@ 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
}
+
+func (r *relayerAdapter) NodeStatuses(ctx context.Context, offset, limit int, chainIDs ...string) (nodes []types.NodeStatus, total int, err error) {
+ if len(chainIDs) > 1 {
+ return nil, 0, fmt.Errorf("internal error: node statuses expects at most one chain id got %v", chainIDs)
+ }
+ if len(chainIDs) == 1 && chainIDs[0] != r.ID() {
+ return nil, 0, fmt.Errorf("node statuses unexpected chain id got %s want %s", chainIDs[0], r.ID())
+ }
+
+ nodes, _, total, err = r.ListNodeStatuses(ctx, int32(limit), "")
+ if err != nil {
+ return nil, 0, err
+ }
+ if len(nodes) < offset {
+ return []types.NodeStatus{}, 0, fmt.Errorf("out of range")
+ }
+ if limit <= 0 {
+ limit = len(nodes)
+ } else if len(nodes) < limit {
+ limit = len(nodes)
+ }
+ return nodes[offset:limit], total, nil
+}
+
+type relayerServerAdapter struct {
+ *relayerAdapter
+}
+
+func (r *relayerServerAdapter) NewPluginProvider(ctx context.Context, rargs types.RelayArgs, pargs types.PluginArgs) (types.PluginProvider, error) {
+ switch types.OCR2PluginType(rargs.ProviderType) {
+ case types.Median:
+ return r.NewMedianProvider(ctx, rargs, pargs)
+ case types.Functions:
+ return r.NewFunctionsProvider(ctx, rargs, pargs)
+ case types.Mercury:
+ return r.NewMercuryProvider(ctx, rargs, pargs)
+ case types.DKG, types.OCR2VRF, types.OCR2Keeper, types.GenericPlugin:
+ return r.relayerAdapter.NewPluginProvider(ctx, rargs, pargs)
+ }
+
+ return nil, fmt.Errorf("provider type not supported: %s", rargs.ProviderType)
+}
+
+// NewRelayerServerAdapter returns a [loop.Relayer] adapted from a [types.Relayer] and [RelayerExt].
+// Unlike NewRelayerAdapter, this behaves like the loop `RelayerServer` and dispatches calls
+// to `NewPluginProvider` according to the passed in `RelayArgs.ProviderType`.
+// This should only be used to adapt relayers not running via GRPC in a LOOPP.
+//
+// nolint:staticcheck // SA1019
+func NewRelayerServerAdapter(r types.Relayer, e RelayerExt) loop.Relayer {
+ ra := &relayerAdapter{Relayer: r, RelayerExt: e}
+ return &relayerServerAdapter{relayerAdapter: ra}
+}
diff --git a/core/services/relay/relay_test.go b/core/services/relay/relay_test.go
index 0ed14b6c5b7..28ee0172c20 100644
--- a/core/services/relay/relay_test.go
+++ b/core/services/relay/relay_test.go
@@ -1,9 +1,12 @@
package relay
import (
+ "context"
"testing"
"github.com/stretchr/testify/assert"
+
+ "github.com/smartcontractkit/chainlink-relay/pkg/types"
)
func TestIdentifier_UnmarshalString(t *testing.T) {
@@ -48,34 +51,91 @@ func TestIdentifier_UnmarshalString(t *testing.T) {
}
func TestNewID(t *testing.T) {
- type args struct {
- n Network
- c ChainID
- }
- tests := []struct {
- name string
- args args
- want ID
- wantErr bool
+ rid := NewID(EVM, "chain id")
+ assert.Equal(t, EVM, rid.Network)
+ assert.Equal(t, "chain id", rid.ChainID)
+}
+
+type staticMedianProvider struct {
+ types.MedianProvider
+}
+
+type staticFunctionsProvider struct {
+ types.FunctionsProvider
+}
+
+type staticMercuryProvider struct {
+ types.MercuryProvider
+}
+
+type mockRelayer struct {
+ types.Relayer
+}
+
+func (m *mockRelayer) NewMedianProvider(rargs types.RelayArgs, pargs types.PluginArgs) (types.MedianProvider, error) {
+ return staticMedianProvider{}, nil
+}
+
+func (m *mockRelayer) NewFunctionsProvider(rargs types.RelayArgs, pargs types.PluginArgs) (types.FunctionsProvider, error) {
+ return staticFunctionsProvider{}, nil
+}
+
+func (m *mockRelayer) NewMercuryProvider(rargs types.RelayArgs, pargs types.PluginArgs) (types.MercuryProvider, error) {
+ return staticMercuryProvider{}, nil
+}
+
+type mockRelayerExt struct {
+ RelayerExt
+}
+
+func isType[T any](p any) bool {
+ _, ok := p.(T)
+ return ok
+}
+
+func TestRelayerServerAdapter(t *testing.T) {
+ r := &mockRelayer{}
+ sa := NewRelayerServerAdapter(r, mockRelayerExt{})
+
+ testCases := []struct {
+ ProviderType string
+ Test func(p any) bool
+ Error string
}{
- {name: "good evm",
- args: args{n: EVM, c: "1"},
- want: ID{Network: EVM, ChainID: "1"},
+ {
+ ProviderType: string(types.Median),
+ Test: isType[types.MedianProvider],
},
- {name: "bad evm",
- args: args{n: EVM, c: "not a number"},
- want: ID{},
- wantErr: true,
+ {
+ ProviderType: string(types.Functions),
+ Test: isType[types.FunctionsProvider],
+ },
+ {
+ ProviderType: string(types.Mercury),
+ Test: isType[types.MercuryProvider],
+ },
+ {
+ ProviderType: "unknown",
+ Error: "provider type not supported",
+ },
+ {
+ ProviderType: string(types.GenericPlugin),
+ Error: "unexpected call to NewPluginProvider",
},
}
- for _, tt := range tests {
- t.Run(tt.name, func(t *testing.T) {
- got, err := NewID(tt.args.n, tt.args.c)
- if (err != nil) != tt.wantErr {
- t.Errorf("NewID() error = %v, wantErr %v", err, tt.wantErr)
- return
- }
- assert.Equal(t, tt.want, got, "got id %v", got)
- })
+
+ for _, tc := range testCases {
+ pp, err := sa.NewPluginProvider(
+ context.Background(),
+ types.RelayArgs{ProviderType: tc.ProviderType},
+ types.PluginArgs{},
+ )
+
+ if tc.Error != "" {
+ assert.ErrorContains(t, err, tc.Error)
+ } else {
+ assert.NoError(t, err)
+ assert.True(t, tc.Test(pp))
+ }
}
}
diff --git a/core/services/s4/address_range.go b/core/services/s4/address_range.go
index bd818798faa..679bb3b846a 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 e276b45b575..bbd4d3baa54 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/envelope.go b/core/services/s4/envelope.go
index 07e4201341c..5c917e7ebda 100644
--- a/core/services/s4/envelope.go
+++ b/core/services/s4/envelope.go
@@ -6,6 +6,7 @@ import (
"fmt"
"github.com/ethereum/go-ethereum/common"
+
"github.com/smartcontractkit/chainlink/v2/core/utils"
)
@@ -62,7 +63,12 @@ func (e Envelope) ToJson() ([]byte, error) {
if err != nil {
return nil, err
}
- payload, err := json.Marshal(e.Payload)
+ nonNilPayload := e.Payload
+ if nonNilPayload == nil {
+ // prevent unwanted "null" values in JSON representation
+ nonNilPayload = []byte{}
+ }
+ payload, err := json.Marshal(nonNilPayload)
if err != nil {
return nil, err
}
diff --git a/core/services/s4/errors.go b/core/services/s4/errors.go
index 408903254bb..aa447f88f39 100644
--- a/core/services/s4/errors.go
+++ b/core/services/s4/errors.go
@@ -3,10 +3,11 @@ package s4
import "errors"
var (
- ErrNotFound = errors.New("not found")
- ErrWrongSignature = errors.New("wrong signature")
- ErrSlotIdTooBig = errors.New("slot id is too big")
- ErrPayloadTooBig = errors.New("payload is too big")
- ErrPastExpiration = errors.New("past expiration")
- ErrVersionTooLow = errors.New("version too low")
+ ErrNotFound = errors.New("not found")
+ ErrWrongSignature = errors.New("wrong signature")
+ ErrSlotIdTooBig = errors.New("slot id is too big")
+ ErrPayloadTooBig = errors.New("payload is too big")
+ ErrPastExpiration = errors.New("past expiration")
+ ErrVersionTooLow = errors.New("version too low")
+ ErrExpirationTooLong = errors.New("expiration too long")
)
diff --git a/core/services/s4/postgres_orm.go b/core/services/s4/postgres_orm.go
index e562273d33a..d0a79dba959 100644
--- a/core/services/s4/postgres_orm.go
+++ b/core/services/s4/postgres_orm.go
@@ -71,7 +71,7 @@ RETURNING id;`, o.tableName)
if errors.Is(err, sql.ErrNoRows) {
return ErrVersionTooLow
}
- return nil
+ return err
}
func (o orm) DeleteExpired(limit uint, utcNow time.Time, qopts ...pg.QOpt) (int64, error) {
diff --git a/core/services/s4/postgres_orm_test.go b/core/services/s4/postgres_orm_test.go
index fdfa007f705..c233fe2361a 100644
--- a/core/services/s4/postgres_orm_test.go
+++ b/core/services/s4/postgres_orm_test.go
@@ -2,6 +2,7 @@ package s4_test
import (
"errors"
+ "math"
"testing"
"time"
@@ -257,3 +258,22 @@ func TestPostgresORM_Namespace(t *testing.T) {
assert.NoError(t, err)
assert.Len(t, snapshotA, n)
}
+
+func TestPostgresORM_BigIntVersion(t *testing.T) {
+ t.Parallel()
+
+ orm := setupORM(t, "test")
+ row := generateTestRows(t, 1)[0]
+ row.Version = math.MaxUint64 - 10
+
+ err := orm.Update(row)
+ assert.NoError(t, err)
+
+ row.Version++
+ err = orm.Update(row)
+ assert.NoError(t, err)
+
+ gotRow, err := orm.Get(row.Address, row.SlotId)
+ assert.NoError(t, err)
+ assert.Equal(t, row, gotRow)
+}
diff --git a/core/services/s4/storage.go b/core/services/s4/storage.go
index b987977cd57..65aa2f4bab5 100644
--- a/core/services/s4/storage.go
+++ b/core/services/s4/storage.go
@@ -12,8 +12,9 @@ import (
// Constraints specifies the global storage constraints.
type Constraints struct {
- MaxPayloadSizeBytes uint `json:"maxPayloadSizeBytes"`
- MaxSlotsPerUser uint `json:"maxSlotsPerUser"`
+ MaxPayloadSizeBytes uint `json:"maxPayloadSizeBytes"`
+ MaxSlotsPerUser uint `json:"maxSlotsPerUser"`
+ MaxExpirationLengthSec uint64 `json:"maxExpirationLengthSec"`
}
// Key identifies a versioned user record.
@@ -75,7 +76,7 @@ var _ Storage = (*storage)(nil)
func NewStorage(lggr logger.Logger, contraints Constraints, orm ORM, clock utils.Clock) Storage {
return &storage{
- lggr: lggr.Named("s4_storage"),
+ lggr: lggr.Named("S4Storage"),
contraints: contraints,
orm: orm,
clock: clock,
@@ -97,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
}
@@ -118,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 {
@@ -128,9 +133,13 @@ func (s *storage) Put(ctx context.Context, key *Key, record *Record, signature [
if len(record.Payload) > int(s.contraints.MaxPayloadSizeBytes) {
return ErrPayloadTooBig
}
- if s.clock.Now().UnixMilli() > record.Expiration {
+ now := s.clock.Now().UnixMilli()
+ if now > record.Expiration {
return ErrPastExpiration
}
+ if record.Expiration-now > int64(s.contraints.MaxExpirationLengthSec)*1000 {
+ return ErrExpirationTooLong
+ }
envelope := NewEnvelopeFromRecord(key, record)
signer, err := envelope.GetSignerAddress(signature)
diff --git a/core/services/s4/storage_test.go b/core/services/s4/storage_test.go
index 1a56e3d5710..11a8f6544ce 100644
--- a/core/services/s4/storage_test.go
+++ b/core/services/s4/storage_test.go
@@ -17,8 +17,9 @@ import (
var (
constraints = s4.Constraints{
- MaxSlotsPerUser: 5,
- MaxPayloadSizeBytes: 32,
+ MaxSlotsPerUser: 5,
+ MaxPayloadSizeBytes: 32,
+ MaxExpirationLengthSec: 3600,
}
)
@@ -100,6 +101,20 @@ func TestStorage_Errors(t *testing.T) {
assert.ErrorIs(t, err, s4.ErrPastExpiration)
})
+ t.Run("ErrExpirationTooLong", func(t *testing.T) {
+ key := &s4.Key{
+ Address: testutils.NewAddress(),
+ SlotId: 1,
+ Version: 0,
+ }
+ record := &s4.Record{
+ Payload: make([]byte, 10),
+ Expiration: now.UnixMilli() + 10000000,
+ }
+ err := storage.Put(testutils.Context(t), key, record, []byte{})
+ assert.ErrorIs(t, err, s4.ErrExpirationTooLong)
+ })
+
t.Run("ErrWrongSignature", func(t *testing.T) {
privateKey, address := testutils.NewPrivateKeyAndAddress(t)
key := &s4.Key{
@@ -202,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/service.go b/core/services/service.go
index b3c1bf36779..5bf61e062d2 100644
--- a/core/services/service.go
+++ b/core/services/service.go
@@ -81,8 +81,5 @@ type ServiceCtx interface {
// again, you need to build a new Service to do so.
Close() error
- // Name returns the fully qualified name of the service
- Name() string
-
Checkable
}
diff --git a/core/services/synchronization/explorer_client.go b/core/services/synchronization/explorer_client.go
deleted file mode 100644
index 4bdcc30b134..00000000000
--- a/core/services/synchronization/explorer_client.go
+++ /dev/null
@@ -1,410 +0,0 @@
-package synchronization
-
-import (
- "context"
- "errors"
- "fmt"
- "net/http"
- "net/url"
- "sync"
- "sync/atomic"
- "time"
-
- "github.com/smartcontractkit/chainlink/v2/core/logger"
- "github.com/smartcontractkit/chainlink/v2/core/services"
- "github.com/smartcontractkit/chainlink/v2/core/static"
- "github.com/smartcontractkit/chainlink/v2/core/utils"
-
- "github.com/gorilla/websocket"
-)
-
-var (
- // ErrReceiveTimeout is returned when no message is received after a
- // specified duration in Receive
- ErrReceiveTimeout = errors.New("timeout waiting for message")
-)
-
-type ConnectionStatus string
-
-const (
- // ConnectionStatusDisconnected is the default state
- ConnectionStatusDisconnected = ConnectionStatus("disconnected")
- // ConnectionStatusConnected is used when the client is successfully connected
- ConnectionStatusConnected = ConnectionStatus("connected")
- // ConnectionStatusError is used when there is an error
- ConnectionStatusError = ConnectionStatus("error")
-)
-
-// SendBufferSize is the number of messages to keep in the buffer before dropping additional ones
-const SendBufferSize = 100
-
-const (
- ExplorerTextMessage = websocket.TextMessage
- ExplorerBinaryMessage = websocket.BinaryMessage
-)
-
-//go:generate mockery --quiet --name ExplorerClient --output ./mocks --case=underscore
-
-// ExplorerClient encapsulates all the functionality needed to
-// push run information to explorer.
-type ExplorerClient interface {
- services.ServiceCtx
- Url() url.URL
- Status() ConnectionStatus
- Send(context.Context, []byte, ...int)
- Receive(context.Context, ...time.Duration) ([]byte, error)
-}
-
-type NoopExplorerClient struct{}
-
-func (NoopExplorerClient) HealthReport() map[string]error { return map[string]error{} }
-func (NoopExplorerClient) Name() string { return "NoopExplorerClient" }
-
-// Url always returns underlying url.
-func (NoopExplorerClient) Url() url.URL { return url.URL{} }
-
-// Status always returns ConnectionStatusDisconnected.
-func (NoopExplorerClient) Status() ConnectionStatus { return ConnectionStatusDisconnected }
-
-// Start is a no-op
-func (NoopExplorerClient) Start(context.Context) error { return nil }
-
-// Close is a no-op
-func (NoopExplorerClient) Close() error { return nil }
-
-// Ready is a no-op
-func (NoopExplorerClient) Ready() error { return nil }
-
-// Send is a no-op
-func (NoopExplorerClient) Send(context.Context, []byte, ...int) {}
-
-// Receive is a no-op
-func (NoopExplorerClient) Receive(context.Context, ...time.Duration) ([]byte, error) { return nil, nil }
-
-type explorerClient struct {
- utils.StartStopOnce
- conn *websocket.Conn
- sendText chan []byte
- sendBinary chan []byte
- dropMessageCount atomic.Uint32
- receive chan []byte
- sleeper utils.Sleeper
- status ConnectionStatus
- url *url.URL
- accessKey string
- secret string
- lggr logger.Logger
-
- chStop utils.StopChan
- wg sync.WaitGroup
- writePumpDone chan struct{}
-
- statusMtx sync.RWMutex
-}
-
-// NewExplorerClient returns a stats pusher using a websocket for
-// delivery.
-func NewExplorerClient(url *url.URL, accessKey, secret string, lggr logger.Logger) ExplorerClient {
- return &explorerClient{
- url: url,
- receive: make(chan []byte),
- sleeper: utils.NewBackoffSleeper(),
- status: ConnectionStatusDisconnected,
- accessKey: accessKey,
- secret: secret,
- lggr: lggr.Named("ExplorerClient"),
-
- sendText: make(chan []byte, SendBufferSize),
- sendBinary: make(chan []byte, SendBufferSize),
- }
-}
-
-// Url returns the URL the client was initialized with
-func (ec *explorerClient) Url() url.URL {
- return *ec.url
-}
-
-// Status returns the current connection status
-func (ec *explorerClient) Status() ConnectionStatus {
- ec.statusMtx.RLock()
- defer ec.statusMtx.RUnlock()
- return ec.status
-}
-
-// Start starts a write pump over a websocket.
-func (ec *explorerClient) Start(context.Context) error {
- return ec.StartOnce("Explorer client", func() error {
- ec.chStop = make(chan struct{})
- ec.wg.Add(1)
- go ec.connectAndWritePump()
- return nil
- })
-}
-
-func (ec *explorerClient) Name() string {
- return ec.lggr.Name()
-}
-
-func (ec *explorerClient) HealthReport() map[string]error {
- return map[string]error{
- ec.Name(): ec.StartStopOnce.Healthy(),
- }
-}
-
-// Send sends data asynchronously across the websocket if it's open, or
-// holds it in a small buffer until connection, throwing away messages
-// once buffer is full.
-// func (ec *explorerClient) Receive(durationParams ...time.Duration) ([]byte, error) {
-func (ec *explorerClient) Send(ctx context.Context, data []byte, messageTypes ...int) {
- messageType := ExplorerTextMessage
- if len(messageTypes) > 0 {
- messageType = messageTypes[0]
- }
- var send chan []byte
- switch messageType {
- case ExplorerTextMessage:
- send = ec.sendText
- case ExplorerBinaryMessage:
- send = ec.sendBinary
- default:
- err := fmt.Errorf("send on explorer client received unsupported message type %d", messageType)
- ec.SvcErrBuffer.Append(err)
- ec.lggr.Critical(err.Error())
- return
- }
- select {
- case send <- data:
- ec.dropMessageCount.Store(0)
- case <-ctx.Done():
- return
- default:
- ec.logBufferFullWithExpBackoff(data)
- }
-}
-
-// logBufferFullWithExpBackoff logs messages at
-// 1
-// 2
-// 4
-// 8
-// 16
-// 32
-// 64
-// 100
-// 200
-// 300
-// etc...
-func (ec *explorerClient) logBufferFullWithExpBackoff(data []byte) {
- count := ec.dropMessageCount.Add(1)
- if count > 0 && (count%100 == 0 || count&(count-1) == 0) {
- ec.lggr.Warnw("explorer client buffer full, dropping message", "data", data, "droppedCount", count)
- }
-}
-
-// Receive blocks the caller while waiting for a response from the server,
-// returning the raw response bytes
-func (ec *explorerClient) Receive(ctx context.Context, durationParams ...time.Duration) ([]byte, error) {
- duration := defaultReceiveTimeout
- if len(durationParams) > 0 {
- duration = durationParams[0]
- }
-
- select {
- case data := <-ec.receive:
- return data, nil
- case <-time.After(duration):
- return nil, ErrReceiveTimeout
- case <-ctx.Done():
- return nil, nil
- }
-}
-
-const (
- // Time allowed to write a message to the peer.
- writeWait = 10 * time.Second
-
- // Time allowed to read the next pong message from the peer.
- pongWait = 60 * time.Second
-
- // Send pings to peer with this period. Must be less than pongWait.
- pingPeriod = (pongWait * 9) / 10
-
- // Maximum message size allowed from peer.
- maxMessageSize = 512
-
- // defaultReceiveTimeout is the default amount of time to wait for receipt of messages
- defaultReceiveTimeout = 30 * time.Second
-)
-
-// Inspired by https://github.com/gorilla/websocket/blob/master/examples/chat/client.go
-// lexical confinement of done chan allows multiple connectAndWritePump routines
-// to clean up independent of itself by reducing shared state. i.e. a passed done, not ec.done.
-func (ec *explorerClient) connectAndWritePump() {
- defer ec.wg.Done()
- ctx, cancel := ec.chStop.NewCtx()
- defer cancel()
- for {
- select {
- case <-time.After(ec.sleeper.After()):
- ec.lggr.Infow("Connecting to explorer", "url", ec.url)
- err := ec.connect(ctx)
- if ctx.Err() != nil {
- return
- } else if err != nil {
- ec.setStatus(ConnectionStatusError)
- ec.lggr.Warn("Failed to connect to explorer (", ec.url.String(), "): ", err)
- break
- }
-
- ec.setStatus(ConnectionStatusConnected)
-
- ec.lggr.Infow("Connected to explorer", "url", ec.url)
- start := time.Now()
- ec.writePumpDone = make(chan struct{})
- ec.wg.Add(1)
- go ec.readPump()
- ec.writePump()
- if time.Since(start) > time.Second {
- ec.sleeper.Reset()
- }
-
- case <-ec.chStop:
- return
- }
- }
-}
-
-func (ec *explorerClient) setStatus(s ConnectionStatus) {
- ec.statusMtx.Lock()
- defer ec.statusMtx.Unlock()
- ec.status = s
-}
-
-// Inspired by https://github.com/gorilla/websocket/blob/master/examples/chat/client.go#L82
-func (ec *explorerClient) writePump() {
- ticker := time.NewTicker(pingPeriod)
- defer func() {
- ticker.Stop()
- ec.wrapConnErrorIf(ec.conn.Close()) // exclusive responsibility to close ws conn
- }()
-
- for {
- select {
- case message, open := <-ec.sendText:
- if !open {
- ec.wrapConnErrorIf(ec.conn.WriteMessage(websocket.CloseMessage, []byte{}))
- }
-
- err := ec.writeMessage(message, websocket.TextMessage)
- if err != nil {
- ec.lggr.Warnw("websocketStatsPusher: error writing text message", "err", err)
- return
- }
-
- case message, open := <-ec.sendBinary:
- if !open {
- ec.wrapConnErrorIf(ec.conn.WriteMessage(websocket.CloseMessage, []byte{}))
- }
-
- err := ec.writeMessage(message, websocket.BinaryMessage)
- if err != nil {
- ec.lggr.Warnw("websocketStatsPusher: error writing binary message", "err", err)
- return
- }
-
- case <-ticker.C:
- ec.wrapConnErrorIf(ec.conn.SetWriteDeadline(time.Now().Add(writeWait)))
- if err := ec.conn.WriteMessage(websocket.PingMessage, nil); err != nil {
- ec.wrapConnErrorIf(err)
- return
- }
-
- case <-ec.writePumpDone:
- return
- case <-ec.chStop:
- return
- }
- }
-}
-
-func (ec *explorerClient) writeMessage(message []byte, messageType int) error {
- ec.wrapConnErrorIf(ec.conn.SetWriteDeadline(time.Now().Add(writeWait)))
- writer, err := ec.conn.NextWriter(messageType)
- if err != nil {
- return err
- }
-
- if _, err := writer.Write(message); err != nil {
- return err
- }
- ec.lggr.Tracew("websocketStatsPusher successfully wrote message", "messageType", messageType, "message", message)
-
- return writer.Close()
-}
-
-func (ec *explorerClient) connect(ctx context.Context) error {
- authHeader := http.Header{}
- authHeader.Add("X-Explore-Chainlink-Accesskey", ec.accessKey)
- authHeader.Add("X-Explore-Chainlink-Secret", ec.secret)
- authHeader.Add("X-Explore-Chainlink-Core-Version", static.Version)
- authHeader.Add("X-Explore-Chainlink-Core-Sha", static.Sha)
-
- conn, _, err := websocket.DefaultDialer.DialContext(ctx, ec.url.String(), authHeader)
- if ctx.Err() != nil {
- return fmt.Errorf("websocketStatsPusher#connect context canceled: %w", ctx.Err())
- } else if err != nil {
- return fmt.Errorf("websocketStatsPusher#connect: %v", err)
- }
-
- ec.conn = conn
- return nil
-}
-
-var expectedCloseMessages = []int{websocket.CloseGoingAway, websocket.CloseAbnormalClosure, websocket.CloseNormalClosure}
-
-// readPump listens on the websocket connection for control messages and
-// response messages (text)
-//
-// For more details on how disconnection messages are handled, see:
-// - https://stackoverflow.com/a/48181794/639773
-// - https://github.com/gorilla/websocket/blob/master/examples/chat/client.go#L56
-func (ec *explorerClient) readPump() {
- defer ec.wg.Done()
- ec.conn.SetReadLimit(maxMessageSize)
- _ = ec.conn.SetReadDeadline(time.Now().Add(pongWait))
- ec.conn.SetPongHandler(func(string) error {
- _ = ec.conn.SetReadDeadline(time.Now().Add(pongWait))
- return nil
- })
-
- for {
- messageType, message, err := ec.conn.ReadMessage()
- if err != nil {
- if websocket.IsUnexpectedCloseError(err, expectedCloseMessages...) {
- ec.lggr.Warnw("Unexpected close error on ExplorerClient", "err", err)
- }
- close(ec.writePumpDone)
- return
- }
-
- switch messageType {
- case websocket.TextMessage:
- ec.receive <- message
- }
- }
-}
-
-func (ec *explorerClient) wrapConnErrorIf(err error) {
- if err != nil && websocket.IsUnexpectedCloseError(err, expectedCloseMessages...) {
- ec.setStatus(ConnectionStatusError)
- ec.lggr.Error(fmt.Sprintf("websocketStatsPusher: %v", err))
- }
-}
-
-func (ec *explorerClient) Close() error {
- return ec.StopOnce("Explorer client", func() error {
- close(ec.chStop)
- ec.wg.Wait()
- return nil
- })
-}
diff --git a/core/services/synchronization/explorer_client_test.go b/core/services/synchronization/explorer_client_test.go
deleted file mode 100644
index 727b8dd6d33..00000000000
--- a/core/services/synchronization/explorer_client_test.go
+++ /dev/null
@@ -1,213 +0,0 @@
-package synchronization_test
-
-import (
- "net/http"
- "net/http/httptest"
- "net/url"
- "testing"
- "time"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/onsi/gomega"
- "github.com/stretchr/testify/assert"
- "github.com/stretchr/testify/require"
-
- "github.com/smartcontractkit/chainlink/v2/core/internal/cltest"
- "github.com/smartcontractkit/chainlink/v2/core/internal/testutils"
- "github.com/smartcontractkit/chainlink/v2/core/logger"
- "github.com/smartcontractkit/chainlink/v2/core/services/synchronization"
- "github.com/smartcontractkit/chainlink/v2/core/static"
-)
-
-func TestWebSocketClient_ReconnectLoop(t *testing.T) {
- wsserver, cleanup := cltest.NewEventWebSocketServer(t)
- defer cleanup()
-
- explorerClient := newTestExplorerClient(t, wsserver.URL)
- require.NoError(t, explorerClient.Start(testutils.Context(t)))
- cltest.CallbackOrTimeout(t, "ws client connects", func() {
- <-wsserver.Connected
- }, testutils.WaitTimeout(t))
-
- // reconnect after server disconnect
- wsserver.WriteCloseMessage()
- cltest.CallbackOrTimeout(t, "ws client reconnects", func() {
- <-wsserver.Disconnected
- <-wsserver.Connected
- }, testutils.WaitTimeout(t))
- require.NoError(t, explorerClient.Close())
-}
-
-func TestWebSocketClient_Authentication(t *testing.T) {
- headerChannel := make(chan http.Header, 1)
- handler := func(w http.ResponseWriter, r *http.Request) {
- headerChannel <- r.Header
- }
- server := httptest.NewServer(http.HandlerFunc(handler))
- defer server.Close()
-
- url := cltest.MustParseURL(t, server.URL)
- url.Scheme = "ws"
- explorerClient := synchronization.NewExplorerClient(url, "accessKey", "secret", logger.TestLogger(t))
- require.NoError(t, explorerClient.Start(testutils.Context(t)))
- defer func() { assert.NoError(t, explorerClient.Close()) }()
-
- cltest.CallbackOrTimeout(t, "receive authentication headers", func() {
- headers := <-headerChannel
- assert.Equal(t, []string{"accessKey"}, headers["X-Explore-Chainlink-Accesskey"])
- assert.Equal(t, []string{"secret"}, headers["X-Explore-Chainlink-Secret"])
- assert.Equal(t, []string{static.Version}, headers["X-Explore-Chainlink-Core-Version"])
- assert.Equal(t, []string{static.Sha}, headers["X-Explore-Chainlink-Core-Sha"])
- })
-}
-
-func TestWebSocketClient_Send_DefaultsToTextMessage(t *testing.T) {
- wsserver, cleanup := cltest.NewEventWebSocketServer(t)
- defer cleanup()
-
- explorerClient := newTestExplorerClient(t, wsserver.URL)
- require.NoError(t, explorerClient.Start(testutils.Context(t)))
- defer func() { assert.NoError(t, explorerClient.Close()) }()
-
- expectation := `{"hello": "world"}`
- explorerClient.Send(testutils.Context(t), []byte(expectation))
- cltest.CallbackOrTimeout(t, "receive stats", func() {
- require.Equal(t, expectation, <-wsserver.ReceivedText)
- }, testutils.WaitTimeout(t))
-}
-
-func TestWebSocketClient_Send_TextMessage(t *testing.T) {
- wsserver, cleanup := cltest.NewEventWebSocketServer(t)
- defer cleanup()
-
- explorerClient := newTestExplorerClient(t, wsserver.URL)
- require.NoError(t, explorerClient.Start(testutils.Context(t)))
- defer func() { assert.NoError(t, explorerClient.Close()) }()
-
- expectation := `{"hello": "world"}`
- explorerClient.Send(testutils.Context(t), []byte(expectation), synchronization.ExplorerTextMessage)
- cltest.CallbackOrTimeout(t, "receive stats", func() {
- require.Equal(t, expectation, <-wsserver.ReceivedText)
- }, testutils.WaitTimeout(t))
-}
-
-func TestWebSocketClient_Send_Binary(t *testing.T) {
- wsserver, cleanup := cltest.NewEventWebSocketServer(t)
- defer cleanup()
-
- explorerClient := newTestExplorerClient(t, wsserver.URL)
- require.NoError(t, explorerClient.Start(testutils.Context(t)))
- defer func() { assert.NoError(t, explorerClient.Close()) }()
-
- address := common.HexToAddress("0xabc123")
- addressBytes := address.Bytes()
- explorerClient.Send(testutils.Context(t), addressBytes, synchronization.ExplorerBinaryMessage)
- cltest.CallbackOrTimeout(t, "receive stats", func() {
- require.Equal(t, addressBytes, <-wsserver.ReceivedBinary)
- }, testutils.WaitTimeout(t))
-}
-
-func TestWebSocketClient_Send_Unsupported(t *testing.T) {
- wsserver, cleanup := cltest.NewEventWebSocketServer(t)
- defer cleanup()
-
- explorerClient := newTestExplorerClient(t, wsserver.URL)
- require.NoError(t, explorerClient.Start(testutils.Context(t)))
-
- explorerClient.Send(testutils.Context(t), []byte(`{"hello": "world"}`), -1)
- require.Contains(t, explorerClient.HealthReport()[explorerClient.Name()].Error(), "send on explorer client received unsupported message type -1")
- require.NoError(t, explorerClient.Close())
-}
-
-func TestWebSocketClient_Send_WithAck(t *testing.T) {
- wsserver, cleanup := cltest.NewEventWebSocketServer(t)
- defer cleanup()
-
- explorerClient := newTestExplorerClient(t, wsserver.URL)
- require.NoError(t, explorerClient.Start(testutils.Context(t)))
- defer func() { assert.NoError(t, explorerClient.Close()) }()
-
- expectation := `{"hello": "world"}`
- explorerClient.Send(testutils.Context(t), []byte(expectation))
- cltest.CallbackOrTimeout(t, "receive stats", func() {
- require.Equal(t, expectation, <-wsserver.ReceivedText)
- err := wsserver.Broadcast(`{"result": 200}`)
- assert.NoError(t, err)
- }, testutils.WaitTimeout(t))
-
- cltest.CallbackOrTimeout(t, "receive response", func() {
- response, err := explorerClient.Receive(testutils.Context(t))
- assert.NoError(t, err)
- assert.NotNil(t, response)
- }, testutils.WaitTimeout(t))
-}
-
-func TestWebSocketClient_Send_WithAckTimeout(t *testing.T) {
- wsserver, cleanup := cltest.NewEventWebSocketServer(t)
- defer cleanup()
-
- explorerClient := newTestExplorerClient(t, wsserver.URL)
- require.NoError(t, explorerClient.Start(testutils.Context(t)))
- defer func() { assert.NoError(t, explorerClient.Close()) }()
-
- expectation := `{"hello": "world"}`
- explorerClient.Send(testutils.Context(t), []byte(expectation))
- cltest.CallbackOrTimeout(t, "receive stats", func() {
- require.Equal(t, expectation, <-wsserver.ReceivedText)
- }, testutils.WaitTimeout(t))
-
- cltest.CallbackOrTimeout(t, "receive response", func() {
- _, err := explorerClient.Receive(testutils.Context(t), 100*time.Millisecond)
- assert.ErrorIs(t, err, synchronization.ErrReceiveTimeout)
- }, testutils.WaitTimeout(t))
-}
-
-func TestWebSocketClient_Status_ConnectAndServerDisconnect(t *testing.T) {
- wsserver, cleanup := cltest.NewEventWebSocketServer(t)
- defer cleanup()
-
- explorerClient := newTestExplorerClient(t, wsserver.URL)
- assert.Equal(t, synchronization.ConnectionStatusDisconnected, explorerClient.Status())
-
- require.NoError(t, explorerClient.Start(testutils.Context(t)))
- defer func() { assert.NoError(t, explorerClient.Close()) }()
- cltest.CallbackOrTimeout(t, "ws client connects", func() {
- <-wsserver.Connected
- }, testutils.WaitTimeout(t))
-
- gomega.NewWithT(t).Eventually(func() synchronization.ConnectionStatus {
- return explorerClient.Status()
- }).Should(gomega.Equal(synchronization.ConnectionStatusConnected))
-
- // this triggers ConnectionStatusError and then the client gets reconnected
- wsserver.WriteCloseMessage()
-
- cltest.CallbackOrTimeout(t, "ws client disconnects and reconnects", func() {
- <-wsserver.Disconnected
- <-wsserver.Connected
- }, testutils.WaitTimeout(t))
-
- // expecting the client to reconnect
- gomega.NewWithT(t).Eventually(func() synchronization.ConnectionStatus {
- return explorerClient.Status()
- }).Should(gomega.Equal(synchronization.ConnectionStatusConnected))
-
- require.Equal(t, 1, wsserver.ConnectionsCount())
-}
-
-func TestWebSocketClient_Status_ConnectError(t *testing.T) {
- badURL, err := url.Parse("http://badhost.com")
- require.NoError(t, err)
-
- errorExplorerClient := newTestExplorerClient(t, badURL)
- require.NoError(t, errorExplorerClient.Start(testutils.Context(t)))
- defer func() { assert.NoError(t, errorExplorerClient.Close()) }()
-
- gomega.NewWithT(t).Eventually(func() synchronization.ConnectionStatus {
- return errorExplorerClient.Status()
- }).Should(gomega.Equal(synchronization.ConnectionStatusError))
-}
-
-func newTestExplorerClient(t *testing.T, wsURL *url.URL) synchronization.ExplorerClient {
- return synchronization.NewExplorerClient(wsURL, "", "", logger.TestLogger(t))
-}
diff --git a/core/services/synchronization/mocks/explorer_client.go b/core/services/synchronization/mocks/explorer_client.go
deleted file mode 100644
index 2aa1616d1ca..00000000000
--- a/core/services/synchronization/mocks/explorer_client.go
+++ /dev/null
@@ -1,178 +0,0 @@
-// Code generated by mockery v2.28.1. DO NOT EDIT.
-
-package mocks
-
-import (
- context "context"
- time "time"
-
- synchronization "github.com/smartcontractkit/chainlink/v2/core/services/synchronization"
- mock "github.com/stretchr/testify/mock"
-
- url "net/url"
-)
-
-// ExplorerClient is an autogenerated mock type for the ExplorerClient type
-type ExplorerClient struct {
- mock.Mock
-}
-
-// Close provides a mock function with given fields:
-func (_m *ExplorerClient) Close() error {
- ret := _m.Called()
-
- var r0 error
- if rf, ok := ret.Get(0).(func() error); ok {
- r0 = rf()
- } else {
- r0 = ret.Error(0)
- }
-
- return r0
-}
-
-// HealthReport provides a mock function with given fields:
-func (_m *ExplorerClient) HealthReport() map[string]error {
- ret := _m.Called()
-
- var r0 map[string]error
- if rf, ok := ret.Get(0).(func() map[string]error); ok {
- r0 = rf()
- } else {
- if ret.Get(0) != nil {
- r0 = ret.Get(0).(map[string]error)
- }
- }
-
- return r0
-}
-
-// Name provides a mock function with given fields:
-func (_m *ExplorerClient) Name() string {
- ret := _m.Called()
-
- var r0 string
- if rf, ok := ret.Get(0).(func() string); ok {
- r0 = rf()
- } else {
- r0 = ret.Get(0).(string)
- }
-
- return r0
-}
-
-// Ready provides a mock function with given fields:
-func (_m *ExplorerClient) Ready() error {
- ret := _m.Called()
-
- var r0 error
- if rf, ok := ret.Get(0).(func() error); ok {
- r0 = rf()
- } else {
- r0 = ret.Error(0)
- }
-
- return r0
-}
-
-// Receive provides a mock function with given fields: _a0, _a1
-func (_m *ExplorerClient) Receive(_a0 context.Context, _a1 ...time.Duration) ([]byte, error) {
- _va := make([]interface{}, len(_a1))
- for _i := range _a1 {
- _va[_i] = _a1[_i]
- }
- var _ca []interface{}
- _ca = append(_ca, _a0)
- _ca = append(_ca, _va...)
- ret := _m.Called(_ca...)
-
- var r0 []byte
- var r1 error
- if rf, ok := ret.Get(0).(func(context.Context, ...time.Duration) ([]byte, error)); ok {
- return rf(_a0, _a1...)
- }
- if rf, ok := ret.Get(0).(func(context.Context, ...time.Duration) []byte); ok {
- r0 = rf(_a0, _a1...)
- } else {
- if ret.Get(0) != nil {
- r0 = ret.Get(0).([]byte)
- }
- }
-
- if rf, ok := ret.Get(1).(func(context.Context, ...time.Duration) error); ok {
- r1 = rf(_a0, _a1...)
- } else {
- r1 = ret.Error(1)
- }
-
- return r0, r1
-}
-
-// Send provides a mock function with given fields: _a0, _a1, _a2
-func (_m *ExplorerClient) Send(_a0 context.Context, _a1 []byte, _a2 ...int) {
- _va := make([]interface{}, len(_a2))
- for _i := range _a2 {
- _va[_i] = _a2[_i]
- }
- var _ca []interface{}
- _ca = append(_ca, _a0, _a1)
- _ca = append(_ca, _va...)
- _m.Called(_ca...)
-}
-
-// Start provides a mock function with given fields: _a0
-func (_m *ExplorerClient) Start(_a0 context.Context) error {
- ret := _m.Called(_a0)
-
- var r0 error
- if rf, ok := ret.Get(0).(func(context.Context) error); ok {
- r0 = rf(_a0)
- } else {
- r0 = ret.Error(0)
- }
-
- return r0
-}
-
-// Status provides a mock function with given fields:
-func (_m *ExplorerClient) Status() synchronization.ConnectionStatus {
- ret := _m.Called()
-
- var r0 synchronization.ConnectionStatus
- if rf, ok := ret.Get(0).(func() synchronization.ConnectionStatus); ok {
- r0 = rf()
- } else {
- r0 = ret.Get(0).(synchronization.ConnectionStatus)
- }
-
- return r0
-}
-
-// Url provides a mock function with given fields:
-func (_m *ExplorerClient) Url() url.URL {
- ret := _m.Called()
-
- var r0 url.URL
- if rf, ok := ret.Get(0).(func() url.URL); ok {
- r0 = rf()
- } else {
- r0 = ret.Get(0).(url.URL)
- }
-
- return r0
-}
-
-type mockConstructorTestingTNewExplorerClient interface {
- mock.TestingT
- Cleanup(func())
-}
-
-// NewExplorerClient creates a new instance of ExplorerClient. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
-func NewExplorerClient(t mockConstructorTestingTNewExplorerClient) *ExplorerClient {
- mock := &ExplorerClient{}
- mock.Mock.Test(t)
-
- t.Cleanup(func() { mock.AssertExpectations(t) })
-
- return mock
-}
diff --git a/core/services/telemetry/explorer.go b/core/services/telemetry/explorer.go
deleted file mode 100644
index aa0f8410404..00000000000
--- a/core/services/telemetry/explorer.go
+++ /dev/null
@@ -1,31 +0,0 @@
-package telemetry
-
-import (
- "context"
-
- ocrtypes "github.com/smartcontractkit/libocr/commontypes"
-
- "github.com/smartcontractkit/chainlink/v2/core/services/synchronization"
-)
-
-var _ MonitoringEndpointGenerator = &ExplorerAgent{}
-
-type ExplorerAgent struct {
- explorerClient synchronization.ExplorerClient
-}
-
-// NewExplorerAgent returns a Agent which is just a thin wrapper over
-// the explorerClient for now
-func NewExplorerAgent(explorerClient synchronization.ExplorerClient) *ExplorerAgent {
- return &ExplorerAgent{explorerClient}
-}
-
-// SendLog sends a telemetry log to the explorer
-func (t *ExplorerAgent) SendLog(log []byte) {
- t.explorerClient.Send(context.Background(), log, synchronization.ExplorerBinaryMessage)
-}
-
-// GenMonitoringEndpoint creates a monitoring endpoint for telemetry
-func (t *ExplorerAgent) GenMonitoringEndpoint(contractID string, telemType synchronization.TelemetryType) ocrtypes.MonitoringEndpoint {
- return t
-}
diff --git a/core/services/telemetry/explorer_test.go b/core/services/telemetry/explorer_test.go
deleted file mode 100644
index c3f50033d35..00000000000
--- a/core/services/telemetry/explorer_test.go
+++ /dev/null
@@ -1,31 +0,0 @@
-package telemetry_test
-
-import (
- "testing"
-
- "github.com/stretchr/testify/assert"
- "github.com/stretchr/testify/mock"
-
- "github.com/smartcontractkit/chainlink/v2/core/services/synchronization"
- "github.com/smartcontractkit/chainlink/v2/core/services/synchronization/mocks"
- "github.com/smartcontractkit/chainlink/v2/core/services/telemetry"
-)
-
-func TestExplorerAgent(t *testing.T) {
- explorerClient := mocks.NewExplorerClient(t)
- explorerAgent := telemetry.NewExplorerAgent(explorerClient)
- monitoringEndpoint := explorerAgent.GenMonitoringEndpoint("0xa", synchronization.OCR)
-
- // Handle the Send call and store the logs
- var sentLog []byte
- explorerClient.On("Send", mock.AnythingOfType("*context.emptyCtx"), mock.AnythingOfType("[]uint8"), synchronization.ExplorerBinaryMessage).Return().Run(func(args mock.Arguments) {
- sentLog = args[1].([]byte)
- })
-
- // Send the log to the monitoring endpoint
- log := []byte("test log")
- monitoringEndpoint.SendLog(log)
-
- // Logs should be sent to the mock as they were passed in
- assert.Equal(t, log, sentLog)
-}
diff --git a/core/services/telemetry/noop.go b/core/services/telemetry/noop.go
index 2603c87875c..71670f2a198 100644
--- a/core/services/telemetry/noop.go
+++ b/core/services/telemetry/noop.go
@@ -11,7 +11,7 @@ var _ MonitoringEndpointGenerator = &NoopAgent{}
type NoopAgent struct {
}
-// SendLog sends a telemetry log to the explorer
+// SendLog sends a telemetry log to the ingress service
func (t *NoopAgent) SendLog(log []byte) {
}
diff --git a/core/services/transmission/integration_test.go b/core/services/transmission/integration_test.go
index 3aa025f0ae0..0484b1d8cd6 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 733c21b45a7..b5fe6cda76f 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,
@@ -367,24 +367,24 @@ func getRespCounts(q pg.Q, chainID uint64, evmFinalityDepth uint32) (
RequestID string
Count int
}{}
- // This query should use the idx_eth_txes_state_from_address_evm_chain_id
+ // This query should use the idx_evm.txes_state_from_address_evm_chain_id
// index, since the quantity of unconfirmed/unstarted/in_progress transactions _should_ be small
// relative to the rest of the data.
unconfirmedQuery := `
SELECT meta->'RequestID' AS request_id, count(meta->'RequestID') AS count
-FROM eth_txes et
+FROM evm.txes et
WHERE et.meta->'RequestID' IS NOT NULL
AND et.state IN ('unconfirmed', 'unstarted', 'in_progress')
GROUP BY meta->'RequestID'
`
// Fetch completed transactions only as far back as the given cutoffBlockNumber. This avoids
- // a table scan of the eth_txes table, which could be large if it is unpruned.
+ // a table scan of the evm.txes table, which could be large if it is unpruned.
confirmedQuery := `
SELECT meta->'RequestID' AS request_id, count(meta->'RequestID') AS count
-FROM eth_txes et JOIN eth_tx_attempts eta on et.id = eta.eth_tx_id
- join eth_receipts er on eta.hash = er.tx_hash
+FROM evm.txes et JOIN evm.tx_attempts eta on et.id = eta.eth_tx_id
+ join evm.receipts er on eta.hash = er.tx_hash
WHERE et.meta->'RequestID' is not null
-AND er.block_number >= (SELECT number FROM evm_heads WHERE evm_chain_id = $1 ORDER BY number DESC LIMIT 1) - $2
+AND er.block_number >= (SELECT number FROM evm.heads WHERE evm_chain_id = $1 ORDER BY number DESC LIMIT 1) - $2
GROUP BY meta->'RequestID'
`
query := unconfirmedQuery + "\nUNION ALL\n" + confirmedQuery
diff --git a/core/services/vrf/delegate_test.go b/core/services/vrf/delegate_test.go
index dba1d818ed4..ae0accc329e 100644
--- a/core/services/vrf/delegate_test.go
+++ b/core/services/vrf/delegate_test.go
@@ -79,8 +79,7 @@ func buildVrfUni(t *testing.T, db *sqlx.DB, cfg chainlink.GeneralConfig) vrfUniv
txm := txmmocks.NewMockEvmTxManager(t)
ks := keystore.New(db, utils.FastScryptParams, lggr, cfg.Database())
relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{LogBroadcaster: lb, KeyStore: ks.Eth(), Client: ec, DB: db, GeneralConfig: cfg, TxManager: txm})
- legacyChains, err := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
- require.NoError(t, err)
+ legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders)
jrm := job.NewORM(db, legacyChains, prm, btORM, ks, lggr, cfg.Database())
t.Cleanup(func() { jrm.Close() })
pr := pipeline.NewRunner(prm, btORM, cfg.JobPipeline(), cfg.WebServer(), legacyChains, ks.Eth(), ks.VRF(), lggr, nil, nil)
@@ -156,7 +155,7 @@ func setup(t *testing.T) (vrfUniverse, *v1.Listener, job.Job) {
logger.TestLogger(t),
cfg.Database(),
mailMon)
- vs := testspecs.GenerateVRFSpec(testspecs.VRFSpecParams{PublicKey: vuni.vrfkey.PublicKey.String()})
+ vs := testspecs.GenerateVRFSpec(testspecs.VRFSpecParams{PublicKey: vuni.vrfkey.PublicKey.String(), EVMChainID: testutils.FixtureChainID.String()})
jb, err := vrfcommon.ValidatedVRFSpec(vs.Toml())
require.NoError(t, err)
err = vuni.jrm.CreateJob(&jb)
@@ -414,7 +413,7 @@ func TestDelegate_InvalidLog(t *testing.T) {
// Ensure we have NOT queued up an eth transaction
var ethTxes []txmgr.DbEthTx
- err = vuni.prm.GetQ().Select(ðTxes, `SELECT * FROM eth_txes;`)
+ err = vuni.prm.GetQ().Select(ðTxes, `SELECT * FROM evm.txes;`)
require.NoError(t, err)
require.Len(t, ethTxes, 0)
}
diff --git a/core/services/vrf/proof/proof_response.go b/core/services/vrf/proof/proof_response.go
index 6d62e18a4f4..4cb58d921a4 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 42b709e298c..14cbb36c9d6 100644
--- a/core/services/vrf/v1/integration_test.go
+++ b/core/services/vrf/v1/integration_test.go
@@ -30,6 +30,7 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/services/vrf/vrftesthelpers"
"github.com/smartcontractkit/chainlink/v2/core/store/models"
"github.com/smartcontractkit/chainlink/v2/core/testdata/testspecs"
+ "github.com/smartcontractkit/chainlink/v2/core/utils"
)
func TestIntegration_VRF_JPV2(t *testing.T) {
@@ -47,6 +48,7 @@ func TestIntegration_VRF_JPV2(t *testing.T) {
t.Run(test.name, func(t *testing.T) {
config, _ := heavyweight.FullTestDBV2(t, fmt.Sprintf("vrf_jpv2_%v", test.eip1559), func(c *chainlink.Config, s *chainlink.Secrets) {
c.EVM[0].GasEstimator.EIP1559DynamicFees = &test.eip1559
+ c.EVM[0].ChainID = (*utils.Big)(testutils.SimulatedChainID)
})
key1 := cltest.MustGenerateRandomKey(t)
key2 := cltest.MustGenerateRandomKey(t)
@@ -133,6 +135,7 @@ func TestIntegration_VRF_WithBHS(t *testing.T) {
c.Feature.LogPoller = ptr(true)
c.EVM[0].FinalityDepth = ptr[uint32](2)
c.EVM[0].LogPollInterval = models.MustNewDuration(time.Second)
+ c.EVM[0].ChainID = (*utils.Big)(testutils.SimulatedChainID)
})
key := cltest.MustGenerateRandomKey(t)
cu := vrftesthelpers.NewVRFCoordinatorUniverse(t, key)
@@ -147,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)
// Ensure log poller is ready and has all logs.
require.NoError(t, app.GetRelayers().LegacyEVMChains().Slice()[0].LogPoller().Ready())
@@ -241,7 +244,9 @@ func createVRFJobRegisterKey(t *testing.T, u vrftesthelpers.CoordinatorUniverse,
Name: "vrf-primary",
CoordinatorAddress: u.RootContractAddress.String(),
MinIncomingConfirmations: incomingConfs,
- PublicKey: vrfKey.PublicKey.String()}).Toml()
+ PublicKey: vrfKey.PublicKey.String(),
+ EVMChainID: testutils.SimulatedChainID.String(),
+ }).Toml()
jb, err := vrfcommon.ValidatedVRFSpec(s)
require.NoError(t, err)
assert.Equal(t, expectedOnChainJobID, jb.ExternalIDEncodeStringToTopic().Bytes())
diff --git a/core/services/vrf/v1/listener_v1.go b/core/services/vrf/v1/listener_v1.go
index 0fce2ebedde..03b92bc15cb 100644
--- a/core/services/vrf/v1/listener_v1.go
+++ b/core/services/vrf/v1/listener_v1.go
@@ -416,6 +416,7 @@ func (lsn *Listener) ProcessRequest(ctx context.Context, req request) bool {
"name": lsn.Job.Name.ValueOrZero(),
"publicKey": lsn.Job.VRFSpec.PublicKey[:],
"from": lsn.fromAddresses(),
+ "evmChainID": lsn.Job.VRFSpec.EVMChainID.String(),
},
"jobRun": map[string]interface{}{
"logBlockHash": req.req.Raw.BlockHash[:],
@@ -428,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 00000000000..b843dbca9eb
--- /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)
+
+ // 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 8e2942ea927..b090c4ad5af 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 43ca198334d..81f3edfbb2e 100644
--- a/core/services/vrf/v2/integration_helpers_test.go
+++ b/core/services/vrf/v2/integration_helpers_test.go
@@ -28,6 +28,7 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/internal/cltest"
"github.com/smartcontractkit/chainlink/v2/core/internal/cltest/heavyweight"
"github.com/smartcontractkit/chainlink/v2/core/internal/testutils"
+ "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/evmtest"
"github.com/smartcontractkit/chainlink/v2/core/services/chainlink"
"github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ethkey"
"github.com/smartcontractkit/chainlink/v2/core/services/signatures/secp256k1"
@@ -240,7 +241,7 @@ func testMultipleConsumersNeedBHS(
_ = vrftesthelpers.CreateAndStartBHSJob(
t, bhsKeyAddresses, app, uni.bhsContractAddress.String(), "",
- v2CoordinatorAddress, v2PlusCoordinatorAddress, "", 0, 200)
+ v2CoordinatorAddress, v2PlusCoordinatorAddress, "", 0, 200, 0)
// Ensure log poller is ready and has all logs.
require.NoError(t, app.GetRelayers().LegacyEVMChains().Slice()[0].LogPoller().Ready())
@@ -385,7 +386,7 @@ func testMultipleConsumersNeedTrustedBHS(
_ = vrftesthelpers.CreateAndStartBHSJob(
t, bhsKeyAddressesStrings, app, "", "",
- v2CoordinatorAddress, v2PlusCoordinatorAddress, uni.trustedBhsContractAddress.String(), 20, 1000)
+ v2CoordinatorAddress, v2PlusCoordinatorAddress, uni.trustedBhsContractAddress.String(), 20, 1000, 0)
// Ensure log poller is ready and has all logs.
chain := app.GetRelayers().LegacyEVMChains().Slice()[0]
@@ -533,6 +534,7 @@ func testSingleConsumerHappyPathBatchFulfillment(
})(c, s)
c.EVM[0].GasEstimator.LimitDefault = ptr[uint32](5_000_000)
c.EVM[0].MinIncomingConfirmations = ptr[uint32](2)
+ c.EVM[0].ChainID = (*utils.Big)(testutils.SimulatedChainID)
})
app := cltest.NewApplicationWithConfigV2AndKeyOnSimulatedBlockchain(t, config, uni.backend, ownerKey, key1)
@@ -1616,6 +1618,7 @@ func testMaliciousConsumer(
c.EVM[0].GasEstimator.PriceMax = assets.GWei(1)
c.EVM[0].GasEstimator.PriceDefault = assets.GWei(1)
c.EVM[0].GasEstimator.FeeCapDefault = assets.GWei(1)
+ c.EVM[0].ChainID = (*utils.Big)(testutils.SimulatedChainID)
})
carol := uni.vrfConsumers[0]
@@ -1640,6 +1643,7 @@ func testMaliciousConsumer(
GasLanePrice: assets.GWei(1),
PublicKey: vrfkey.PublicKey.String(),
V2: true,
+ EVMChainID: testutils.SimulatedChainID.String(),
}).Toml()
jb, err := vrfcommon.ValidatedVRFSpec(s)
require.NoError(t, err)
@@ -1681,7 +1685,7 @@ func testMaliciousConsumer(
}, testutils.WaitTimeout(t), 1*time.Second).Should(gomega.BeTrue())
// The fulfillment tx should succeed
- ch, err := app.GetRelayers().LegacyEVMChains().Default()
+ ch, err := app.GetRelayers().LegacyEVMChains().Get(evmtest.MustGetDefaultChainID(t, config.EVMConfigs()).String())
require.NoError(t, err)
r, err := ch.Client().TransactionReceipt(testutils.Context(t), attempts[0].Hash)
require.NoError(t, err)
diff --git a/core/services/vrf/v2/integration_v2_plus_test.go b/core/services/vrf/v2/integration_v2_plus_test.go
index 4e1cf62d01d..2f20842aa57 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,
@@ -486,6 +487,9 @@ func TestVRFV2PlusIntegration_SingleConsumer_EOA_Request_Batching_Enabled(t *tes
}
func TestVRFV2PlusIntegration_SingleConsumer_EIP150_HappyPath(t *testing.T) {
+ // See: https://smartcontract-it.atlassian.net/browse/VRF-589
+ // Temporarily skipping to figure out issue with test
+ t.Skip()
t.Parallel()
ownerKey := cltest.MustGenerateRandomKey(t)
uni := newVRFCoordinatorV2PlusUniverse(t, ownerKey, 1, false)
@@ -714,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)
@@ -784,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)
@@ -1134,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()
@@ -1235,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 6ae1cb020a5..1f6a9dd3f92 100644
--- a/core/services/vrf/v2/integration_v2_test.go
+++ b/core/services/vrf/v2/integration_v2_test.go
@@ -128,22 +128,22 @@ type coordinatorV2Universe struct {
}
const (
- ConfirmedEthTxesV2Query = `SELECT * FROM eth_txes
- WHERE eth_txes.state = 'confirmed'
- AND eth_txes.meta->>'RequestID' = $1
- AND CAST(eth_txes.meta->>'SubId' AS NUMERIC) = $2 LIMIT 1`
- ConfirmedEthTxesV2PlusQuery = `SELECT * FROM eth_txes
- WHERE eth_txes.state = 'confirmed'
- AND eth_txes.meta->>'RequestID' = $1
- AND CAST(eth_txes.meta->>'GlobalSubId' AS NUMERIC) = $2 LIMIT 1`
+ ConfirmedEthTxesV2Query = `SELECT * FROM evm.txes
+ WHERE evm.txes.state = 'confirmed'
+ AND evm.txes.meta->>'RequestID' = $1
+ AND CAST(evm.txes.meta->>'SubId' AS NUMERIC) = $2 LIMIT 1`
+ ConfirmedEthTxesV2PlusQuery = `SELECT * FROM evm.txes
+ WHERE evm.txes.state = 'confirmed'
+ AND evm.txes.meta->>'RequestID' = $1
+ AND CAST(evm.txes.meta->>'GlobalSubId' AS NUMERIC) = $2 LIMIT 1`
ConfirmedEthTxesV2BatchQuery = `
- SELECT * FROM eth_txes
- WHERE eth_txes.state = 'confirmed'
- AND CAST(eth_txes.meta->>'SubId' AS NUMERIC) = $1`
+ SELECT * FROM evm.txes
+ WHERE evm.txes.state = 'confirmed'
+ AND CAST(evm.txes.meta->>'SubId' AS NUMERIC) = $1`
ConfirmedEthTxesV2PlusBatchQuery = `
- SELECT * FROM eth_txes
- WHERE eth_txes.state = 'confirmed'
- AND CAST(eth_txes.meta->>'GlobalSubId' AS NUMERIC) = $1`
+ SELECT * FROM evm.txes
+ WHERE evm.txes.state = 'confirmed'
+ AND CAST(evm.txes.meta->>'GlobalSubId' AS NUMERIC) = $1`
)
func newVRFCoordinatorV2Universe(t *testing.T, key ethkey.KeyV2, numConsumers int) coordinatorV2Universe {
@@ -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())
}
@@ -554,6 +554,7 @@ func createVRFJobs(
V2: true,
GasLanePrice: gasLanePrices[i],
VRFOwnerAddress: vrfOwnerString,
+ EVMChainID: testutils.SimulatedChainID.String(),
}).Toml()
jb, err := vrfcommon.ValidatedVRFSpec(spec)
@@ -802,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 {
@@ -1067,6 +1068,7 @@ func testEoa(
}
func TestVRFV2Integration_SingleConsumer_EIP150_HappyPath(t *testing.T) {
+ t.Skip("TODO: VRF-617")
t.Parallel()
ownerKey := cltest.MustGenerateRandomKey(t)
uni := newVRFCoordinatorV2Universe(t, ownerKey, 1)
@@ -1318,6 +1320,7 @@ 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)
@@ -1995,7 +1998,7 @@ func TestFulfillmentCost(t *testing.T) {
func TestStartingCountsV1(t *testing.T) {
cfg, db := heavyweight.FullTestDBNoFixturesV2(t, "vrf_test_starting_counts", nil)
- _, err := db.Exec(`INSERT INTO evm_heads (hash, number, parent_hash, created_at, timestamp, evm_chain_id)
+ _, err := db.Exec(`INSERT INTO evm.heads (hash, number, parent_hash, created_at, timestamp, evm_chain_id)
VALUES ($1, 4, $2, NOW(), NOW(), 1337)`, utils.NewHash(), utils.NewHash())
require.NoError(t, err)
@@ -2099,19 +2102,18 @@ func TestStartingCountsV1(t *testing.T) {
ChainID: chainID.ToInt(),
})
}
- txes := append(confirmedTxes, unconfirmedTxes...)
- sql := `INSERT INTO eth_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)
+ 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 txes {
- dbEtx := txmgr.DbEthTxFromEthTx(&tx)
+ for _, tx := range append(confirmedTxes, unconfirmedTxes...) {
+ var dbEtx txmgr.DbEthTx
+ dbEtx.FromTx(&tx) //nolint:gosec // just copying fields
_, err = db.NamedExec(sql, &dbEtx)
- txmgr.DbEthTxToEthTx(dbEtx, &tx)
require.NoError(t, err)
}
- // add eth_tx_attempts for confirmed
+ // add evm.tx_attempts for confirmed
broadcastBlock := int64(1)
- txAttempts := []txmgr.TxAttempt{}
+ var txAttempts []txmgr.TxAttempt
for i := range confirmedTxes {
txAttempts = append(txAttempts, txmgr.TxAttempt{
TxID: int64(i + 1),
@@ -2124,7 +2126,7 @@ VALUES (:nonce, :from_address, :to_address, :encoded_payload, :value, :gas_limit
ChainSpecificFeeLimit: uint32(100),
})
}
- // add eth_tx_attempts for unconfirmed
+ // add evm.tx_attempts for unconfirmed
for i := range unconfirmedTxes {
txAttempts = append(txAttempts, txmgr.TxAttempt{
TxID: int64(i + 1 + len(confirmedTxes)),
@@ -2139,16 +2141,16 @@ VALUES (:nonce, :from_address, :to_address, :encoded_payload, :value, :gas_limit
for _, txAttempt := range txAttempts {
t.Log("tx attempt eth tx id: ", txAttempt.TxID)
}
- sql = `INSERT INTO eth_tx_attempts (eth_tx_id, gas_price, signed_raw_tx, hash, state, created_at, chain_specific_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)
+ var dbAttempt txmgr.DbEthTxAttempt
+ dbAttempt.FromTxAttempt(&attempt) //nolint:gosec // just copying fields
_, err = db.NamedExec(sql, &dbAttempt)
- txmgr.DbEthTxAttemptToEthTxAttempt(dbAttempt, &attempt)
require.NoError(t, err)
}
- // add eth_receipts
+ // add evm.receipts
receipts := []txmgr.Receipt{}
for i := 0; i < 4; i++ {
receipts = append(receipts, txmgr.Receipt{
@@ -2160,10 +2162,10 @@ VALUES (:nonce, :from_address, :to_address, :encoded_payload, :value, :gas_limit
CreatedAt: time.Now(),
})
}
- sql = `INSERT INTO eth_receipts (block_hash, tx_hash, block_number, transaction_index, receipt, created_at)
+ 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 9b643d4f571..6a1ad3e8b2e 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)
@@ -72,7 +72,7 @@ const (
backoffFactor = 1.3
V2ReservedLinkQuery = `SELECT SUM(CAST(meta->>'MaxLink' AS NUMERIC(78, 0)))
- FROM eth_txes
+ FROM evm.txes
WHERE meta->>'MaxLink' IS NOT NULL
AND evm_chain_id = $1
AND CAST(meta->>'SubId' AS NUMERIC) = $2
@@ -80,7 +80,7 @@ const (
GROUP BY meta->>'SubId'`
V2PlusReservedLinkQuery = `SELECT SUM(CAST(meta->>'MaxLink' AS NUMERIC(78, 0)))
- FROM eth_txes
+ FROM evm.txes
WHERE meta->>'MaxLink' IS NOT NULL
AND evm_chain_id = $1
AND CAST(meta->>'GlobalSubId' AS NUMERIC) = $2
@@ -88,7 +88,7 @@ const (
GROUP BY meta->>'GlobalSubId'`
V2PlusReservedEthQuery = `SELECT SUM(CAST(meta->>'MaxEth' AS NUMERIC(78, 0)))
- FROM eth_txes
+ FROM evm.txes
WHERE meta->>'MaxEth' IS NOT NULL
AND evm_chain_id = $1
AND CAST(meta->>'GlobalSubId' AS NUMERIC) = $2
@@ -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
@@ -241,6 +241,12 @@ type listenerV2 struct {
deduper *vrfcommon.LogDeduper
}
+func (lsn *listenerV2) HealthReport() map[string]error {
+ return map[string]error{lsn.Name(): lsn.Healthy()}
+}
+
+func (lsn *listenerV2) Name() string { return lsn.l.Name() }
+
// Start starts listenerV2.
func (lsn *listenerV2) Start(ctx context.Context) error {
return lsn.StartOnce("VRFListenerV2", func() error {
@@ -487,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
}
@@ -923,7 +929,7 @@ func (lsn *listenerV2) enqueueForceFulfillment(
RequestTxHash: &requestTxHash,
// No max link since simulation failed
},
- }, pg.WithQueryer(tx), pg.WithParentCtx(ctx))
+ })
return err
})
return
@@ -1092,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 {
@@ -1137,7 +1143,7 @@ func (lsn *listenerV2) processRequestsPerSubHelper(
VRFCoordinatorAddress: &coordinatorAddress,
VRFRequestBlockNumber: new(big.Int).SetUint64(p.req.req.Raw().BlockNumber),
},
- }, pg.WithQueryer(tx), pg.WithParentCtx(ctx))
+ })
return err
})
if err != nil {
@@ -1415,6 +1421,7 @@ func (lsn *listenerV2) simulateFulfillment(
"name": lsn.job.Name.ValueOrZero(),
"publicKey": lsn.job.VRFSpec.PublicKey[:],
"maxGasPrice": maxGasPriceWei.ToInt().String(),
+ "evmChainID": lsn.job.VRFSpec.EVMChainID.String(),
},
"jobRun": map[string]interface{}{
"logBlockHash": req.req.Raw().BlockHash.Bytes(),
@@ -1489,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"])
}
@@ -1591,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 dd63ec8208e..77e279d8f7c 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"
@@ -34,17 +34,17 @@ import (
)
const (
- addEthTxQuery = `INSERT INTO eth_txes (from_address, to_address, encoded_payload, value, gas_limit, state, created_at, meta, subject, evm_chain_id, min_confirmations, pipeline_task_run_id)
+ addEthTxQuery = `INSERT INTO evm.txes (from_address, to_address, encoded_payload, value, gas_limit, state, created_at, meta, subject, evm_chain_id, min_confirmations, pipeline_task_run_id)
VALUES (
$1, $2, $3, $4, $5, $6, NOW(), $7, $8, $9, $10, $11
)
- RETURNING "eth_txes".*`
+ RETURNING "txes".*`
- addConfirmedEthTxQuery = `INSERT INTO eth_txes (nonce, broadcast_at, initial_broadcast_at, error, from_address, to_address, encoded_payload, value, gas_limit, state, created_at, meta, subject, evm_chain_id, min_confirmations, pipeline_task_run_id)
+ addConfirmedEthTxQuery = `INSERT INTO evm.txes (nonce, broadcast_at, initial_broadcast_at, error, from_address, to_address, encoded_payload, value, gas_limit, state, created_at, meta, subject, evm_chain_id, min_confirmations, pipeline_task_run_id)
VALUES (
$1, NOW(), NOW(), NULL, $2, $3, $4, $5, $6, 'confirmed', NOW(), $7, $8, $9, $10, $11
)
- RETURNING "eth_txes".*`
+ RETURNING "txes".*`
)
func txMetaSubIDs(t *testing.T, vrfVersion vrfcommon.Version, subID *big.Int) (*uint64, *string) {
@@ -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 c1e3b46b26a..e8c3a8ccb13 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)
@@ -193,7 +193,7 @@ func (lsn *listenerV2) processBatch(
GlobalSubID: txMetaGlobalSubID,
RequestTxHashes: txHashes,
},
- }, pg.WithQueryer(tx))
+ })
return errors.Wrap(err, "create batch fulfillment eth transaction")
})
diff --git a/core/services/vrf/v2/listener_v2_types_test.go b/core/services/vrf/v2/listener_v2_types_test.go
index 11bb7c98769..5391e18589b 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 d40e2bc747f..15af16f6fd9 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,
) job.Job {
jid := uuid.New()
s := testspecs.GenerateBlockhashStoreSpec(testspecs.BlockhashStoreSpecParams{
@@ -61,6 +62,7 @@ func CreateAndStartBHSJob(
CoordinatorV2PlusAddress: coordinatorV2PlusAddress,
WaitBlocks: 100,
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 e373ff8087a..ca85a4d1621 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.go b/core/sessions/orm.go
index bac552cadbb..eaac211f242 100644
--- a/core/sessions/orm.go
+++ b/core/sessions/orm.go
@@ -52,11 +52,11 @@ type orm struct {
var _ ORM = (*orm)(nil)
func NewORM(db *sqlx.DB, sd time.Duration, lggr logger.Logger, cfg pg.QConfig, auditLogger audit.AuditLogger) ORM {
- namedLogger := lggr.Named("SessionsORM")
+ lggr = lggr.Named("SessionsORM")
return &orm{
- q: pg.NewQ(db, namedLogger, cfg),
+ q: pg.NewQ(db, lggr, cfg),
sessionDuration: sd,
- lggr: lggr.Named("SessionsORM"),
+ lggr: lggr,
auditLogger: auditLogger,
}
}
@@ -86,43 +86,44 @@ func (o *orm) ListUsers() (users []User, err error) {
return
}
+// findValidSession finds an unexpired session by its ID and returns the associated email.
+func (o *orm) findValidSession(sessionID string) (email string, err error) {
+ if err := o.q.Get(&email, "SELECT email FROM sessions WHERE id = $1 AND last_used + $2 >= now() FOR UPDATE", sessionID, o.sessionDuration); err != nil {
+ o.lggr.Infof("query result: %v", email)
+ return email, errors.Wrap(err, "no matching user for provided session token")
+ }
+ return email, nil
+}
+
+// updateSessionLastUsed updates a session by its ID and sets the LastUsed field to now().
+func (o *orm) updateSessionLastUsed(sessionID string) error {
+ return o.q.ExecQ("UPDATE sessions SET last_used = now() WHERE id = $1", sessionID)
+}
+
// ErrUserSessionExpired defines the error triggered when the user session has expired
-var ErrUserSessionExpired = errors.New("session missing or expired, please login again")
+var (
+ ErrUserSessionExpired = errors.New("user session missing or expired, please login again")
+ ErrEmptySessionID = errors.New("session ID cannot be empty")
+)
// AuthorizedUserWithSession will return the API user associated with the Session ID if it
// exists and hasn't expired, and update session's LastUsed field.
-func (o *orm) AuthorizedUserWithSession(sessionID string) (User, error) {
+func (o *orm) AuthorizedUserWithSession(sessionID string) (user User, err error) {
if len(sessionID) == 0 {
- return User{}, errors.New("Session ID cannot be empty")
+ return User{}, ErrEmptySessionID
}
- var user User
- err := o.q.Transaction(func(tx pg.Queryer) error {
- // First find user based on session token
- var foundSession struct {
- Email string
- Valid bool
- }
- if err := tx.Get(&foundSession, "SELECT email, last_used + $2 >= now() as valid FROM sessions WHERE id = $1 FOR UPDATE", sessionID, o.sessionDuration); err != nil {
- return errors.Wrap(err, "no matching user for provided session token")
- }
-
- if !foundSession.Valid {
- return ErrUserSessionExpired
- }
-
- if err := tx.Get(&user, "SELECT * FROM users WHERE lower(email) = lower($1)", foundSession.Email); err != nil {
- return errors.Wrap(err, "no matching user for provided session email")
- }
- // Session valid and tied to user, update last_used
- _, err := tx.Exec("UPDATE sessions SET last_used = now() WHERE id = $1 AND last_used + $2 >= now()", sessionID, o.sessionDuration)
- if err != nil {
- return errors.Wrap(err, "unable to update sessions table")
- }
- return nil
- })
+ email, err := o.findValidSession(sessionID)
+ if err != nil {
+ return User{}, ErrUserSessionExpired
+ }
+ user, err = o.findUser(email)
if err != nil {
+ return User{}, ErrUserSessionExpired
+ }
+
+ if err := o.updateSessionLastUsed(sessionID); err != nil {
return User{}, err
}
diff --git a/core/sessions/orm_test.go b/core/sessions/orm_test.go
index 681b50987bf..804ea2dbb87 100644
--- a/core/sessions/orm_test.go
+++ b/core/sessions/orm_test.go
@@ -59,9 +59,9 @@ func TestORM_AuthorizedUserWithSession(t *testing.T) {
wantEmail string
}{
{"authorized", "correctID", cltest.MustParseDuration(t, "3m"), "", "have@email"},
- {"expired", "correctID", cltest.MustParseDuration(t, "0m"), "session missing or expired, please login again", ""},
- {"incorrect", "wrong", cltest.MustParseDuration(t, "3m"), "no matching user for provided session token: sql: no rows in result set", ""},
- {"empty", "", cltest.MustParseDuration(t, "3m"), "Session ID cannot be empty", ""},
+ {"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 {
diff --git a/core/store/migrate/migrate.go b/core/store/migrate/migrate.go
index 97714b68bef..69cf9a78247 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 97d0ec5b182..d6135ce4529 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"
@@ -10,13 +12,20 @@ import (
"github.com/stretchr/testify/require"
"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"
@@ -350,7 +359,7 @@ func TestMigrate_101_GenericOCR2(t *testing.T) {
require.NoError(t, err)
type PluginValues struct {
- PluginType job.OCR2PluginType
+ PluginType types.OCR2PluginType
PluginConfig job.JSONConfig
}
@@ -360,7 +369,7 @@ func TestMigrate_101_GenericOCR2(t *testing.T) {
err = db.Get(&pluginValues, sql)
require.NoError(t, err)
- require.Equal(t, job.Median, pluginValues.PluginType)
+ require.Equal(t, types.Median, pluginValues.PluginType)
require.Equal(t, job.JSONConfig{"juelsPerFeeCoinSource": spec.JuelsPerFeeCoinPipeline}, pluginValues.PluginConfig)
err = goose.Down(db.DB, migrationDir)
@@ -400,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/0189_create_automation_upkeep_state.sql b/core/store/migrate/migrations/0189_create_automation_upkeep_state.sql
new file mode 100644
index 00000000000..ffd4efea111
--- /dev/null
+++ b/core/store/migrate/migrations/0189_create_automation_upkeep_state.sql
@@ -0,0 +1,25 @@
+-- +goose Up
+
+CREATE TABLE evm_upkeep_states (
+ id SERIAL PRIMARY KEY,
+ work_id TEXT NOT NULL,
+ evm_chain_id NUMERIC(20) NOT NULL,
+ upkeep_id NUMERIC(78) NOT NULL, -- upkeep id is an evm word (uint256) which has a max size of precision 78
+ completion_state SMALLINT NOT NULL,
+ ineligibility_reason SMALLINT NOT NULL,
+ block_number BIGINT NOT NULL,
+ inserted_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP NOT NULL,
+ CONSTRAINT work_id_len_chk CHECK (
+ length(work_id) > 0 AND length(work_id) < 255
+ )
+);
+
+CREATE UNIQUE INDEX idx_evm_upkeep_state_chainid_workid ON evm_upkeep_states (evm_chain_id, work_id);
+CREATE INDEX idx_evm_upkeep_state_added_at_chain_id ON evm_upkeep_states (evm_chain_id, inserted_at);
+
+-- +goose Down
+
+DROP INDEX IF EXISTS idx_evm_upkeep_state_chainid_workid;
+DROP INDEX IF EXISTS idx_evm_upkeep_state_added_at_chain_id;
+
+DROP TABLE evm_upkeep_states;
\ No newline at end of file
diff --git a/core/store/migrate/migrations/0190_add_job_id_to_mercury_tables.sql b/core/store/migrate/migrations/0190_add_job_id_to_mercury_tables.sql
new file mode 100644
index 00000000000..5f76142be3c
--- /dev/null
+++ b/core/store/migrate/migrations/0190_add_job_id_to_mercury_tables.sql
@@ -0,0 +1,11 @@
+-- +goose Up
+
+DELETE FROM feed_latest_reports;
+ALTER TABLE feed_latest_reports ADD COLUMN job_id INTEGER NOT NULL REFERENCES jobs(id) DEFERRABLE INITIALLY IMMEDIATE;
+DELETE FROM mercury_transmit_requests;
+ALTER TABLE mercury_transmit_requests ADD COLUMN job_id INTEGER NOT NULL REFERENCES jobs(id) DEFERRABLE INITIALLY IMMEDIATE;;
+
+-- +goose Down
+
+ALTER TABLE feed_latest_reports DROP COLUMN job_id;
+ALTER TABLE mercury_transmit_requests DROP COLUMN job_id;
diff --git a/core/store/migrate/migrations/0191_mercury_tables_job_id_cascade.sql b/core/store/migrate/migrations/0191_mercury_tables_job_id_cascade.sql
new file mode 100644
index 00000000000..a407feb9c0f
--- /dev/null
+++ b/core/store/migrate/migrations/0191_mercury_tables_job_id_cascade.sql
@@ -0,0 +1,11 @@
+-- +goose Up
+ALTER TABLE mercury_transmit_requests DROP CONSTRAINT mercury_transmit_requests_job_id_fkey;
+ALTER TABLE mercury_transmit_requests ADD CONSTRAINT mercury_transmit_requests_job_id_fkey FOREIGN KEY (job_id) REFERENCES jobs(id) ON DELETE CASCADE DEFERRABLE INITIALLY IMMEDIATE;
+ALTER TABLE feed_latest_reports DROP CONSTRAINT feed_latest_reports_job_id_fkey;
+ALTER TABLE feed_latest_reports ADD CONSTRAINT feed_latest_reports_job_id_fkey FOREIGN KEY (job_id) REFERENCES jobs(id) ON DELETE CASCADE DEFERRABLE INITIALLY IMMEDIATE;
+
+-- +goose Down
+ALTER TABLE mercury_transmit_requests DROP CONSTRAINT mercury_transmit_requests_job_id_fkey;
+ALTER TABLE mercury_transmit_requests ADD CONSTRAINT mercury_transmit_requests_job_id_fkey FOREIGN KEY (job_id) REFERENCES jobs(id) DEFERRABLE INITIALLY IMMEDIATE;
+ALTER TABLE feed_latest_reports DROP CONSTRAINT feed_latest_reports_job_id_fkey;
+ALTER TABLE feed_latest_reports ADD CONSTRAINT feed_latest_reports_job_id_fkey FOREIGN KEY (job_id) REFERENCES jobs(id) DEFERRABLE INITIALLY IMMEDIATE;
diff --git a/core/store/migrate/migrations/0192_add_request_id_column_eth_txes_table.sql b/core/store/migrate/migrations/0192_add_request_id_column_eth_txes_table.sql
new file mode 100644
index 00000000000..6a9ab7846d1
--- /dev/null
+++ b/core/store/migrate/migrations/0192_add_request_id_column_eth_txes_table.sql
@@ -0,0 +1,7 @@
+-- +goose Up
+
+ALTER TABLE eth_txes ADD COLUMN idempotency_key varchar(2000) UNIQUE;
+
+-- +goose Down
+
+ALTER TABLE eth_txes DROP COLUMN idempotency_key;
diff --git a/core/store/migrate/migrations/0193_s4_alter_version_type.sql b/core/store/migrate/migrations/0193_s4_alter_version_type.sql
new file mode 100644
index 00000000000..36179d5d7f0
--- /dev/null
+++ b/core/store/migrate/migrations/0193_s4_alter_version_type.sql
@@ -0,0 +1,7 @@
+-- +goose Up
+
+ALTER TABLE "s4".shared ALTER COLUMN version TYPE NUMERIC;
+
+-- +goose Down
+
+ALTER TABLE "s4".shared ALTER COLUMN version TYPE INT USING version::integer;
diff --git a/core/store/migrate/migrations/0194_evm_schema.sql b/core/store/migrate/migrations/0194_evm_schema.sql
new file mode 100644
index 00000000000..fc55028c16e
--- /dev/null
+++ b/core/store/migrate/migrations/0194_evm_schema.sql
@@ -0,0 +1,164 @@
+-- +goose Up
+CREATE SCHEMA evm;
+SET search_path TO evm,public;
+
+ALTER TABLE public.evm_forwarders SET SCHEMA evm;
+ALTER TABLE evm.evm_forwarders RENAME TO forwarders;
+
+ALTER TABLE public.evm_heads SET SCHEMA evm;
+ALTER TABLE evm.evm_heads RENAME TO heads;
+
+ALTER TABLE public.evm_key_states SET SCHEMA evm;
+ALTER TABLE evm.evm_key_states RENAME TO key_states;
+
+ALTER TABLE public.evm_log_poller_blocks SET SCHEMA evm;
+ALTER TABLE evm.evm_log_poller_blocks RENAME TO log_poller_blocks;
+
+ALTER TABLE public.evm_log_poller_filters SET SCHEMA evm;
+ALTER TABLE evm.evm_log_poller_filters RENAME TO log_poller_filters;
+
+
+
+ALTER TABLE public.evm_upkeep_states SET SCHEMA evm;
+ALTER TABLE evm.evm_upkeep_states RENAME TO upkeep_states;
+
+ALTER TABLE public.eth_receipts SET SCHEMA evm;
+ALTER TABLE evm.eth_receipts RENAME TO receipts;
+
+ALTER TABLE public.eth_tx_attempts SET SCHEMA evm;
+ALTER TABLE evm.eth_tx_attempts RENAME TO tx_attempts;
+
+---------------------
+-- Handle log triggers
+---------------------
+DROP TRIGGER IF EXISTS notify_insert_on_evm_logs_topics ON PUBLIC.evm_logs;
+DROP FUNCTION IF EXISTS public.notifysavedlogtopics();
+
+ALTER TABLE public.evm_logs SET SCHEMA evm;
+ALTER TABLE evm.evm_logs RENAME TO logs;
+
+-- +goose StatementBegin
+CREATE OR REPLACE FUNCTION evm.notifysavedlogtopics() RETURNS trigger
+ LANGUAGE plpgsql
+AS $$
+BEGIN
+ PERFORM pg_notify(
+ 'evm.insert_on_logs'::text,
+ -- hex encoded address plus comma separated list of hex encoded topic values
+ -- e.g. ":,"
+ encode(NEW.address, 'hex') || ':' || array_to_string(array(SELECT encode(unnest(NEW.topics), 'hex')), ',')
+ );
+ RETURN NULL;
+END
+$$;
+
+DROP TRIGGER IF EXISTS notify_insert_on_logs_topics ON evm.logs;
+CREATE TRIGGER notify_insert_on_logs_topics AFTER INSERT ON evm.logs FOR EACH ROW EXECUTE PROCEDURE evm.notifysavedlogtopics();
+-- +goose StatementEnd
+
+---------------------
+-- Handle tx triggers
+---------------------
+DROP TRIGGER IF EXISTS notify_eth_tx_insertion on public.eth_txes;
+DROP FUNCTION IF EXISTS public.notifyethtxinsertion();
+
+ALTER TABLE public.eth_txes SET SCHEMA evm;
+ALTER TABLE evm.eth_txes RENAME TO txes;
+
+
+-- +goose StatementBegin
+CREATE OR REPLACE FUNCTION evm.notifytxinsertion() RETURNS trigger
+ LANGUAGE plpgsql
+ AS $$
+ BEGIN
+ PERFORM pg_notify('evm.insert_on_txes'::text, encode(NEW.from_address, 'hex'));
+ RETURN NULL;
+ END
+ $$;
+
+DROP TRIGGER IF EXISTS notify_tx_insertion on evm.txes;
+CREATE TRIGGER notify_tx_insertion AFTER INSERT ON evm.txes FOR EACH ROW EXECUTE PROCEDURE evm.notifytxinsertion();
+-- +goose StatementEnd
+
+
+-- +goose Down
+SET search_path TO evm,public;
+ALTER TABLE evm.forwarders SET SCHEMA public;
+ALTER TABLE public.forwarders RENAME TO evm_forwarders;
+
+ALTER TABLE evm.heads SET SCHEMA public;
+ALTER TABLE public.heads RENAME TO evm_heads;
+
+ALTER TABLE evm.key_states SET SCHEMA public;
+ALTER TABLE public.key_states RENAME TO evm_key_states;
+
+ALTER TABLE evm.log_poller_blocks SET SCHEMA public;
+ALTER TABLE public.log_poller_blocks RENAME TO evm_log_poller_blocks;
+
+ALTER TABLE evm.log_poller_filters SET SCHEMA public;
+ALTER TABLE public.log_poller_filters RENAME TO evm_log_poller_filters;
+
+ALTER TABLE evm.upkeep_states SET SCHEMA public;
+ALTER table public.upkeep_states RENAME TO evm_upkeep_states;
+
+ALTER TABLE evm.receipts SET SCHEMA public;
+ALTER TABLE public.receipts RENAME TO eth_receipts;
+
+ALTER TABLE evm.tx_attempts SET SCHEMA public;
+ALTER TABLE public.tx_attempts RENAME TO eth_tx_attempts;
+
+
+---------------------
+-- Handle log triggers
+---------------------
+
+DROP TRIGGER IF EXISTS notify_insert_on_logs_topics ON evm.logs;
+DROP FUNCTION IF EXISTS evm.notifysavedlogtopics();
+
+ALTER TABLE evm.logs SET SCHEMA public;
+ALTER TABLE public.logs RENAME TO evm_logs;
+
+-- +goose StatementBegin
+CREATE OR REPLACE FUNCTION PUBLIC.notifysavedlogtopics() RETURNS trigger
+ LANGUAGE plpgsql
+AS $$
+BEGIN
+ PERFORM pg_notify(
+ 'insert_on_evm_logs'::text,
+ -- hex encoded address plus comma separated list of hex encoded topic values
+ -- e.g. ":,"
+ encode(NEW.address, 'hex') || ':' || array_to_string(array(SELECT encode(unnest(NEW.topics), 'hex')), ',')
+ );
+ RETURN NULL;
+END
+$$;
+
+DROP TRIGGER IF EXISTS notify_insert_on_evm_logs_topics ON PUBLIC.evm_logs;
+CREATE TRIGGER notify_insert_on_evm_logs_topics AFTER INSERT ON PUBLIC.evm_logs FOR EACH ROW EXECUTE PROCEDURE PUBLIC.notifysavedlogtopics();
+-- +goose StatementEnd
+
+---------------------
+-- Handle tx triggers
+---------------------
+
+DROP TRIGGER IF EXISTS notify_tx_insertion on evm.txes;
+DROP FUNCTION IF EXISTS evm.notifytxinsertion();
+
+ALTER TABLE evm.txes SET SCHEMA public;
+ALTER TABLE public.txes RENAME TO eth_txes;
+
+-- +goose StatementBegin
+CREATE OR REPLACE FUNCTION public.notifyethtxinsertion() RETURNS trigger
+ LANGUAGE plpgsql
+ AS $$
+ BEGIN
+ PERFORM pg_notify('insert_on_eth_txes'::text, encode(NEW.from_address, 'hex'));
+ RETURN NULL;
+ END
+ $$;
+
+DROP TRIGGER IF EXISTS notify_eth_tx_insertion on public.eth_txes;
+CREATE TRIGGER notify_eth_tx_insertion AFTER INSERT ON public.eth_txes FOR EACH ROW EXECUTE PROCEDURE public.notifyethtxinsertion();
+-- +goose StatementEnd
+
+DROP SCHEMA evm;
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
new file mode 100644
index 00000000000..b1387cc51f0
--- /dev/null
+++ b/core/store/migrate/migrations/0195_add_not_null_to_evm_chain_id_in_job_specs.go
@@ -0,0 +1,71 @@
+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() {
+ goose.AddMigrationContext(Up195, Down195)
+}
+
+const (
+ addNullConstraintsToSpecs = `
+ ALTER TABLE direct_request_specs ALTER COLUMN evm_chain_id SET NOT NULL;
+ ALTER TABLE flux_monitor_specs ALTER COLUMN evm_chain_id SET NOT NULL;
+ ALTER TABLE ocr_oracle_specs ALTER COLUMN evm_chain_id SET NOT NULL;
+ ALTER TABLE keeper_specs ALTER COLUMN evm_chain_id SET NOT NULL;
+ ALTER TABLE vrf_specs ALTER COLUMN evm_chain_id SET NOT NULL;
+ ALTER TABLE blockhash_store_specs ALTER COLUMN evm_chain_id SET NOT NULL;
+ ALTER TABLE block_header_feeder_specs ALTER COLUMN evm_chain_id SET NOT NULL;
+ `
+
+ dropNullConstraintsFromSpecs = `
+ ALTER TABLE direct_request_specs ALTER COLUMN evm_chain_id DROP NOT NULL;
+ ALTER TABLE flux_monitor_specs ALTER COLUMN evm_chain_id DROP NOT NULL;
+ ALTER TABLE ocr_oracle_specs ALTER COLUMN evm_chain_id DROP NOT NULL;
+ ALTER TABLE keeper_specs ALTER COLUMN evm_chain_id DROP NOT NULL;
+ ALTER TABLE vrf_specs ALTER COLUMN evm_chain_id DROP NOT NULL;
+ ALTER TABLE blockhash_store_specs ALTER COLUMN evm_chain_id DROP NOT NULL;
+ ALTER TABLE block_header_feeder_specs ALTER COLUMN evm_chain_id DROP NOT NULL;
+ `
+)
+
+// 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")
+}
+
+// nolint
+func Down195(ctx context.Context, tx *sql.Tx) error {
+ if _, err := tx.ExecContext(ctx, dropNullConstraintsFromSpecs); err != nil {
+ return err
+ }
+ return nil
+}
diff --git a/core/store/migrate/migrations/0196_add_txhash_index_evm_logs.sql b/core/store/migrate/migrations/0196_add_txhash_index_evm_logs.sql
new file mode 100644
index 00000000000..a0bfe31dd9a
--- /dev/null
+++ b/core/store/migrate/migrations/0196_add_txhash_index_evm_logs.sql
@@ -0,0 +1,5 @@
+-- +goose Up
+create index evm_logs_idx_tx_hash on evm.logs (tx_hash);
+
+-- +goose Down
+DROP INDEX IF EXISTS evm_logs_idx_tx_hash;
\ No newline at end of file
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 00000000000..74a7a74cd4b
--- /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/models/common.go b/core/store/models/common.go
index 9b7d181da88..fc7f7762046 100644
--- a/core/store/models/common.go
+++ b/core/store/models/common.go
@@ -367,6 +367,8 @@ type SendEtherRequest struct {
Amount assets.Eth `json:"amount"`
EVMChainID *utils.Big `json:"evmChainID"`
AllowHigherAmounts bool `json:"allowHigherAmounts"`
+ SkipWaitTxAttempt bool `json:"skipWaitTxAttempt"`
+ WaitAttemptTimeout *time.Duration `json:"waitAttemptTimeout"`
}
// AddressCollection is an array of common.Address
diff --git a/core/store/models/common_test.go b/core/store/models/common_test.go
index 1f514142b80..57b7ca73c6b 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 4c44f3b9c5e..3dd7c675d50 100644
--- a/core/testdata/testspecs/v2_specs.go
+++ b/core/testdata/testspecs/v2_specs.go
@@ -44,6 +44,7 @@ type = "directrequest"
schemaVersion = 1
name = "%s"
contractAddress = "0x613a38AC1659769640aaE063C651F48E0250454C"
+evmChainID = "0"
observationSource = """
ds1 [type=http method=GET url="http://example.com" allowunrestrictednetworkaccess="true"];
ds1_parse [type=jsonparse path="USD"];
@@ -57,6 +58,7 @@ schemaVersion = 1
name = "example eth request event spec"
contractAddress = "0x613a38AC1659769640aaE063C651F48E0250454C"
externalJobID = "123e4567-e89b-12d3-a456-426655440004"
+evmChainID = "0"
observationSource = """
ds1 [type=http method=GET url="http://example.com" allowunrestrictednetworkaccess="true"];
ds1_parse [type=jsonparse path="USD"];
@@ -72,6 +74,7 @@ minContractPaymentLinkJuels = "1000000000000000000000"
name = "example eth request event spec with requesters and min contract payment"
contractAddress = "0x613a38AC1659769640aaE063C651F48E0250454C"
externalJobID = "123e4567-e89b-12d3-a456-426655440014"
+evmChainID = 0
observationSource = """
ds1 [type=http method=GET url="http://example.com" allowunrestrictednetworkaccess="true"];
ds1_parse [type=jsonparse path="USD"];
@@ -85,6 +88,7 @@ schemaVersion = 1
name = "example flux monitor spec"
contractAddress = "0x3cCad4715152693fE3BC4460591e3D3Fbd071b42"
externalJobID = "123e4567-e89b-12d3-a456-426655440005"
+evmChainID = 0
threshold = 0.5
absoluteThreshold = 0.0 # optional
@@ -251,6 +255,7 @@ type VRFSpecParams struct {
FromAddresses []string
PublicKey string
ObservationSource string
+ EVMChainID string
RequestedConfsDelay int
RequestTimeout time.Duration
V2 bool
@@ -353,14 +358,16 @@ vrf [type=vrfv2
estimate_gas [type=estimategaslimit
to="%s"
multiplier="1.1"
- data="$(vrf.output)"]
+ data="$(vrf.output)"
+]
simulate [type=ethcall
to="%s"
gas="$(estimate_gas)"
gasPrice="$(jobSpec.maxGasPrice)"
extractRevertReason=true
contract="%s"
- data="$(vrf.output)"]
+ data="$(vrf.output)"
+]
decode_log->vrf->estimate_gas->simulate
`, coordinatorAddress, coordinatorAddress, coordinatorAddress)
}
@@ -378,26 +385,32 @@ generate_proof [type=vrfv2plus
estimate_gas [type=estimategaslimit
to="%s"
multiplier="1.1"
- data="$(generate_proof.output)"]
+ data="$(generate_proof.output)"
+]
simulate_fulfillment [type=ethcall
to="%s"
gas="$(estimate_gas)"
gasPrice="$(jobSpec.maxGasPrice)"
extractRevertReason=true
contract="%s"
- data="$(generate_proof.output)"]
+ data="$(generate_proof.output)"
+]
decode_log->generate_proof->estimate_gas->simulate_fulfillment
`, coordinatorAddress, coordinatorAddress, coordinatorAddress)
}
if params.ObservationSource != "" {
observationSource = params.ObservationSource
}
+ if params.EVMChainID == "" {
+ params.EVMChainID = "0"
+ }
template := `
externalJobID = "%s"
type = "vrf"
schemaVersion = 1
name = "%s"
coordinatorAddress = "%s"
+evmChainID = "%s"
batchCoordinatorAddress = "%s"
batchFulfillmentEnabled = %v
batchFulfillmentGasMultiplier = %s
@@ -414,7 +427,7 @@ observationSource = """
"""
`
toml := fmt.Sprintf(template,
- jobID, name, coordinatorAddress, batchCoordinatorAddress,
+ jobID, name, coordinatorAddress, params.EVMChainID, batchCoordinatorAddress,
params.BatchFulfillmentEnabled, strconv.FormatFloat(batchFulfillmentGasMultiplier, 'f', 2, 64),
confirmations, params.RequestedConfsDelay, requestTimeout.String(), publicKey, chunkSize,
params.BackoffInitialDelay.String(), params.BackoffMaxDelay.String(), gasLanePrice.String(), observationSource)
@@ -438,6 +451,7 @@ observationSource = """
MinIncomingConfirmations: confirmations,
PublicKey: publicKey,
ObservationSource: observationSource,
+ EVMChainID: params.EVMChainID,
RequestedConfsDelay: params.RequestedConfsDelay,
RequestTimeout: requestTimeout,
ChunkSize: chunkSize,
@@ -492,7 +506,7 @@ func GenerateOCRSpec(params OCRSpecParams) OCRSpec {
if params.DS2BridgeName != "" {
ds2BridgeName = params.DS2BridgeName
}
- // set to empty so it defaults to the default evm chain id
+
evmChainID := "0"
if params.EVMChainID != "" {
evmChainID = params.EVMChainID
@@ -592,6 +606,7 @@ type BlockhashStoreSpecParams struct {
CoordinatorV2Address string
CoordinatorV2PlusAddress string
WaitBlocks int
+ HeartbeatPeriod time.Duration
LookbackBlocks int
BlockhashStoreAddress string
TrustedBlockhashStoreAddress string
@@ -690,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-cbor.toml b/core/testdata/tomlspecs/direct-request-spec-cbor.toml
index 2a51cefef7b..500c4973d88 100644
--- a/core/testdata/tomlspecs/direct-request-spec-cbor.toml
+++ b/core/testdata/tomlspecs/direct-request-spec-cbor.toml
@@ -3,6 +3,7 @@ schemaVersion = 1
name = "example eth request event spec"
contractAddress = "0x613a38AC1659769640aaE063C651F48E0250454C"
externalJobID = "0EEC7E1D-D0D2-476C-A1A8-72DFB6633F90"
+evmChainID = 1337
observationSource = """
decode_log [type=ethabidecodelog
abi="OracleRequest(bytes32 indexed specId, address requester, bytes32 requestId, uint256 payment, address callbackAddr, bytes4 callbackFunctionId, uint256 cancelExpiration, uint256 dataVersion, bytes data)"
diff --git a/core/testdata/tomlspecs/direct-request-spec.toml b/core/testdata/tomlspecs/direct-request-spec.toml
index d3c866102bc..35c0cc9274e 100644
--- a/core/testdata/tomlspecs/direct-request-spec.toml
+++ b/core/testdata/tomlspecs/direct-request-spec.toml
@@ -1,5 +1,6 @@
type = "directrequest"
schemaVersion = 1
+evmChainID = "0"
name = "example eth request event spec"
contractAddress = "0x613a38AC1659769640aaE063C651F48E0250454C"
externalJobID = "0EEC7E1D-D0D2-476C-A1A8-72DFB6633F47"
diff --git a/core/testdata/tomlspecs/multiword-response-spec.toml b/core/testdata/tomlspecs/multiword-response-spec.toml
index 825f96946b1..31da76b797c 100644
--- a/core/testdata/tomlspecs/multiword-response-spec.toml
+++ b/core/testdata/tomlspecs/multiword-response-spec.toml
@@ -2,6 +2,7 @@ type = "directrequest"
schemaVersion = 1
name = "example eth request event spec"
contractAddress = "0x613a38AC1659769640aaE063C651F48E0250454C"
+evmChainID = "1337"
externalJobID = "0EEC7E1D-D0D2-476C-A1A8-72DFB6633F47"
observationSource = """
decode_log [type=ethabidecodelog
diff --git a/core/testdata/tomlspecs/ocr-bootstrap-spec.toml b/core/testdata/tomlspecs/ocr-bootstrap-spec.toml
index ce12800f634..9df0a861960 100644
--- a/core/testdata/tomlspecs/ocr-bootstrap-spec.toml
+++ b/core/testdata/tomlspecs/ocr-bootstrap-spec.toml
@@ -2,6 +2,7 @@ type = "offchainreporting"
schemaVersion = 1
contractAddress = "0x27548a32b9aD5D64c5945EaE9Da5337bc3169D15"
externalJobID = "0EEC7E1D-D0D2-476C-A1A8-72DFB6633F50"
+evmChainID = "0"
p2pBootstrapPeers = [
"/dns4/chain.link/tcp/1234/p2p/16Uiu2HAm58SP7UL8zsnpeuwHfytLocaqgnyaYKP8wu7qRdrixLju",
]
diff --git a/core/utils/big_test.go b/core/utils/big_test.go
index ca8be3f90b8..e46d46a0651 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/thread_control.go b/core/utils/thread_control.go
new file mode 100644
index 00000000000..8f7fff42496
--- /dev/null
+++ b/core/utils/thread_control.go
@@ -0,0 +1,44 @@
+package utils
+
+import (
+ "context"
+ "sync"
+)
+
+var _ ThreadControl = &threadControl{}
+
+// ThreadControl is a helper for managing a group of goroutines.
+type ThreadControl interface {
+ // Go starts a goroutine and tracks the lifetime of the goroutine.
+ Go(fn func(context.Context))
+ // Close cancels the goroutines and waits for all of them to exit.
+ Close()
+}
+
+func NewThreadControl() *threadControl {
+ tc := &threadControl{
+ stop: make(chan struct{}),
+ }
+
+ return tc
+}
+
+type threadControl struct {
+ threadsWG sync.WaitGroup
+ stop StopChan
+}
+
+func (tc *threadControl) Go(fn func(context.Context)) {
+ tc.threadsWG.Add(1)
+ go func() {
+ defer tc.threadsWG.Done()
+ ctx, cancel := tc.stop.NewCtx()
+ defer cancel()
+ fn(ctx)
+ }()
+}
+
+func (tc *threadControl) Close() {
+ close(tc.stop)
+ tc.threadsWG.Wait()
+}
diff --git a/core/utils/thread_control_test.go b/core/utils/thread_control_test.go
new file mode 100644
index 00000000000..9001ca7241c
--- /dev/null
+++ b/core/utils/thread_control_test.go
@@ -0,0 +1,27 @@
+package utils
+
+import (
+ "context"
+ "sync/atomic"
+ "testing"
+
+ "github.com/stretchr/testify/require"
+)
+
+func TestThreadControl_Close(t *testing.T) {
+ n := 10
+ tc := NewThreadControl()
+
+ finished := atomic.Int32{}
+
+ for i := 0; i < n; i++ {
+ tc.Go(func(ctx context.Context) {
+ <-ctx.Done()
+ finished.Add(1)
+ })
+ }
+
+ tc.Close()
+
+ require.Equal(t, int32(n), finished.Load())
+}
diff --git a/core/web/auth/auth_test.go b/core/web/auth/auth_test.go
index 1adfeadfb17..ce369fce1b2 100644
--- a/core/web/auth/auth_test.go
+++ b/core/web/auth/auth_test.go
@@ -307,7 +307,7 @@ func TestRBAC_Routemap_Admin(t *testing.T) {
// Assert all admin routes
// no endpoint should return StatusUnauthorized
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
for _, route := range routesRolesMap {
func() {
var resp *http.Response
@@ -344,9 +344,8 @@ func TestRBAC_Routemap_Edit(t *testing.T) {
defer ts.Close()
// Create a test edit user to work with
- testUser := cltest.CreateUserWithRole(t, sessions.UserRoleEdit)
- require.NoError(t, app.SessionORM().CreateUser(&testUser))
- client := app.NewHTTPClient(testUser.Email)
+ u := &cltest.User{Role: sessions.UserRoleEdit}
+ client := app.NewHTTPClient(u)
// Assert all edit routes
for _, route := range routesRolesMap {
@@ -392,9 +391,8 @@ func TestRBAC_Routemap_Run(t *testing.T) {
defer ts.Close()
// Create a test run user to work with
- testUser := cltest.CreateUserWithRole(t, sessions.UserRoleRun)
- require.NoError(t, app.SessionORM().CreateUser(&testUser))
- client := app.NewHTTPClient(testUser.Email)
+ u := &cltest.User{Role: sessions.UserRoleRun}
+ client := app.NewHTTPClient(u)
// Assert all run routes
for _, route := range routesRolesMap {
@@ -440,9 +438,8 @@ func TestRBAC_Routemap_ViewOnly(t *testing.T) {
defer ts.Close()
// Create a test run user to work with
- testUser := cltest.CreateUserWithRole(t, sessions.UserRoleView)
- require.NoError(t, app.SessionORM().CreateUser(&testUser))
- client := app.NewHTTPClient(testUser.Email)
+ u := &cltest.User{Role: sessions.UserRoleView}
+ client := app.NewHTTPClient(u)
// Assert all view only routes
for i, route := range routesRolesMap {
diff --git a/core/web/bridge_types_controller_test.go b/core/web/bridge_types_controller_test.go
index 75baa8b9b46..7184b05f5e0 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)
})
}
@@ -134,7 +135,7 @@ func TestValidateBridgeNotExist(t *testing.T) {
func BenchmarkBridgeTypesController_Index(b *testing.B) {
app := cltest.NewApplication(b)
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
b.ResetTimer()
for n := 0; n < b.N; n++ {
@@ -149,7 +150,7 @@ func TestBridgeTypesController_Index(t *testing.T) {
app := cltest.NewApplication(t)
require.NoError(t, app.Start(testutils.Context(t)))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
bt, err := setupBridgeControllerIndex(t, app.BridgeORM())
assert.NoError(t, err)
@@ -217,7 +218,7 @@ func TestBridgeTypesController_Create_Success(t *testing.T) {
app := cltest.NewApplication(t)
require.NoError(t, app.Start(testutils.Context(t)))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
resp, cleanup := client.Post(
"/v2/bridge_types",
@@ -245,7 +246,7 @@ func TestBridgeTypesController_Update_Success(t *testing.T) {
app := cltest.NewApplication(t)
require.NoError(t, app.Start(testutils.Context(t)))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
bridgeName := testutils.RandomizeName("BRidgea")
bt := &bridges.BridgeType{
@@ -271,7 +272,7 @@ func TestBridgeController_Show(t *testing.T) {
app := cltest.NewApplication(t)
require.NoError(t, app.Start(testutils.Context(t)))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
bt := &bridges.BridgeType{
Name: bridges.MustParseBridgeName(testutils.RandomizeName("showbridge")),
@@ -301,7 +302,7 @@ func TestBridgeTypesController_Create_AdapterExistsError(t *testing.T) {
app := cltest.NewApplication(t)
require.NoError(t, app.Start(testutils.Context(t)))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
resp, cleanup := client.Post(
"/v2/bridge_types",
@@ -317,7 +318,7 @@ func TestBridgeTypesController_Create_BindJSONError(t *testing.T) {
app := cltest.NewApplication(t)
require.NoError(t, app.Start(testutils.Context(t)))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
resp, cleanup := client.Post(
"/v2/bridge_types",
@@ -333,7 +334,7 @@ func TestBridgeTypesController_Create_DatabaseError(t *testing.T) {
app := cltest.NewApplication(t)
require.NoError(t, app.Start(testutils.Context(t)))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
resp, cleanup := client.Post(
"/v2/bridge_types",
diff --git a/core/web/build_info_controller_test.go b/core/web/build_info_controller_test.go
index 96e7758363d..9a71951ed3d 100644
--- a/core/web/build_info_controller_test.go
+++ b/core/web/build_info_controller_test.go
@@ -18,7 +18,7 @@ func TestBuildInfoController_Show_APICredentials(t *testing.T) {
app := cltest.NewApplicationEVMDisabled(t)
require.NoError(t, app.Start(testutils.Context(t)))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
resp, cleanup := client.Get("/v2/build_info")
defer cleanup()
diff --git a/core/web/common.go b/core/web/common.go
index 1afc1636ba5..ae2158d153b 100644
--- a/core/web/common.go
+++ b/core/web/common.go
@@ -9,15 +9,13 @@ import (
)
var (
- ErrMissingChainID = errors.New("evmChainID does not match any local chains")
- ErrInvalidChainID = errors.New("invalid evmChainID")
- ErrMultipleChains = errors.New("more than one chain available, you must specify evmChainID parameter")
+ ErrMissingChainID = errors.New("chain id does not match any local chains")
+ ErrEmptyChainID = errors.New("chainID is empty")
+ ErrInvalidChainID = errors.New("invalid chain id")
+ ErrMultipleChains = errors.New("more than one chain available, you must specify chain id parameter")
)
func getChain(legacyChains evm.LegacyChainContainer, chainIDstr string) (chain evm.Chain, err error) {
- if legacyChains.Len() > 1 {
- return nil, ErrMultipleChains
- }
if chainIDstr != "" && chainIDstr != "" {
// evm keys are expected to be parsable as a big int
@@ -32,9 +30,9 @@ func getChain(legacyChains evm.LegacyChainContainer, chainIDstr string) (chain e
return chain, nil
}
- chain, err = legacyChains.Default()
- if err != nil {
- return nil, err
+ if legacyChains.Len() > 1 {
+ return nil, ErrMultipleChains
}
- return chain, nil
+
+ return nil, ErrEmptyChainID
}
diff --git a/core/web/cors_test.go b/core/web/cors_test.go
index 760b9066902..120a27c645b 100644
--- a/core/web/cors_test.go
+++ b/core/web/cors_test.go
@@ -29,7 +29,7 @@ func TestCors_DefaultOrigins(t *testing.T) {
t.Run(test.origin, func(t *testing.T) {
app := cltest.NewApplicationWithConfig(t, config)
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
headers := map[string]string{"Origin": test.origin}
resp, cleanup := client.Get("/v2/chains/evm", headers)
@@ -61,7 +61,7 @@ func TestCors_OverrideOrigins(t *testing.T) {
})
app := cltest.NewApplicationWithConfig(t, config)
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
headers := map[string]string{"Origin": test.origin}
resp, cleanup := client.Get("/v2/chains/evm", headers)
diff --git a/core/web/cosmos_chains_controller_test.go b/core/web/cosmos_chains_controller_test.go
index f670076d748..f443fb64228 100644
--- a/core/web/cosmos_chains_controller_test.go
+++ b/core/web/cosmos_chains_controller_test.go
@@ -48,7 +48,7 @@ BlockRate = '6s'
BlocksUntilTxTimeout = 30
ConfirmPollPeriod = '1s'
FallbackGasPrice = '9.999'
-FeeToken = 'ucosm'
+GasToken = 'ucosm'
GasLimitMultiplier = '1.55555'
MaxMsgsPerBatch = 100
OCR2CachePollPeriod = '4s'
@@ -185,7 +185,7 @@ func setupCosmosChainsControllerTestV2(t *testing.T, cfgs ...*cosmos.CosmosConfi
app := cltest.NewApplicationWithConfig(t, cfg)
require.NoError(t, app.Start(testutils.Context(t)))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
return &TestCosmosChainsController{
app: app,
diff --git a/core/web/cosmos_keys_controller_test.go b/core/web/cosmos_keys_controller_test.go
index b5f3ba82973..479ee686d57 100644
--- a/core/web/cosmos_keys_controller_test.go
+++ b/core/web/cosmos_keys_controller_test.go
@@ -41,7 +41,7 @@ func TestCosmosKeysController_Create_HappyPath(t *testing.T) {
app := cltest.NewApplicationEVMDisabled(t)
require.NoError(t, app.Start(testutils.Context(t)))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
keyStore := app.GetKeyStore()
response, cleanup := client.Post("/v2/keys/cosmos", nil)
@@ -98,7 +98,7 @@ func setupCosmosKeysControllerTests(t *testing.T) (cltest.HTTPClientCleaner, key
require.NoError(t, app.Start(testutils.Context(t)))
require.NoError(t, app.KeyStore.Cosmos().Add(cltest.DefaultCosmosKey))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
return client, app.GetKeyStore()
}
diff --git a/core/web/cosmos_nodes_controller.go b/core/web/cosmos_nodes_controller.go
index 756d1ded741..121d7d8422b 100644
--- a/core/web/cosmos_nodes_controller.go
+++ b/core/web/cosmos_nodes_controller.go
@@ -10,7 +10,9 @@ import (
var ErrCosmosNotEnabled = errChainDisabled{name: "Cosmos", tomlKey: "Cosmos.Enabled"}
func NewCosmosNodesController(app chainlink.Application) NodesController {
+ scopedNodeStatuser := NewNetworkScopedNodeStatuser(app.GetRelayers(), relay.Cosmos)
+
return newNodesController[presenters.CosmosNodeResource](
- app.GetRelayers().List(chainlink.FilterRelayersByType(relay.Cosmos)), ErrCosmosNotEnabled, presenters.NewCosmosNodeResource, app.GetAuditLogger(),
+ scopedNodeStatuser, ErrCosmosNotEnabled, presenters.NewCosmosNodeResource, app.GetAuditLogger(),
)
}
diff --git a/core/web/cosmos_transfer_controller.go b/core/web/cosmos_transfer_controller.go
index 2409a05e6a4..afe0fe16d1e 100644
--- a/core/web/cosmos_transfer_controller.go
+++ b/core/web/cosmos_transfer_controller.go
@@ -58,9 +58,9 @@ func (tc *CosmosTransfersController) Create(c *gin.Context) {
jsonAPIError(c, http.StatusUnprocessableEntity, errors.Errorf("withdrawal source address is missing: %v", tr.FromAddress))
return
}
- coin, err := denom.ConvertDecCoinToDenom(sdk.NewDecCoinFromDec(tr.Token, tr.Amount), chain.Config().FeeToken())
+ coin, err := denom.ConvertDecCoinToDenom(sdk.NewDecCoinFromDec(tr.Token, tr.Amount), chain.Config().GasToken())
if err != nil {
- jsonAPIError(c, http.StatusBadRequest, errors.Errorf("unable to convert %s to %s: %v", tr.Token, chain.Config().FeeToken(), err))
+ jsonAPIError(c, http.StatusBadRequest, errors.Errorf("unable to convert %s to %s: %v", tr.Token, chain.Config().GasToken(), err))
return
} else if !coin.Amount.IsPositive() {
jsonAPIError(c, http.StatusBadRequest, errors.Errorf("amount must be greater than zero: %s", coin.Amount))
diff --git a/core/web/dkgencrypt_keys_controller_test.go b/core/web/dkgencrypt_keys_controller_test.go
index 605d6f00087..5d8b1ab2328 100644
--- a/core/web/dkgencrypt_keys_controller_test.go
+++ b/core/web/dkgencrypt_keys_controller_test.go
@@ -103,7 +103,7 @@ func setupDKGEncryptKeysControllerTests(t *testing.T) (cltest.HTTPClientCleaner,
require.NoError(t, app.Start(testutils.Context(t)))
require.NoError(t, app.KeyStore.DKGEncrypt().Add(cltest.DefaultDKGEncryptKey))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
return client, app.GetKeyStore()
}
diff --git a/core/web/dkgsign_keys_controller_test.go b/core/web/dkgsign_keys_controller_test.go
index ee5be661fc1..0d6d167df99 100644
--- a/core/web/dkgsign_keys_controller_test.go
+++ b/core/web/dkgsign_keys_controller_test.go
@@ -103,7 +103,7 @@ func setupDKGSignKeysControllerTests(t *testing.T) (cltest.HTTPClientCleaner, ke
require.NoError(t, app.Start(testutils.Context(t)))
require.NoError(t, app.KeyStore.DKGSign().Add(cltest.DefaultDKGSignKey))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
return client, app.GetKeyStore()
}
diff --git a/core/web/eth_keys_controller_test.go b/core/web/eth_keys_controller_test.go
index 0ef01257e17..c36ca0aeb5a 100644
--- a/core/web/eth_keys_controller_test.go
+++ b/core/web/eth_keys_controller_test.go
@@ -56,7 +56,7 @@ func TestETHKeysController_Index_Success(t *testing.T) {
require.NoError(t, app.Start(testutils.Context(t)))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
resp, cleanup := client.Get("/v2/keys/evm")
defer cleanup()
require.Equal(t, http.StatusOK, resp.StatusCode)
@@ -100,7 +100,7 @@ func TestETHKeysController_Index_Errors(t *testing.T) {
require.NoError(t, app.Start(testutils.Context(t)))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
resp, cleanup := client.Get("/v2/keys/eth")
defer cleanup()
require.Equal(t, http.StatusOK, resp.StatusCode)
@@ -134,7 +134,7 @@ func TestETHKeysController_Index_Disabled(t *testing.T) {
require.NoError(t, app.Start(testutils.Context(t)))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
resp, cleanup := client.Get("/v2/keys/eth")
defer cleanup()
require.Equal(t, http.StatusOK, resp.StatusCode)
@@ -169,7 +169,7 @@ func TestETHKeysController_Index_NotDev(t *testing.T) {
app := cltest.NewApplicationWithConfigAndKey(t, cfg, ethClient)
require.NoError(t, app.Start(testutils.Context(t)))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
resp, cleanup := client.Get("/v2/keys/eth")
defer cleanup()
require.Equal(t, http.StatusOK, resp.StatusCode)
@@ -194,7 +194,7 @@ func TestETHKeysController_Index_NoAccounts(t *testing.T) {
app := cltest.NewApplication(t)
require.NoError(t, app.Start(testutils.Context(t)))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
resp, cleanup := client.Get("/v2/keys/eth")
defer cleanup()
@@ -224,11 +224,16 @@ func TestETHKeysController_CreateSuccess(t *testing.T) {
linkBalance := assets.NewLinkFromJuels(42)
ethClient.On("LINKBalance", mock.Anything, mock.Anything, mock.Anything).Return(linkBalance, nil)
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
require.NoError(t, app.Start(testutils.Context(t)))
- resp, cleanup := client.Post("/v2/keys/evm", nil)
+ chainURL := url.URL{Path: "/v2/keys/evm"}
+ query := chainURL.Query()
+ query.Set("evmChainID", cltest.FixtureChainID.String())
+ chainURL.RawQuery = query.Encode()
+
+ resp, cleanup := client.Post(chainURL.String(), nil)
defer cleanup()
cltest.AssertServerResponse(t, resp, http.StatusOK)
@@ -261,7 +266,7 @@ func TestETHKeysController_ChainSuccess_UpdateNonce(t *testing.T) {
require.NoError(t, app.Start(testutils.Context(t)))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
chainURL := url.URL{Path: "/v2/keys/evm/chain"}
query := chainURL.Query()
@@ -305,7 +310,7 @@ func TestETHKeysController_ChainSuccess_Disable(t *testing.T) {
require.NoError(t, app.Start(testutils.Context(t)))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
chainURL := url.URL{Path: "/v2/keys/evm/chain"}
query := chainURL.Query()
@@ -349,7 +354,7 @@ func TestETHKeysController_ChainSuccess_Enable(t *testing.T) {
require.NoError(t, app.Start(testutils.Context(t)))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
chainURL := url.URL{Path: "/v2/keys/evm/chain"}
query := chainURL.Query()
@@ -409,11 +414,11 @@ func TestETHKeysController_ChainSuccess_ResetWithAbandon(t *testing.T) {
assert.NoError(t, err)
var count int
- err = app.GetSqlxDB().Get(&count, `SELECT count(*) FROM eth_txes WHERE from_address = $1 AND state = 'fatal_error'`, addr)
+ err = app.GetSqlxDB().Get(&count, `SELECT count(*) FROM evm.txes WHERE from_address = $1 AND state = 'fatal_error'`, addr)
require.NoError(t, err)
assert.Equal(t, 0, count)
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
chainURL := url.URL{Path: "/v2/keys/evm/chain"}
query := chainURL.Query()
@@ -436,7 +441,7 @@ func TestETHKeysController_ChainSuccess_ResetWithAbandon(t *testing.T) {
assert.Equal(t, false, updatedKey.Disabled)
var s string
- err = app.GetSqlxDB().Get(&s, `SELECT error FROM eth_txes WHERE from_address = $1 AND state = 'fatal_error'`, addr)
+ err = app.GetSqlxDB().Get(&s, `SELECT error FROM evm.txes WHERE from_address = $1 AND state = 'fatal_error'`, addr)
require.NoError(t, err)
assert.Equal(t, "abandoned", s)
}
@@ -458,7 +463,7 @@ func TestETHKeysController_ChainFailure_InvalidAbandon(t *testing.T) {
require.NoError(t, app.Start(testutils.Context(t)))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
chainURL := url.URL{Path: "/v2/keys/evm/chain"}
query := chainURL.Query()
@@ -492,7 +497,7 @@ func TestETHKeysController_ChainFailure_InvalidEnabled(t *testing.T) {
require.NoError(t, app.Start(testutils.Context(t)))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
chainURL := url.URL{Path: "/v2/keys/evm/chain"}
query := chainURL.Query()
@@ -523,7 +528,7 @@ func TestETHKeysController_ChainFailure_InvalidAddress(t *testing.T) {
require.NoError(t, app.Start(testutils.Context(t)))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
chainURL := url.URL{Path: "/v2/keys/evm/chain"}
query := chainURL.Query()
@@ -553,7 +558,7 @@ func TestETHKeysController_ChainFailure_MissingAddress(t *testing.T) {
require.NoError(t, app.Start(testutils.Context(t)))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
chainURL := url.URL{Path: "/v2/keys/evm/chain"}
query := chainURL.Query()
@@ -583,7 +588,7 @@ func TestETHKeysController_ChainFailure_InvalidChainID(t *testing.T) {
require.NoError(t, app.Start(testutils.Context(t)))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
chainURL := url.URL{Path: "/v2/keys/evm/chain"}
query := chainURL.Query()
@@ -616,7 +621,7 @@ func TestETHKeysController_ChainFailure_MissingChainID(t *testing.T) {
require.NoError(t, app.Start(testutils.Context(t)))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
chainURL := url.URL{Path: "/v2/keys/evm/chain"}
query := chainURL.Query()
@@ -649,7 +654,7 @@ func TestETHKeysController_ChainFailure_InvalidNonce(t *testing.T) {
require.NoError(t, app.Start(testutils.Context(t)))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
chainURL := url.URL{Path: "/v2/keys/evm/chain"}
query := chainURL.Query()
@@ -685,7 +690,7 @@ func TestETHKeysController_DeleteSuccess(t *testing.T) {
require.NoError(t, app.Start(testutils.Context(t)))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
chainURL := url.URL{Path: "/v2/keys/evm/" + addr0.Hex()}
resp, cleanup := client.Delete(chainURL.String())
defer cleanup()
@@ -727,7 +732,7 @@ func TestETHKeysController_DeleteFailure_InvalidAddress(t *testing.T) {
require.NoError(t, app.Start(testutils.Context(t)))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
chainURL := url.URL{Path: "/v2/keys/evm" + "/bad_address"}
resp, cleanup := client.Delete(chainURL.String())
@@ -748,7 +753,7 @@ func TestETHKeysController_DeleteFailure_KeyMissing(t *testing.T) {
require.NoError(t, app.Start(testutils.Context(t)))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
chainURL := url.URL{Path: "/v2/keys/evm/" + testutils.NewAddress().Hex()}
resp, cleanup := client.Delete(chainURL.String())
diff --git a/core/web/evm_chains_controller_test.go b/core/web/evm_chains_controller_test.go
index 6c779868d1b..02e493a43b2 100644
--- a/core/web/evm_chains_controller_test.go
+++ b/core/web/evm_chains_controller_test.go
@@ -204,7 +204,7 @@ func setupEVMChainsControllerTest(t *testing.T, cfg chainlink.GeneralConfig) *Te
app := cltest.NewApplicationWithConfig(t, cfg)
require.NoError(t, app.Start(testutils.Context(t)))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
return &TestEVMChainsController{
app: app,
diff --git a/core/web/evm_forwarders_controller_test.go b/core/web/evm_forwarders_controller_test.go
index 705fce05c02..8927c014022 100644
--- a/core/web/evm_forwarders_controller_test.go
+++ b/core/web/evm_forwarders_controller_test.go
@@ -32,7 +32,7 @@ func setupEVMForwardersControllerTest(t *testing.T, overrideFn func(c *chainlink
app := cltest.NewApplicationWithConfig(t, configtest.NewGeneralConfig(t, overrideFn))
require.NoError(t, app.Start(testutils.Context(t)))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
return &TestEVMForwardersController{
app: app,
diff --git a/core/web/evm_nodes_controller.go b/core/web/evm_nodes_controller.go
index aba0faca8e8..c8d0b91c0f7 100644
--- a/core/web/evm_nodes_controller.go
+++ b/core/web/evm_nodes_controller.go
@@ -7,6 +7,8 @@ import (
)
func NewEVMNodesController(app chainlink.Application) NodesController {
+ scopedNodeStatuser := NewNetworkScopedNodeStatuser(app.GetRelayers(), relay.EVM)
+
return newNodesController[presenters.EVMNodeResource](
- app.GetRelayers().List(chainlink.FilterRelayersByType(relay.EVM)), ErrEVMNotEnabled, presenters.NewEVMNodeResource, app.GetAuditLogger())
+ scopedNodeStatuser, ErrEVMNotEnabled, presenters.NewEVMNodeResource, app.GetAuditLogger())
}
diff --git a/core/web/evm_transactions_controller_test.go b/core/web/evm_transactions_controller_test.go
index 475bb778300..951d9d99259 100644
--- a/core/web/evm_transactions_controller_test.go
+++ b/core/web/evm_transactions_controller_test.go
@@ -27,7 +27,7 @@ func TestTransactionsController_Index_Success(t *testing.T) {
db := app.GetSqlxDB()
txStore := cltest.NewTestTxStore(t, app.GetSqlxDB(), app.GetConfig().Database())
ethKeyStore := cltest.NewKeyStore(t, db, app.Config.Database()).Eth()
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
_, from := cltest.MustInsertRandomKey(t, ethKeyStore, 0)
cltest.MustInsertConfirmedEthTxWithLegacyAttempt(t, txStore, 0, 1, from) // tx1
@@ -69,7 +69,7 @@ func TestTransactionsController_Index_Error(t *testing.T) {
app := cltest.NewApplicationWithKey(t)
require.NoError(t, app.Start(testutils.Context(t)))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
resp, cleanup := client.Get("/v2/transactions?size=TrainingDay")
t.Cleanup(cleanup)
cltest.AssertServerResponse(t, resp, 422)
@@ -82,7 +82,7 @@ func TestTransactionsController_Show_Success(t *testing.T) {
require.NoError(t, app.Start(testutils.Context(t)))
txStore := cltest.NewTestTxStore(t, app.GetSqlxDB(), app.GetConfig().Database())
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
_, from := cltest.MustInsertRandomKey(t, app.KeyStore.Eth(), 0)
tx := cltest.MustInsertUnconfirmedEthTxWithBroadcastLegacyAttempt(t, txStore, 1, from)
@@ -115,7 +115,7 @@ func TestTransactionsController_Show_NotFound(t *testing.T) {
require.NoError(t, app.Start(testutils.Context(t)))
txStore := cltest.NewTestTxStore(t, app.GetSqlxDB(), app.GetConfig().Database())
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
_, from := cltest.MustInsertRandomKey(t, app.KeyStore.Eth(), 0)
tx := cltest.MustInsertUnconfirmedEthTxWithBroadcastLegacyAttempt(t, txStore, 1, from)
require.Len(t, tx.TxAttempts, 1)
diff --git a/core/web/evm_transfer_controller.go b/core/web/evm_transfer_controller.go
index a42ab923c90..69d55b54bba 100644
--- a/core/web/evm_transfer_controller.go
+++ b/core/web/evm_transfer_controller.go
@@ -1,14 +1,19 @@
package web
import (
+ "context"
+ "fmt"
"math/big"
"net/http"
+ "time"
"github.com/ethereum/go-ethereum/common"
"github.com/pkg/errors"
+ commontxmgr "github.com/smartcontractkit/chainlink/v2/common/txmgr"
"github.com/smartcontractkit/chainlink/v2/core/assets"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm"
+ "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr"
"github.com/smartcontractkit/chainlink/v2/core/logger/audit"
"github.com/smartcontractkit/chainlink/v2/core/services/chainlink"
"github.com/smartcontractkit/chainlink/v2/core/store/models"
@@ -68,7 +73,24 @@ func (tc *EVMTransfersController) Create(c *gin.Context) {
"ethTX": etx,
})
- jsonAPIResponse(c, presenters.NewEthTxResource(etx), "eth_tx")
+ // skip waiting for txmgr to create TxAttempt
+ if tr.SkipWaitTxAttempt {
+ jsonAPIResponse(c, presenters.NewEthTxResource(etx), "eth_tx")
+ return
+ }
+
+ timeout := 10 * time.Second // default
+ if tr.WaitAttemptTimeout != nil {
+ timeout = *tr.WaitAttemptTimeout
+ }
+
+ // wait and retrieve tx attempt matching tx ID
+ attempt, err := FindTxAttempt(c, timeout, etx, tc.App.TxmStorageService().FindTxWithAttempts)
+ if err != nil {
+ jsonAPIError(c, http.StatusGatewayTimeout, fmt.Errorf("failed to find transaction within timeout: %w", err))
+ return
+ }
+ jsonAPIResponse(c, presenters.NewEthTxResourceFromAttempt(attempt), "eth_tx")
}
// ValidateEthBalanceForTransfer validates that the current balance can cover the transaction amount
@@ -107,3 +129,33 @@ func ValidateEthBalanceForTransfer(c *gin.Context, chain evm.Chain, fromAddr com
return nil
}
+
+func FindTxAttempt(ctx context.Context, timeout time.Duration, etx txmgr.Tx, FindTxWithAttempts func(int64) (txmgr.Tx, error)) (attempt txmgr.TxAttempt, err error) {
+ recheckTime := time.Second
+ tick := time.After(0)
+ ctx, cancel := context.WithTimeout(ctx, timeout)
+ defer cancel()
+ for {
+ select {
+ case <-ctx.Done():
+ return attempt, fmt.Errorf("%w - tx may still have been broadcast", ctx.Err())
+ case <-tick:
+ etx, err = FindTxWithAttempts(etx.ID)
+ if err != nil {
+ return attempt, fmt.Errorf("failed to find transaction: %w", err)
+ }
+ }
+
+ // exit if tx attempts are found
+ // also validate etx.State != unstarted (ensure proper tx state for tx with attempts)
+ if len(etx.TxAttempts) > 0 && etx.State != commontxmgr.TxUnstarted {
+ break
+ }
+ tick = time.After(recheckTime)
+ }
+
+ // attach original tx to attempt
+ attempt = etx.TxAttempts[0]
+ attempt.Tx = etx
+ return attempt, nil
+}
diff --git a/core/web/evm_transfer_controller_test.go b/core/web/evm_transfer_controller_test.go
index c58b810e67c..8b44b3eb6b6 100644
--- a/core/web/evm_transfer_controller_test.go
+++ b/core/web/evm_transfer_controller_test.go
@@ -2,17 +2,26 @@ package web_test
import (
"bytes"
+ "context"
"encoding/json"
+ "fmt"
"math/big"
"net/http"
"testing"
+ "time"
"github.com/smartcontractkit/chainlink/v2/core/assets"
+ "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr"
+ evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types"
"github.com/smartcontractkit/chainlink/v2/core/internal/cltest"
"github.com/smartcontractkit/chainlink/v2/core/internal/testutils"
configtest2 "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/configtest/v2"
+ "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/evmtest"
"github.com/smartcontractkit/chainlink/v2/core/services/chainlink"
"github.com/smartcontractkit/chainlink/v2/core/store/models"
+ "github.com/smartcontractkit/chainlink/v2/core/utils"
+ "github.com/smartcontractkit/chainlink/v2/core/web"
+ "github.com/smartcontractkit/chainlink/v2/core/web/presenters"
"github.com/ethereum/go-ethereum/common"
"github.com/stretchr/testify/assert"
@@ -36,7 +45,7 @@ func TestTransfersController_CreateSuccess_From(t *testing.T) {
app := cltest.NewApplicationWithKey(t, ethClient, key)
require.NoError(t, app.Start(testutils.Context(t)))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
amount, err := assets.NewEthValueS("100")
require.NoError(t, err)
@@ -45,6 +54,8 @@ func TestTransfersController_CreateSuccess_From(t *testing.T) {
DestinationAddress: common.HexToAddress("0xFA01FA015C8A5332987319823728982379128371"),
FromAddress: key.Address,
Amount: amount,
+ SkipWaitTxAttempt: true,
+ EVMChainID: utils.NewBig(evmtest.MustGetDefaultChainID(t, app.Config.EVMConfigs())),
}
body, err := json.Marshal(&request)
@@ -57,7 +68,7 @@ func TestTransfersController_CreateSuccess_From(t *testing.T) {
assert.Equal(t, http.StatusOK, resp.StatusCode)
assert.Len(t, errors.Errors, 0)
- cltest.AssertCount(t, app.GetSqlxDB(), "eth_txes", 1)
+ cltest.AssertCount(t, app.GetSqlxDB(), "evm.txes", 1)
}
func TestTransfersController_CreateSuccess_From_WEI(t *testing.T) {
@@ -76,7 +87,7 @@ func TestTransfersController_CreateSuccess_From_WEI(t *testing.T) {
app := cltest.NewApplicationWithKey(t, ethClient, key)
require.NoError(t, app.Start(testutils.Context(t)))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
amount := assets.NewEthValue(1000000000000000000)
@@ -84,6 +95,8 @@ func TestTransfersController_CreateSuccess_From_WEI(t *testing.T) {
DestinationAddress: common.HexToAddress("0xFA01FA015C8A5332987319823728982379128371"),
FromAddress: key.Address,
Amount: amount,
+ SkipWaitTxAttempt: true,
+ EVMChainID: utils.NewBig(evmtest.MustGetDefaultChainID(t, app.Config.EVMConfigs())),
}
body, err := json.Marshal(&request)
@@ -96,7 +109,7 @@ func TestTransfersController_CreateSuccess_From_WEI(t *testing.T) {
assert.Equal(t, http.StatusOK, resp.StatusCode)
assert.Len(t, errors.Errors, 0)
- cltest.AssertCount(t, app.GetSqlxDB(), "eth_txes", 1)
+ cltest.AssertCount(t, app.GetSqlxDB(), "evm.txes", 1)
}
func TestTransfersController_CreateSuccess_From_BalanceMonitorDisabled(t *testing.T) {
@@ -119,7 +132,7 @@ func TestTransfersController_CreateSuccess_From_BalanceMonitorDisabled(t *testin
app := cltest.NewApplicationWithConfigAndKey(t, config, ethClient, key)
require.NoError(t, app.Start(testutils.Context(t)))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
amount, err := assets.NewEthValueS("100")
require.NoError(t, err)
@@ -128,6 +141,8 @@ func TestTransfersController_CreateSuccess_From_BalanceMonitorDisabled(t *testin
DestinationAddress: common.HexToAddress("0xFA01FA015C8A5332987319823728982379128371"),
FromAddress: key.Address,
Amount: amount,
+ SkipWaitTxAttempt: true,
+ EVMChainID: utils.NewBig(evmtest.MustGetDefaultChainID(t, app.Config.EVMConfigs())),
}
body, err := json.Marshal(&request)
@@ -140,7 +155,7 @@ func TestTransfersController_CreateSuccess_From_BalanceMonitorDisabled(t *testin
assert.Equal(t, http.StatusOK, resp.StatusCode)
assert.Len(t, errors.Errors, 0)
- cltest.AssertCount(t, app.GetSqlxDB(), "eth_txes", 1)
+ cltest.AssertCount(t, app.GetSqlxDB(), "evm.txes", 1)
}
func TestTransfersController_TransferZeroAddressError(t *testing.T) {
@@ -152,11 +167,12 @@ func TestTransfersController_TransferZeroAddressError(t *testing.T) {
amount, err := assets.NewEthValueS("100")
require.NoError(t, err)
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
request := models.SendEtherRequest{
DestinationAddress: common.HexToAddress("0xFA01FA015C8A5332987319823728982379128371"),
FromAddress: common.HexToAddress("0x0000000000000000000000000000000000000000"),
Amount: amount,
+ EVMChainID: utils.NewBig(evmtest.MustGetDefaultChainID(t, app.Config.EVMConfigs())),
}
body, err := json.Marshal(&request)
@@ -181,7 +197,7 @@ func TestTransfersController_TransferBalanceToLowError(t *testing.T) {
app := cltest.NewApplicationWithKey(t, ethClient, key)
require.NoError(t, app.Start(testutils.Context(t)))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
amount, err := assets.NewEthValueS("100")
require.NoError(t, err)
@@ -191,6 +207,7 @@ func TestTransfersController_TransferBalanceToLowError(t *testing.T) {
DestinationAddress: common.HexToAddress("0xFA01FA015C8A5332987319823728982379128371"),
Amount: amount,
AllowHigherAmounts: false,
+ EVMChainID: utils.NewBig(evmtest.MustGetDefaultChainID(t, app.Config.EVMConfigs())),
}
body, err := json.Marshal(&request)
@@ -218,7 +235,7 @@ func TestTransfersController_TransferBalanceToLowError_ZeroBalance(t *testing.T)
app := cltest.NewApplicationWithKey(t, ethClient, key)
require.NoError(t, app.Start(testutils.Context(t)))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
amount, err := assets.NewEthValueS("100")
require.NoError(t, err)
@@ -228,6 +245,7 @@ func TestTransfersController_TransferBalanceToLowError_ZeroBalance(t *testing.T)
DestinationAddress: common.HexToAddress("0xFA01FA015C8A5332987319823728982379128371"),
Amount: amount,
AllowHigherAmounts: false,
+ EVMChainID: utils.NewBig(evmtest.MustGetDefaultChainID(t, app.Config.EVMConfigs())),
}
body, err := json.Marshal(&request)
@@ -245,7 +263,7 @@ func TestTransfersController_JSONBindingError(t *testing.T) {
app := cltest.NewApplicationWithKey(t)
require.NoError(t, app.Start(testutils.Context(t)))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
resp, cleanup := client.Post("/v2/transfers", bytes.NewBuffer([]byte(`{"address":""}`)))
t.Cleanup(cleanup)
@@ -265,24 +283,32 @@ func TestTransfersController_CreateSuccess_eip1559(t *testing.T) {
ethClient.On("PendingNonceAt", mock.Anything, key.Address).Return(uint64(1), nil)
ethClient.On("BalanceAt", mock.Anything, key.Address, (*big.Int)(nil)).Return(balance.ToInt(), nil)
+ ethClient.On("SequenceAt", mock.Anything, mock.Anything, mock.Anything).Return(evmtypes.Nonce(0), nil).Maybe()
config := configtest2.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) {
c.EVM[0].GasEstimator.EIP1559DynamicFees = ptr(true)
c.EVM[0].GasEstimator.Mode = ptr("FixedPrice")
+ c.EVM[0].ChainID = (*utils.Big)(testutils.FixtureChainID)
+ // NOTE: FallbackPollInterval is used in this test to quickly create TxAttempts
+ // Testing triggers requires committing transactions and does not work with transactional tests
+ c.Database.Listener.FallbackPollInterval = models.MustNewDuration(time.Second)
})
app := cltest.NewApplicationWithConfigAndKey(t, config, ethClient, key)
require.NoError(t, app.Start(testutils.Context(t)))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
amount, err := assets.NewEthValueS("100")
require.NoError(t, err)
+ timeout := 5 * time.Second
request := models.SendEtherRequest{
DestinationAddress: common.HexToAddress("0xFA01FA015C8A5332987319823728982379128371"),
FromAddress: key.Address,
Amount: amount,
+ WaitAttemptTimeout: &timeout,
+ EVMChainID: utils.NewBig(evmtest.MustGetDefaultChainID(t, config.EVMConfigs())),
}
body, err := json.Marshal(&request)
@@ -291,9 +317,76 @@ func TestTransfersController_CreateSuccess_eip1559(t *testing.T) {
resp, cleanup := client.Post("/v2/transfers", bytes.NewBuffer(body))
t.Cleanup(cleanup)
- errors := cltest.ParseJSONAPIErrors(t, resp.Body)
- assert.Equal(t, http.StatusOK, resp.StatusCode)
- assert.Len(t, errors.Errors, 0)
+ cltest.AssertServerResponse(t, resp, http.StatusOK)
+
+ resource := presenters.EthTxResource{}
+ err = web.ParseJSONAPIResponse(cltest.ParseResponseBody(t, resp), &resource)
+ assert.NoError(t, err)
- cltest.AssertCount(t, app.GetSqlxDB(), "eth_txes", 1)
+ cltest.AssertCount(t, app.GetSqlxDB(), "evm.txes", 1)
+
+ // check returned data
+ assert.NotEmpty(t, resource.Hash)
+ assert.NotEmpty(t, resource.To)
+ assert.NotEmpty(t, resource.From)
+ assert.NotEmpty(t, resource.Nonce)
+ assert.NotEqual(t, "unstarted", resource.State)
+}
+
+func TestTransfersController_FindTxAttempt(t *testing.T) {
+ ctx := testutils.Context(t)
+ tx := txmgr.Tx{ID: 1}
+ attempt := txmgr.TxAttempt{ID: 2}
+ txWithAttempt := txmgr.Tx{ID: 1, TxAttempts: []txmgr.TxAttempt{attempt}}
+
+ // happy path
+ t.Run("happy_path", func(t *testing.T) {
+ timeout := 5 * time.Second
+ var done bool
+ find := func(_ int64) (txmgr.Tx, error) {
+ if !done {
+ done = true
+ return tx, nil
+ }
+ return txWithAttempt, nil
+ }
+ a, err := web.FindTxAttempt(ctx, timeout, tx, find)
+ require.NoError(t, err)
+ assert.Equal(t, tx.ID, a.Tx.ID)
+ assert.Equal(t, attempt.ID, a.ID)
+ })
+
+ // failed to find tx
+ t.Run("failed to find tx", func(t *testing.T) {
+ find := func(_ int64) (txmgr.Tx, error) {
+ return txmgr.Tx{}, fmt.Errorf("ERRORED")
+ }
+ _, err := web.FindTxAttempt(ctx, time.Second, tx, find)
+ assert.ErrorContains(t, err, "failed to find transaction")
+ })
+
+ // timeout
+ t.Run("timeout", func(t *testing.T) {
+ find := func(_ int64) (txmgr.Tx, error) {
+ return tx, nil
+ }
+ _, err := web.FindTxAttempt(ctx, time.Second, tx, find)
+ assert.ErrorContains(t, err, "context deadline exceeded")
+ })
+
+ // context canceled
+ t.Run("context canceled", func(t *testing.T) {
+ find := func(_ int64) (txmgr.Tx, error) {
+ return tx, nil
+ }
+
+ ctx, cancel := context.WithCancel(ctx)
+ go func() {
+ time.Sleep(1 * time.Second)
+ cancel()
+ }()
+
+ _, err := web.FindTxAttempt(ctx, 5*time.Second, tx, find)
+ assert.ErrorContains(t, err, "context canceled")
+ })
}
diff --git a/core/web/evm_tx_attempts_controller_test.go b/core/web/evm_tx_attempts_controller_test.go
index 9fd19cb10fe..abf80add213 100644
--- a/core/web/evm_tx_attempts_controller_test.go
+++ b/core/web/evm_tx_attempts_controller_test.go
@@ -21,7 +21,7 @@ func TestTxAttemptsController_Index_Success(t *testing.T) {
require.NoError(t, app.Start(testutils.Context(t)))
txStore := cltest.NewTestTxStore(t, app.GetSqlxDB(), app.GetConfig().Database())
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
_, from := cltest.MustInsertRandomKey(t, app.KeyStore.Eth(), 0)
@@ -51,7 +51,7 @@ func TestTxAttemptsController_Index_Error(t *testing.T) {
app := cltest.NewApplicationWithKey(t)
require.NoError(t, app.Start(testutils.Context(t)))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
resp, cleanup := client.Get("/v2/tx_attempts?size=TrainingDay")
t.Cleanup(cleanup)
cltest.AssertServerResponse(t, resp, 422)
diff --git a/core/web/external_initiators_controller_test.go b/core/web/external_initiators_controller_test.go
index 5fb8969d265..bc7d46a4f91 100644
--- a/core/web/external_initiators_controller_test.go
+++ b/core/web/external_initiators_controller_test.go
@@ -74,7 +74,7 @@ func TestExternalInitiatorsController_Index(t *testing.T) {
}))
require.NoError(t, app.Start(testutils.Context(t)))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
db := app.GetSqlxDB()
borm := bridges.NewORM(db, logger.TestLogger(t), app.GetConfig().Database())
@@ -140,7 +140,7 @@ func TestExternalInitiatorsController_Create_success(t *testing.T) {
}))
require.NoError(t, app.Start(testutils.Context(t)))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
resp, cleanup := client.Post("/v2/external_initiators",
bytes.NewBufferString(`{"name":"bitcoin","url":"http://without.a.name"}`),
@@ -168,7 +168,7 @@ func TestExternalInitiatorsController_Create_without_URL(t *testing.T) {
}))
require.NoError(t, app.Start(testutils.Context(t)))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
resp, cleanup := client.Post("/v2/external_initiators",
bytes.NewBufferString(`{"name":"no-url"}`),
@@ -196,7 +196,7 @@ func TestExternalInitiatorsController_Create_invalid(t *testing.T) {
}))
require.NoError(t, app.Start(testutils.Context(t)))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
resp, cleanup := client.Post("/v2/external_initiators",
bytes.NewBufferString(`{"url":"http://without.a.name"}`),
@@ -220,7 +220,7 @@ func TestExternalInitiatorsController_Delete(t *testing.T) {
err := app.BridgeORM().CreateExternalInitiator(&exi)
require.NoError(t, err)
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
resp, cleanup := client.Delete("/v2/external_initiators/" + exi.Name)
t.Cleanup(cleanup)
@@ -236,7 +236,7 @@ func TestExternalInitiatorsController_DeleteNotFound(t *testing.T) {
}))
require.NoError(t, app.Start(testutils.Context(t)))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
tests := []struct {
Name string
diff --git a/core/web/features_controller_test.go b/core/web/features_controller_test.go
index 82b68bcbac5..33520093347 100644
--- a/core/web/features_controller_test.go
+++ b/core/web/features_controller_test.go
@@ -21,7 +21,7 @@ func Test_FeaturesController_List(t *testing.T) {
c.Feature.UICSAKeys = &csa
}))
require.NoError(t, app.Start(testutils.Context(t)))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
resp, cleanup := client.Get("/v2/features")
t.Cleanup(cleanup)
diff --git a/core/web/health_controller_test.go b/core/web/health_controller_test.go
index 020038b2f3f..5f915dfedce 100644
--- a/core/web/health_controller_test.go
+++ b/core/web/health_controller_test.go
@@ -40,7 +40,7 @@ func TestHealthController_Readyz(t *testing.T) {
app.HealthChecker = healthChecker
require.NoError(t, app.Start(testutils.Context(t)))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
resp, cleanup := client.Get("/readyz")
t.Cleanup(cleanup)
assert.Equal(t, tc.status, resp.StatusCode)
diff --git a/core/web/jobs_controller_test.go b/core/web/jobs_controller_test.go
index b8b68e402d5..f18fcdd8c29 100644
--- a/core/web/jobs_controller_test.go
+++ b/core/web/jobs_controller_test.go
@@ -7,6 +7,7 @@ import (
"fmt"
"io"
"net/http"
+ "net/url"
"strconv"
"sync"
"testing"
@@ -186,7 +187,7 @@ func TestJobController_Create_HappyPath(t *testing.T) {
name = "example keeper spec"
contractAddress = "0x9E40733cC9df84636505f4e6Db28DCa0dC5D1bba"
fromAddress = "0xa8037A20989AFcBC51798de9762b351D63ff462e"
- evmChainId = 4
+ evmChainID = 0
minIncomingConfigurations = 1
externalJobID = "123e4567-e89b-12d3-a456-426655440002"
`,
@@ -358,7 +359,7 @@ func TestJobsController_Create_WebhookSpec(t *testing.T) {
_, fetchBridge := cltest.MustCreateBridge(t, app.GetSqlxDB(), cltest.BridgeOpts{}, app.GetConfig().Database())
_, submitBridge := cltest.MustCreateBridge(t, app.GetSqlxDB(), cltest.BridgeOpts{}, app.GetConfig().Database())
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
tomlStr := fmt.Sprintf(testspecs.WebhookSpecNoBody, fetchBridge.Name.String(), submitBridge.Name.String())
body, _ := json.Marshal(web.CreateJobRequest{
@@ -381,7 +382,7 @@ func TestJobsController_FailToCreate_EmptyJsonAttribute(t *testing.T) {
app := cltest.NewApplicationEVMDisabled(t)
require.NoError(t, app.Start(testutils.Context(t)))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
tomlBytes := cltest.MustReadFile(t, "../testdata/tomlspecs/webhook-job-spec-with-empty-json.toml")
body, _ := json.Marshal(web.CreateJobRequest{
@@ -398,7 +399,12 @@ func TestJobsController_FailToCreate_EmptyJsonAttribute(t *testing.T) {
func TestJobsController_Index_HappyPath(t *testing.T) {
_, client, ocrJobSpecFromFile, _, ereJobSpecFromFile, _ := setupJobSpecsControllerTestsWithJobs(t)
- response, cleanup := client.Get("/v2/jobs")
+ url := url.URL{Path: "/v2/jobs"}
+ query := url.Query()
+ query.Set("evmChainID", cltest.FixtureChainID.String())
+ url.RawQuery = query.Encode()
+
+ response, cleanup := client.Get(url.String())
t.Cleanup(cleanup)
cltest.AssertServerResponse(t, response, http.StatusOK)
@@ -487,7 +493,7 @@ func TestJobsController_Update_HappyPath(t *testing.T) {
_, bridge := cltest.MustCreateBridge(t, app.GetSqlxDB(), cltest.BridgeOpts{}, app.GetConfig().Database())
_, bridge2 := cltest.MustCreateBridge(t, app.GetSqlxDB(), cltest.BridgeOpts{}, app.GetConfig().Database())
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
var jb job.Job
ocrspec := testspecs.GenerateOCRSpec(testspecs.OCRSpecParams{
@@ -549,7 +555,7 @@ func TestJobsController_Update_NonExistentID(t *testing.T) {
_, bridge := cltest.MustCreateBridge(t, app.GetSqlxDB(), cltest.BridgeOpts{}, app.GetConfig().Database())
_, bridge2 := cltest.MustCreateBridge(t, app.GetSqlxDB(), cltest.BridgeOpts{}, app.GetConfig().Database())
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
var jb job.Job
ocrspec := testspecs.GenerateOCRSpec(testspecs.OCRSpecParams{
@@ -629,7 +635,7 @@ func setupJobsControllerTests(t *testing.T) (ta *cltest.TestApplication, cc clte
app := cltest.NewApplicationWithConfigAndKey(t, cfg, cltest.DefaultP2PKey)
require.NoError(t, app.Start(testutils.Context(t)))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
vrfKeyStore := app.GetKeyStore().VRF()
_, err := vrfKeyStore.Create()
require.NoError(t, err)
@@ -650,10 +656,10 @@ func setupJobSpecsControllerTestsWithJobs(t *testing.T) (*cltest.TestApplication
_, bridge := cltest.MustCreateBridge(t, app.GetSqlxDB(), cltest.BridgeOpts{}, app.GetConfig().Database())
_, bridge2 := cltest.MustCreateBridge(t, app.GetSqlxDB(), cltest.BridgeOpts{}, app.GetConfig().Database())
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
var jb job.Job
- ocrspec := testspecs.GenerateOCRSpec(testspecs.OCRSpecParams{DS1BridgeName: bridge.Name.String(), DS2BridgeName: bridge2.Name.String()})
+ ocrspec := testspecs.GenerateOCRSpec(testspecs.OCRSpecParams{DS1BridgeName: bridge.Name.String(), DS2BridgeName: bridge2.Name.String(), EVMChainID: testutils.FixtureChainID.String()})
err := toml.Unmarshal([]byte(ocrspec.Toml()), &jb)
require.NoError(t, err)
var ocrSpec job.OCROracleSpec
diff --git a/core/web/loader/chain.go b/core/web/loader/chain.go
index 77e231ace13..c91c2f02a3b 100644
--- a/core/web/loader/chain.go
+++ b/core/web/loader/chain.go
@@ -7,6 +7,7 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/chains"
"github.com/smartcontractkit/chainlink/v2/core/services/chainlink"
+ "github.com/smartcontractkit/chainlink/v2/core/services/relay"
)
type chainBatcher struct {
@@ -17,14 +18,14 @@ func (b *chainBatcher) loadByIDs(_ context.Context, keys dataloader.Keys) []*dat
// Create a map for remembering the order of keys passed in
keyOrder := make(map[string]int, len(keys))
// Collect the keys to search for
- var chainIDs []string
+ var chainIDs []relay.ChainID
for ix, key := range keys {
- chainIDs = append(chainIDs, key.String())
+ chainIDs = append(chainIDs, relay.ChainID(key.String()))
keyOrder[key.String()] = ix
}
// Fetch the chains
- cs, _, err := b.app.EVMORM().Chains(0, -1, chainIDs...)
+ cs, _, err := b.app.EVMORM().Chains(chainIDs...)
if err != nil {
return []*dataloader.Result{{Data: nil, Error: err}}
}
diff --git a/core/web/loader/loader_test.go b/core/web/loader/loader_test.go
index d5123053cf2..0dd45a1735d 100644
--- a/core/web/loader/loader_test.go
+++ b/core/web/loader/loader_test.go
@@ -81,7 +81,7 @@ func TestLoader_Nodes(t *testing.T) {
}
rcInterops := chainlinkmocks.NewRelayerChainInteroperators(t)
rcInterops.On("NodeStatuses", mock.Anything, 0, -1,
- relayID2.String(), relayID1.String(), notARelayID.String()).Return([]relaytypes.NodeStatus{
+ relayID2, relayID1, notARelayID).Return([]relaytypes.NodeStatus{
genNodeStat(chainID2.String()), genNodeStat(chainID1.String()),
}, 2, nil)
diff --git a/core/web/loader/node.go b/core/web/loader/node.go
index fb0c58d1f2c..9ea6062dc29 100644
--- a/core/web/loader/node.go
+++ b/core/web/loader/node.go
@@ -20,15 +20,15 @@ func (b *nodeBatcher) loadByChainIDs(ctx context.Context, keys dataloader.Keys)
keyOrder := make(map[string]int, len(keys))
// Collect the keys to search for
// note backward compatibility -- this only ever supported evm chains
- var evmrelayIdStrs []string
+ evmrelayIDs := make([]relay.ID, 0, len(keys))
for ix, key := range keys {
rid := relay.ID{Network: relay.EVM, ChainID: relay.ChainID(key.String())}
- evmrelayIdStrs = append(evmrelayIdStrs, rid.String())
+ evmrelayIDs = append(evmrelayIDs, rid)
keyOrder[key.String()] = ix
}
- allNodes, _, err := b.app.GetRelayers().NodeStatuses(ctx, 0, -1, evmrelayIdStrs...)
+ allNodes, _, err := b.app.GetRelayers().NodeStatuses(ctx, 0, -1, evmrelayIDs...)
if err != nil {
return []*dataloader.Result{{Data: nil, Error: err}}
}
diff --git a/core/web/log_controller_test.go b/core/web/log_controller_test.go
index 7a427bcb8ea..029dc4e8d3f 100644
--- a/core/web/log_controller_test.go
+++ b/core/web/log_controller_test.go
@@ -41,7 +41,7 @@ func TestLogController_GetLogConfig(t *testing.T) {
app := cltest.NewApplicationWithConfig(t, cfg)
require.NoError(t, app.Start(testutils.Context(t)))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
resp, err := client.HTTPClient.Get("/v2/log")
require.NoError(t, err)
@@ -112,7 +112,7 @@ func TestLogController_PatchLogConfig(t *testing.T) {
t.Run(tc.Description, func(t *testing.T) {
app := cltest.NewApplicationEVMDisabled(t)
require.NoError(t, app.Start(testutils.Context(t)))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
request := web.LogPatchRequest{Level: tc.logLevel, SqlEnabled: tc.logSql}
diff --git a/core/web/loop_registry.go b/core/web/loop_registry.go
index 4bbcef2b44a..345ff03704e 100644
--- a/core/web/loop_registry.go
+++ b/core/web/loop_registry.go
@@ -48,19 +48,12 @@ func (l *LoopRegistryServer) discoveryHandler(w http.ResponseWriter, req *http.R
w.Header().Set("Content-Type", "application/json")
var groups []*targetgroup.Group
- for _, registeredPlugin := range l.registry.List() {
- // create a metric target for each running plugin
- target := &targetgroup.Group{
- Targets: []model.LabelSet{
- // target address will be called by external prometheus
- {model.AddressLabel: model.LabelValue(fmt.Sprintf("%s:%d", l.discoveryHostName, l.exposedPromPort))},
- },
- Labels: map[model.LabelName]model.LabelValue{
- model.MetricsPathLabel: model.LabelValue(pluginMetricPath(registeredPlugin.Name)),
- },
- }
+ // add node metrics to service discovery
+ groups = append(groups, metricTarget(l.discoveryHostName, l.exposedPromPort, "/metrics"))
- groups = append(groups, target)
+ // add all the plugins
+ for _, registeredPlugin := range l.registry.List() {
+ groups = append(groups, metricTarget(l.discoveryHostName, l.exposedPromPort, pluginMetricPath(registeredPlugin.Name)))
}
b, err := l.jsonMarshalFn(groups)
@@ -80,6 +73,18 @@ func (l *LoopRegistryServer) discoveryHandler(w http.ResponseWriter, req *http.R
}
+func metricTarget(hostName string, port int, path string) *targetgroup.Group {
+ return &targetgroup.Group{
+ Targets: []model.LabelSet{
+ // target address will be called by external prometheus
+ {model.AddressLabel: model.LabelValue(fmt.Sprintf("%s:%d", hostName, port))},
+ },
+ Labels: map[model.LabelName]model.LabelValue{
+ model.MetricsPathLabel: model.LabelValue(path),
+ },
+ }
+}
+
// pluginMetricHandlers routes from endpoints published in service discovery to the the backing LOOP endpoint
func (l *LoopRegistryServer) pluginMetricHandler(gc *gin.Context) {
pluginName := gc.Param("name")
diff --git a/core/web/loop_registry_test.go b/core/web/loop_registry_test.go
index 5f737952aec..848579214f3 100644
--- a/core/web/loop_registry_test.go
+++ b/core/web/loop_registry_test.go
@@ -1,6 +1,7 @@
package web_test
import (
+ "encoding/json"
"fmt"
"io"
"net/http"
@@ -8,6 +9,9 @@ import (
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
+ "github.com/prometheus/common/model"
+ "github.com/prometheus/prometheus/discovery/targetgroup"
+ "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/smartcontractkit/chainlink/v2/core/internal/cltest"
@@ -67,7 +71,13 @@ func TestLoopRegistry(t *testing.T) {
// shim a reference to the promserver that is running in our mock loop
// this ensures the client.Get calls below have a reference to mock loop impl
- expectedEndPoint := "/plugins/mockLoopImpl/metrics"
+ expectedLooppEndPoint, expectedCoreEndPoint := "/plugins/mockLoopImpl/metrics", "/metrics"
+
+ // note we expect this to be an ordered result
+ expectedLabels := []model.LabelSet{
+ model.LabelSet{"__metrics_path__": model.LabelValue(expectedCoreEndPoint)},
+ model.LabelSet{"__metrics_path__": model.LabelValue(expectedLooppEndPoint)},
+ }
require.NoError(t, app.KeyStore.OCR().Add(cltest.DefaultOCRKey))
require.NoError(t, app.Start(testutils.Context(t)))
@@ -86,7 +96,7 @@ func TestLoopRegistry(t *testing.T) {
defer mockLoop.close()
mockLoop.run()
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
t.Run("discovery endpoint", func(t *testing.T) {
// under the covers this is routing thru the app into loop registry
@@ -97,12 +107,22 @@ func TestLoopRegistry(t *testing.T) {
b, err := io.ReadAll(resp.Body)
require.NoError(t, err)
t.Logf("discovery response %s", b)
- require.Contains(t, string(b), expectedEndPoint)
+ var got []*targetgroup.Group
+ require.NoError(t, json.Unmarshal(b, &got))
+
+ gotLabels := make([]model.LabelSet, 0)
+ for _, ls := range got {
+ gotLabels = append(gotLabels, ls.Labels)
+ }
+ assert.Equal(t, len(expectedLabels), len(gotLabels))
+ for i := range expectedLabels {
+ assert.EqualValues(t, expectedLabels[i], gotLabels[i])
+ }
})
t.Run("plugin metrics OK", func(t *testing.T) {
// plugin name `mockLoopImpl` matches key in PluginConfigs
- resp, cleanup := client.Get(expectedEndPoint)
+ resp, cleanup := client.Get(expectedLooppEndPoint)
t.Cleanup(cleanup)
cltest.AssertServerResponse(t, resp, http.StatusOK)
@@ -117,6 +137,17 @@ func TestLoopRegistry(t *testing.T) {
require.Contains(t, string(b), expectedMetric)
})
+ t.Run("core metrics OK", func(t *testing.T) {
+ // core node metrics endpoint
+ resp, cleanup := client.Get(expectedCoreEndPoint)
+ t.Cleanup(cleanup)
+ cltest.AssertServerResponse(t, resp, http.StatusOK)
+
+ b, err := io.ReadAll(resp.Body)
+ require.NoError(t, err)
+ t.Logf("core metrics response %s", b)
+ })
+
t.Run("no existent plugin metrics ", func(t *testing.T) {
// request plugin that doesn't exist
resp, cleanup := client.Get("/plugins/noexist/metrics")
diff --git a/core/web/nodes_controller.go b/core/web/nodes_controller.go
index e65f3e68a8a..1eddc67c364 100644
--- a/core/web/nodes_controller.go
+++ b/core/web/nodes_controller.go
@@ -1,6 +1,7 @@
package web
import (
+ "context"
"net/http"
"github.com/gin-gonic/gin"
@@ -8,8 +9,9 @@ import (
"github.com/smartcontractkit/chainlink-relay/pkg/types"
- "github.com/smartcontractkit/chainlink/v2/core/chains"
"github.com/smartcontractkit/chainlink/v2/core/logger/audit"
+ "github.com/smartcontractkit/chainlink/v2/core/services/chainlink"
+ "github.com/smartcontractkit/chainlink/v2/core/services/relay"
)
type NodesController interface {
@@ -17,15 +19,32 @@ type NodesController interface {
Index(c *gin.Context, size, page, offset int)
}
+type NetworkScopedNodeStatuser struct {
+ network relay.Network
+ relayers chainlink.RelayerChainInteroperators
+}
+
+func NewNetworkScopedNodeStatuser(relayers chainlink.RelayerChainInteroperators, network relay.Network) *NetworkScopedNodeStatuser {
+ scoped := relayers.List(chainlink.FilterRelayersByType(network))
+ return &NetworkScopedNodeStatuser{
+ network: network,
+ relayers: scoped,
+ }
+}
+
+func (n *NetworkScopedNodeStatuser) NodeStatuses(ctx context.Context, offset, limit int, relayIDs ...relay.ID) (nodes []types.NodeStatus, count int, err error) {
+ return n.relayers.NodeStatuses(ctx, offset, limit, relayIDs...)
+}
+
type nodesController[R jsonapi.EntityNamer] struct {
- nodeSet chains.NodesStatuser
+ nodeSet *NetworkScopedNodeStatuser
errNotEnabled error
newResource func(status types.NodeStatus) R
auditLogger audit.AuditLogger
}
func newNodesController[R jsonapi.EntityNamer](
- nodeSet chains.NodesStatuser,
+ nodeSet *NetworkScopedNodeStatuser,
errNotEnabled error,
newResource func(status types.NodeStatus) R,
auditLogger audit.AuditLogger,
@@ -55,7 +74,14 @@ func (n *nodesController[R]) Index(c *gin.Context, size, page, offset int) {
nodes, count, err = n.nodeSet.NodeStatuses(c, offset, size)
} else {
// fetch nodes for chain ID
- nodes, count, err = n.nodeSet.NodeStatuses(c, offset, size, id)
+ // backward compatibility
+ var rid relay.ID
+ err := rid.UnmarshalString(id)
+ if err != nil {
+ rid.ChainID = relay.ChainID(id)
+ rid.Network = n.nodeSet.network
+ }
+ nodes, count, err = n.nodeSet.NodeStatuses(c, offset, size, rid)
}
var resources []R
diff --git a/core/web/ocr2_keys_controller_test.go b/core/web/ocr2_keys_controller_test.go
index 418510cea1d..f69ed41f9dd 100644
--- a/core/web/ocr2_keys_controller_test.go
+++ b/core/web/ocr2_keys_controller_test.go
@@ -101,7 +101,7 @@ func setupOCR2KeysControllerTests(t *testing.T) (cltest.HTTPClientCleaner, keyst
app := cltest.NewApplicationEVMDisabled(t)
require.NoError(t, app.Start(testutils.Context(t)))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
require.NoError(t, app.KeyStore.OCR2().Add(cltest.DefaultOCR2Key))
diff --git a/core/web/ocr_keys_controller_test.go b/core/web/ocr_keys_controller_test.go
index 94a8ad8d079..911947fcb72 100644
--- a/core/web/ocr_keys_controller_test.go
+++ b/core/web/ocr_keys_controller_test.go
@@ -89,7 +89,7 @@ func setupOCRKeysControllerTests(t *testing.T) (cltest.HTTPClientCleaner, keysto
app := cltest.NewApplicationEVMDisabled(t)
require.NoError(t, app.Start(testutils.Context(t)))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
require.NoError(t, app.KeyStore.OCR().Add(cltest.DefaultOCRKey))
diff --git a/core/web/p2p_keys_controller_test.go b/core/web/p2p_keys_controller_test.go
index 2eb3e4e95ff..4df5f4d91b2 100644
--- a/core/web/p2p_keys_controller_test.go
+++ b/core/web/p2p_keys_controller_test.go
@@ -43,7 +43,7 @@ func TestP2PKeysController_Create_HappyPath(t *testing.T) {
app := cltest.NewApplicationEVMDisabled(t)
require.NoError(t, app.Start(testutils.Context(t)))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
keyStore := app.GetKeyStore()
response, cleanup := client.Post("/v2/keys/p2p", nil)
@@ -115,7 +115,7 @@ func setupP2PKeysControllerTests(t *testing.T) (cltest.HTTPClientCleaner, keysto
require.NoError(t, app.KeyStore.OCR().Add(cltest.DefaultOCRKey))
require.NoError(t, app.KeyStore.P2P().Add(cltest.DefaultP2PKey))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
return client, app.GetKeyStore()
}
diff --git a/core/web/ping_controller_test.go b/core/web/ping_controller_test.go
index a8e6c2058f9..0040f7dfdad 100644
--- a/core/web/ping_controller_test.go
+++ b/core/web/ping_controller_test.go
@@ -22,7 +22,7 @@ func TestPingController_Show_APICredentials(t *testing.T) {
app := cltest.NewApplicationEVMDisabled(t)
require.NoError(t, app.Start(testutils.Context(t)))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
resp, cleanup := client.Get("/v2/ping")
defer cleanup()
diff --git a/core/web/pipeline_job_spec_errors_controller_test.go b/core/web/pipeline_job_spec_errors_controller_test.go
index 13c02379674..8ec77a84f05 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/pipeline_runs_controller_test.go b/core/web/pipeline_runs_controller_test.go
index 4af7a761827..8e53384856d 100644
--- a/core/web/pipeline_runs_controller_test.go
+++ b/core/web/pipeline_runs_controller_test.go
@@ -5,6 +5,7 @@ import (
"fmt"
"io"
"net/http"
+ "net/url"
"strconv"
"strings"
"testing"
@@ -68,7 +69,7 @@ func TestPipelineRunsController_CreateWithBody_HappyPath(t *testing.T) {
// Make the request
{
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
body := strings.NewReader(`{"data":{"result":"123.45"}}`)
response, cleanup := client.Post("/v2/jobs/"+uuid.String()+"/runs", body)
defer cleanup()
@@ -129,7 +130,7 @@ func TestPipelineRunsController_CreateNoBody_HappyPath(t *testing.T) {
// Make the request (authorized as user)
{
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
response, cleanup := client.Post("/v2/jobs/"+uuid.String()+"/runs", nil)
defer cleanup()
cltest.AssertServerResponse(t, response, http.StatusOK)
@@ -149,7 +150,12 @@ func TestPipelineRunsController_CreateNoBody_HappyPath(t *testing.T) {
func TestPipelineRunsController_Index_GlobalHappyPath(t *testing.T) {
client, jobID, runIDs := setupPipelineRunsControllerTests(t)
- response, cleanup := client.Get("/v2/pipeline/runs")
+ url := url.URL{Path: "/v2/pipeline/runs"}
+ query := url.Query()
+ query.Set("evmChainID", cltest.FixtureChainID.String())
+ url.RawQuery = query.Encode()
+
+ response, cleanup := client.Get(url.String())
defer cleanup()
cltest.AssertServerResponse(t, response, http.StatusOK)
@@ -237,7 +243,7 @@ func TestPipelineRunsController_ShowRun_InvalidID(t *testing.T) {
t.Parallel()
app := cltest.NewApplicationEVMDisabled(t)
require.NoError(t, app.Start(testutils.Context(t)))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
response, cleanup := client.Get("/v2/jobs/1/runs/invalid-run-ID")
defer cleanup()
@@ -257,7 +263,7 @@ func setupPipelineRunsControllerTests(t *testing.T) (cltest.HTTPClientCleaner, i
app := cltest.NewApplicationWithConfigAndKey(t, cfg, ethClient, cltest.DefaultP2PKey)
require.NoError(t, app.Start(testutils.Context(t)))
require.NoError(t, app.KeyStore.OCR().Add(cltest.DefaultOCRKey))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
key, _ := cltest.MustInsertRandomKey(t, app.KeyStore.Eth())
@@ -266,6 +272,7 @@ func setupPipelineRunsControllerTests(t *testing.T) (cltest.HTTPClientCleaner, i
schemaVersion = 1
externalJobID = "0EEC7E1D-D0D2-476C-A1A8-72DFB6633F46"
contractAddress = "%s"
+ evmChainID = "0"
p2pBootstrapPeers = [
"/dns4/chain.link/tcp/1234/p2p/16Uiu2HAm58SP7UL8zsnpeuwHfytLocaqgnyaYKP8wu7qRdrixLju",
]
diff --git a/core/web/presenters/job.go b/core/web/presenters/job.go
index 01e01c9fa1e..b1f42ebc68f 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 a069a3e1ba5..bb79c8e953c 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/eth_key_test.go b/core/web/resolver/eth_key_test.go
index 0df24ef9ff1..26e061b164f 100644
--- a/core/web/resolver/eth_key_test.go
+++ b/core/web/resolver/eth_key_test.go
@@ -8,7 +8,6 @@ import (
gqlerrors "github.com/graph-gophers/graphql-go/errors"
"github.com/pkg/errors"
"github.com/stretchr/testify/mock"
- "github.com/stretchr/testify/require"
"github.com/smartcontractkit/chainlink/v2/core/assets"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm"
@@ -91,8 +90,7 @@ func TestResolver_ETHKeys(t *testing.T) {
cfg := configtest.NewGeneralConfig(t, nil)
m := map[string]evm.Chain{states[0].EVMChainID.String(): f.Mocks.chain}
- legacyEVMChains, err := evm.NewLegacyChains(cfg, m)
- require.NoError(t, err)
+ legacyEVMChains := evm.NewLegacyChains(m, cfg.EVMConfigs())
f.Mocks.ethKs.On("GetStatesForKeys", keys).Return(states, nil)
f.Mocks.ethKs.On("Get", keys[0].Address.Hex()).Return(keys[0], nil)
@@ -252,7 +250,7 @@ func TestResolver_ETHKeys(t *testing.T) {
},
{
- name: "Empty set on #chainSet.Get()",
+ name: "Empty set on legacy evm chains",
authenticated: true,
before: func(f *gqlTestFramework) {
states := []ethkey.State{
diff --git a/core/web/resolver/feeds_manager_chain_config.go b/core/web/resolver/feeds_manager_chain_config.go
index e6498a9a7b6..6d4e4c88e55 100644
--- a/core/web/resolver/feeds_manager_chain_config.go
+++ b/core/web/resolver/feeds_manager_chain_config.go
@@ -111,6 +111,10 @@ func (r *OCR2JobConfigResolver) Multiaddr() *string {
return r.cfg.Multiaddr.Ptr()
}
+func (r *OCR2JobConfigResolver) ForwarderAddress() *string {
+ return r.cfg.ForwarderAddress.Ptr()
+}
+
func (r *OCR2JobConfigResolver) P2PPeerID() *string {
return r.cfg.P2PPeerID.Ptr()
}
diff --git a/core/web/resolver/feeds_manager_chain_config_test.go b/core/web/resolver/feeds_manager_chain_config_test.go
index eaa7b04c303..24730a01648 100644
--- a/core/web/resolver/feeds_manager_chain_config_test.go
+++ b/core/web/resolver/feeds_manager_chain_config_test.go
@@ -14,13 +14,14 @@ import (
func Test_CreateFeedsManagerChainConfig(t *testing.T) {
var (
- mgrID = int64(100)
- cfgID = int64(1)
- chainID = "42"
- accountAddr = "0x0000001"
- adminAddr = "0x0000002"
- peerID = null.StringFrom("p2p_12D3KooWMoejJznyDuEk5aX6GvbjaG12UzeornPCBNzMRqdwrFJw")
- keyBundleID = null.StringFrom("6fdb8235e16e099de91df7ef8a8088e9deea0ed6ae106b133e5d985a8a9e1562")
+ mgrID = int64(100)
+ cfgID = int64(1)
+ chainID = "42"
+ accountAddr = "0x0000001"
+ adminAddr = "0x0000002"
+ forwarderAddr = "0x0000003"
+ peerID = null.StringFrom("p2p_12D3KooWMoejJznyDuEk5aX6GvbjaG12UzeornPCBNzMRqdwrFJw")
+ keyBundleID = null.StringFrom("6fdb8235e16e099de91df7ef8a8088e9deea0ed6ae106b133e5d985a8a9e1562")
mutation = `
mutation CreateFeedsManagerChainConfig($input: CreateFeedsManagerChainConfigInput!) {
@@ -45,21 +46,22 @@ func Test_CreateFeedsManagerChainConfig(t *testing.T) {
}`
variables = map[string]interface{}{
"input": map[string]interface{}{
- "feedsManagerID": stringutils.FromInt64(mgrID),
- "chainID": chainID,
- "chainType": "EVM",
- "accountAddr": accountAddr,
- "adminAddr": adminAddr,
- "fluxMonitorEnabled": false,
- "ocr1Enabled": true,
- "ocr1IsBootstrap": false,
- "ocr1P2PPeerID": peerID.String,
- "ocr1KeyBundleID": keyBundleID.String,
- "ocr2Enabled": true,
- "ocr2IsBootstrap": false,
- "ocr2P2PPeerID": peerID.String,
- "ocr2KeyBundleID": keyBundleID.String,
- "ocr2Plugins": `{"commit":true,"execute":true,"median":false,"mercury":true}`,
+ "feedsManagerID": stringutils.FromInt64(mgrID),
+ "chainID": chainID,
+ "chainType": "EVM",
+ "accountAddr": accountAddr,
+ "adminAddr": adminAddr,
+ "fluxMonitorEnabled": false,
+ "ocr1Enabled": true,
+ "ocr1IsBootstrap": false,
+ "ocr1P2PPeerID": peerID.String,
+ "ocr1KeyBundleID": keyBundleID.String,
+ "ocr2Enabled": true,
+ "ocr2IsBootstrap": false,
+ "ocr2P2PPeerID": peerID.String,
+ "ocr2KeyBundleID": keyBundleID.String,
+ "ocr2Plugins": `{"commit":true,"execute":true,"median":false,"mercury":true}`,
+ "ocr2ForwarderAddress": forwarderAddr,
},
}
)
@@ -86,9 +88,10 @@ func Test_CreateFeedsManagerChainConfig(t *testing.T) {
KeyBundleID: keyBundleID,
},
OCR2Config: feeds.OCR2ConfigModel{
- Enabled: true,
- P2PPeerID: peerID,
- KeyBundleID: keyBundleID,
+ Enabled: true,
+ P2PPeerID: peerID,
+ KeyBundleID: keyBundleID,
+ ForwarderAddress: null.StringFrom(forwarderAddr),
Plugins: feeds.Plugins{
Commit: true,
Execute: true,
@@ -112,9 +115,10 @@ func Test_CreateFeedsManagerChainConfig(t *testing.T) {
KeyBundleID: keyBundleID,
},
OCR2Config: feeds.OCR2ConfigModel{
- Enabled: true,
- P2PPeerID: peerID,
- KeyBundleID: keyBundleID,
+ Enabled: true,
+ P2PPeerID: peerID,
+ KeyBundleID: keyBundleID,
+ ForwarderAddress: null.StringFrom(forwarderAddr),
Plugins: feeds.Plugins{
Commit: true,
Execute: true,
@@ -265,9 +269,12 @@ func Test_DeleteFeedsManagerChainConfig(t *testing.T) {
func Test_UpdateFeedsManagerChainConfig(t *testing.T) {
var (
- cfgID = int64(1)
- peerID = null.StringFrom("p2p_12D3KooWMoejJznyDuEk5aX6GvbjaG12UzeornPCBNzMRqdwrFJw")
- keyBundleID = null.StringFrom("6fdb8235e16e099de91df7ef8a8088e9deea0ed6ae106b133e5d985a8a9e1562")
+ cfgID = int64(1)
+ peerID = null.StringFrom("p2p_12D3KooWMoejJznyDuEk5aX6GvbjaG12UzeornPCBNzMRqdwrFJw")
+ keyBundleID = null.StringFrom("6fdb8235e16e099de91df7ef8a8088e9deea0ed6ae106b133e5d985a8a9e1562")
+ accountAddr = "0x0000001"
+ adminAddr = "0x0000002"
+ forwarderAddr = "0x0000003"
mutation = `
mutation UpdateFeedsManagerChainConfig($id: ID!, $input: UpdateFeedsManagerChainConfigInput!) {
@@ -293,18 +300,19 @@ func Test_UpdateFeedsManagerChainConfig(t *testing.T) {
variables = map[string]interface{}{
"id": "1",
"input": map[string]interface{}{
- "accountAddr": "0x0000001",
- "adminAddr": "0x0000001",
- "fluxMonitorEnabled": false,
- "ocr1Enabled": true,
- "ocr1IsBootstrap": false,
- "ocr1P2PPeerID": peerID.String,
- "ocr1KeyBundleID": keyBundleID.String,
- "ocr2Enabled": true,
- "ocr2IsBootstrap": false,
- "ocr2P2PPeerID": peerID.String,
- "ocr2KeyBundleID": keyBundleID.String,
- "ocr2Plugins": `{"commit":true,"execute":true,"median":false,"mercury":true}`,
+ "accountAddr": accountAddr,
+ "adminAddr": adminAddr,
+ "fluxMonitorEnabled": false,
+ "ocr1Enabled": true,
+ "ocr1IsBootstrap": false,
+ "ocr1P2PPeerID": peerID.String,
+ "ocr1KeyBundleID": keyBundleID.String,
+ "ocr2Enabled": true,
+ "ocr2IsBootstrap": false,
+ "ocr2P2PPeerID": peerID.String,
+ "ocr2KeyBundleID": keyBundleID.String,
+ "ocr2Plugins": `{"commit":true,"execute":true,"median":false,"mercury":true}`,
+ "ocr2ForwarderAddress": forwarderAddr,
},
}
)
@@ -318,8 +326,8 @@ func Test_UpdateFeedsManagerChainConfig(t *testing.T) {
f.App.On("GetFeedsService").Return(f.Mocks.feedsSvc)
f.Mocks.feedsSvc.On("UpdateChainConfig", mock.Anything, feeds.ChainConfig{
ID: cfgID,
- AccountAddress: "0x0000001",
- AdminAddress: "0x0000001",
+ AccountAddress: accountAddr,
+ AdminAddress: adminAddr,
FluxMonitorConfig: feeds.FluxMonitorConfig{
Enabled: false,
},
@@ -329,9 +337,10 @@ func Test_UpdateFeedsManagerChainConfig(t *testing.T) {
KeyBundleID: null.StringFrom(keyBundleID.String),
},
OCR2Config: feeds.OCR2ConfigModel{
- Enabled: true,
- P2PPeerID: peerID,
- KeyBundleID: keyBundleID,
+ Enabled: true,
+ P2PPeerID: peerID,
+ KeyBundleID: keyBundleID,
+ ForwarderAddress: null.StringFrom(forwarderAddr),
Plugins: feeds.Plugins{
Commit: true,
Execute: true,
@@ -342,8 +351,8 @@ func Test_UpdateFeedsManagerChainConfig(t *testing.T) {
}).Return(cfgID, nil)
f.Mocks.feedsSvc.On("GetChainConfig", cfgID).Return(&feeds.ChainConfig{
ID: cfgID,
- AccountAddress: "0x0000001",
- AdminAddress: "0x0000001",
+ AccountAddress: accountAddr,
+ AdminAddress: adminAddr,
FluxMonitorConfig: feeds.FluxMonitorConfig{
Enabled: false,
},
@@ -353,9 +362,10 @@ func Test_UpdateFeedsManagerChainConfig(t *testing.T) {
KeyBundleID: null.StringFrom(keyBundleID.String),
},
OCR2Config: feeds.OCR2ConfigModel{
- Enabled: true,
- P2PPeerID: peerID,
- KeyBundleID: keyBundleID,
+ Enabled: true,
+ P2PPeerID: peerID,
+ KeyBundleID: keyBundleID,
+ ForwarderAddress: null.StringFrom(forwarderAddr),
Plugins: feeds.Plugins{
Commit: true,
Execute: true,
diff --git a/core/web/resolver/mutation.go b/core/web/resolver/mutation.go
index 5af263d9395..68cbb0b7896 100644
--- a/core/web/resolver/mutation.go
+++ b/core/web/resolver/mutation.go
@@ -151,23 +151,24 @@ func (r *Resolver) DeleteCSAKey(ctx context.Context, args struct {
}
type createFeedsManagerChainConfigInput struct {
- FeedsManagerID string
- ChainID string
- ChainType string
- AccountAddr string
- AdminAddr string
- FluxMonitorEnabled bool
- OCR1Enabled bool
- OCR1IsBootstrap *bool
- OCR1Multiaddr *string
- OCR1P2PPeerID *string
- OCR1KeyBundleID *string
- OCR2Enabled bool
- OCR2IsBootstrap *bool
- OCR2Multiaddr *string
- OCR2P2PPeerID *string
- OCR2KeyBundleID *string
- OCR2Plugins string
+ FeedsManagerID string
+ ChainID string
+ ChainType string
+ AccountAddr string
+ AdminAddr string
+ FluxMonitorEnabled bool
+ OCR1Enabled bool
+ OCR1IsBootstrap *bool
+ OCR1Multiaddr *string
+ OCR1P2PPeerID *string
+ OCR1KeyBundleID *string
+ OCR2Enabled bool
+ OCR2IsBootstrap *bool
+ OCR2Multiaddr *string
+ OCR2ForwarderAddress *string
+ OCR2P2PPeerID *string
+ OCR2KeyBundleID *string
+ OCR2Plugins string
}
func (r *Resolver) CreateFeedsManagerChainConfig(ctx context.Context, args struct {
@@ -217,12 +218,13 @@ func (r *Resolver) CreateFeedsManagerChainConfig(ctx context.Context, args struc
}
params.OCR2Config = feeds.OCR2ConfigModel{
- Enabled: args.Input.OCR2Enabled,
- IsBootstrap: *args.Input.OCR2IsBootstrap,
- Multiaddr: null.StringFromPtr(args.Input.OCR2Multiaddr),
- P2PPeerID: null.StringFromPtr(args.Input.OCR2P2PPeerID),
- KeyBundleID: null.StringFromPtr(args.Input.OCR2KeyBundleID),
- Plugins: plugins,
+ Enabled: args.Input.OCR2Enabled,
+ IsBootstrap: *args.Input.OCR2IsBootstrap,
+ Multiaddr: null.StringFromPtr(args.Input.OCR2Multiaddr),
+ ForwarderAddress: null.StringFromPtr(args.Input.OCR2ForwarderAddress),
+ P2PPeerID: null.StringFromPtr(args.Input.OCR2P2PPeerID),
+ KeyBundleID: null.StringFromPtr(args.Input.OCR2KeyBundleID),
+ Plugins: plugins,
}
}
@@ -287,20 +289,21 @@ func (r *Resolver) DeleteFeedsManagerChainConfig(ctx context.Context, args struc
}
type updateFeedsManagerChainConfigInput struct {
- AccountAddr string
- AdminAddr string
- FluxMonitorEnabled bool
- OCR1Enabled bool
- OCR1IsBootstrap *bool
- OCR1Multiaddr *string
- OCR1P2PPeerID *string
- OCR1KeyBundleID *string
- OCR2Enabled bool
- OCR2IsBootstrap *bool
- OCR2Multiaddr *string
- OCR2P2PPeerID *string
- OCR2KeyBundleID *string
- OCR2Plugins string
+ AccountAddr string
+ AdminAddr string
+ FluxMonitorEnabled bool
+ OCR1Enabled bool
+ OCR1IsBootstrap *bool
+ OCR1Multiaddr *string
+ OCR1P2PPeerID *string
+ OCR1KeyBundleID *string
+ OCR2Enabled bool
+ OCR2IsBootstrap *bool
+ OCR2Multiaddr *string
+ OCR2ForwarderAddress *string
+ OCR2P2PPeerID *string
+ OCR2KeyBundleID *string
+ OCR2Plugins string
}
func (r *Resolver) UpdateFeedsManagerChainConfig(ctx context.Context, args struct {
@@ -344,12 +347,13 @@ func (r *Resolver) UpdateFeedsManagerChainConfig(ctx context.Context, args struc
}
params.OCR2Config = feeds.OCR2ConfigModel{
- Enabled: args.Input.OCR2Enabled,
- IsBootstrap: *args.Input.OCR2IsBootstrap,
- Multiaddr: null.StringFromPtr(args.Input.OCR2Multiaddr),
- P2PPeerID: null.StringFromPtr(args.Input.OCR2P2PPeerID),
- KeyBundleID: null.StringFromPtr(args.Input.OCR2KeyBundleID),
- Plugins: plugins,
+ Enabled: args.Input.OCR2Enabled,
+ IsBootstrap: *args.Input.OCR2IsBootstrap,
+ Multiaddr: null.StringFromPtr(args.Input.OCR2Multiaddr),
+ ForwarderAddress: null.StringFromPtr(args.Input.OCR2ForwarderAddress),
+ P2PPeerID: null.StringFromPtr(args.Input.OCR2P2PPeerID),
+ KeyBundleID: null.StringFromPtr(args.Input.OCR2KeyBundleID),
+ Plugins: plugins,
}
}
diff --git a/core/web/resolver/query.go b/core/web/resolver/query.go
index 22b95a2d2ef..e9fd18cf19a 100644
--- a/core/web/resolver/query.go
+++ b/core/web/resolver/query.go
@@ -15,6 +15,7 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/chains"
"github.com/smartcontractkit/chainlink/v2/core/services/keystore"
"github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/vrfkey"
+ "github.com/smartcontractkit/chainlink/v2/core/services/relay"
evmrelay "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm"
"github.com/smartcontractkit/chainlink/v2/core/utils/stringutils"
)
@@ -68,7 +69,7 @@ func (r *Resolver) Chain(ctx context.Context, args struct{ ID graphql.ID }) (*Ch
return nil, err
}
- cs, _, err := r.App.EVMORM().Chains(0, -1, string(args.ID))
+ cs, _, err := r.App.EVMORM().Chains(relay.ChainID(args.ID))
if err != nil {
return nil, err
}
@@ -94,12 +95,20 @@ func (r *Resolver) Chains(ctx context.Context, args struct {
offset := pageOffset(args.Offset)
limit := pageLimit(args.Limit)
- page, count, err := r.App.EVMORM().Chains(offset, limit)
+ chains, count, err := r.App.EVMORM().Chains()
if err != nil {
return nil, err
}
+ // bound the chain results
+ if offset >= len(chains) {
+ return nil, fmt.Errorf("offset %d out of range", offset)
+ }
+ end := len(chains)
+ if limit > 0 && offset+limit < end {
+ end = offset + limit
+ }
- return NewChainsPayload(page, int32(count)), nil
+ return NewChainsPayload(chains[offset:end], int32(count)), nil
}
// FeedsManager retrieves a feeds manager by id.
diff --git a/core/web/resolver/spec.go b/core/web/resolver/spec.go
index fa3e5a14fa0..48040d118a7 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 8c6dadc880e..04bfffbe05e 100644
--- a/core/web/resolver/spec_test.go
+++ b/core/web/resolver/spec_test.go
@@ -9,6 +9,7 @@ import (
"github.com/stretchr/testify/require"
"gopkg.in/guregu/null.v4"
+ "github.com/smartcontractkit/chainlink-relay/pkg/types"
"github.com/smartcontractkit/chainlink/v2/core/assets"
clnull "github.com/smartcontractkit/chainlink/v2/core/null"
"github.com/smartcontractkit/chainlink/v2/core/services/job"
@@ -515,7 +516,7 @@ func TestResolver_OCR2Spec(t *testing.T) {
Relay: relay.EVM,
RelayConfig: relayConfig,
TransmitterID: null.StringFrom(transmitterAddress.String()),
- PluginType: job.Median,
+ PluginType: types.Median,
PluginConfig: pluginConfig,
},
}, nil)
@@ -778,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,
@@ -804,6 +806,7 @@ func TestResolver_BlockhashStoreSpec(t *testing.T) {
blockhashStoreAddress
trustedBlockhashStoreAddress
trustedBlockhashStoreBatchSize
+ heartbeatPeriod
}
}
}
@@ -827,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/resolver/testdata/config-empty-effective.toml b/core/web/resolver/testdata/config-empty-effective.toml
index 8c3eef53f6a..45e92a147d3 100644
--- a/core/web/resolver/testdata/config-empty-effective.toml
+++ b/core/web/resolver/testdata/config-empty-effective.toml
@@ -1,4 +1,3 @@
-ExplorerURL = ''
InsecureFastScrypt = false
RootDir = '~/.chainlink'
ShutdownGracePeriod = '5s'
diff --git a/core/web/resolver/testdata/config-full.toml b/core/web/resolver/testdata/config-full.toml
index 96f24b1955c..ff7eb832c9c 100644
--- a/core/web/resolver/testdata/config-full.toml
+++ b/core/web/resolver/testdata/config-full.toml
@@ -1,4 +1,3 @@
-ExplorerURL = 'http://explorer.url'
InsecureFastScrypt = true
RootDir = 'test/root/dir'
ShutdownGracePeriod = '10s'
@@ -324,7 +323,7 @@ BlockRate = '1m0s'
BlocksUntilTxTimeout = 12
ConfirmPollPeriod = '1s'
FallbackGasPrice = '0.001'
-FeeToken = 'ucosm'
+GasToken = 'ucosm'
GasLimitMultiplier = '1.2'
MaxMsgsPerBatch = 17
OCR2CachePollPeriod = '1m0s'
diff --git a/core/web/resolver/testdata/config-multi-chain-effective.toml b/core/web/resolver/testdata/config-multi-chain-effective.toml
index d6b38349b83..665de9be8cb 100644
--- a/core/web/resolver/testdata/config-multi-chain-effective.toml
+++ b/core/web/resolver/testdata/config-multi-chain-effective.toml
@@ -1,4 +1,3 @@
-ExplorerURL = ''
InsecureFastScrypt = false
RootDir = 'my/root/dir'
ShutdownGracePeriod = '5s'
@@ -456,7 +455,7 @@ BlockRate = '6s'
BlocksUntilTxTimeout = 30
ConfirmPollPeriod = '1s'
FallbackGasPrice = '0.015'
-FeeToken = 'ucosm'
+GasToken = 'ucosm'
GasLimitMultiplier = '1.5'
MaxMsgsPerBatch = 13
OCR2CachePollPeriod = '4s'
@@ -474,7 +473,7 @@ BlockRate = '6s'
BlocksUntilTxTimeout = 20
ConfirmPollPeriod = '1s'
FallbackGasPrice = '0.015'
-FeeToken = 'ucosm'
+GasToken = 'ucosm'
GasLimitMultiplier = '1.5'
MaxMsgsPerBatch = 100
OCR2CachePollPeriod = '4s'
diff --git a/core/web/resolver/testdata/config-multi-chain.toml b/core/web/resolver/testdata/config-multi-chain.toml
index eee786e69bf..543fb3156bd 100644
--- a/core/web/resolver/testdata/config-multi-chain.toml
+++ b/core/web/resolver/testdata/config-multi-chain.toml
@@ -72,7 +72,7 @@ WSURL = 'wss://web.socket/test/bar'
[[Cosmos]]
ChainID = 'Ibiza-808'
Bech32Prefix = 'wasm'
-FeeToken = 'ucosm'
+GasToken = 'ucosm'
MaxMsgsPerBatch = 13
[[Cosmos.Nodes]]
@@ -83,7 +83,7 @@ TendermintURL = 'http://columbus.cosmos.com'
ChainID = 'Malaga-420'
Bech32Prefix = 'wasm'
BlocksUntilTxTimeout = 20
-FeeToken = 'ucosm'
+GasToken = 'ucosm'
[[Cosmos.Nodes]]
Name = 'secondary'
diff --git a/core/web/router_test.go b/core/web/router_test.go
index 05d8141f71a..424ef4296f4 100644
--- a/core/web/router_test.go
+++ b/core/web/router_test.go
@@ -39,7 +39,7 @@ func TestTokenAuthRequired_SessionCredentials(t *testing.T) {
ts := httptest.NewServer(router)
defer ts.Close()
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
resp, cleanup := client.Post("/v2/bridge_types/", nil)
defer cleanup()
diff --git a/core/web/schema/type/feeds_manager.graphql b/core/web/schema/type/feeds_manager.graphql
index c59c9213ff8..0d6d5f61788 100644
--- a/core/web/schema/type/feeds_manager.graphql
+++ b/core/web/schema/type/feeds_manager.graphql
@@ -49,6 +49,7 @@ type OCR2JobConfig {
enabled: Boolean!
isBootstrap: Boolean!
multiaddr: String
+ forwarderAddress: String
p2pPeerID: String
keyBundleID: String
plugins: Plugins!
@@ -117,6 +118,7 @@ input CreateFeedsManagerChainConfigInput {
ocr2Enabled: Boolean!
ocr2IsBootstrap: Boolean
ocr2Multiaddr: String
+ ocr2ForwarderAddress: String
ocr2P2PPeerID: String
ocr2KeyBundleID: String
ocr2Plugins: String!
@@ -157,6 +159,7 @@ input UpdateFeedsManagerChainConfigInput {
ocr2Enabled: Boolean!
ocr2IsBootstrap: Boolean
ocr2Multiaddr: String
+ ocr2ForwarderAddress: String
ocr2P2PPeerID: String
ocr2KeyBundleID: String
ocr2Plugins: String!
diff --git a/core/web/schema/type/spec.graphql b/core/web/schema/type/spec.graphql
index c92a1dd1ea9..cdcbabf9ef0 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/solana_chains_controller_test.go b/core/web/solana_chains_controller_test.go
index e6055840804..3112c42856f 100644
--- a/core/web/solana_chains_controller_test.go
+++ b/core/web/solana_chains_controller_test.go
@@ -186,7 +186,7 @@ func setupSolanaChainsControllerTestV2(t *testing.T, cfgs ...*solana.SolanaConfi
app := cltest.NewApplicationWithConfig(t, cfg)
require.NoError(t, app.Start(testutils.Context(t)))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
return &TestSolanaChainsController{
app: app,
diff --git a/core/web/solana_keys_controller_test.go b/core/web/solana_keys_controller_test.go
index cd5f70857cd..b32a844a395 100644
--- a/core/web/solana_keys_controller_test.go
+++ b/core/web/solana_keys_controller_test.go
@@ -41,7 +41,7 @@ func TestSolanaKeysController_Create_HappyPath(t *testing.T) {
app := cltest.NewApplicationEVMDisabled(t)
require.NoError(t, app.Start(testutils.Context(t)))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
keyStore := app.GetKeyStore()
response, cleanup := client.Post("/v2/keys/solana", nil)
@@ -99,7 +99,7 @@ func setupSolanaKeysControllerTests(t *testing.T) (cltest.HTTPClientCleaner, key
require.NoError(t, app.KeyStore.OCR().Add(cltest.DefaultOCRKey))
require.NoError(t, app.KeyStore.Solana().Add(cltest.DefaultSolanaKey))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
return client, app.GetKeyStore()
}
diff --git a/core/web/solana_nodes_controller.go b/core/web/solana_nodes_controller.go
index 1c12418a5b2..d5fbc05ccf5 100644
--- a/core/web/solana_nodes_controller.go
+++ b/core/web/solana_nodes_controller.go
@@ -10,6 +10,8 @@ import (
var ErrSolanaNotEnabled = errChainDisabled{name: "Solana", tomlKey: "Solana.Enabled"}
func NewSolanaNodesController(app chainlink.Application) NodesController {
+ scopedNodeStatuser := NewNetworkScopedNodeStatuser(app.GetRelayers(), relay.Solana)
+
return newNodesController[presenters.SolanaNodeResource](
- app.GetRelayers().List(chainlink.FilterRelayersByType(relay.Solana)), ErrSolanaNotEnabled, presenters.NewSolanaNodeResource, app.GetAuditLogger())
+ scopedNodeStatuser, ErrSolanaNotEnabled, presenters.NewSolanaNodeResource, app.GetAuditLogger())
}
diff --git a/core/web/solana_transfer_controller.go b/core/web/solana_transfer_controller.go
index 8238f775626..df750586a46 100644
--- a/core/web/solana_transfer_controller.go
+++ b/core/web/solana_transfer_controller.go
@@ -54,14 +54,12 @@ func (tc *SolanaTransfersController) Create(c *gin.Context) {
if errors.Is(err, chainlink.ErrNoSuchRelayer) {
jsonAPIError(c, http.StatusBadRequest, err)
return
- } else {
- jsonAPIError(c, http.StatusInternalServerError, err)
- return
}
+ jsonAPIError(c, http.StatusInternalServerError, err)
+ return
}
- // note the [loop.Relayer] API is in intermediate state. we found the relayer above; we should not need to pass
- // the chain id here
- err = relayer.SendTx(c, tr.SolanaChainID, tr.From.String(), tr.To.String(), amount, !tr.AllowHigherAmounts)
+
+ err = relayer.Transact(c, tr.From.String(), tr.To.String(), amount, !tr.AllowHigherAmounts)
if err != nil {
switch err {
case chains.ErrNotFound, chains.ErrChainIDEmpty:
diff --git a/core/web/starknet_keys_controller_test.go b/core/web/starknet_keys_controller_test.go
index d14216ed4aa..c3337e14d2d 100644
--- a/core/web/starknet_keys_controller_test.go
+++ b/core/web/starknet_keys_controller_test.go
@@ -41,7 +41,7 @@ func TestStarkNetKeysController_Create_HappyPath(t *testing.T) {
app := cltest.NewApplicationEVMDisabled(t)
require.NoError(t, app.Start(testutils.Context(t)))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
keyStore := app.GetKeyStore()
response, cleanup := client.Post("/v2/keys/starknet", nil)
@@ -99,7 +99,7 @@ func setupStarkNetKeysControllerTests(t *testing.T) (cltest.HTTPClientCleaner, k
require.NoError(t, app.KeyStore.OCR().Add(cltest.DefaultOCRKey))
require.NoError(t, app.KeyStore.StarkNet().Add(cltest.DefaultStarkNetKey))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
return client, app.GetKeyStore()
}
diff --git a/core/web/starknet_nodes_controller.go b/core/web/starknet_nodes_controller.go
index 5c6e5c4d575..d2881f2e65a 100644
--- a/core/web/starknet_nodes_controller.go
+++ b/core/web/starknet_nodes_controller.go
@@ -10,6 +10,8 @@ import (
var ErrStarkNetNotEnabled = errChainDisabled{name: "StarkNet", tomlKey: "Starknet.Enabled"}
func NewStarkNetNodesController(app chainlink.Application) NodesController {
+ scopedNodeStatuser := NewNetworkScopedNodeStatuser(app.GetRelayers(), relay.StarkNet)
+
return newNodesController[presenters.StarkNetNodeResource](
- app.GetRelayers().List(chainlink.FilterRelayersByType(relay.StarkNet)), ErrStarkNetNotEnabled, presenters.NewStarkNetNodeResource, app.GetAuditLogger())
+ scopedNodeStatuser, ErrStarkNetNotEnabled, presenters.NewStarkNetNodeResource, app.GetAuditLogger())
}
diff --git a/core/web/user_controller_test.go b/core/web/user_controller_test.go
index bde232b1bcf..cdb9c9953da 100644
--- a/core/web/user_controller_test.go
+++ b/core/web/user_controller_test.go
@@ -25,7 +25,8 @@ func TestUserController_UpdatePassword(t *testing.T) {
app := cltest.NewApplicationEVMDisabled(t)
require.NoError(t, app.Start(testutils.Context(t)))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ u := cltest.User{}
+ client := app.NewHTTPClient(&u)
testCases := []struct {
name string
@@ -56,10 +57,10 @@ func TestUserController_UpdatePassword(t *testing.T) {
},
{
name: "New password includes api email",
- reqBody: fmt.Sprintf(`{"newPassword": "%slonglonglonglong", "oldPassword": "%s"}`, cltest.APIEmailAdmin, cltest.Password),
+ reqBody: fmt.Sprintf(`{"newPassword": "%slonglonglonglong", "oldPassword": "%s"}`, u.Email, cltest.Password),
wantStatusCode: http.StatusUnprocessableEntity,
wantErrCount: 1,
- wantErrMessage: fmt.Sprintf("%s %s\n", utils.ErrMsgHeader, "password may not contain: \"apiuser@chainlink.test\""),
+ wantErrMessage: fmt.Sprintf("%s %s%s\n", utils.ErrMsgHeader, "password may not contain: ", fmt.Sprintf(`"%s"`, u.Email)),
},
{
name: "Success",
@@ -90,7 +91,7 @@ func TestUserController_CreateUser(t *testing.T) {
app := cltest.NewApplicationEVMDisabled(t)
require.NoError(t, app.Start(testutils.Context(t)))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
longPassword := strings.Repeat("x", sessions.MaxBcryptPasswordLength+1)
@@ -185,7 +186,8 @@ func TestUserController_UpdateRole(t *testing.T) {
app := cltest.NewApplicationEVMDisabled(t)
require.NoError(t, app.Start(testutils.Context(t)))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ u := cltest.User{}
+ client := app.NewHTTPClient(&u)
user := cltest.MustRandomUser(t)
err := app.SessionORM().CreateUser(&user)
require.NoError(t, err)
@@ -232,7 +234,7 @@ func TestUserController_DeleteUser(t *testing.T) {
app := cltest.NewApplicationEVMDisabled(t)
require.NoError(t, app.Start(testutils.Context(t)))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
user := cltest.MustRandomUser(t)
err := app.SessionORM().CreateUser(&user)
require.NoError(t, err)
@@ -258,7 +260,7 @@ func TestUserController_NewAPIToken(t *testing.T) {
app := cltest.NewApplicationEVMDisabled(t)
require.NoError(t, app.Start(testutils.Context(t)))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
req, err := json.Marshal(sessions.ChangeAuthTokenRequest{
Password: cltest.Password,
})
@@ -280,7 +282,7 @@ func TestUserController_NewAPIToken_unauthorized(t *testing.T) {
app := cltest.NewApplicationEVMDisabled(t)
require.NoError(t, app.Start(testutils.Context(t)))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
req, err := json.Marshal(sessions.ChangeAuthTokenRequest{
Password: "wrong-password",
})
@@ -296,7 +298,7 @@ func TestUserController_DeleteAPIKey(t *testing.T) {
app := cltest.NewApplicationEVMDisabled(t)
require.NoError(t, app.Start(testutils.Context(t)))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
req, err := json.Marshal(sessions.ChangeAuthTokenRequest{
Password: cltest.Password,
})
@@ -313,7 +315,7 @@ func TestUserController_DeleteAPIKey_unauthorized(t *testing.T) {
app := cltest.NewApplicationEVMDisabled(t)
require.NoError(t, app.Start(testutils.Context(t)))
- client := app.NewHTTPClient(cltest.APIEmailAdmin)
+ client := app.NewHTTPClient(&cltest.User{})
req, err := json.Marshal(sessions.ChangeAuthTokenRequest{
Password: "wrong-password",
})
diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md
index a5c31a8b4d7..4032ce80687 100644
--- a/docs/CHANGELOG.md
+++ b/docs/CHANGELOG.md
@@ -13,8 +13,46 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
+## 2.6.0 - 2023-10-18
+
+### Added
+
+- 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 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`
+
+### 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 `
+- 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
+
## 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.
+
### Upcoming Required Configuration Change
- Starting in 2.6.0, chainlink nodes will no longer allow insecure configuration for production builds. Any TOML configuration that sets the following line will fail validation checks in `node start` or `node validate`:
@@ -39,6 +77,7 @@ AllowSimplePasswords=true
### Added
- Added the ability to specify and merge fields from multiple secrets files. Overrides of fields and keys are not allowed.
+- Added new database table `evm_upkeep_states` to persist eligibility state for recently checked upkeeps.
### Upcoming Required Configuration Change
diff --git a/docs/CONFIG.md b/docs/CONFIG.md
index efbe9cbbf01..ceb3d3dfe08 100644
--- a/docs/CONFIG.md
+++ b/docs/CONFIG.md
@@ -20,19 +20,12 @@ HTTPURL = 'https://foo.bar' # Required
## Global
```toml
-ExplorerURL = 'ws://explorer.url' # Example
InsecureFastScrypt = false # Default
RootDir = '~/.chainlink' # Default
ShutdownGracePeriod = '5s' # Default
```
-### ExplorerURL
-```toml
-ExplorerURL = 'ws://explorer.url' # Example
-```
-ExplorerURL is the websocket URL used by the node to push stats. This variable is required to deliver telemetry.
-
### InsecureFastScrypt
:warning: **_ADVANCED_**: _Do not change this setting unless you know what you are doing._
```toml
@@ -3378,7 +3371,7 @@ ObservationGracePeriod = '1s'
[OCR2]
[OCR2.Automation]
-GasLimit = 5300000
+GasLimit = 14500000
```
@@ -4004,7 +3997,7 @@ ObservationGracePeriod = '1s'
[OCR2]
[OCR2.Automation]
-GasLimit = 5300000
+GasLimit = 14500000
```
@@ -4018,7 +4011,7 @@ BlockBackfillSkip = false
FinalityDepth = 1
FinalityTagEnabled = false
LogBackfillBatchSize = 1000
-LogPollInterval = '30s'
+LogPollInterval = '3s'
LogKeepBlocksDepth = 100000
MinIncomingConfirmations = 1
MinContractPayment = '0.00001 link'
@@ -4033,7 +4026,7 @@ MaxInFlight = 16
MaxQueued = 250
ReaperInterval = '1h0m0s'
ReaperThreshold = '168h0m0s'
-ResendAfterThreshold = '2m0s'
+ResendAfterThreshold = '1m0s'
[BalanceMonitor]
Enabled = true
@@ -4095,7 +4088,7 @@ BlockBackfillSkip = false
FinalityDepth = 1
FinalityTagEnabled = false
LogBackfillBatchSize = 1000
-LogPollInterval = '30s'
+LogPollInterval = '3s'
LogKeepBlocksDepth = 100000
MinIncomingConfirmations = 1
MinContractPayment = '0.00001 link'
@@ -4110,7 +4103,7 @@ MaxInFlight = 16
MaxQueued = 250
ReaperInterval = '1h0m0s'
ReaperThreshold = '168h0m0s'
-ResendAfterThreshold = '2m0s'
+ResendAfterThreshold = '1m0s'
[BalanceMonitor]
Enabled = true
@@ -5140,7 +5133,7 @@ BlockRate = '6s' # Default
BlocksUntilTxTimeout = 30 # Default
ConfirmPollPeriod = '1s' # Default
FallbackGasPrice = '0.015' # Default
-FeeToken = 'ucosm' # Default
+GasToken = 'ucosm' # Default
GasLimitMultiplier = '1.5' # Default
MaxMsgsPerBatch = 100 # Default
OCR2CachePollPeriod = '4s' # Default
@@ -5191,11 +5184,11 @@ FallbackGasPrice = '0.015' # Default
```
FallbackGasPrice sets a fallback gas price to use when the estimator is not available.
-### FeeToken
+### GasToken
```toml
-FeeToken = 'ucosm' # Default
+GasToken = 'ucosm' # Default
```
-FeeToken is the token denomination which is being used to pay gas fees on this chain.
+GasToken is the token denomination which is being used to pay gas fees on this chain.
### GasLimitMultiplier
```toml
diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md
index 5d0a8475a6f..a31c46e2558 100644
--- a/docs/CONTRIBUTING.md
+++ b/docs/CONTRIBUTING.md
@@ -1,19 +1,17 @@
# Contributing to ChainLink
First, thank you for considering contributing to ChainLink.
-The Chainlink source code is [licensed under the MIT license](https://github.com/smartcontractkit/chainlink/blob/master/LICENSE).
We value contributions of any size or type from anyone!
The smallest of fixes can make the biggest difference.
-Please dive in. Feel free to ask questions on [our Gitter](https://gitter.im/smartcontractkit-chainlink/Lobby), open an issue, or send a pull request on GitHub.
+Please dive in. Feel free to ask questions on [the Chainlink Official Discord](https://discord.gg/aSK4zew),
+open an issue, or send a pull request on GitHub.
We follow an [agile development process](http://agilemanifesto.org/).
-You can view our current priorities for development listed on [Pivotal Tracker](https://www.pivotaltracker.com/n/projects/2129823).
If you run into a bug or have a problem, the best action is to open an issue on GitHub (please search for related closed issues first).
-The GitHub issue will be migrated to Tracker and prioritized. We'll keep you updated as the issue progresses.
If you're interested in helping out with the development cycle, feel free to tackle open issues. We've even set aside a few that are [good introductory issues](https://github.com/smartcontractkit/chainlink/issues?q=is%3Aissue+label%3A%22good+first+issue%22).
-If you see something you'd like to help with [on Tracker](https://www.pivotaltracker.com/n/projects/2129823),
-reach out to us [on Gitter](https://gitter.im/smartcontractkit-chainlink/Lobby) to coordinate.
+If you see something you'd like to help with,
+reach out to us [on Discord](https://discord.gg/aSK4zew) to coordinate.
## Testing
diff --git a/docs/SECRETS.md b/docs/SECRETS.md
index 3bbf51cae6f..af316cab14b 100644
--- a/docs/SECRETS.md
+++ b/docs/SECRETS.md
@@ -51,30 +51,6 @@ AllowSimplePasswords skips the password complexity check normally enforced on UR
Environment variable: `CL_DATABASE_ALLOW_SIMPLE_PASSWORDS`
-## Explorer
-```toml
-[Explorer]
-AccessKey = "access_key" # Example
-Secret = "secret" # Example
-```
-
-
-### AccessKey
-```toml
-AccessKey = "access_key" # Example
-```
-AccessKey is the access key for authenticating with the Explorer.
-
-Environment variable: `CL_EXPLORER_ACCESS_KEY`
-
-### Secret
-```toml
-Secret = "secret" # Example
-```
-Secret is the secret for authenticating with the Explorer.
-
-Environment variable: `CL_EXPLORER_SECRET`
-
## Password
```toml
[Password]
@@ -135,6 +111,7 @@ Environment variable: `CL_PROMETHEUS_AUTH_TOKEN`
Username = "A-Mercury-Username" # Example
Password = "A-Mercury-Password" # Example
URL = "https://example.com" # Example
+LegacyURL = "https://example.v1.com" # Example
```
@@ -154,7 +131,13 @@ Password is used for basic auth of the Mercury endpoint
```toml
URL = "https://example.com" # Example
```
-URL is the Mercury endpoint URL which is used by OCR2 Automation to access Mercury price feed
+URL is the Mercury endpoint base URL used to access Mercury price feed
+
+### LegacyURL
+```toml
+LegacyURL = "https://example.v1.com" # Example
+```
+LegacyURL is the Mercury legacy endpoint base URL used to access Mercury v0.2 price feed
## Threshold
```toml
diff --git a/go.mod b/go.mod
index e6afe0f8d18..d0fd99a8287 100644
--- a/go.mod
+++ b/go.mod
@@ -1,17 +1,18 @@
module github.com/smartcontractkit/chainlink/v2
-go 1.20
+go 1.21
require (
github.com/CosmWasm/wasmd v0.40.1
github.com/Depado/ginprom v1.7.11
github.com/Masterminds/semver/v3 v3.2.1
github.com/Masterminds/sprig/v3 v3.2.3
- github.com/avast/retry-go/v4 v4.3.4
+ github.com/avast/retry-go/v4 v4.5.0
github.com/btcsuite/btcd v0.23.4
github.com/cometbft/cometbft v0.37.2
github.com/cosmos/cosmos-sdk v0.47.4
github.com/danielkov/gin-helmet v0.0.0-20171108135313-1387e224435e
+ github.com/esote/minmaxheap v1.0.0
github.com/ethereum/go-ethereum v1.12.0
github.com/fatih/color v1.15.0
github.com/fxamacker/cbor/v2 v2.4.0
@@ -24,16 +25,17 @@ require (
github.com/gin-gonic/gin v1.9.1
github.com/go-webauthn/webauthn v0.8.2
github.com/gogo/protobuf v1.3.3
- github.com/google/pprof v0.0.0-20230602150820-91b7bce49751
- github.com/google/uuid v1.3.0
+ github.com/google/pprof v0.0.0-20230705174524-200ffdc848b8
+ github.com/google/uuid v1.3.1
github.com/gorilla/securecookie v1.1.1
github.com/gorilla/sessions v1.2.1
github.com/gorilla/websocket v1.5.0
+ github.com/grafana/pyroscope-go v1.0.2
github.com/graph-gophers/dataloader v5.0.0+incompatible
github.com/graph-gophers/graphql-go v1.3.0
github.com/hashicorp/go-plugin v1.4.10
github.com/hdevalence/ed25519consensus v0.1.0
- github.com/jackc/pgconn v1.14.0
+ github.com/jackc/pgconn v1.14.1
github.com/jackc/pgtype v1.14.0
github.com/jackc/pgx/v4 v4.18.1
github.com/jpillora/backoff v1.0.0
@@ -51,35 +53,34 @@ 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
github.com/prometheus/client_model v0.4.0
github.com/prometheus/common v0.44.0
- github.com/prometheus/prometheus v0.45.0
- github.com/pyroscope-io/client v0.7.1
+ github.com/prometheus/prometheus v0.46.0
github.com/robfig/cron/v3 v3.0.1
- github.com/rogpeppe/go-internal v1.10.0
+ github.com/rogpeppe/go-internal v1.11.0
github.com/scylladb/go-reflectx v1.0.1
- github.com/shirou/gopsutil/v3 v3.22.12
+ github.com/shirou/gopsutil/v3 v3.23.8
github.com/shopspring/decimal v1.3.1
github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704
- github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20230824124058-9b063c470048 // TODO: update when https://github.com/smartcontractkit/chainlink-cosmos/pull/356 is merged
- github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230824125819-215fd09979a2
- github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230802143301-165000751a85
- github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20230802150127-d2c95679d61a
- github.com/smartcontractkit/libocr v0.0.0-20230816220705-665e93233ae5
- github.com/smartcontractkit/ocr2keepers v0.7.17
+ github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20230913032705-f924d753cc47
+ 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/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-20230823081604-f2a0e6b108bb
- github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230823081604-f2a0e6b108bb
+ github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1
+ github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1
github.com/smartcontractkit/wsrpc v0.7.2
github.com/spf13/cast v1.5.1
github.com/stretchr/testify v1.8.4
github.com/theodesp/go-heaps v0.0.0-20190520121037-88e35354fe0a
- github.com/tidwall/gjson v1.14.4
+ github.com/tidwall/gjson v1.16.0
github.com/ugorji/go/codec v1.2.11
github.com/ulule/limiter/v3 v3.11.2
github.com/umbracle/ethgo v0.1.3
@@ -90,7 +91,7 @@ require (
go.uber.org/multierr v1.11.0
go.uber.org/zap v1.24.0
golang.org/x/crypto v0.11.0
- golang.org/x/exp v0.0.0-20230711153332-06a737ee72cb
+ golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1
golang.org/x/net v0.12.0
golang.org/x/sync v0.3.0
golang.org/x/term v0.10.0
@@ -149,7 +150,7 @@ require (
github.com/cosmos/ledger-cosmos-go v0.12.1 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/danieljoos/wincred v1.1.2 // indirect
- github.com/davecgh/go-spew v1.1.1 // indirect
+ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect
github.com/deckarep/golang-set/v2 v2.3.0 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect
@@ -195,6 +196,7 @@ require (
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/gopacket v1.1.19 // indirect
github.com/gorilla/context v1.1.1 // indirect
+ github.com/grafana/pyroscope-go/godeltaprof v0.1.3 // indirect
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect
github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.0-rc.0 // indirect
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0-rc.3 // indirect
@@ -203,7 +205,7 @@ require (
github.com/gtank/merlin v0.1.1 // indirect
github.com/gtank/ristretto255 v0.1.2 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
- github.com/hashicorp/go-hclog v1.4.0 // indirect
+ github.com/hashicorp/go-hclog v1.5.0 // indirect
github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hashicorp/golang-lru v0.6.0 // indirect
@@ -308,7 +310,6 @@ require (
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
github.com/prometheus/procfs v0.11.0 // indirect
- github.com/pyroscope-io/godeltaprof v0.1.0 // indirect
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect
github.com/rivo/uniseg v0.4.4 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
@@ -332,7 +333,7 @@ require (
github.com/tidwall/btree v1.6.0 // indirect
github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.0 // indirect
- github.com/tklauser/go-sysconf v0.3.11 // indirect
+ github.com/tklauser/go-sysconf v0.3.12 // indirect
github.com/tklauser/numcpus v0.6.1 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/tyler-smith/go-bip39 v1.1.0 // indirect
@@ -355,10 +356,10 @@ require (
go.uber.org/atomic v1.11.0 // indirect
go.uber.org/ratelimit v0.2.0 // indirect
golang.org/x/arch v0.3.0 // indirect
- golang.org/x/sys v0.10.0 // indirect
- google.golang.org/genproto v0.0.0-20230706204954-ccb25ca9f130 // indirect
- google.golang.org/genproto/googleapis/api v0.0.0-20230629202037-9506855d4529 // indirect
- google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 // indirect
+ golang.org/x/sys v0.11.0 // indirect
+ google.golang.org/genproto v0.0.0-20230717213848-3f92550aa753 // indirect
+ google.golang.org/genproto/googleapis/api v0.0.0-20230717213848-3f92550aa753 // indirect
+ google.golang.org/genproto/googleapis/rpc v0.0.0-20230717213848-3f92550aa753 // indirect
google.golang.org/grpc v1.56.2 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect
diff --git a/go.sum b/go.sum
index 589d6cece36..59356146049 100644
--- a/go.sum
+++ b/go.sum
@@ -19,18 +19,22 @@ 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=
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
-cloud.google.com/go/compute v1.20.1 h1:6aKEtlUiwEpJzM001l0yFkpXmUVXaN8W+fbkb2AZNbg=
+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.0 h1:67gSqaPukx7O8WLLHMa0PNs3EBGd2eE4d+psbO/CO94=
+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=
@@ -101,38 +109,46 @@ 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=
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
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=
github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA=
github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4=
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
-github.com/avast/retry-go/v4 v4.3.4 h1:pHLkL7jvCvP317I8Ge+Km2Yhntv3SdkJm7uekkqbKhM=
-github.com/avast/retry-go/v4 v4.3.4/go.mod h1:rv+Nla6Vk3/ilU0H51VHddWHiwimzX66yZ0JT6T+UvE=
+github.com/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.276 h1:ywPlx9C5Yc482dUgAZ9bHpQ6onVvJvYE9FJWsNDCEy0=
+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/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=
@@ -144,6 +160,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=
@@ -155,6 +172,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=
@@ -165,6 +183,7 @@ 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.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s=
@@ -172,8 +191,10 @@ github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZX
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=
@@ -186,6 +207,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=
@@ -194,10 +216,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=
@@ -211,6 +236,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.7.0 h1:uBjbrBx4QzU0zOEnU8KxoDl18dMNgDh+zZRUE0ucsbo=
@@ -218,6 +244,7 @@ github.com/cometbft/cometbft-db v0.7.0/go.mod h1:yiKJIm2WKrt6x8Cyxtq9YTEcIMPcEe4
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=
@@ -238,6 +265,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=
@@ -249,33 +277,40 @@ github.com/cosmos/ics23/go v0.9.1-0.20221207100636-b1abd8678aab/go.mod h1:2Cwqas
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=
github.com/danielkov/gin-helmet v0.0.0-20171108135313-1387e224435e h1:5jVSh2l/ho6ajWhSPNN84eHEdq3dp0T7+f6r3Tc6hsk=
github.com/danielkov/gin-helmet v0.0.0-20171108135313-1387e224435e/go.mod h1:IJgIiGUARc4aOr4bOQ85klmjsShkEEfiRc6q/yBSfo8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
+github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davidlazar/go-crypto v0.0.0-20170701192655-dcfb0a7ac018/go.mod h1:rQYf4tfk5sSwFsnDg3qYaBxSjsD9S8+59vW0dKUgme4=
github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c h1:pFUpOrbxDR6AkioZ1ySsx5yxlDQZ8stG2b88gTPxgJU=
github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c/go.mod h1:6UhI8N9EjYm1c2odKpFpAYeR8dsBeM7PtzQhRgxRr9U=
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=
@@ -298,7 +333,9 @@ 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/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
@@ -312,13 +349,19 @@ github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5y
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
-github.com/envoyproxy/protoc-gen-validate v1.0.1 h1:kt9FtLiooDc0vbwTLhdg3dyNX1K9Qwa1EK9LcD4jVUQ=
+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/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c h1:8ISkoahWXwZR41ois5lSJBSVw4D0OV19Ht/JSTzvSv0=
+github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c/go.mod h1:Yg+htXGokKKdzcwhuNDwVvN+uBxDGXJ7G/VN1d8fa64=
github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 h1:JWuenKqqX8nojtoVVWjGfOF9635RETekkoH6Cc9SX0A=
+github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg=
github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4 h1:7HZCaLC5+BZpmbhCOZJ293Lz68O7PYrF2EzeiFMwCLk=
+github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4/go.mod h1:5tD+neXqOorC30/tWg0LCSkrqj/AR6gu8yY8/fpw1q0=
github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8=
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=
@@ -327,11 +370,15 @@ 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=
@@ -377,6 +424,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=
@@ -402,6 +450,7 @@ 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-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=
@@ -413,11 +462,13 @@ github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg
github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
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=
@@ -459,6 +510,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=
@@ -524,6 +576,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=
@@ -535,25 +588,30 @@ github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLe
github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
-github.com/google/pprof v0.0.0-20230602150820-91b7bce49751 h1:hR7/MlvK23p6+lIw9SN1TigNLn9ZnF3W4SYRKq2gAHs=
-github.com/google/pprof v0.0.0-20230602150820-91b7bce49751/go.mod h1:Jh3hGz2jkYak8qXPD19ryItVnUgpgeqzdkY/D0EaeuA=
+github.com/google/pprof v0.0.0-20230705174524-200ffdc848b8 h1:n6vlPhxsA+BW/XsS5+uqi7GyzaLa5MH7qlSLBZtRdiA=
+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/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.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
-github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-github.com/googleapis/enterprise-certificate-proxy v0.2.3 h1:yk9/cqRKtT9wXZSsRH9aurXEpJX+U6FLtpYTdC3R06k=
+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.11.0 h1:9V9PWXEsWnPpQhu/PeQIkS4eGzMlTLGgt80cUUI8Ki4=
+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=
@@ -564,6 +622,10 @@ github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/ad
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
+github.com/grafana/pyroscope-go v1.0.2 h1:dEFgO9VbhYTwuwpCC5coTpuW0JjISEWDZtvRAW9v5Tw=
+github.com/grafana/pyroscope-go v1.0.2/go.mod h1:bShDKsVZdzxq+Ol6no0JKigU9y5FTWUcFditMXaH09o=
+github.com/grafana/pyroscope-go/godeltaprof v0.1.3 h1:eunWpv1B3Z7ZK9o4499EmQGlY+CsDmSZ4FbxjRx37uk=
+github.com/grafana/pyroscope-go/godeltaprof v0.1.3/go.mod h1:1HSPtjU8vLG0jE9JrTdzjgFqdJ/VgN7fvxBNq3luJko=
github.com/graph-gophers/dataloader v5.0.0+incompatible h1:R+yjsbrNq1Mo3aPG+Z/EKYrXrXXUNJHOgbRt+U6jOug=
github.com/graph-gophers/dataloader v5.0.0+incompatible/go.mod h1:jk4jk0c5ZISbKaMe8WsVopGB5/15GvGHMdMdPtwlRp4=
github.com/graph-gophers/graphql-go v1.3.0 h1:Eb9x/q6MFpCLz7jBCiP/WTxjSDrYLR1QY41SORZyNJ0=
@@ -594,12 +656,15 @@ 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-hclog v1.4.0 h1:ctuWFGrhFha8BnnzxqeRGidlEcQkDyL5u8J8t5eA11I=
-github.com/hashicorp/go-hclog v1.4.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
+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=
github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc=
github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
@@ -611,13 +676,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=
@@ -659,6 +727,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.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
@@ -721,8 +790,9 @@ github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsU
github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o=
github.com/jackc/pgconn v1.9.0/go.mod h1:YctiPyvzfU11JFxoXokUOOKQXQmDMoJL9vJzHH8/2JY=
github.com/jackc/pgconn v1.9.1-0.20210724152538-d89c8390a530/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI=
-github.com/jackc/pgconn v1.14.0 h1:vrbA9Ud87g6JdFWkHTJXppVce58qPIdP7N8y0Ml/A7Q=
github.com/jackc/pgconn v1.14.0/go.mod h1:9mBNlny0UvkgJdCDvdVHYSjI+8tD2rnKK69Wz8ti++E=
+github.com/jackc/pgconn v1.14.1 h1:smbxIaZA08n6YuxEX1sDyjV/qkbtUtkH20qLkR9MUR4=
+github.com/jackc/pgconn v1.14.1/go.mod h1:9mBNlny0UvkgJdCDvdVHYSjI+8tD2rnKK69Wz8ti++E=
github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE=
github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8=
github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE=
@@ -775,13 +845,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/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA=
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
@@ -802,6 +875,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/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=
@@ -1063,6 +1137,7 @@ 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/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=
@@ -1093,6 +1168,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=
@@ -1110,6 +1186,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=
@@ -1133,6 +1210,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=
@@ -1214,6 +1292,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=
@@ -1233,6 +1312,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=
@@ -1246,12 +1326,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=
@@ -1261,8 +1344,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/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=
@@ -1306,20 +1389,19 @@ github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsT
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
github.com/prometheus/procfs v0.11.0 h1:5EAgkfkMl659uZPbe9AS2N68a7Cc1TJbPEuGzFuRbyk=
github.com/prometheus/procfs v0.11.0/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM=
-github.com/prometheus/prometheus v0.45.0 h1:O/uG+Nw4kNxx/jDPxmjsSDd+9Ohql6E7ZSY1x5x/0KI=
-github.com/prometheus/prometheus v0.45.0/go.mod h1:jC5hyO8ItJBnDWGecbEucMyXjzxGv9cxsxsjS9u5s1w=
+github.com/prometheus/prometheus v0.46.0 h1:9JSdXnsuT6YsbODEhSQMwxNkGwPExfmzqG73vCMk/Kw=
+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/pyroscope-io/client v0.7.1 h1:yFRhj3vbgjBxehvxQmedmUWJQ4CAfCHhn+itPsuWsHw=
-github.com/pyroscope-io/client v0.7.1/go.mod h1:4h21iOU4pUOq0prKyDlvYRL+SCKsBc5wKiEtV+rJGqU=
-github.com/pyroscope-io/godeltaprof v0.1.0 h1:UBqtjt0yZi4jTxqZmLAs34XG6ycS3vUTlhEUSq4NHLE=
-github.com/pyroscope-io/godeltaprof v0.1.0/go.mod h1:psMITXp90+8pFenXkKIpNhrfmI9saQnPbba27VIaiQE=
github.com/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=
@@ -1332,13 +1414,15 @@ github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTE
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
-github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
-github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
+github.com/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.29.1 h1:cO+d60CHkknCbvzEWxP0S9K6KqyTjrCNUy1LdQLCGPc=
+github.com/rs/zerolog v1.29.1/go.mod h1:Le6ESbR7hc+DP6Lt1THiV8CQSdkkNrd3R0XbEgp3ZBU=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
@@ -1355,8 +1439,10 @@ github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI=
github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
-github.com/shirou/gopsutil/v3 v3.22.12 h1:oG0ns6poeUSxf78JtOsfygNWuEHYYz8hnnNg7P04TJs=
-github.com/shirou/gopsutil/v3 v3.22.12/go.mod h1:Xd7P1kwZcp5VW52+9XsirIKd/BROzbb2wdX3Kqlz9uI=
+github.com/shirou/gopsutil/v3 v3.23.8 h1:xnATPiybo6GgdRoC4YoGnxXZFRc3dqQTGi73oLvvBrE=
+github.com/shirou/gopsutil/v3 v3.23.8/go.mod h1:7hmCaBn+2ZwaZOr6jmPBZDfawwMGuo1id3C6aM8EDqQ=
+github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ=
+github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k=
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8=
@@ -1369,30 +1455,30 @@ github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704 h1:T3lFWumvbfM1u/etVq42Afwq/jtNSBSOA8n5jntnNPo=
github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704/go.mod h1:2QuJdEouTWjh5BDy5o/vgGXQtR4Gz8yH1IYB5eT7u4M=
-github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20230824124058-9b063c470048 h1:OHj8qzXajBAIT9TBnHN5LVGoCxvso/4JgCeg/l76Tgk=
-github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20230824124058-9b063c470048/go.mod h1:xMwqRdj5vqYhCJXgKVqvyAwdcqM6ZAEhnwEQ4Khsop8=
-github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230824125819-215fd09979a2 h1:z9PIgm0klhunwPy+KZYR4E9vCpjgJaMOyQRLCYgfoLk=
-github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230824125819-215fd09979a2/go.mod h1:gWclxGW7rLkbjXn7FGizYlyKhp/boekto4MEYGyiMG4=
-github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230802143301-165000751a85 h1:/fm02hYSUdhbSh7xPn7os9yHj7dnl8aLs2+nFXPiB4g=
-github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230802143301-165000751a85/go.mod h1:H3/j2l84FsxYevCLNERdVasI7FVr+t2mkpv+BCJLSVw=
-github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20230802150127-d2c95679d61a h1:b3rjvZLpTV45TmCV+ALX+EDDslf91pnDUugP54Lu9FA=
-github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20230802150127-d2c95679d61a/go.mod h1:LL+FLf10gOUHrF3aUsRGEZlT/w8DaW5T/eEo/54W68c=
+github.com/smartcontractkit/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-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/go-plugin v0.0.0-20230605132010-0f4d515d1472 h1:x3kNwgFlDmbE/n0gTSRMt9GBDfsfGrs4X9b9arPZtFI=
github.com/smartcontractkit/go-plugin v0.0.0-20230605132010-0f4d515d1472/go.mod h1:6/1TEzT0eQznvI/gV2CM29DLSkAK/e58mUWKVsPaph0=
github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f h1:hgJif132UCdjo8u43i7iPN1/MFnu49hv7lFGFftCHKU=
github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f/go.mod h1:MvMXoufZAtqExNexqi4cjrNYE9MefKddKylxjS+//n0=
-github.com/smartcontractkit/libocr v0.0.0-20230816220705-665e93233ae5 h1:rzbqGoScs9VHGnyCKF7AoQEuUfwJnzcKmGIfaczeanA=
-github.com/smartcontractkit/libocr v0.0.0-20230816220705-665e93233ae5/go.mod h1:2lyRkw/qLQgUWlrWWmq5nj0y90rWeO6Y+v+fCakRgb0=
-github.com/smartcontractkit/ocr2keepers v0.7.17 h1:847GG2SHyHIPc3yu+dhB+1HfeLRhSjyiKnhw3umpoJw=
-github.com/smartcontractkit/ocr2keepers v0.7.17/go.mod h1:AjcIEKeNnU7NRlvnuMCTjBIQ1kpW0YHhlFdeDa/3hs0=
+github.com/smartcontractkit/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=
github.com/smartcontractkit/sqlx v1.3.5-0.20210805004948-4be295aacbeb/go.mod h1:HNUu4cJekUdsJbwRBCiOybtkPJEfGRELQPe2tkoDEyk=
-github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230823081604-f2a0e6b108bb h1:xNLGJcARfz9HCUKla6wH0gmwsG1/FTAWWeOplW2J72A=
-github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230823081604-f2a0e6b108bb/go.mod h1:q6f4fe39oZPdsh1i57WznEZgxd8siidMaSFq3wdPmVg=
-github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230823081604-f2a0e6b108bb h1:jyhgdafuZsex+kEHDIgq8o8wuVoPTr9wsGmuBtcFbEk=
-github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230823081604-f2a0e6b108bb/go.mod h1:G5Sd/yzHWf26rQ+X0nG9E0buKPqRGPMJAfk2gwCzOOw=
+github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 h1:yiKnypAqP8l0OX0P3klzZ7SCcBUxy5KqTAKZmQOvSQE=
+github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1/go.mod h1:q6f4fe39oZPdsh1i57WznEZgxd8siidMaSFq3wdPmVg=
+github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 h1:Dai1bn+Q5cpeGMQwRdjOdVjG8mmFFROVkSKuUgBErRQ=
+github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1/go.mod h1:G5Sd/yzHWf26rQ+X0nG9E0buKPqRGPMJAfk2gwCzOOw=
github.com/smartcontractkit/wsrpc v0.7.2 h1:iBXzMeg7vc5YoezIQBq896y25BARw7OKbhrb6vPbtRQ=
github.com/smartcontractkit/wsrpc v0.7.2/go.mod h1:sj7QX2NQibhkhxTfs3KOhAj/5xwgqMipTvJVSssT9i0=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
@@ -1471,15 +1557,14 @@ github.com/theodesp/go-heaps v0.0.0-20190520121037-88e35354fe0a/go.mod h1:/sfW47
github.com/tidwall/btree v1.6.0 h1:LDZfKfQIBHGHWSwckhXI0RPSXzlo+KYdjK7FWSqOzzg=
github.com/tidwall/btree v1.6.0/go.mod h1:twD9XRA5jj9VUQGELzDO4HPQTNJsoWWfYEL+EUQ2cKY=
github.com/tidwall/gjson v1.9.3/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
-github.com/tidwall/gjson v1.14.4 h1:uo0p8EbA09J7RQaflQ1aBRffTR7xedD2bcIVSYxLnkM=
-github.com/tidwall/gjson v1.14.4/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
+github.com/tidwall/gjson v1.16.0 h1:SyXa+dsSPpUlcwEDuKuEBJEz5vzTvOea+9rjyYodQFg=
+github.com/tidwall/gjson v1.16.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
-github.com/tklauser/go-sysconf v0.3.11 h1:89WgdJhk5SNwJfu+GKyYveZ4IaJ7xAkecBo+KdJV0CM=
-github.com/tklauser/go-sysconf v0.3.11/go.mod h1:GqXfhXY3kiPa0nAXPDIQIWzJbMCB7AmcWpGR8lSZfqI=
-github.com/tklauser/numcpus v0.6.0/go.mod h1:FEZLMke0lhOUG6w2JadTzp0a+Nl8PF/GFkQ5UVIcaL4=
+github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU=
+github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk=
github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
@@ -1497,6 +1582,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=
@@ -1508,6 +1594,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=
@@ -1533,6 +1620,7 @@ github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQ
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
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=
@@ -1543,7 +1631,6 @@ github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
-github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw=
github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
@@ -1593,6 +1680,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=
@@ -1663,8 +1751,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
-golang.org/x/exp v0.0.0-20230711153332-06a737ee72cb h1:xIApU0ow1zwMa2uL1VDNeQlNVFTWMQxZUZCMDy0Q4Us=
-golang.org/x/exp v0.0.0-20230711153332-06a737ee72cb/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc=
+golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 h1:MGwJjxBy0HJshjDNfLsYO8xppfqWlA5ZT9OhtUUhTNw=
+golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@@ -1692,6 +1780,7 @@ golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
+golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -1764,7 +1853,8 @@ golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210413134643-5e61552d6c78/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.8.0 h1:6dkIjl3j3LtZ/O3sTgZTMsLKSftL/B8Zgq4huOIIUu8=
+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=
@@ -1868,12 +1958,11 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
-golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=
+golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
@@ -1978,6 +2067,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=
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=
@@ -2000,7 +2090,8 @@ google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz513
google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=
google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
-google.golang.org/api v0.126.0 h1:q4GJq+cAdMAC7XP7njvQ4tvohGLiSlytuL4BQxbIZ+o=
+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=
@@ -2055,12 +2146,12 @@ google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6D
google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210401141331-865547bb08e2/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=
google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24=
-google.golang.org/genproto v0.0.0-20230706204954-ccb25ca9f130 h1:Au6te5hbKUV8pIYWHqOUZ1pva5qK/rwbIhoXEUB9Lu8=
-google.golang.org/genproto v0.0.0-20230706204954-ccb25ca9f130/go.mod h1:O9kGHb51iE/nOGvQaDUuadVYqovW56s5emA88lQnj6Y=
-google.golang.org/genproto/googleapis/api v0.0.0-20230629202037-9506855d4529 h1:s5YSX+ZH5b5vS9rnpGymvIyMpLRJizowqDlOuyjXnTk=
-google.golang.org/genproto/googleapis/api v0.0.0-20230629202037-9506855d4529/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 h1:bVf09lpb+OJbByTj913DRJioFFAjf/ZGxEz7MajTp2U=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM=
+google.golang.org/genproto v0.0.0-20230717213848-3f92550aa753 h1:+VoAg+OKmWaommL56xmZSE2sUK8A7m6SUO7X89F2tbw=
+google.golang.org/genproto v0.0.0-20230717213848-3f92550aa753/go.mod h1:iqkVr8IRpZ53gx1dEnWlCUIEwDWqWARWrbzpasaTNYM=
+google.golang.org/genproto/googleapis/api v0.0.0-20230717213848-3f92550aa753 h1:lCbbUxUDD+DiXx9Q6F/ttL0aAu7N2pz8XnmMm8ZW4NE=
+google.golang.org/genproto/googleapis/api v0.0.0-20230717213848-3f92550aa753/go.mod h1:rsr7RhLuwsDKL7RmgDDCUc6yaGr1iqceVb5Wv6f6YvQ=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20230717213848-3f92550aa753 h1:XUODHrpzJEUeWmVo/jfNTLj0YyVveOo28oE6vkFbkO4=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20230717213848-3f92550aa753/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM=
google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
@@ -2151,6 +2242,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=
@@ -2160,16 +2252,27 @@ 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=
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.6 h1:s+C3xAMLwGmlI31Nyn/eAehUlZPwfYZu2JXM621Q5/k=
+nhooyr.io/websocket v1.8.6/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 563ef48e9a6..68b6d994197 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/Makefile b/integration-tests/Makefile
index 110c119df75..287bb939635 100644
--- a/integration-tests/Makefile
+++ b/integration-tests/Makefile
@@ -78,30 +78,6 @@ run: # Need to set network first in case it's unset. Doesn't matter for the runn
## All commands will use 16 threads to run tests in parallel. To change this, use -test.parallel n
# Smoke
-.PHONY: test_smoke_raw # Run smoke tests without any gotestfmt or default args
-test_smoke_raw:
- go test $(args) ./smoke
-
-.PHONY: test_smoke
-test_smoke: install_gotestfmt ## Run all smoke tests
- TEST_LOG_LEVEL="disabled" \
- go test -timeout 24h -count=1 -json $(args) ./smoke 2>&1 | tee /tmp/gotest.log | gotestfmt
-
-.PHONY: test_smoke_simulated
-test_smoke_simulated: install_gotestfmt ## Run all smoke tests on simulated blockchain
- TEST_LOG_LEVEL="disabled" \
- SELECTED_NETWORKS="SIMULATED,SIMULATED_1,SIMULATED_2" \
- go test -timeout 1h -count=1 -json $(args) ./smoke 2>&1 | tee /tmp/gotest.log | gotestfmt
-
-.PHONY: test_smoke_verbose
-test_smoke_verbose: ## Run all smoke tests with verbose logging
- go test -timeout 24h -count=1 -v $(args) ./smoke
-
-.PHONY: test_smoke_simulated_verbose
-test_smoke_simulated_verbose: ## Run all smoke tests with verbose logging
- SELECTED_NETWORKS="SIMULATED,SIMULATED_1,SIMULATED_2" \
- go test -timeout 24h -count=1 -v $(args) ./smoke
-
.PHONY: test_smoke_product
test_smoke_product: ## Run smoke tests for specific product ex: make test_smoke_product product="cron" args="--focus @cron -p"
ARGS="$(args)" PRODUCT=$(product) ./scripts/run_product_tests
diff --git a/integration-tests/README.md b/integration-tests/README.md
index 3a2a59e0fbf..c0b673fa92b 100644
--- a/integration-tests/README.md
+++ b/integration-tests/README.md
@@ -2,205 +2,40 @@
Here lives the integration tests for chainlink, utilizing our [chainlink-testing-framework](https://github.com/smartcontractkit/chainlink-testing-framework).
-## Full Setup
+## NOTE: Move to Testcontainers
-Prerequisites to run the tests from your local machine. Best for debugging and developing new tests, or checking changes to the framework. This can be a bit complex however, so if you just want to run the tests, see the [Just Run](#just-run) section.
+If you have previously run these smoke tests using GitHub Actions or some sort of Kubernetes setup, that method is no longer necessary. We have moved the majority of our tests to utilize plain Docker containers (with the help of [Testcontainers](https://golang.testcontainers.org/)). This should make tests faster, more stable, and enable you to run them on your local machine without much hassle.
-
- Details
+## Requirements
-### Install Dependencies
+1. [Go](https://go.dev/)
+2. [Docker](https://www.docker.com/)
+3. You'll probably want to [increase the resources available to Docker](https://stackoverflow.com/questions/44533319/how-to-assign-more-memory-to-docker-container) as most tests require quite a few containers (e.g. OCR requires 6 Chainlink nodes, 6 databases, a simulated blockchain, and a mock server).
-Run the below command to install all dependencies.
+## Configure
-```sh
-make install_qa_tools
-```
+See the [example.env](./example.env) file for environment variables you can set to configure things like network settings, Chainlink version, and log level. Remember to use `source .env` to activate your settings.
-Or you can choose to do it manually.
+## Build
-
- Install Go
+If you'd like to run the tests on a local build of Chainlink, you can point to your own docker image, or build a fresh one with `make`.
- [Install](https://go.dev/doc/install)
-
+`make build_docker_image image= tag=`
-
- Install NodeJS
+e.g.
- [Install](https://nodejs.org/en/download/)
-
+`make build_docker_image image=chainlink tag=test-tag`
-
- Install Helm Charts
+## Run
- [Install Helm](https://helm.sh/docs/intro/install/#through-package-managers) if you don't already have it. Then add necessary charts with the below commands.
+`go test ./smoke/_test.go`
- ```sh
- helm repo add chainlink-qa https://raw.githubusercontent.com/smartcontractkit/qa-charts/gh-pages/
- helm repo add bitnami https://charts.bitnami.com/bitnami
- helm repo update
- ```
+It's generally recommended to run only one test at a time on a local machine as it needs a lot of docker containers and can peg your resources otherwise. You will see docker containers spin up on your machine for each component of the test where you can inspect logs.
-
+## Analyze
-## Connect to a Kubernetes Cluster
+You can see the results of each test in the terminal with normal `go test` output. If a test fails, logs of each Chainlink container will dump into the `smoke/logs/` folder for later analysis. You can also see these logs in CI uploaded as GitHub artifacts.
-Integration tests require a connection to an actively running kubernetes cluster. [Minikube](https://minikube.sigs.k8s.io/docs/start/)
-can work fine for some tests, but in order to run more rigorous tests, or to run with any parallelism, you'll need to either
-increase minikube's resources significantly, or get a more substantial cluster.
-This is necessary to deploy ephemeral testing environments, which include external adapters, chainlink nodes and their DBs,
-as well as some simulated blockchains, all depending on the types of tests and networks being used.
+## Running Soak, Performance, Benchmark, and Chaos Tests
-### Setup Kubernetes Cluster using k3d
-
-[k3d](https://k3d.io/) is a lightweight wrapper to run k3s (a lightweight kubernetes distribution) in docker. It's a great way to run a local kubernetes cluster for testing.
-To create a new cluster you can run:
-
-```sh
-k3d cluster create test-k8s --registry-create test-k8s-registry:0.0.0.0:5000
-```
-
-This will create a cluster with a local registry running on port 5000. You can then use the registry to push images to and pull images from.
-
-To build and push chainlink image to the registry you can run:
-
-```sh
-make build_push_docker_image
-````
-
-To stop the cluster you can run:
-
-```sh
-k3d cluster stop test-k8s
-```
-
-To start an existing cluster you can run:
-
-```sh
-k3d cluster start test-k8s
-```
-
-## Configure Environment
-
-See the [example.env](./example.env) file and use it as a template for your own `.env` file. This allows you to configure general settings like what name to associate with your tests, and which Chainlink version to use when running them.
-
-You can also specify `EVM_KEYS` and `EVM_URLS` for running on live chains, or use specific identifiers as shown in the [example.env](./example.env) file.
-
-Other `EVM_*` variables are retrieved when running with the `@general` tag, and is helpful for doing quick sanity checks on new chains or when tweaking variables.
-
-**The tests will not automatically load your .env file. Remember to run `source .env` for changes to take effect.**
-
-## How to Run
-
-Most of the time, you'll want to run tests on a simulated chain, for the purposes of speed and cost.
-
-### Smoke
-
-Run all smoke tests with the below command. Will use your `SELECTED_NETWORKS` env var for which network to run on.
-
-```sh
-make test_smoke # Run all smoke tests on the chosen SELECTED_NETWORKS
-SELECTED_NETWORKS="GOERLI" make test_smoke # Run all smoke tests on GOERLI network
-make test_smoke_simulated # Run all smoke tests on a simulated network
-```
-
-Run all smoke tests in parallel, only using simulated blockchains. *Note: As of now, you can only run tests in parallel on simulated chains, not on live ones. Running on parallel tests on live chains will give errors*
-
-```sh
-make test_smoke_simulated args="-test.parallel="
-```
-
-You can also run specific tests and debug tests in vscode by setting up your .vscode/settings.json with this information. Just replace all the "" with your information before running a test.
-
-```json
-{
- "makefile.extensionOutputFolder": "./.vscode",
- "go.testEnvVars": {
- "LOG_LEVEL": "debug",
- "SELECTED_NETWORKS": "SIMULATED,SIMULATED_1,SIMULATED_2",
- "CHAINLINK_IMAGE":".dkr.ecr.us-west-2.amazonaws.com/chainlink",
- "CHAINLINK_VERSION":"develop",
- "CHAINLINK_ENV_USER":"",
- "TEST_LOG_LEVEL":"debug",
- "AWS_ACCESS_KEY_ID":"",
- "AWS_SECRET_ACCESS_KEY":"",
- "AWS_SESSION_TOKEN":""
- },
- "go.testTimeout": "900s"
-}
-```
-
-You can also run your tests inside of kubernetes instead of from locally to reduce local resource usage and the number of ports that get forwarded to the cluster. This is not recommended for normal developement since building and pushing the image can be time heavy depending on your internet upload speeds. To do this you will want to either pull down an already built chainlink-tests image or build one yourself. To build and push one yourself you can run:
-
-```sh
-make build_test_image tag= base_tag=latest suite="smoke soak chaos reorg migration performance" push=true
-```
-
-Once that is done building you can add this to your go.testEnvVars in .vscode/settings.json with the correct account number and tag filled out.
-
-```json
- "TEST_SUITE": "smoke",
- "TEST_ARGS": "-test.timeout 30m",
- "ENV_JOB_IMAGE":".dkr.ecr.us-west-2.amazonaws.com/chainlink-env-tests:",
-```
-
-Once that is done you can run/debug your test using the vscode test view just like normal.
-
-### Soak
-
-Currently we have 2 soak tests, both can be triggered using make commands.
-
-```sh
-make test_soak_ocr
-make test_soak_keeper
-```
-
-Soak tests will pull all their network information from the env vars that you can set in the `.env` file. *Reminder to run `source .env` for changes to take effect.*
-
-To configure specific parameters of how the soak tests run (e.g. test length, number of contracts), adjust the values in your `.env` file, you can use `example.env` as reference
-
-
-#### Running with custom image
-On each PR navigate to the `integration-tests` job, here you will find the images for both chainlink-tests and core. In your env file you need to replace:
-
-`ENV_JOB_IMAGE="image-location/chainlink-tests:"`
-
-`CHAINLINK_IMAGE="public.ecr.aws/chainlink/chainlink"`
-
-`export CHAINLINK_VERSION=""`
-
-After all the env vars are exported, run the tests. This will kick off a remote runner that will be in charge of running the tests. Locally the test should pass quickly and a namespace will be displayed in the output e.g
-`INF Creating new namespace Namespace=soak-ocr-goerli-testnet-957b2`
-
-#### Logs and monitoring
-- Pod logs: `kubectl logs -n soak-ocr-goerli-testnet-957b2 -c node -f chainlink-0-1`
-- Remote runner logs: `kubectl logs -n soak-ocr-goerli-testnet-957b2 -f remote-runner-cs2as`
-- Navigate to Grafana chainlink testing insights for all logs
-
-### Performance
-
-Currently, all performance tests are only run on simulated blockchains.
-
-```sh
-make test_perf
-```
-
-## Common Issues
-
-- When upgrading to a new version, it's possible the helm charts have changed. There are a myriad of errors that can result from this, so it's best to just try running `helm repo update` when encountering an error you're unsure of.
-- Docker failing to pull image, make sure you are referencing the correct ECR repo in AWS since develop images are not pushed to the public one.
- - If tests hang for some time this is usually the case, so make sure to check the logs each time tests are failing to start
-
-
-
-
-## Just Run
-
-If you're making changes to chainlink code, or just want to run some tests without a complex setup, follow the below steps.
-
-1. [Install Go](https://go.dev/doc/install)
-2. [Install GitHub CLI](https://cli.github.com/)
-3. Authenticate with GitHub CLI: `gh auth login`
-4. `make run`
-5. Follow the setup wizard and watch your tests run in the GitHub Action.
\ No newline at end of file
+These tests remain bound to a Kubernetes run environment, and require more complex setup and running instructions not documented here. We endeavor to make these easier to run and configure, but for the time being please seek a member of the QA/Test Tooling team if you want to run these.
diff --git a/integration-tests/actions/actions.go b/integration-tests/actions/actions.go
index ffb71cb7424..e37c3738ff8 100644
--- a/integration-tests/actions/actions.go
+++ b/integration-tests/actions/actions.go
@@ -19,6 +19,7 @@ import (
"github.com/smartcontractkit/chainlink-env/environment"
"github.com/smartcontractkit/chainlink-testing-framework/blockchain"
ctfClient "github.com/smartcontractkit/chainlink-testing-framework/client"
+ "github.com/smartcontractkit/chainlink-testing-framework/logging"
"github.com/smartcontractkit/chainlink-testing-framework/testreporters"
"github.com/smartcontractkit/chainlink-testing-framework/utils"
@@ -251,7 +252,7 @@ func TeardownSuite(
failingLogLevel zapcore.Level, // Examines logs after the test, and fails the test if any Chainlink logs are found at or above provided level
clients ...blockchain.EVMClient,
) error {
- l := utils.GetTestLogger(t)
+ l := logging.GetTestLogger(t)
if err := testreporters.WriteTeardownLogs(t, env, optionalTestReporter, failingLogLevel); err != nil {
return errors.Wrap(err, "Error dumping environment logs, leaving environment running for manual retrieval")
}
@@ -263,7 +264,7 @@ func TeardownSuite(
for _, c := range clients {
if c != nil && chainlinkNodes != nil && len(chainlinkNodes) > 0 {
- if err := returnFunds(chainlinkNodes, c); err != nil {
+ if err := ReturnFunds(chainlinkNodes, c); err != nil {
// This printed line is required for tests that use real funds to propagate the failure
// out to the system running the test. Do not remove
fmt.Println(environment.FAILED_FUND_RETURN)
@@ -295,7 +296,7 @@ func TeardownRemoteSuite(
optionalTestReporter testreporters.TestReporter, // Optionally pass in a test reporter to log further metrics
client blockchain.EVMClient,
) error {
- l := utils.GetTestLogger(t)
+ l := logging.GetTestLogger(t)
var err error
if err = testreporters.SendReport(t, namespace, "./", optionalTestReporter); err != nil {
l.Warn().Err(err).Msg("Error writing test report")
@@ -306,7 +307,7 @@ func TeardownRemoteSuite(
l.Warn().Msgf("Error deleting jobs %+v", err)
}
- if err = returnFunds(chainlinkNodes, client); err != nil {
+ if err = ReturnFunds(chainlinkNodes, client); err != nil {
l.Error().Err(err).Str("Namespace", namespace).
Msg("Error attempting to return funds from chainlink nodes to network's default wallet. " +
"Environment is left running so you can try manually!")
@@ -337,8 +338,9 @@ func DeleteAllJobs(chainlinkNodes []*client.ChainlinkK8sClient) error {
return nil
}
-// Returns all the funds from the chainlink nodes to the networks default address
-func returnFunds(chainlinkNodes []*client.ChainlinkK8sClient, blockchainClient blockchain.EVMClient) error {
+// ReturnFunds attempts to return all the funds from the chainlink nodes to the network's default address
+// all from a remote, k8s style environment
+func ReturnFunds(chainlinkNodes []*client.ChainlinkK8sClient, blockchainClient blockchain.EVMClient) error {
if blockchainClient == nil {
return errors.New("blockchain client is nil, unable to return funds from chainlink nodes")
}
diff --git a/integration-tests/actions/actions_local.go b/integration-tests/actions/actions_local.go
new file mode 100644
index 00000000000..d2e2fde3217
--- /dev/null
+++ b/integration-tests/actions/actions_local.go
@@ -0,0 +1,25 @@
+// Package actions enables common chainlink interactions
+package actions
+
+import (
+ "github.com/pkg/errors"
+
+ "github.com/smartcontractkit/chainlink/integration-tests/docker/test_env"
+)
+
+// UpgradeChainlinkNodeVersions upgrades all Chainlink nodes to a new version, and then runs the test environment
+// to apply the upgrades
+func UpgradeChainlinkNodeVersionsLocal(
+ newImage, newVersion string,
+ nodes ...*test_env.ClNode,
+) error {
+ if newImage == "" && newVersion == "" {
+ return errors.New("unable to upgrade node version, found empty image and version, must provide either a new image or a new version")
+ }
+ for _, node := range nodes {
+ if err := node.UpgradeVersion(node.NodeConfig, newImage, newVersion); err != nil {
+ return err
+ }
+ }
+ return nil
+}
diff --git a/integration-tests/actions/automation_ocr_helpers.go b/integration-tests/actions/automation_ocr_helpers.go
index 4561bc1764a..fb94d6109b4 100644
--- a/integration-tests/actions/automation_ocr_helpers.go
+++ b/integration-tests/actions/automation_ocr_helpers.go
@@ -11,25 +11,23 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/lib/pq"
- ocr3 "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3confighelper"
- "github.com/stretchr/testify/require"
- "gopkg.in/guregu/null.v4"
"github.com/smartcontractkit/chainlink-testing-framework/blockchain"
- "github.com/smartcontractkit/chainlink-testing-framework/utils"
+ "github.com/smartcontractkit/chainlink-testing-framework/logging"
+ "github.com/smartcontractkit/chainlink/v2/core/services/job"
+ "github.com/smartcontractkit/chainlink/v2/core/services/keystore/chaintype"
+ "github.com/smartcontractkit/chainlink/v2/core/store/models"
ocr2 "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper"
+ ocr3 "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3confighelper"
+ "github.com/smartcontractkit/libocr/offchainreporting2plus/types"
ocr2keepers20config "github.com/smartcontractkit/ocr2keepers/pkg/v2/config"
ocr2keepers30config "github.com/smartcontractkit/ocr2keepers/pkg/v3/config"
+ "github.com/stretchr/testify/require"
+ "gopkg.in/guregu/null.v4"
"github.com/smartcontractkit/chainlink/integration-tests/client"
"github.com/smartcontractkit/chainlink/integration-tests/contracts"
"github.com/smartcontractkit/chainlink/integration-tests/contracts/ethereum"
-
- "github.com/smartcontractkit/libocr/offchainreporting2plus/types"
-
- "github.com/smartcontractkit/chainlink/v2/core/services/job"
- "github.com/smartcontractkit/chainlink/v2/core/services/keystore/chaintype"
- "github.com/smartcontractkit/chainlink/v2/core/store/models"
)
func BuildAutoOCR2ConfigVars(
@@ -50,7 +48,7 @@ func BuildAutoOCR2ConfigVarsWithKeyIndex(
deltaStage time.Duration,
keyIndex int,
) (contracts.OCRv2Config, error) {
- l := utils.GetTestLogger(t)
+ l := logging.GetTestLogger(t)
S, oracleIdentities, err := GetOracleIdentitiesWithKeyIndex(chainlinkNodes, keyIndex)
if err != nil {
return contracts.OCRv2Config{}, err
@@ -71,7 +69,7 @@ func BuildAutoOCR2ConfigVarsWithKeyIndex(
GasLimitPerReport: 5_300_000,
GasOverheadPerUpkeep: 300_000,
MinConfirmations: 0,
- MaxUpkeepBatchSize: 1,
+ MaxUpkeepBatchSize: 10,
})
if err != nil {
return contracts.OCRv2Config{}, err
@@ -174,7 +172,7 @@ func CreateOCRKeeperJobs(
keyIndex int,
registryVersion ethereum.KeeperRegistryVersion,
) {
- l := utils.GetTestLogger(t)
+ l := logging.GetTestLogger(t)
bootstrapNode := chainlinkNodes[0]
bootstrapP2PIds, err := bootstrapNode.MustReadP2PKeys()
require.NoError(t, err, "Shouldn't fail reading P2P keys from bootstrap node")
@@ -250,17 +248,11 @@ func DeployAutoOCRRegistryAndRegistrar(
t *testing.T,
registryVersion ethereum.KeeperRegistryVersion,
registrySettings contracts.KeeperRegistrySettings,
- numberOfUpkeeps int,
linkToken contracts.LinkToken,
contractDeployer contracts.ContractDeployer,
client blockchain.EVMClient,
) (contracts.KeeperRegistry, contracts.KeeperRegistrar) {
registry := deployRegistry(t, registryVersion, registrySettings, contractDeployer, client, linkToken)
-
- // Fund the registry with 1 LINK * amount of KeeperConsumerPerformance contracts
- err := linkToken.Transfer(registry.Address(), big.NewInt(0).Mul(big.NewInt(1e18), big.NewInt(int64(numberOfUpkeeps))))
- require.NoError(t, err, "Funding keeper registry contract shouldn't fail")
-
registrar := deployRegistrar(t, registryVersion, registry, linkToken, contractDeployer, client)
return registry, registrar
diff --git a/integration-tests/actions/automation_ocr_helpers_local.go b/integration-tests/actions/automation_ocr_helpers_local.go
new file mode 100644
index 00000000000..86738b0247d
--- /dev/null
+++ b/integration-tests/actions/automation_ocr_helpers_local.go
@@ -0,0 +1,259 @@
+package actions
+
+//revive:disable:dot-imports
+import (
+ "encoding/json"
+ "fmt"
+ "time"
+
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/lib/pq"
+ "github.com/pkg/errors"
+ "github.com/rs/zerolog"
+ "gopkg.in/guregu/null.v4"
+
+ "github.com/smartcontractkit/chainlink/integration-tests/client"
+ "github.com/smartcontractkit/chainlink/integration-tests/contracts"
+ "github.com/smartcontractkit/chainlink/integration-tests/contracts/ethereum"
+ ocr2 "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper"
+ ocr3 "github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3confighelper"
+ "github.com/smartcontractkit/libocr/offchainreporting2plus/types"
+ ocr2keepers20config "github.com/smartcontractkit/ocr2keepers/pkg/v2/config"
+ ocr2keepers30config "github.com/smartcontractkit/ocr2keepers/pkg/v3/config"
+
+ "github.com/smartcontractkit/chainlink/v2/core/services/job"
+ "github.com/smartcontractkit/chainlink/v2/core/services/keystore/chaintype"
+ "github.com/smartcontractkit/chainlink/v2/core/store/models"
+)
+
+func BuildAutoOCR2ConfigVarsLocal(
+ l zerolog.Logger,
+ chainlinkNodes []*client.ChainlinkClient,
+ registryConfig contracts.KeeperRegistrySettings,
+ registrar string,
+ deltaStage time.Duration,
+) (contracts.OCRv2Config, error) {
+ return BuildAutoOCR2ConfigVarsWithKeyIndexLocal(l, chainlinkNodes, registryConfig, registrar, deltaStage, 0)
+}
+
+func BuildAutoOCR2ConfigVarsWithKeyIndexLocal(
+ l zerolog.Logger,
+ chainlinkNodes []*client.ChainlinkClient,
+ registryConfig contracts.KeeperRegistrySettings,
+ registrar string,
+ deltaStage time.Duration,
+ keyIndex int,
+) (contracts.OCRv2Config, error) {
+ S, oracleIdentities, err := GetOracleIdentitiesWithKeyIndexLocal(chainlinkNodes, keyIndex)
+ if err != nil {
+ return contracts.OCRv2Config{}, err
+ }
+
+ var offC []byte
+ var signerOnchainPublicKeys []types.OnchainPublicKey
+ var transmitterAccounts []types.Account
+ var f uint8
+ var offchainConfigVersion uint64
+ var offchainConfig []byte
+
+ if registryConfig.RegistryVersion == ethereum.RegistryVersion_2_1 {
+ offC, err = json.Marshal(ocr2keepers30config.OffchainConfig{
+ TargetProbability: "0.999",
+ TargetInRounds: 1,
+ PerformLockoutWindow: 3600000, // Intentionally set to be higher than in prod for testing purpose
+ GasLimitPerReport: 5_300_000,
+ GasOverheadPerUpkeep: 300_000,
+ MinConfirmations: 0,
+ MaxUpkeepBatchSize: 1,
+ })
+ if err != nil {
+ return contracts.OCRv2Config{}, err
+ }
+
+ signerOnchainPublicKeys, transmitterAccounts, f, _, offchainConfigVersion, offchainConfig, err = ocr3.ContractSetConfigArgsForTests(
+ 10*time.Second, // deltaProgress time.Duration,
+ 15*time.Second, // deltaResend time.Duration,
+ 500*time.Millisecond, // deltaInitial time.Duration,
+ 1000*time.Millisecond, // deltaRound time.Duration,
+ 200*time.Millisecond, // deltaGrace time.Duration,
+ 300*time.Millisecond, // deltaCertifiedCommitRequest time.Duration
+ deltaStage, // deltaStage time.Duration,
+ 24, // rMax uint64,
+ S, // s []int,
+ oracleIdentities, // oracles []OracleIdentityExtra,
+ offC, // reportingPluginConfig []byte,
+ 20*time.Millisecond, // maxDurationQuery time.Duration,
+ 20*time.Millisecond, // maxDurationObservation time.Duration, // good to here
+ 1200*time.Millisecond, // maxDurationShouldAcceptAttestedReport time.Duration,
+ 20*time.Millisecond, // maxDurationShouldTransmitAcceptedReport time.Duration,
+ 1, // f int,
+ nil, // onchainConfig []byte,
+ )
+ if err != nil {
+ return contracts.OCRv2Config{}, err
+ }
+ } else {
+ offC, err = json.Marshal(ocr2keepers20config.OffchainConfig{
+ TargetProbability: "0.999",
+ TargetInRounds: 1,
+ PerformLockoutWindow: 3600000, // Intentionally set to be higher than in prod for testing purpose
+ GasLimitPerReport: 5_300_000,
+ GasOverheadPerUpkeep: 300_000,
+ SamplingJobDuration: 3000,
+ MinConfirmations: 0,
+ MaxUpkeepBatchSize: 1,
+ })
+ if err != nil {
+ return contracts.OCRv2Config{}, err
+ }
+
+ signerOnchainPublicKeys, transmitterAccounts, f, _, offchainConfigVersion, offchainConfig, err = ocr2.ContractSetConfigArgsForTests(
+ 10*time.Second, // deltaProgress time.Duration,
+ 15*time.Second, // deltaResend time.Duration,
+ 3000*time.Millisecond, // deltaRound time.Duration,
+ 200*time.Millisecond, // deltaGrace time.Duration,
+ deltaStage, // deltaStage time.Duration,
+ 24, // rMax uint8,
+ S, // s []int,
+ oracleIdentities, // oracles []OracleIdentityExtra,
+ offC, // reportingPluginConfig []byte,
+ 20*time.Millisecond, // maxDurationQuery time.Duration,
+ 20*time.Millisecond, // maxDurationObservation time.Duration,
+ 1200*time.Millisecond, // maxDurationReport time.Duration,
+ 20*time.Millisecond, // maxDurationShouldAcceptFinalizedReport time.Duration,
+ 20*time.Millisecond, // maxDurationShouldTransmitAcceptedReport time.Duration,
+ 1, // f int,
+ nil, // onchainConfig []byte,
+ )
+ if err != nil {
+ return contracts.OCRv2Config{}, err
+ }
+ }
+
+ var signers []common.Address
+ for _, signer := range signerOnchainPublicKeys {
+ if len(signer) != 20 {
+ return contracts.OCRv2Config{}, fmt.Errorf("OnChainPublicKey '%v' has wrong length for address", signer)
+ }
+ signers = append(signers, common.BytesToAddress(signer))
+ }
+
+ var transmitters []common.Address
+ for _, transmitter := range transmitterAccounts {
+ if !common.IsHexAddress(string(transmitter)) {
+ return contracts.OCRv2Config{}, fmt.Errorf("TransmitAccount '%s' is not a valid Ethereum address", string(transmitter))
+ }
+ transmitters = append(transmitters, common.HexToAddress(string(transmitter)))
+ }
+
+ onchainConfig, err := registryConfig.EncodeOnChainConfig(registrar)
+ if err != nil {
+ return contracts.OCRv2Config{}, err
+ }
+
+ l.Info().Msg("Done building OCR config")
+ return contracts.OCRv2Config{
+ Signers: signers,
+ Transmitters: transmitters,
+ F: f,
+ OnchainConfig: onchainConfig,
+ OffchainConfigVersion: offchainConfigVersion,
+ OffchainConfig: offchainConfig,
+ }, nil
+}
+
+// CreateOCRKeeperJobs bootstraps the first node and to the other nodes sends ocr jobs
+func CreateOCRKeeperJobsLocal(
+ l zerolog.Logger,
+ chainlinkNodes []*client.ChainlinkClient,
+ registryAddr string,
+ chainID int64,
+ keyIndex int,
+ registryVersion ethereum.KeeperRegistryVersion,
+) error {
+ bootstrapNode := chainlinkNodes[0]
+ bootstrapP2PIds, err := bootstrapNode.MustReadP2PKeys()
+ if err != nil {
+ l.Error().Err(err).Msg("Shouldn't fail reading P2P keys from bootstrap node")
+ return err
+ }
+ bootstrapP2PId := bootstrapP2PIds.Data[0].Attributes.PeerID
+
+ var contractVersion string
+ if registryVersion == ethereum.RegistryVersion_2_1 {
+ contractVersion = "v2.1"
+ } else if registryVersion == ethereum.RegistryVersion_2_0 {
+ contractVersion = "v2.0"
+ } else {
+ return errors.New("v2.0 and v2.1 are the only supported versions")
+ }
+
+ bootstrapSpec := &client.OCR2TaskJobSpec{
+ Name: "ocr2 bootstrap node " + registryAddr,
+ JobType: "bootstrap",
+ OCR2OracleSpec: job.OCR2OracleSpec{
+ ContractID: registryAddr,
+ Relay: "evm",
+ RelayConfig: map[string]interface{}{
+ "chainID": int(chainID),
+ },
+ ContractConfigTrackerPollInterval: *models.NewInterval(time.Second * 15),
+ },
+ }
+ _, err = bootstrapNode.MustCreateJob(bootstrapSpec)
+ if err != nil {
+ l.Error().Err(err).Msg("Shouldn't fail creating bootstrap job on bootstrap node")
+ return err
+ }
+
+ P2Pv2Bootstrapper := fmt.Sprintf("%s@%s:%d", bootstrapP2PId, bootstrapNode.InternalIP(), 6690)
+ for nodeIndex := 1; nodeIndex < len(chainlinkNodes); nodeIndex++ {
+ nodeTransmitterAddress, err := chainlinkNodes[nodeIndex].EthAddresses()
+ if err != nil {
+ l.Error().Err(err).Msgf("Shouldn't fail getting primary ETH address from OCR node %d", nodeIndex+1)
+ return err
+ }
+ nodeOCRKeys, err := chainlinkNodes[nodeIndex].MustReadOCR2Keys()
+ if err != nil {
+ l.Error().Err(err).Msgf("Shouldn't fail getting OCR keys from OCR node %d", nodeIndex+1)
+ return err
+ }
+ var nodeOCRKeyId []string
+ for _, key := range nodeOCRKeys.Data {
+ if key.Attributes.ChainType == string(chaintype.EVM) {
+ nodeOCRKeyId = append(nodeOCRKeyId, key.ID)
+ break
+ }
+ }
+
+ autoOCR2JobSpec := client.OCR2TaskJobSpec{
+ Name: "ocr2 " + registryAddr,
+ JobType: "offchainreporting2",
+ OCR2OracleSpec: job.OCR2OracleSpec{
+ PluginType: "ocr2automation",
+ Relay: "evm",
+ RelayConfig: map[string]interface{}{
+ "chainID": int(chainID),
+ },
+ PluginConfig: map[string]interface{}{
+ "mercuryCredentialName": "\"cred1\"",
+ "contractVersion": "\"" + contractVersion + "\"",
+ },
+ ContractConfigTrackerPollInterval: *models.NewInterval(time.Second * 15),
+ ContractID: registryAddr, // registryAddr
+ OCRKeyBundleID: null.StringFrom(nodeOCRKeyId[0]), // get node ocr2config.ID
+ TransmitterID: null.StringFrom(nodeTransmitterAddress[keyIndex]), // node addr
+ P2PV2Bootstrappers: pq.StringArray{P2Pv2Bootstrapper}, // bootstrap node key and address @bootstrap:8000
+ },
+ }
+
+ _, err = chainlinkNodes[nodeIndex].MustCreateJob(&autoOCR2JobSpec)
+ if err != nil {
+ l.Error().Err(err).Msgf("Shouldn't fail creating OCR Task job on OCR node %d err: %+v", nodeIndex+1, err)
+ return err
+ }
+
+ }
+ l.Info().Msg("Done creating OCR automation jobs")
+ return nil
+}
diff --git a/integration-tests/actions/keeper_helpers.go b/integration-tests/actions/keeper_helpers.go
index 98c9a51e1c8..f824e75019d 100644
--- a/integration-tests/actions/keeper_helpers.go
+++ b/integration-tests/actions/keeper_helpers.go
@@ -13,7 +13,7 @@ import (
"github.com/stretchr/testify/require"
"github.com/smartcontractkit/chainlink-testing-framework/blockchain"
- "github.com/smartcontractkit/chainlink-testing-framework/utils"
+ "github.com/smartcontractkit/chainlink-testing-framework/logging"
"github.com/smartcontractkit/chainlink/integration-tests/client"
"github.com/smartcontractkit/chainlink/integration-tests/contracts"
@@ -27,6 +27,7 @@ func CreateKeeperJobs(
chainlinkNodes []*client.ChainlinkK8sClient,
keeperRegistry contracts.KeeperRegistry,
ocrConfig contracts.OCRv2Config,
+ evmChainID string,
) {
// Send keeper jobs to registry and chainlink nodes
primaryNode := chainlinkNodes[0]
@@ -49,6 +50,7 @@ func CreateKeeperJobs(
Name: fmt.Sprintf("keeper-test-%s", keeperRegistry.Address()),
ContractAddress: keeperRegistry.Address(),
FromAddress: chainlinkNodeAddress,
+ EVMChainID: evmChainID,
MinIncomingConfirmations: 1,
})
require.NoError(t, err, "Creating KeeperV2 Job shouldn't fail")
@@ -61,6 +63,7 @@ func CreateKeeperJobsWithKeyIndex(
keeperRegistry contracts.KeeperRegistry,
keyIndex int,
ocrConfig contracts.OCRv2Config,
+ evmChainID string,
) {
// Send keeper jobs to registry and chainlink nodes
primaryNode := chainlinkNodes[0]
@@ -83,6 +86,7 @@ func CreateKeeperJobsWithKeyIndex(
Name: fmt.Sprintf("keeper-test-%s", keeperRegistry.Address()),
ContractAddress: keeperRegistry.Address(),
FromAddress: chainlinkNodeAddress[keyIndex],
+ EVMChainID: evmChainID,
MinIncomingConfirmations: 1,
})
require.NoError(t, err, "Creating KeeperV2 Job shouldn't fail")
@@ -335,7 +339,7 @@ func RegisterUpkeepContracts(t *testing.T, linkToken contracts.LinkToken, linkFu
}
func RegisterUpkeepContractsWithCheckData(t *testing.T, linkToken contracts.LinkToken, linkFunds *big.Int, client blockchain.EVMClient, upkeepGasLimit uint32, registry contracts.KeeperRegistry, registrar contracts.KeeperRegistrar, numberOfContracts int, upkeepAddresses []string, checkData [][]byte, isLogTrigger bool) []*big.Int {
- l := utils.GetTestLogger(t)
+ l := logging.GetTestLogger(t)
registrationTxHashes := make([]common.Hash, 0)
upkeepIds := make([]*big.Int, 0)
for contractCount, upkeepAddress := range upkeepAddresses {
@@ -394,7 +398,7 @@ func RegisterUpkeepContractsWithCheckData(t *testing.T, linkToken contracts.Link
}
func DeployKeeperConsumers(t *testing.T, contractDeployer contracts.ContractDeployer, client blockchain.EVMClient, numberOfContracts int, isLogTrigger bool) []contracts.KeeperConsumer {
- l := utils.GetTestLogger(t)
+ l := logging.GetTestLogger(t)
keeperConsumerContracts := make([]contracts.KeeperConsumer, 0)
for contractCount := 0; contractCount < numberOfContracts; contractCount++ {
@@ -437,7 +441,7 @@ func DeployKeeperConsumersPerformance(
checkGasToBurn, // How much gas should be burned on checkUpkeep() calls
performGasToBurn int64, // How much gas should be burned on performUpkeep() calls
) []contracts.KeeperConsumerPerformance {
- l := utils.GetTestLogger(t)
+ l := logging.GetTestLogger(t)
upkeeps := make([]contracts.KeeperConsumerPerformance, 0)
for contractCount := 0; contractCount < numberOfContracts; contractCount++ {
@@ -474,7 +478,7 @@ func DeployPerformDataChecker(
numberOfContracts int,
expectedData []byte,
) []contracts.KeeperPerformDataChecker {
- l := utils.GetTestLogger(t)
+ l := logging.GetTestLogger(t)
upkeeps := make([]contracts.KeeperPerformDataChecker, 0)
for contractCount := 0; contractCount < numberOfContracts; contractCount++ {
@@ -506,7 +510,7 @@ func DeployUpkeepCounters(
testRange *big.Int,
interval *big.Int,
) []contracts.UpkeepCounter {
- l := utils.GetTestLogger(t)
+ l := logging.GetTestLogger(t)
upkeepCounters := make([]contracts.UpkeepCounter, 0)
for contractCount := 0; contractCount < numberOfContracts; contractCount++ {
@@ -539,7 +543,7 @@ func DeployUpkeepPerformCounterRestrictive(
testRange *big.Int,
averageEligibilityCadence *big.Int,
) []contracts.UpkeepPerformCounterRestrictive {
- l := utils.GetTestLogger(t)
+ l := logging.GetTestLogger(t)
upkeepCounters := make([]contracts.UpkeepPerformCounterRestrictive, 0)
for contractCount := 0; contractCount < numberOfContracts; contractCount++ {
diff --git a/integration-tests/actions/keeper_helpers_local.go b/integration-tests/actions/keeper_helpers_local.go
index 6fc7ef43dbe..d9d15b33a3e 100644
--- a/integration-tests/actions/keeper_helpers_local.go
+++ b/integration-tests/actions/keeper_helpers_local.go
@@ -3,26 +3,29 @@ package actions
import (
"fmt"
- "github.com/rs/zerolog/log"
+ "github.com/rs/zerolog"
+
"github.com/smartcontractkit/chainlink/integration-tests/client"
"github.com/smartcontractkit/chainlink/integration-tests/contracts"
)
func CreateKeeperJobsLocal(
+ l zerolog.Logger,
chainlinkNodes []*client.ChainlinkClient,
keeperRegistry contracts.KeeperRegistry,
ocrConfig contracts.OCRv2Config,
+ evmChainID string,
) ([]*client.Job, error) {
// Send keeper jobs to registry and chainlink nodes
primaryNode := chainlinkNodes[0]
primaryNodeAddress, err := primaryNode.PrimaryEthAddress()
if err != nil {
- log.Error().Err(err).Msg("Reading ETH Keys from Chainlink Client shouldn't fail")
+ l.Error().Err(err).Msg("Reading ETH Keys from Chainlink Client shouldn't fail")
return nil, err
}
nodeAddresses, err := ChainlinkNodeAddressesLocal(chainlinkNodes)
if err != nil {
- log.Error().Err(err).Msg("Retrieving on-chain wallet addresses for chainlink nodes shouldn't fail")
+ l.Error().Err(err).Msg("Retrieving on-chain wallet addresses for chainlink nodes shouldn't fail")
return nil, err
}
nodeAddressesStr, payees := make([]string, 0), make([]string, 0)
@@ -32,24 +35,25 @@ func CreateKeeperJobsLocal(
}
err = keeperRegistry.SetKeepers(nodeAddressesStr, payees, ocrConfig)
if err != nil {
- log.Error().Err(err).Msg("Setting keepers in the registry shouldn't fail")
+ l.Error().Err(err).Msg("Setting keepers in the registry shouldn't fail")
return nil, err
}
jobs := []*client.Job{}
for _, chainlinkNode := range chainlinkNodes {
chainlinkNodeAddress, err := chainlinkNode.PrimaryEthAddress()
if err != nil {
- log.Error().Err(err).Msg("Error retrieving chainlink node address")
+ l.Error().Err(err).Msg("Error retrieving chainlink node address")
return nil, err
}
job, err := chainlinkNode.MustCreateJob(&client.KeeperJobSpec{
Name: fmt.Sprintf("keeper-test-%s", keeperRegistry.Address()),
ContractAddress: keeperRegistry.Address(),
FromAddress: chainlinkNodeAddress,
+ EVMChainID: evmChainID,
MinIncomingConfirmations: 1,
})
if err != nil {
- log.Error().Err(err).Msg("Creating KeeperV2 Job shouldn't fail")
+ l.Error().Err(err).Msg("Creating KeeperV2 Job shouldn't fail")
return nil, err
}
jobs = append(jobs, job)
diff --git a/integration-tests/actions/ocr2_helpers.go b/integration-tests/actions/ocr2_helpers.go
index 3c37233a0d3..aead74f2bdd 100644
--- a/integration-tests/actions/ocr2_helpers.go
+++ b/integration-tests/actions/ocr2_helpers.go
@@ -10,6 +10,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/lib/pq"
+ "github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"golang.org/x/sync/errgroup"
"gopkg.in/guregu/null.v4"
@@ -34,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)
@@ -360,13 +362,14 @@ func StartNewOCR2Round(
ocrInstances []contracts.OffchainAggregatorV2,
client blockchain.EVMClient,
timeout time.Duration,
+ logger zerolog.Logger,
) error {
for i := 0; i < len(ocrInstances); i++ {
err := ocrInstances[i].RequestNewRound()
if err != nil {
return fmt.Errorf("requesting new OCR round %d have failed: %w", i+1, err)
}
- ocrRound := contracts.NewOffchainAggregatorV2RoundConfirmer(ocrInstances[i], big.NewInt(roundNumber), timeout)
+ ocrRound := contracts.NewOffchainAggregatorV2RoundConfirmer(ocrInstances[i], big.NewInt(roundNumber), timeout, logger)
client.AddHeaderEventSubscription(ocrInstances[i].Address(), ocrRound)
err = client.WaitForEvents()
if err != nil {
diff --git a/integration-tests/actions/ocr2_helpers_local.go b/integration-tests/actions/ocr2_helpers_local.go
index c1e863561da..0b20e4cfee7 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/ocr2vrf_actions/ocr2vrf_config_helpers.go b/integration-tests/actions/ocr2vrf_actions/ocr2vrf_config_helpers.go
index 05b983c2f1e..ce693964323 100644
--- a/integration-tests/actions/ocr2vrf_actions/ocr2vrf_config_helpers.go
+++ b/integration-tests/actions/ocr2vrf_actions/ocr2vrf_config_helpers.go
@@ -16,7 +16,7 @@ import (
"go.dedis.ch/kyber/v3/group/edwards25519"
"gopkg.in/guregu/null.v4"
- "github.com/smartcontractkit/chainlink-testing-framework/utils"
+ "github.com/smartcontractkit/chainlink-testing-framework/logging"
"github.com/smartcontractkit/chainlink/v2/core/services/job"
"github.com/smartcontractkit/chainlink/v2/core/services/keystore/chaintype"
"github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper"
@@ -39,7 +39,7 @@ func CreateOCR2VRFJobs(
chainID int64,
keyIndex int,
) {
- l := utils.GetTestLogger(t)
+ l := logging.GetTestLogger(t)
p2pV2Bootstrapper := createBootstrapJob(t, bootstrapNode, OCR2VRFPluginConfig.DKGConfig.DKGContractAddress, chainID)
createNonBootstrapJobs(t, nonBootstrapNodes, OCR2VRFPluginConfig, chainID, keyIndex, p2pV2Bootstrapper)
@@ -120,7 +120,7 @@ func BuildOCR2DKGConfigVars(
t *testing.T,
ocr2VRFPluginConfig *OCR2VRFPluginConfig,
) contracts.OCRv2Config {
- l := utils.GetTestLogger(t)
+ l := logging.GetTestLogger(t)
var onchainPublicKeys []common.Address
for _, onchainPublicKey := range ocr2VRFPluginConfig.OCR2Config.OnchainPublicKeys {
onchainPublicKeys = append(onchainPublicKeys, common.HexToAddress(onchainPublicKey))
@@ -272,7 +272,7 @@ func BuildOCR2VRFConfigVars(
t *testing.T,
ocr2VRFPluginConfig *OCR2VRFPluginConfig,
) contracts.OCRv2Config {
- l := utils.GetTestLogger(t)
+ l := logging.GetTestLogger(t)
var onchainPublicKeys []common.Address
for _, onchainPublicKey := range ocr2VRFPluginConfig.OCR2Config.OnchainPublicKeys {
onchainPublicKeys = append(onchainPublicKeys, common.HexToAddress(onchainPublicKey))
diff --git a/integration-tests/actions/ocr2vrf_actions/ocr2vrf_steps.go b/integration-tests/actions/ocr2vrf_actions/ocr2vrf_steps.go
index c550fe73a22..c123aaff6a2 100644
--- a/integration-tests/actions/ocr2vrf_actions/ocr2vrf_steps.go
+++ b/integration-tests/actions/ocr2vrf_actions/ocr2vrf_steps.go
@@ -13,7 +13,7 @@ import (
ocr2vrftypes "github.com/smartcontractkit/ocr2vrf/types"
"github.com/smartcontractkit/chainlink-testing-framework/blockchain"
- "github.com/smartcontractkit/chainlink-testing-framework/utils"
+ "github.com/smartcontractkit/chainlink-testing-framework/logging"
"github.com/smartcontractkit/chainlink/v2/core/services/keystore/chaintype"
chainlinkutils "github.com/smartcontractkit/chainlink/v2/core/utils"
@@ -25,7 +25,7 @@ import (
)
func SetAndWaitForVRFBeaconProcessToFinish(t *testing.T, ocr2VRFPluginConfig *OCR2VRFPluginConfig, vrfBeacon contracts.VRFBeacon) {
- l := utils.GetTestLogger(t)
+ l := logging.GetTestLogger(t)
ocr2VrfConfig := BuildOCR2VRFConfigVars(t, ocr2VRFPluginConfig)
l.Debug().Interface("OCR2 VRF Config", ocr2VrfConfig).Msg("OCR2 VRF Config prepared")
@@ -45,7 +45,7 @@ func SetAndWaitForVRFBeaconProcessToFinish(t *testing.T, ocr2VRFPluginConfig *OC
}
func SetAndWaitForDKGProcessToFinish(t *testing.T, ocr2VRFPluginConfig *OCR2VRFPluginConfig, dkg contracts.DKG) {
- l := utils.GetTestLogger(t)
+ l := logging.GetTestLogger(t)
ocr2DkgConfig := BuildOCR2DKGConfigVars(t, ocr2VRFPluginConfig)
// set config for DKG OCR
@@ -208,7 +208,7 @@ func RequestAndRedeemRandomness(
confirmationDelay *big.Int,
randomnessTransmissionEventTimeout time.Duration,
) *big.Int {
- l := utils.GetTestLogger(t)
+ l := logging.GetTestLogger(t)
receipt, err := consumer.RequestRandomness(
numberOfRandomWordsToRequest,
subscriptionID,
@@ -244,7 +244,7 @@ func RequestRandomnessFulfillmentAndWaitForFulfilment(
confirmationDelay *big.Int,
randomnessTransmissionEventTimeout time.Duration,
) *big.Int {
- l := utils.GetTestLogger(t)
+ l := logging.GetTestLogger(t)
receipt, err := consumer.RequestRandomnessFulfillment(
numberOfRandomWordsToRequest,
subscriptionID,
diff --git a/integration-tests/actions/ocr_helpers.go b/integration-tests/actions/ocr_helpers.go
index bff96c73042..cfc8cfe589b 100644
--- a/integration-tests/actions/ocr_helpers.go
+++ b/integration-tests/actions/ocr_helpers.go
@@ -8,6 +8,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/google/uuid"
+ "github.com/rs/zerolog"
"github.com/stretchr/testify/require"
"golang.org/x/sync/errgroup"
@@ -186,6 +187,7 @@ func CreateOCRJobs(
workerNodes []*client.ChainlinkK8sClient,
mockValue int,
mockserver *ctfClient.MockserverClient,
+ evmChainID string,
) error {
for _, ocrInstance := range ocrInstances {
bootstrapP2PIds, err := bootstrapNode.MustReadP2PKeys()
@@ -196,6 +198,7 @@ func CreateOCRJobs(
bootstrapSpec := &client.OCRBootstrapJobSpec{
Name: fmt.Sprintf("bootstrap-%s", uuid.New().String()),
ContractAddress: ocrInstance.Address(),
+ EVMChainID: evmChainID,
P2PPeerID: bootstrapP2PId,
IsBootstrapPeer: true,
}
@@ -240,6 +243,7 @@ func CreateOCRJobs(
bootstrapPeers := []*client.ChainlinkClient{bootstrapNode.ChainlinkClient}
ocrSpec := &client.OCRTaskJobSpec{
ContractAddress: ocrInstance.Address(),
+ EVMChainID: evmChainID,
P2PPeerID: nodeP2PId,
P2PBootstrapPeers: bootstrapPeers,
KeyBundleID: nodeOCRKeyId,
@@ -264,6 +268,7 @@ func CreateOCRJobsWithForwarder(
workerNodes []*client.ChainlinkK8sClient,
mockValue int,
mockserver *ctfClient.MockserverClient,
+ evmChainID string,
) {
for _, ocrInstance := range ocrInstances {
bootstrapP2PIds, err := bootstrapNode.MustReadP2PKeys()
@@ -272,6 +277,7 @@ func CreateOCRJobsWithForwarder(
bootstrapSpec := &client.OCRBootstrapJobSpec{
Name: fmt.Sprintf("bootstrap-%s", uuid.New().String()),
ContractAddress: ocrInstance.Address(),
+ EVMChainID: evmChainID,
P2PPeerID: bootstrapP2PId,
IsBootstrapPeer: true,
}
@@ -302,6 +308,7 @@ func CreateOCRJobsWithForwarder(
bootstrapPeers := []*client.ChainlinkClient{bootstrapNode.ChainlinkClient}
ocrSpec := &client.OCRTaskJobSpec{
ContractAddress: ocrInstance.Address(),
+ EVMChainID: evmChainID,
P2PPeerID: nodeP2PId,
P2PBootstrapPeers: bootstrapPeers,
KeyBundleID: nodeOCRKeyId,
@@ -320,13 +327,14 @@ func StartNewRound(
roundNumber int64,
ocrInstances []contracts.OffchainAggregator,
client blockchain.EVMClient,
+ logger zerolog.Logger,
) error {
for i := 0; i < len(ocrInstances); i++ {
err := ocrInstances[i].RequestNewRound()
if err != nil {
return fmt.Errorf("requesting new OCR round %d have failed: %w", i+1, err)
}
- ocrRound := contracts.NewOffchainAggregatorRoundConfirmer(ocrInstances[i], big.NewInt(roundNumber), client.GetNetworkConfig().Timeout.Duration)
+ ocrRound := contracts.NewOffchainAggregatorRoundConfirmer(ocrInstances[i], big.NewInt(roundNumber), client.GetNetworkConfig().Timeout.Duration, logger)
client.AddHeaderEventSubscription(ocrInstances[i].Address(), ocrRound)
err = client.WaitForEvents()
if err != nil {
diff --git a/integration-tests/actions/ocr_helpers_local.go b/integration-tests/actions/ocr_helpers_local.go
index 13fc01dcea6..ae2f3686daf 100644
--- a/integration-tests/actions/ocr_helpers_local.go
+++ b/integration-tests/actions/ocr_helpers_local.go
@@ -2,18 +2,20 @@ package actions
import (
"fmt"
+ "math/big"
+ "strings"
+
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/common"
"github.com/google/uuid"
"github.com/pkg/errors"
- "github.com/rs/zerolog/log"
+ "github.com/rs/zerolog"
"github.com/smartcontractkit/chainlink-testing-framework/blockchain"
ctfClient "github.com/smartcontractkit/chainlink-testing-framework/client"
+ "golang.org/x/sync/errgroup"
+
"github.com/smartcontractkit/chainlink/integration-tests/client"
"github.com/smartcontractkit/chainlink/integration-tests/contracts"
- "golang.org/x/sync/errgroup"
- "math/big"
- "strings"
)
/*
@@ -140,6 +142,7 @@ func CreateOCRJobsLocal(
workerNodes []*client.ChainlinkClient,
mockValue int,
mockserver *ctfClient.MockserverClient,
+ evmChainID string,
) error {
for _, ocrInstance := range ocrInstances {
bootstrapP2PIds, err := bootstrapNode.MustReadP2PKeys()
@@ -150,6 +153,7 @@ func CreateOCRJobsLocal(
bootstrapSpec := &client.OCRBootstrapJobSpec{
Name: fmt.Sprintf("bootstrap-%s", uuid.New().String()),
ContractAddress: ocrInstance.Address(),
+ EVMChainID: evmChainID,
P2PPeerID: bootstrapP2PId,
IsBootstrapPeer: true,
}
@@ -194,6 +198,7 @@ func CreateOCRJobsLocal(
bootstrapPeers := []*client.ChainlinkClient{bootstrapNode}
ocrSpec := &client.OCRTaskJobSpec{
ContractAddress: ocrInstance.Address(),
+ EVMChainID: evmChainID,
P2PPeerID: nodeP2PId,
P2PBootstrapPeers: bootstrapPeers,
KeyBundleID: nodeOCRKeyId,
@@ -266,13 +271,14 @@ func TrackForwarderLocal(
chainClient blockchain.EVMClient,
authorizedForwarder common.Address,
node *client.ChainlinkClient,
+ logger zerolog.Logger,
) error {
chainID := chainClient.GetChainID()
_, _, err := node.TrackForwarder(chainID, authorizedForwarder)
if err != nil {
return errors.Wrap(err, "failed to track forwarder")
}
- log.Info().Str("NodeURL", node.Config.URL).
+ logger.Info().Str("NodeURL", node.Config.URL).
Str("ForwarderAddress", authorizedForwarder.Hex()).
Str("ChaindID", chainID.String()).
Msg("Forwarder tracked")
@@ -353,6 +359,7 @@ func CreateOCRJobsWithForwarderLocal(
workerNodes []*client.ChainlinkClient,
mockValue int,
mockserver *ctfClient.MockserverClient,
+ evmChainID string,
) error {
for _, ocrInstance := range ocrInstances {
bootstrapP2PIds, err := bootstrapNode.MustReadP2PKeys()
@@ -363,6 +370,7 @@ func CreateOCRJobsWithForwarderLocal(
bootstrapSpec := &client.OCRBootstrapJobSpec{
Name: fmt.Sprintf("bootstrap-%s", uuid.New().String()),
ContractAddress: ocrInstance.Address(),
+ EVMChainID: evmChainID,
P2PPeerID: bootstrapP2PId,
IsBootstrapPeer: true,
}
@@ -407,6 +415,7 @@ func CreateOCRJobsWithForwarderLocal(
bootstrapPeers := []*client.ChainlinkClient{bootstrapNode}
ocrSpec := &client.OCRTaskJobSpec{
ContractAddress: ocrInstance.Address(),
+ EVMChainID: evmChainID,
P2PPeerID: nodeP2PId,
P2PBootstrapPeers: bootstrapPeers,
KeyBundleID: nodeOCRKeyId,
diff --git a/integration-tests/actions/operator_forwarder_helpers.go b/integration-tests/actions/operator_forwarder_helpers.go
index 7add64fbe99..37b50c4fa9a 100644
--- a/integration-tests/actions/operator_forwarder_helpers.go
+++ b/integration-tests/actions/operator_forwarder_helpers.go
@@ -12,7 +12,7 @@ import (
"github.com/stretchr/testify/require"
"github.com/smartcontractkit/chainlink-testing-framework/blockchain"
- "github.com/smartcontractkit/chainlink-testing-framework/utils"
+ "github.com/smartcontractkit/chainlink-testing-framework/logging"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/operator_factory"
"github.com/smartcontractkit/chainlink/integration-tests/client"
@@ -91,7 +91,7 @@ func ProcessNewEvent(
contractABI *abi.ABI,
chainClient blockchain.EVMClient,
) {
- l := utils.GetTestLogger(t)
+ l := logging.GetTestLogger(t)
errorChan := make(chan error)
eventConfirmed := make(chan bool)
err := chainClient.ProcessEvent(eventDetails.Name, event, eventConfirmed, errorChan)
@@ -138,7 +138,7 @@ func SubscribeOperatorFactoryEvents(
chainClient blockchain.EVMClient,
operatorFactoryInstance contracts.OperatorFactory,
) {
- l := utils.GetTestLogger(t)
+ l := logging.GetTestLogger(t)
contractABI, err := operator_factory.OperatorFactoryMetaData.GetAbi()
require.NoError(t, err, "Getting contract abi for OperatorFactory shouldn't fail")
latestBlockNum, err := chainClient.LatestBlockNumber(context.Background())
@@ -186,7 +186,7 @@ func TrackForwarder(
authorizedForwarder common.Address,
node *client.ChainlinkK8sClient,
) {
- l := utils.GetTestLogger(t)
+ l := logging.GetTestLogger(t)
chainID := chainClient.GetChainID()
_, _, err := node.TrackForwarder(chainID, authorizedForwarder)
require.NoError(t, err, "Forwarder track should be created")
diff --git a/integration-tests/actions/vrfv2plus/vrfv2plus_constants/constants.go b/integration-tests/actions/vrfv2plus/vrfv2plus_constants/constants.go
new file mode 100644
index 00000000000..bb266e7c2c5
--- /dev/null
+++ b/integration-tests/actions/vrfv2plus/vrfv2plus_constants/constants.go
@@ -0,0 +1,40 @@
+package vrfv2plus_constants
+
+import (
+ "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 (
+ LinkNativeFeedResponse = big.NewInt(1e18)
+ MinimumConfirmations = uint16(3)
+ RandomnessRequestCountPerRequest = uint16(1)
+ VRFSubscriptionFundingAmountLink = big.NewInt(10)
+ VRFSubscriptionFundingAmountNativeToken = big.NewInt(1)
+ ChainlinkNodeFundingAmountNative = big.NewFloat(0.1)
+ NumberOfWords = uint32(3)
+ CallbackGasLimit = uint32(1000000)
+ MaxGasLimitVRFCoordinatorConfig = uint32(2.5e6)
+ StalenessSeconds = uint32(86400)
+ GasAfterPaymentCalculation = uint32(33825)
+
+ VRFCoordinatorV2_5FeeConfig = vrf_coordinator_v2_5.VRFCoordinatorV25FeeConfig{
+ FulfillmentFlatFeeLinkPPM: 500,
+ FulfillmentFlatFeeNativePPM: 500,
+ }
+
+ VRFCoordinatorV2PlusUpgradedVersionFeeConfig = vrf_v2plus_upgraded_version.VRFCoordinatorV2PlusUpgradedVersionFeeConfig{
+ 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
new file mode 100644
index 00000000000..c227d490eb9
--- /dev/null
+++ b/integration-tests/actions/vrfv2plus/vrfv2plus_models.go
@@ -0,0 +1,35 @@
+package vrfv2plus
+
+import (
+ "math/big"
+
+ "github.com/smartcontractkit/chainlink/integration-tests/client"
+ "github.com/smartcontractkit/chainlink/integration-tests/contracts"
+)
+
+type VRFV2PlusEncodedProvingKey [2]*big.Int
+
+// VRFV2PlusKeyData defines a jobs into and proving key info
+type VRFV2PlusKeyData struct {
+ VRFKey *client.VRFKey
+ EncodedProvingKey VRFV2PlusEncodedProvingKey
+ KeyHash [32]byte
+}
+
+type VRFV2PlusData struct {
+ VRFV2PlusKeyData
+ VRFJob *client.Job
+ PrimaryEthAddress string
+ ChainID *big.Int
+}
+
+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
new file mode 100644
index 00000000000..8c3c2a733ac
--- /dev/null
+++ b/integration-tests/actions/vrfv2plus/vrfv2plus_steps.go
@@ -0,0 +1,655 @@
+package vrfv2plus
+
+import (
+ "context"
+ "fmt"
+ "math/big"
+ "time"
+
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/google/uuid"
+ "github.com/pkg/errors"
+ "github.com/rs/zerolog"
+ "github.com/smartcontractkit/chainlink-testing-framework/blockchain"
+ "github.com/smartcontractkit/chainlink/integration-tests/actions"
+ "github.com/smartcontractkit/chainlink/integration-tests/actions/vrfv2plus/vrfv2plus_constants"
+ "github.com/smartcontractkit/chainlink/integration-tests/client"
+ "github.com/smartcontractkit/chainlink/integration-tests/contracts"
+ "github.com/smartcontractkit/chainlink/integration-tests/docker/test_env"
+ "github.com/smartcontractkit/chainlink/integration-tests/types/config/node"
+ "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"
+)
+
+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"
+ 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 DeployVRFV2_5Contracts(
+ contractDeployer contracts.ContractDeployer,
+ chainClient blockchain.EVMClient,
+ consumerContractsAmount int,
+) (*VRFV2_5Contracts, error) {
+ bhs, err := contractDeployer.DeployBlockhashStore()
+ if err != nil {
+ return nil, errors.Wrap(err, ErrDeployBlockHashStore)
+ }
+ err = chainClient.WaitForEvents()
+ if err != nil {
+ return nil, errors.Wrap(err, ErrWaitTXsComplete)
+ }
+ coordinator, err := contractDeployer.DeployVRFCoordinatorV2_5(bhs.Address())
+ if err != nil {
+ return nil, errors.Wrap(err, ErrDeployCoordinator)
+ }
+ err = chainClient.WaitForEvents()
+ if err != nil {
+ return nil, errors.Wrap(err, ErrWaitTXsComplete)
+ }
+ consumers, err := DeployVRFV2PlusConsumers(contractDeployer, coordinator, consumerContractsAmount)
+ if err != nil {
+ return nil, err
+ }
+ err = chainClient.WaitForEvents()
+ if err != nil {
+ return nil, errors.Wrap(err, ErrWaitTXsComplete)
+ }
+ return &VRFV2_5Contracts{coordinator, bhs, consumers}, nil
+}
+
+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())
+ if err != nil {
+ return nil, errors.Wrap(err, ErrAdvancedConsumer)
+ }
+ consumers = append(consumers, loadTestConsumer)
+ }
+ 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,
+ nativeTokenPrimaryKeyAddress string,
+ pubKeyCompressed string,
+ chainID string,
+ minIncomingConfirmations uint16,
+) (*client.Job, error) {
+ jobUUID := uuid.New()
+ os := &client.VRFV2PlusTxPipelineSpec{
+ Address: coordinatorAddress,
+ }
+ ost, err := os.String()
+ if err != nil {
+ return nil, errors.Wrap(err, ErrParseJob)
+ }
+
+ job, err := chainlinkNode.MustCreateJob(&client.VRFV2PlusJobSpec{
+ Name: fmt.Sprintf("vrf-v2-plus-%s", jobUUID),
+ CoordinatorAddress: coordinatorAddress,
+ FromAddresses: []string{nativeTokenPrimaryKeyAddress},
+ EVMChainID: chainID,
+ MinIncomingConfirmations: int(minIncomingConfirmations),
+ PublicKey: pubKeyCompressed,
+ ExternalJobID: jobUUID.String(),
+ ObservationSource: ost,
+ BatchFulfillmentEnabled: false,
+ })
+ if err != nil {
+ return nil, errors.Wrap(err, ErrCreatingVRFv2PlusJob)
+ }
+
+ return job, nil
+}
+
+func VRFV2_5RegisterProvingKey(
+ vrfKey *client.VRFKey,
+ oracleAddress string,
+ coordinator contracts.VRFCoordinatorV2_5,
+) (VRFV2PlusEncodedProvingKey, error) {
+ provingKey, err := actions.EncodeOnChainVRFProvingKey(*vrfKey)
+ if err != nil {
+ return VRFV2PlusEncodedProvingKey{}, errors.Wrap(err, ErrEncodingProvingKey)
+ }
+ err = coordinator.RegisterProvingKey(
+ oracleAddress,
+ provingKey,
+ )
+ if err != nil {
+ return VRFV2PlusEncodedProvingKey{}, errors.Wrap(err, ErrRegisterProvingKey)
+ }
+ return provingKey, nil
+}
+
+func VRFV2PlusUpgradedVersionRegisterProvingKey(
+ vrfKey *client.VRFKey,
+ oracleAddress string,
+ coordinator contracts.VRFCoordinatorV2PlusUpgradedVersion,
+) (VRFV2PlusEncodedProvingKey, error) {
+ provingKey, err := actions.EncodeOnChainVRFProvingKey(*vrfKey)
+ if err != nil {
+ return VRFV2PlusEncodedProvingKey{}, errors.Wrap(err, ErrEncodingProvingKey)
+ }
+ err = coordinator.RegisterProvingKey(
+ oracleAddress,
+ provingKey,
+ )
+ if err != nil {
+ return VRFV2PlusEncodedProvingKey{}, errors.Wrap(err, ErrRegisterProvingKey)
+ }
+ return provingKey, nil
+}
+
+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)
+ }
+ _, err = linkToken.TransferAndCall(coordinator.Address(), big.NewInt(0).Mul(linkFundingAmount, big.NewInt(1e18)), encodedSubId)
+ if err != nil {
+ return errors.Wrap(err, ErrSendingLinkToken)
+ }
+ return chainClient.WaitForEvents()
+}
+
+func SetupVRFV2_5Environment(
+ env *test_env.CLClusterTestEnv,
+ linkToken contracts.LinkToken,
+ mockNativeLINKFeed contracts.MockETHLINKFeed,
+ consumerContractsAmount int,
+) (*VRFV2_5Contracts, *big.Int, *VRFV2PlusData, error) {
+
+ vrfv2_5Contracts, err := DeployVRFV2_5Contracts(env.ContractDeployer, env.EVMClient, consumerContractsAmount)
+ if err != nil {
+ return nil, nil, nil, errors.Wrap(err, ErrDeployVRFV2_5Contracts)
+ }
+
+ err = vrfv2_5Contracts.Coordinator.SetConfig(
+ vrfv2plus_constants.MinimumConfirmations,
+ vrfv2plus_constants.MaxGasLimitVRFCoordinatorConfig,
+ vrfv2plus_constants.StalenessSeconds,
+ vrfv2plus_constants.GasAfterPaymentCalculation,
+ vrfv2plus_constants.LinkNativeFeedResponse,
+ vrfv2plus_constants.VRFCoordinatorV2_5FeeConfig,
+ )
+ if err != nil {
+ return nil, nil, nil, errors.Wrap(err, ErrSetVRFCoordinatorConfig)
+ }
+
+ subID, err := CreateSubAndFindSubID(env, vrfv2_5Contracts.Coordinator)
+ if err != nil {
+ return nil, nil, nil, err
+ }
+
+ err = env.EVMClient.WaitForEvents()
+ if err != nil {
+ return nil, nil, nil, errors.Wrap(err, ErrWaitTXsComplete)
+ }
+ 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 = vrfv2_5Contracts.Coordinator.SetLINKAndLINKNativeFeed(linkToken.Address(), mockNativeLINKFeed.Address())
+ if err != nil {
+ 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, linkToken, vrfv2_5Contracts.Coordinator, subID)
+ if err != nil {
+ return nil, nil, nil, err
+ }
+
+ vrfKey, err := env.GetAPIs()[0].MustCreateVRFKey()
+ if err != nil {
+ return nil, nil, nil, errors.Wrap(err, ErrCreatingVRFv2PlusKey)
+ }
+ pubKeyCompressed := vrfKey.Data.ID
+
+ nativeTokenPrimaryKeyAddress, err := env.GetAPIs()[0].PrimaryEthAddress()
+ if err != nil {
+ return nil, nil, nil, errors.Wrap(err, ErrNodePrimaryKey)
+ }
+ provingKey, err := VRFV2_5RegisterProvingKey(vrfKey, nativeTokenPrimaryKeyAddress, vrfv2_5Contracts.Coordinator)
+ if err != nil {
+ return nil, nil, nil, errors.Wrap(err, ErrRegisteringProvingKey)
+ }
+ keyHash, err := vrfv2_5Contracts.Coordinator.HashOfKey(context.Background(), provingKey)
+ if err != nil {
+ return nil, nil, nil, errors.Wrap(err, ErrCreatingProvingKeyHash)
+ }
+
+ chainID := env.EVMClient.GetChainID()
+
+ job, err := CreateVRFV2PlusJob(
+ env.GetAPIs()[0],
+ vrfv2_5Contracts.Coordinator.Address(),
+ nativeTokenPrimaryKeyAddress,
+ pubKeyCompressed,
+ chainID.String(),
+ vrfv2plus_constants.MinimumConfirmations,
+ )
+ if err != nil {
+ return nil, nil, nil, errors.Wrap(err, ErrCreateVRFV2PlusJobs)
+ }
+
+ // this part is here because VRFv2 can work with only a specific key
+ // [[EVM.KeySpecific]]
+ // Key = '...'
+ addr, err := env.CLNodes[0].API.PrimaryEthAddress()
+ if err != nil {
+ return nil, nil, nil, errors.Wrap(err, ErrGetPrimaryKey)
+ }
+ nodeConfig := node.NewConfig(env.CLNodes[0].NodeConfig,
+ node.WithVRFv2EVMEstimator(addr),
+ )
+ err = env.CLNodes[0].Restart(nodeConfig)
+ if err != nil {
+ return nil, nil, nil, errors.Wrap(err, ErrRestartCLNode)
+ }
+
+ vrfv2PlusKeyData := VRFV2PlusKeyData{
+ VRFKey: vrfKey,
+ EncodedProvingKey: provingKey,
+ KeyHash: keyHash,
+ }
+
+ data := VRFV2PlusData{
+ vrfv2PlusKeyData,
+ job,
+ nativeTokenPrimaryKeyAddress,
+ chainID,
+ }
+
+ return vrfv2_5Contracts, subID, &data, nil
+}
+
+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,
+ )
+ 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)
+ }
+ err = env.EVMClient.WaitForEvents()
+ if err != nil {
+ return nil, errors.Wrap(err, ErrWaitTXsComplete)
+ }
+ subID, err := coordinator.FindSubscriptionID()
+ if err != nil {
+ return nil, errors.Wrap(err, ErrFindSubID)
+ }
+ return subID, nil
+}
+
+func GetUpgradedCoordinatorTotalBalance(coordinator contracts.VRFCoordinatorV2PlusUpgradedVersion) (linkTotalBalance *big.Int, nativeTokenTotalBalance *big.Int, err error) {
+ linkTotalBalance, err = coordinator.GetLinkTotalBalance(context.Background())
+ if err != nil {
+ return nil, nil, errors.Wrap(err, ErrLinkTotalBalance)
+ }
+ nativeTokenTotalBalance, err = coordinator.GetNativeTokenTotalBalance(context.Background())
+ if err != nil {
+ return nil, nil, errors.Wrap(err, ErrNativeTokenBalance)
+ }
+ return
+}
+
+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)
+ }
+ nativeTokenTotalBalance, err = coordinator.GetNativeTokenTotalBalance(context.Background())
+ if err != nil {
+ return nil, nil, errors.Wrap(err, ErrNativeTokenBalance)
+ }
+ return
+}
+
+func FundSubscription(env *test_env.CLClusterTestEnv, linkAddress contracts.LinkToken, coordinator contracts.VRFCoordinatorV2_5, subID *big.Int) error {
+ //Native Billing
+ err := coordinator.FundSubscriptionWithNative(subID, big.NewInt(0).Mul(vrfv2plus_constants.VRFSubscriptionFundingAmountNativeToken, big.NewInt(1e18)))
+ if err != nil {
+ return errors.Wrap(err, ErrFundSubWithNativeToken)
+ }
+
+ err = FundVRFCoordinatorV2_5Subscription(linkAddress, coordinator, env.EVMClient, subID, vrfv2plus_constants.VRFSubscriptionFundingAmountLink)
+ if err != nil {
+ return errors.Wrap(err, ErrFundSubWithLinkToken)
+ }
+ err = env.EVMClient.WaitForEvents()
+ if err != nil {
+ return errors.Wrap(err, ErrWaitTXsComplete)
+ }
+
+ return nil
+}
+
+func RequestRandomnessAndWaitForFulfillment(
+ consumer contracts.VRFv2PlusLoadTestConsumer,
+ 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_v2plus_upgraded_version.VRFCoordinatorV2PlusUpgradedVersionRandomWordsFulfilled, 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)
+ }
+
+ randomWordsRequestedEvent, err := coordinator.WaitForRandomWordsRequestedEvent(
+ [][32]byte{vrfv2PlusData.KeyHash},
+ []*big.Int{subID},
+ []common.Address{common.HexToAddress(consumer.Address())},
+ time.Minute*1,
+ )
+ if err != nil {
+ return nil, errors.Wrap(err, ErrWaitRandomWordsRequestedEvent)
+ }
+
+ l.Debug().
+ Str("Request ID", randomWordsRequestedEvent.RequestId.String()).
+ Str("Subscription ID", randomWordsRequestedEvent.SubId.String()).
+ Str("Sender Address", randomWordsRequestedEvent.Sender.String()).
+ Interface("Keyhash", randomWordsRequestedEvent.KeyHash).
+ 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(
+ []*big.Int{subID},
+ []*big.Int{randomWordsRequestedEvent.RequestId},
+ time.Minute*2,
+ )
+ if err != nil {
+ return nil, errors.Wrap(err, ErrWaitRandomWordsFulfilledEvent)
+ }
+
+ l.Debug().
+ 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 DirectFundingRequestRandomnessAndWaitForFulfillment(
+ consumer contracts.VRFv2PlusWrapperLoadTestConsumer,
+ coordinator contracts.VRFCoordinatorV2_5,
+ vrfv2PlusData *VRFV2PlusData,
+ subID *big.Int,
+ isNativeBilling bool,
+ l zerolog.Logger,
+) (*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, "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(consumerAddress)},
+ time.Minute*1,
+ )
+ if err != nil {
+ return nil, errors.Wrap(err, ErrWaitRandomWordsRequestedEvent)
+ }
+
+ l.Debug().
+ Str("Request ID", randomWordsRequestedEvent.RequestId.String()).
+ Str("Subscription ID", randomWordsRequestedEvent.SubId.String()).
+ Str("Sender Address", randomWordsRequestedEvent.Sender.String()).
+ Interface("Keyhash", randomWordsRequestedEvent.KeyHash).
+ 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(
+ []*big.Int{subID},
+ []*big.Int{randomWordsRequestedEvent.RequestId},
+ time.Minute*2,
+ )
+ if err != nil {
+ return nil, errors.Wrap(err, ErrWaitRandomWordsFulfilledEvent)
+ }
+
+ l.Debug().
+ 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/benchmark/keeper_test.go b/integration-tests/benchmark/keeper_test.go
index 12c233ecf0e..59406e51583 100644
--- a/integration-tests/benchmark/keeper_test.go
+++ b/integration-tests/benchmark/keeper_test.go
@@ -18,13 +18,13 @@ import (
"github.com/smartcontractkit/chainlink-env/pkg/helm/ethereum"
"github.com/smartcontractkit/chainlink-env/pkg/helm/reorg"
"github.com/smartcontractkit/chainlink-testing-framework/blockchain"
- "github.com/smartcontractkit/chainlink-testing-framework/utils"
+ "github.com/smartcontractkit/chainlink-testing-framework/logging"
+ "github.com/smartcontractkit/chainlink-testing-framework/networks"
"github.com/smartcontractkit/chainlink/integration-tests/actions"
"github.com/smartcontractkit/chainlink/integration-tests/client"
"github.com/smartcontractkit/chainlink/integration-tests/contracts"
eth_contracts "github.com/smartcontractkit/chainlink/integration-tests/contracts/ethereum"
- "github.com/smartcontractkit/chainlink/integration-tests/networks"
"github.com/smartcontractkit/chainlink/integration-tests/testsetups"
)
@@ -41,12 +41,11 @@ Enabled = true
AnnounceAddresses = ["0.0.0.0:6690"]
ListenAddresses = ["0.0.0.0:6690"]
[Keeper]
-TurnLookBack = 0`
+TurnLookBack = 0
+[WebServer]
+HTTPWriteTimeout = '1h'`
simulatedEVMNonDevTOML = `
-[[EVM]]
-ChainID = 1337
-MinContractPayment = '0'
Enabled = true
FinalityDepth = 50
LogPollInterval = '1s'
@@ -115,7 +114,7 @@ LimitDefault = 5_000_000`
var (
NumberOfNodes, _ = strconv.Atoi(getEnv("NUMBEROFNODES", "6"))
- RegistryToTest = getEnv("REGISTRY", "2_0")
+ RegistryToTest = getEnv("REGISTRY", "2_1")
NumberOfUpkeeps, _ = strconv.Atoi(getEnv("NUMBEROFUPKEEPS", "500"))
CheckGasToBurn, _ = strconv.ParseInt(getEnv("CHECKGASTOBURN", "100000"), 0, 64)
PerformGasToBurn, _ = strconv.ParseInt(getEnv("PERFORMGASTOBURN", "50000"), 0, 64)
@@ -142,7 +141,7 @@ type NetworkConfig struct {
}
func TestAutomationBenchmark(t *testing.T) {
- l := utils.GetTestLogger(t)
+ l := logging.GetTestLogger(t)
testEnvironment, benchmarkNetwork := SetupAutomationBenchmarkEnv(t)
if testEnvironment.WillUseRemoteRunner() {
return
@@ -154,7 +153,7 @@ func TestAutomationBenchmark(t *testing.T) {
l.Info().Str("Namespace", testEnvironment.Cfg.Namespace).Msg("Connected to Keepers Benchmark Environment")
- chainClient, err := blockchain.NewEVMClient(benchmarkNetwork, testEnvironment)
+ chainClient, err := blockchain.NewEVMClient(benchmarkNetwork, testEnvironment, l)
require.NoError(t, err, "Error connecting to blockchain")
registryVersions := addRegistry(RegistryToTest)
keeperBenchmarkTest := testsetups.NewKeeperBenchmarkTest(
@@ -217,10 +216,17 @@ func addRegistry(registryToTest string) []eth_contracts.KeeperRegistryVersion {
return []eth_contracts.KeeperRegistryVersion{eth_contracts.RegistryVersion_1_3}
case "2_0":
return []eth_contracts.KeeperRegistryVersion{eth_contracts.RegistryVersion_2_0}
+ case "2_1":
+ return []eth_contracts.KeeperRegistryVersion{eth_contracts.RegistryVersion_2_1}
case "2_0-1_3":
return []eth_contracts.KeeperRegistryVersion{eth_contracts.RegistryVersion_2_0, eth_contracts.RegistryVersion_1_3}
+ case "2_1-2_0-1_3":
+ return []eth_contracts.KeeperRegistryVersion{eth_contracts.RegistryVersion_2_1,
+ eth_contracts.RegistryVersion_2_0, eth_contracts.RegistryVersion_1_3}
case "2_0-Multiple":
return repeatRegistries(eth_contracts.RegistryVersion_2_0, NumberOfRegistries)
+ case "2_1-Multiple":
+ return repeatRegistries(eth_contracts.RegistryVersion_1_0, NumberOfRegistries)
default:
return []eth_contracts.KeeperRegistryVersion{eth_contracts.RegistryVersion_2_0}
}
@@ -238,13 +244,13 @@ var networkConfig = map[string]NetworkConfig{
"SimulatedGeth": {
upkeepSLA: int64(20),
blockTime: time.Second,
- deltaStage: time.Duration(0),
+ deltaStage: 30 * time.Second,
funding: big.NewFloat(100_000),
},
- "simulated": {
+ "geth": {
upkeepSLA: int64(20),
blockTime: time.Second,
- deltaStage: time.Duration(0),
+ deltaStage: 30 * time.Second,
funding: big.NewFloat(100_000),
},
"GoerliTestnet": {
@@ -292,12 +298,12 @@ func getEnv(key, fallback string) string {
}
func SetupAutomationBenchmarkEnv(t *testing.T) (*environment.Environment, blockchain.EVMNetwork) {
- l := utils.GetTestLogger(t)
+ l := logging.GetTestLogger(t)
testNetwork := networks.SelectedNetwork // Environment currently being used to run benchmark test on
blockTime := "1"
networkDetailTOML := `MinIncomingConfirmations = 1`
- if strings.Contains(RegistryToTest, "2_0") {
+ if strings.Contains(RegistryToTest, "2_") {
NumberOfNodes++
}
@@ -331,7 +337,7 @@ func SetupAutomationBenchmarkEnv(t *testing.T) (*environment.Environment, blockc
// Test can run on simulated, simulated-non-dev, testnets
if testNetwork.Name == networks.SimulatedEVMNonDev.Name {
- keeperBenchmarkBaseTOML = keeperBenchmarkBaseTOML + simulatedEVMNonDevTOML
+ networkDetailTOML = simulatedEVMNonDevTOML
testEnvironment.
AddHelm(reorg.New(&reorg.Props{
NetworkName: testNetwork.Name,
diff --git a/integration-tests/chaos/automation_chaos_test.go b/integration-tests/chaos/automation_chaos_test.go
index dd2a39a57be..1b18b9f6ab7 100644
--- a/integration-tests/chaos/automation_chaos_test.go
+++ b/integration-tests/chaos/automation_chaos_test.go
@@ -18,13 +18,14 @@ import (
"github.com/smartcontractkit/chainlink-env/pkg/helm/chainlink"
"github.com/smartcontractkit/chainlink-env/pkg/helm/ethereum"
"github.com/smartcontractkit/chainlink-testing-framework/blockchain"
+ "github.com/smartcontractkit/chainlink-testing-framework/logging"
+ "github.com/smartcontractkit/chainlink-testing-framework/networks"
"github.com/smartcontractkit/chainlink-testing-framework/utils"
"github.com/smartcontractkit/chainlink/integration-tests/actions"
"github.com/smartcontractkit/chainlink/integration-tests/client"
"github.com/smartcontractkit/chainlink/integration-tests/contracts"
eth_contracts "github.com/smartcontractkit/chainlink/integration-tests/contracts/ethereum"
- "github.com/smartcontractkit/chainlink/integration-tests/networks"
)
var (
@@ -108,7 +109,7 @@ const (
func TestAutomationChaos(t *testing.T) {
t.Parallel()
- l := utils.GetTestLogger(t)
+ l := logging.GetTestLogger(t)
testCases := map[string]struct {
networkChart environment.ConnectedChart
@@ -200,10 +201,11 @@ func TestAutomationChaos(t *testing.T) {
err = testEnvironment.Client.LabelChaosGroup(testEnvironment.Cfg.Namespace, "instance=", 2, 5, ChaosGroupMajorityPlus)
require.NoError(t, err)
- chainClient, err := blockchain.NewEVMClient(network, testEnvironment)
+ chainClient, err := blockchain.NewEVMClient(network, testEnvironment, l)
require.NoError(t, err, "Error connecting to blockchain")
- contractDeployer, err := contracts.NewContractDeployer(chainClient)
+ contractDeployer, err := contracts.NewContractDeployer(chainClient, l)
require.NoError(t, err, "Error building contract deployer")
+
chainlinkNodes, err := client.ConnectChainlinkNodes(testEnvironment)
require.NoError(t, err, "Error connecting to Chainlink nodes")
chainClient.ParallelTransactions(true)
@@ -229,15 +231,18 @@ func TestAutomationChaos(t *testing.T) {
t,
eth_contracts.RegistryVersion_2_0,
defaultOCRRegistryConfig,
- numberOfUpkeeps,
linkToken,
contractDeployer,
chainClient,
)
+ // Fund the registry with LINK
+ err = linkToken.Transfer(registry.Address(), big.NewInt(0).Mul(big.NewInt(1e18), big.NewInt(int64(numberOfUpkeeps))))
+ require.NoError(t, err, "Funding keeper registry contract shouldn't fail")
+
actions.CreateOCRKeeperJobs(t, chainlinkNodes, registry.Address(), network.ChainID, 0, eth_contracts.RegistryVersion_2_0)
nodesWithoutBootstrap := chainlinkNodes[1:]
- ocrConfig, err := actions.BuildAutoOCR2ConfigVars(t, nodesWithoutBootstrap, defaultOCRRegistryConfig, registrar.Address(), 5*time.Second)
+ ocrConfig, err := actions.BuildAutoOCR2ConfigVars(t, nodesWithoutBootstrap, defaultOCRRegistryConfig, registrar.Address(), 30*time.Second)
require.NoError(t, err, "Error building OCR config vars")
err = registry.SetConfig(defaultOCRRegistryConfig, ocrConfig)
require.NoError(t, err, "Registry config should be be set successfully")
diff --git a/integration-tests/chaos/functions/full.yaml b/integration-tests/chaos/functions/full.yaml
new file mode 100644
index 00000000000..9d62f899c62
--- /dev/null
+++ b/integration-tests/chaos/functions/full.yaml
@@ -0,0 +1,232 @@
+apiVersion: chaos-mesh.org/v1alpha1
+kind: Workflow
+metadata:
+ namespace: chainlink
+ name: chainlink-flow
+spec:
+ entry: entry
+ templates:
+ # root entry
+ - name: entry
+ templateType: Serial
+ deadline: 1h
+ children:
+ - killing
+ - network-delay-internal
+# - external-deps-failure
+ # children chaos group
+ - name: killing
+ templateType: Serial
+ children:
+ - gateway-kill
+ - don-minority-kill
+ - don-majority-kill
+ - adapters-minority-kill
+ - adapters-majority-kill
+ # children chaos group
+ - name: network-delay-internal
+ templateType: Serial
+ children:
+ - gateway-delay
+ - don-minority-delay
+ - don-majority-delay
+ - adapters-minority-delay
+ - adapters-majority-delay
+ # children chaos group
+ - name: external-deps-failure
+ templateType: Serial
+ children:
+ - ea-url-resolve-failure
+
+ # experiments (killing)
+ - name: gateway-kill
+ templateType: PodChaos
+ deadline: 1m
+ podChaos:
+ selector:
+ namespaces:
+ - chainlink
+ labelSelectors:
+ 'app.kubernetes.io/instance': cln-gateway-staging1-node
+ mode: one
+ action: pod-kill
+ - name: don-minority-kill
+ templateType: PodChaos
+ deadline: 1m
+ podChaos:
+ selector:
+ namespaces:
+ - chainlink
+ expressionSelectors:
+ - key: app.kubernetes.io/instance
+ operator: In
+ values:
+ - clc-ocr2-dr-matic-testnet-nodes-0
+ - clc-ocr2-dr-matic-testnet-boot
+ mode: all
+ action: pod-kill
+ - name: don-majority-kill
+ templateType: PodChaos
+ deadline: 1m
+ podChaos:
+ selector:
+ namespaces:
+ - chainlink
+ expressionSelectors:
+ - key: app.kubernetes.io/instance
+ operator: In
+ values:
+ - clc-ocr2-dr-matic-testnet-nodes-1
+ - clc-ocr2-dr-matic-testnet-nodes-0
+ - clc-ocr2-dr-matic-testnet-boot
+ mode: all
+ action: pod-kill
+ - name: adapters-minority-kill
+ templateType: PodChaos
+ deadline: 1m
+ podChaos:
+ selector:
+ namespaces:
+ - adapters
+ expressionSelectors:
+ - key: app.kubernetes.io/instance
+ operator: In
+ values:
+ - universal-mumbai-0
+ mode: all
+ action: pod-kill
+ - name: adapters-majority-kill
+ templateType: PodChaos
+ deadline: 1m
+ podChaos:
+ selector:
+ namespaces:
+ - adapters
+ expressionSelectors:
+ - key: app.kubernetes.io/instance
+ operator: In
+ values:
+ - universal-mumbai-1
+ - universal-mumbai-0
+ mode: all
+ action: pod-kill
+
+ # TODO: enable when chaosd is installed on all the nodes
+ # experiments (delays)
+ - name: gateway-delay
+ templateType: NetworkChaos
+ deadline: 1m
+ networkChaos:
+ selector:
+ namespaces:
+ - chainlink
+ labelSelectors:
+ 'app.kubernetes.io/instance': cln-gateway-staging1-node
+ mode: all
+ action: delay
+ delay:
+ latency: 200ms
+ correlation: '0'
+ jitter: 0ms
+ direction: to
+ - name: don-minority-delay
+ templateType: NetworkChaos
+ deadline: 1m
+ networkChaos:
+ selector:
+ namespaces:
+ - chainlink
+ expressionSelectors:
+ - key: app.kubernetes.io/instance
+ operator: In
+ values:
+ - clc-ocr2-dr-matic-testnet-nodes-0
+ - clc-ocr2-dr-matic-testnet-boot
+ mode: all
+ action: delay
+ delay:
+ latency: 200ms
+ correlation: '0'
+ jitter: 0ms
+ direction: to
+ - name: don-majority-delay
+ templateType: NetworkChaos
+ deadline: 1m
+ networkChaos:
+ selector:
+ namespaces:
+ - chainlink
+ expressionSelectors:
+ - key: app.kubernetes.io/instance
+ operator: In
+ values:
+ - clc-ocr2-dr-matic-testnet-nodes-1
+ - clc-ocr2-dr-matic-testnet-nodes-0
+ - clc-ocr2-dr-matic-testnet-boot
+ mode: all
+ action: delay
+ delay:
+ latency: 200ms
+ correlation: '0'
+ jitter: 0ms
+ direction: to
+ - name: adapters-minority-delay
+ templateType: NetworkChaos
+ deadline: 1m
+ networkChaos:
+ selector:
+ namespaces:
+ - adapters
+ expressionSelectors:
+ - key: app.kubernetes.io/instance
+ operator: In
+ values:
+ - universal-mumbai-0
+ mode: all
+ action: delay
+ delay:
+ latency: 200ms
+ correlation: '0'
+ jitter: 0ms
+ direction: to
+ - name: adapters-majority-delay
+ templateType: NetworkChaos
+ deadline: 1m
+ networkChaos:
+ selector:
+ namespaces:
+ - adapters
+ expressionSelectors:
+ - key: app.kubernetes.io/instance
+ operator: In
+ values:
+ - universal-mumbai-1
+ - universal-mumbai-0
+ mode: all
+ action: delay
+ delay:
+ latency: 200ms
+ correlation: '0'
+ jitter: 0ms
+ direction: to
+
+ # experiments (external deps failure)
+# - name: ea-url-resolve-failure
+# templateType: NetworkChaos
+# deadline: 3m
+# networkChaos:
+# selector:
+# namespaces:
+# - chainlink
+# mode: all
+# action: partition
+# direction: to
+# target:
+# selector:
+# namespaces:
+# - chainlink
+# mode: all
+# externalTargets:
+# - >-
+# my-url.com
+
diff --git a/integration-tests/chaos/ocr2vrf_chaos_test.go b/integration-tests/chaos/ocr2vrf_chaos_test.go
index 7d10107ba56..fd51fa55db5 100644
--- a/integration-tests/chaos/ocr2vrf_chaos_test.go
+++ b/integration-tests/chaos/ocr2vrf_chaos_test.go
@@ -16,6 +16,8 @@ import (
"github.com/smartcontractkit/chainlink-env/pkg/helm/chainlink"
"github.com/smartcontractkit/chainlink-env/pkg/helm/ethereum"
"github.com/smartcontractkit/chainlink-testing-framework/blockchain"
+ "github.com/smartcontractkit/chainlink-testing-framework/logging"
+ "github.com/smartcontractkit/chainlink-testing-framework/networks"
"github.com/smartcontractkit/chainlink-testing-framework/utils"
"github.com/smartcontractkit/chainlink/integration-tests/actions"
@@ -24,12 +26,11 @@ import (
"github.com/smartcontractkit/chainlink/integration-tests/client"
"github.com/smartcontractkit/chainlink/integration-tests/config"
"github.com/smartcontractkit/chainlink/integration-tests/contracts"
- "github.com/smartcontractkit/chainlink/integration-tests/networks"
)
func TestOCR2VRFChaos(t *testing.T) {
t.Parallel()
- l := utils.GetTestLogger(t)
+ l := logging.GetTestLogger(t)
loadedNetwork := networks.SelectedNetwork
defaultOCR2VRFSettings := map[string]interface{}{
@@ -139,9 +140,9 @@ func TestOCR2VRFChaos(t *testing.T) {
err = testEnvironment.Client.LabelChaosGroup(testEnvironment.Cfg.Namespace, "instance=", 3, 5, ChaosGroupMajority)
require.NoError(t, err)
- chainClient, err := blockchain.NewEVMClient(testNetwork, testEnvironment)
+ chainClient, err := blockchain.NewEVMClient(testNetwork, testEnvironment, l)
require.NoError(t, err, "Error connecting to blockchain")
- contractDeployer, err := contracts.NewContractDeployer(chainClient)
+ contractDeployer, err := contracts.NewContractDeployer(chainClient, l)
require.NoError(t, err, "Error building contract deployer")
chainlinkNodes, err := client.ConnectChainlinkNodes(testEnvironment)
require.NoError(t, err, "Error connecting to Chainlink nodes")
diff --git a/integration-tests/chaos/ocr_chaos_test.go b/integration-tests/chaos/ocr_chaos_test.go
index 58b4d5bea65..569a0d1b70c 100644
--- a/integration-tests/chaos/ocr_chaos_test.go
+++ b/integration-tests/chaos/ocr_chaos_test.go
@@ -20,13 +20,14 @@ import (
mockservercfg "github.com/smartcontractkit/chainlink-env/pkg/helm/mockserver-cfg"
"github.com/smartcontractkit/chainlink-testing-framework/blockchain"
ctfClient "github.com/smartcontractkit/chainlink-testing-framework/client"
+ "github.com/smartcontractkit/chainlink-testing-framework/logging"
+ "github.com/smartcontractkit/chainlink-testing-framework/networks"
"github.com/smartcontractkit/chainlink-testing-framework/utils"
"github.com/smartcontractkit/chainlink/integration-tests/actions"
"github.com/smartcontractkit/chainlink/integration-tests/client"
"github.com/smartcontractkit/chainlink/integration-tests/config"
"github.com/smartcontractkit/chainlink/integration-tests/contracts"
- "github.com/smartcontractkit/chainlink/integration-tests/networks"
)
var (
@@ -58,7 +59,7 @@ func TestMain(m *testing.M) {
func TestOCRChaos(t *testing.T) {
t.Parallel()
- l := utils.GetTestLogger(t)
+ l := logging.GetTestLogger(t)
testCases := map[string]struct {
networkChart environment.ConnectedChart
clChart environment.ConnectedChart
@@ -152,9 +153,9 @@ func TestOCRChaos(t *testing.T) {
err = testEnvironment.Client.LabelChaosGroup(testEnvironment.Cfg.Namespace, "instance=", 2, 5, ChaosGroupMajorityPlus)
require.NoError(t, err)
- chainClient, err := blockchain.NewEVMClient(blockchain.SimulatedEVMNetwork, testEnvironment)
+ chainClient, err := blockchain.NewEVMClient(blockchain.SimulatedEVMNetwork, testEnvironment, l)
require.NoError(t, err, "Connecting to blockchain nodes shouldn't fail")
- cd, err := contracts.NewContractDeployer(chainClient)
+ cd, err := contracts.NewContractDeployer(chainClient, l)
require.NoError(t, err, "Deploying contracts shouldn't fail")
chainlinkNodes, err := client.ConnectChainlinkNodes(testEnvironment)
@@ -184,7 +185,7 @@ func TestOCRChaos(t *testing.T) {
require.NoError(t, err)
err = chainClient.WaitForEvents()
require.NoError(t, err)
- err = actions.CreateOCRJobs(ocrInstances, bootstrapNode, workerNodes, 5, ms)
+ err = actions.CreateOCRJobs(ocrInstances, bootstrapNode, workerNodes, 5, ms, chainClient.GetChainID().String())
require.NoError(t, err)
chaosApplied := false
diff --git a/integration-tests/client/chainlink.go b/integration-tests/client/chainlink.go
index 7d3bd0284d0..8a79cb3ec95 100644
--- a/integration-tests/client/chainlink.go
+++ b/integration-tests/client/chainlink.go
@@ -9,11 +9,13 @@ import (
"sync"
"time"
+ "os"
+
"github.com/ethereum/go-ethereum/common"
"github.com/go-resty/resty/v2"
+ "github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"golang.org/x/sync/errgroup"
- "os"
)
const (
@@ -39,10 +41,11 @@ type ChainlinkClient struct {
pageSize int
primaryEthAddress string
ethAddresses []string
+ l zerolog.Logger
}
// NewChainlinkClient creates a new Chainlink model using a provided config
-func NewChainlinkClient(c *ChainlinkConfig) (*ChainlinkClient, error) {
+func NewChainlinkClient(c *ChainlinkConfig, logger zerolog.Logger) (*ChainlinkClient, error) {
rc, err := initRestyClient(c.URL, c.Email, c.Password, c.HTTPTimeout)
if err != nil {
return nil, err
@@ -55,6 +58,7 @@ func NewChainlinkClient(c *ChainlinkConfig) (*ChainlinkClient, error) {
Config: c,
APIClient: rc,
pageSize: 25,
+ l: logger,
}, nil
}
@@ -92,8 +96,8 @@ func (c *ChainlinkClient) URL() string {
// CreateJobRaw creates a Chainlink job based on the provided spec string
func (c *ChainlinkClient) CreateJobRaw(spec string) (*Job, *http.Response, error) {
job := &Job{}
- log.Info().Str("Node URL", c.Config.URL).Msg("Creating Job")
- log.Trace().Str("Node URL", c.Config.URL).Str("Job Body", spec).Msg("Creating Job")
+ c.l.Info().Str("Node URL", c.Config.URL).Msg("Creating Job")
+ c.l.Trace().Str("Node URL", c.Config.URL).Str("Job Body", spec).Msg("Creating Job")
resp, err := c.APIClient.R().
SetBody(&JobForm{
TOML: spec,
@@ -123,8 +127,8 @@ func (c *ChainlinkClient) CreateJob(spec JobSpec) (*Job, *http.Response, error)
if err != nil {
return nil, nil, err
}
- log.Info().Str("Node URL", c.Config.URL).Str("Type", spec.Type()).Msg("Creating Job")
- log.Trace().Str("Node URL", c.Config.URL).Str("Type", spec.Type()).Str("Spec", specString).Msg("Creating Job")
+ c.l.Info().Str("Node URL", c.Config.URL).Str("Type", spec.Type()).Msg("Creating Job")
+ c.l.Trace().Str("Node URL", c.Config.URL).Str("Type", spec.Type()).Str("Spec", specString).Msg("Creating Job")
resp, err := c.APIClient.R().
SetBody(&JobForm{
TOML: specString,
@@ -140,7 +144,7 @@ func (c *ChainlinkClient) CreateJob(spec JobSpec) (*Job, *http.Response, error)
// ReadJobs reads all jobs from the Chainlink node
func (c *ChainlinkClient) ReadJobs() (*ResponseSlice, *http.Response, error) {
specObj := &ResponseSlice{}
- log.Info().Str(NodeURL, c.Config.URL).Msg("Getting Jobs")
+ c.l.Info().Str(NodeURL, c.Config.URL).Msg("Getting Jobs")
resp, err := c.APIClient.R().
SetResult(&specObj).
Get("/v2/jobs")
@@ -153,7 +157,7 @@ func (c *ChainlinkClient) ReadJobs() (*ResponseSlice, *http.Response, error) {
// ReadJob reads a job with the provided ID from the Chainlink node
func (c *ChainlinkClient) ReadJob(id string) (*Response, *http.Response, error) {
specObj := &Response{}
- log.Info().Str(NodeURL, c.Config.URL).Str("ID", id).Msg("Reading Job")
+ c.l.Info().Str(NodeURL, c.Config.URL).Str("ID", id).Msg("Reading Job")
resp, err := c.APIClient.R().
SetResult(&specObj).
SetPathParams(map[string]string{
@@ -178,7 +182,7 @@ func (c *ChainlinkClient) MustDeleteJob(id string) error {
// DeleteJob deletes a job with a provided ID from the Chainlink node
func (c *ChainlinkClient) DeleteJob(id string) (*http.Response, error) {
- log.Info().Str(NodeURL, c.Config.URL).Str("ID", id).Msg("Deleting Job")
+ c.l.Info().Str(NodeURL, c.Config.URL).Str("ID", id).Msg("Deleting Job")
resp, err := c.APIClient.R().
SetPathParams(map[string]string{
"id": id,
@@ -194,7 +198,7 @@ func (c *ChainlinkClient) DeleteJob(id string) (*http.Response, error) {
func (c *ChainlinkClient) CreateSpec(spec string) (*Spec, *http.Response, error) {
s := &Spec{}
r := strings.NewReplacer("\n", "", " ", "", "\\", "") // Makes it more compact and readable for logging
- log.Info().Str(NodeURL, c.Config.URL).Str("Spec", r.Replace(spec)).Msg("Creating Spec")
+ c.l.Info().Str(NodeURL, c.Config.URL).Str("Spec", r.Replace(spec)).Msg("Creating Spec")
resp, err := c.APIClient.R().
SetBody([]byte(spec)).
SetResult(&s).
@@ -208,7 +212,7 @@ func (c *ChainlinkClient) CreateSpec(spec string) (*Spec, *http.Response, error)
// ReadSpec reads a job spec with the provided ID on the Chainlink node
func (c *ChainlinkClient) ReadSpec(id string) (*Response, *http.Response, error) {
specObj := &Response{}
- log.Info().Str(NodeURL, c.Config.URL).Str("ID", id).Msg("Reading Spec")
+ c.l.Info().Str(NodeURL, c.Config.URL).Str("ID", id).Msg("Reading Spec")
resp, err := c.APIClient.R().
SetResult(&specObj).
SetPathParams(map[string]string{
@@ -234,7 +238,7 @@ func (c *ChainlinkClient) MustReadRunsByJob(jobID string) (*JobRunsResponse, err
// ReadRunsByJob reads all runs for a job
func (c *ChainlinkClient) ReadRunsByJob(jobID string) (*JobRunsResponse, *http.Response, error) {
runsObj := &JobRunsResponse{}
- log.Debug().Str(NodeURL, c.Config.URL).Str("JobID", jobID).Msg("Reading runs for a job")
+ c.l.Debug().Str(NodeURL, c.Config.URL).Str("JobID", jobID).Msg("Reading runs for a job")
resp, err := c.APIClient.R().
SetResult(&runsObj).
SetPathParams(map[string]string{
@@ -249,7 +253,7 @@ func (c *ChainlinkClient) ReadRunsByJob(jobID string) (*JobRunsResponse, *http.R
// DeleteSpec deletes a job spec with the provided ID from the Chainlink node
func (c *ChainlinkClient) DeleteSpec(id string) (*http.Response, error) {
- log.Info().Str(NodeURL, c.Config.URL).Str("ID", id).Msg("Deleting Spec")
+ c.l.Info().Str(NodeURL, c.Config.URL).Str("ID", id).Msg("Deleting Spec")
resp, err := c.APIClient.R().
SetPathParams(map[string]string{
"id": id,
@@ -272,7 +276,7 @@ func (c *ChainlinkClient) MustCreateBridge(bta *BridgeTypeAttributes) error {
}
func (c *ChainlinkClient) CreateBridge(bta *BridgeTypeAttributes) (*http.Response, error) {
- log.Info().Str(NodeURL, c.Config.URL).Str("Name", bta.Name).Msg("Creating Bridge")
+ c.l.Info().Str(NodeURL, c.Config.URL).Str("Name", bta.Name).Msg("Creating Bridge")
resp, err := c.APIClient.R().
SetBody(bta).
Post("/v2/bridge_types")
@@ -285,7 +289,7 @@ func (c *ChainlinkClient) CreateBridge(bta *BridgeTypeAttributes) (*http.Respons
// ReadBridge reads a bridge from the Chainlink node based on the provided name
func (c *ChainlinkClient) ReadBridge(name string) (*BridgeType, *http.Response, error) {
bt := BridgeType{}
- log.Info().Str(NodeURL, c.Config.URL).Str("Name", name).Msg("Reading Bridge")
+ c.l.Info().Str(NodeURL, c.Config.URL).Str("Name", name).Msg("Reading Bridge")
resp, err := c.APIClient.R().
SetPathParams(map[string]string{
"name": name,
@@ -300,7 +304,7 @@ func (c *ChainlinkClient) ReadBridge(name string) (*BridgeType, *http.Response,
// DeleteBridge deletes a bridge on the Chainlink node based on the provided name
func (c *ChainlinkClient) DeleteBridge(name string) (*http.Response, error) {
- log.Info().Str(NodeURL, c.Config.URL).Str("Name", name).Msg("Deleting Bridge")
+ c.l.Info().Str(NodeURL, c.Config.URL).Str("Name", name).Msg("Deleting Bridge")
resp, err := c.APIClient.R().
SetPathParams(map[string]string{
"name": name,
@@ -315,7 +319,7 @@ func (c *ChainlinkClient) DeleteBridge(name string) (*http.Response, error) {
// CreateOCRKey creates an OCRKey on the Chainlink node
func (c *ChainlinkClient) CreateOCRKey() (*OCRKey, *http.Response, error) {
ocrKey := &OCRKey{}
- log.Info().Str(NodeURL, c.Config.URL).Msg("Creating OCR Key")
+ c.l.Info().Str(NodeURL, c.Config.URL).Msg("Creating OCR Key")
resp, err := c.APIClient.R().
SetResult(ocrKey).
Post("/v2/keys/ocr")
@@ -329,7 +333,7 @@ func (c *ChainlinkClient) CreateOCRKey() (*OCRKey, *http.Response, error) {
// the request is unsuccessful
func (c *ChainlinkClient) MustReadOCRKeys() (*OCRKeys, error) {
ocrKeys := &OCRKeys{}
- log.Info().Str(NodeURL, c.Config.URL).Msg("Reading OCR Keys")
+ c.l.Info().Str(NodeURL, c.Config.URL).Msg("Reading OCR Keys")
resp, err := c.APIClient.R().
SetResult(ocrKeys).
Get("/v2/keys/ocr")
@@ -350,7 +354,7 @@ func (c *ChainlinkClient) MustReadOCRKeys() (*OCRKeys, error) {
// DeleteOCRKey deletes an OCRKey based on the provided ID
func (c *ChainlinkClient) DeleteOCRKey(id string) (*http.Response, error) {
- log.Info().Str(NodeURL, c.Config.URL).Str("ID", id).Msg("Deleting OCR Key")
+ c.l.Info().Str(NodeURL, c.Config.URL).Str("ID", id).Msg("Deleting OCR Key")
resp, err := c.APIClient.R().
SetPathParams(map[string]string{
"id": id,
@@ -365,7 +369,7 @@ func (c *ChainlinkClient) DeleteOCRKey(id string) (*http.Response, error) {
// CreateOCR2Key creates an OCR2Key on the Chainlink node
func (c *ChainlinkClient) CreateOCR2Key(chain string) (*OCR2Key, *http.Response, error) {
ocr2Key := &OCR2Key{}
- log.Info().Str(NodeURL, c.Config.URL).Msg("Creating OCR2 Key")
+ c.l.Info().Str(NodeURL, c.Config.URL).Msg("Creating OCR2 Key")
resp, err := c.APIClient.R().
SetPathParams(map[string]string{
"chain": chain,
@@ -381,7 +385,7 @@ func (c *ChainlinkClient) CreateOCR2Key(chain string) (*OCR2Key, *http.Response,
// ReadOCR2Keys reads all OCR2Keys from the Chainlink node
func (c *ChainlinkClient) ReadOCR2Keys() (*OCR2Keys, *http.Response, error) {
ocr2Keys := &OCR2Keys{}
- log.Info().Str(NodeURL, c.Config.URL).Msg("Reading OCR2 Keys")
+ c.l.Info().Str(NodeURL, c.Config.URL).Msg("Reading OCR2 Keys")
resp, err := c.APIClient.R().
SetResult(ocr2Keys).
Get("/v2/keys/ocr2")
@@ -391,7 +395,7 @@ func (c *ChainlinkClient) ReadOCR2Keys() (*OCR2Keys, *http.Response, error) {
// MustReadOCR2Keys reads all OCR2Keys from the Chainlink node returns err if response not 200
func (c *ChainlinkClient) MustReadOCR2Keys() (*OCR2Keys, error) {
ocr2Keys := &OCR2Keys{}
- log.Info().Str(NodeURL, c.Config.URL).Msg("Reading OCR2 Keys")
+ c.l.Info().Str(NodeURL, c.Config.URL).Msg("Reading OCR2 Keys")
resp, err := c.APIClient.R().
SetResult(ocr2Keys).
Get("/v2/keys/ocr2")
@@ -404,7 +408,7 @@ func (c *ChainlinkClient) MustReadOCR2Keys() (*OCR2Keys, error) {
// DeleteOCR2Key deletes an OCR2Key based on the provided ID
func (c *ChainlinkClient) DeleteOCR2Key(id string) (*http.Response, error) {
- log.Info().Str(NodeURL, c.Config.URL).Str("ID", id).Msg("Deleting OCR2 Key")
+ c.l.Info().Str(NodeURL, c.Config.URL).Str("ID", id).Msg("Deleting OCR2 Key")
resp, err := c.APIClient.R().
SetPathParams(map[string]string{
"id": id,
@@ -419,7 +423,7 @@ func (c *ChainlinkClient) DeleteOCR2Key(id string) (*http.Response, error) {
// CreateP2PKey creates an P2PKey on the Chainlink node
func (c *ChainlinkClient) CreateP2PKey() (*P2PKey, *http.Response, error) {
p2pKey := &P2PKey{}
- log.Info().Str(NodeURL, c.Config.URL).Msg("Creating P2P Key")
+ c.l.Info().Str(NodeURL, c.Config.URL).Msg("Creating P2P Key")
resp, err := c.APIClient.R().
SetResult(p2pKey).
Post("/v2/keys/p2p")
@@ -433,7 +437,7 @@ func (c *ChainlinkClient) CreateP2PKey() (*P2PKey, *http.Response, error) {
// the request is unsuccessful
func (c *ChainlinkClient) MustReadP2PKeys() (*P2PKeys, error) {
p2pKeys := &P2PKeys{}
- log.Info().Str(NodeURL, c.Config.URL).Msg("Reading P2P Keys")
+ c.l.Info().Str(NodeURL, c.Config.URL).Msg("Reading P2P Keys")
resp, err := c.APIClient.R().
SetResult(p2pKeys).
Get("/v2/keys/p2p")
@@ -443,7 +447,7 @@ func (c *ChainlinkClient) MustReadP2PKeys() (*P2PKeys, error) {
err = VerifyStatusCode(resp.StatusCode(), http.StatusOK)
if len(p2pKeys.Data) == 0 {
err = fmt.Errorf("Found no P2P Keys on the Chainlink node. Node URL: %s", c.Config.URL)
- log.Err(err).Msg("Error getting P2P keys")
+ c.l.Err(err).Msg("Error getting P2P keys")
return nil, err
}
for index := range p2pKeys.Data {
@@ -454,7 +458,7 @@ func (c *ChainlinkClient) MustReadP2PKeys() (*P2PKeys, error) {
// DeleteP2PKey deletes a P2PKey on the Chainlink node based on the provided ID
func (c *ChainlinkClient) DeleteP2PKey(id int) (*http.Response, error) {
- log.Info().Str(NodeURL, c.Config.URL).Int("ID", id).Msg("Deleting P2P Key")
+ c.l.Info().Str(NodeURL, c.Config.URL).Int("ID", id).Msg("Deleting P2P Key")
resp, err := c.APIClient.R().
SetPathParams(map[string]string{
"id": fmt.Sprint(id),
@@ -470,7 +474,7 @@ func (c *ChainlinkClient) DeleteP2PKey(id int) (*http.Response, error) {
// the request is unsuccessful
func (c *ChainlinkClient) MustReadETHKeys() (*ETHKeys, error) {
ethKeys := ÐKeys{}
- log.Info().Str(NodeURL, c.Config.URL).Msg("Reading ETH Keys")
+ c.l.Info().Str(NodeURL, c.Config.URL).Msg("Reading ETH Keys")
resp, err := c.APIClient.R().
SetResult(ethKeys).
Get("/v2/keys/eth")
@@ -479,7 +483,7 @@ func (c *ChainlinkClient) MustReadETHKeys() (*ETHKeys, error) {
}
err = VerifyStatusCode(resp.StatusCode(), http.StatusOK)
if len(ethKeys.Data) == 0 {
- log.Warn().Str(NodeURL, c.Config.URL).Msg("Found no ETH Keys on the node")
+ c.l.Warn().Str(NodeURL, c.Config.URL).Msg("Found no ETH Keys on the node")
}
return ethKeys, err
}
@@ -487,7 +491,7 @@ func (c *ChainlinkClient) MustReadETHKeys() (*ETHKeys, error) {
// UpdateEthKeyMaxGasPriceGWei updates the maxGasPriceGWei for an eth key
func (c *ChainlinkClient) UpdateEthKeyMaxGasPriceGWei(keyId string, gWei int) (*ETHKey, *http.Response, error) {
ethKey := ÐKey{}
- log.Info().Str(NodeURL, c.Config.URL).Str("ID", keyId).Int("maxGasPriceGWei", gWei).Msg("Update maxGasPriceGWei for eth key")
+ c.l.Info().Str(NodeURL, c.Config.URL).Str("ID", keyId).Int("maxGasPriceGWei", gWei).Msg("Update maxGasPriceGWei for eth key")
resp, err := c.APIClient.R().
SetPathParams(map[string]string{
"keyId": keyId,
@@ -608,7 +612,7 @@ func (c *ChainlinkClient) ExportEVMKeys() ([]*ExportedEVMKey, error) {
exportedKeys = append(exportedKeys, exportedKey)
}
}
- log.Info().
+ c.l.Info().
Str(NodeURL, c.Config.URL).
Str("Password", ChainlinkKeyPassword).
Msg("Exported EVM Keys")
@@ -636,7 +640,7 @@ func (c *ChainlinkClient) ExportEVMKeysForChain(chainid string) ([]*ExportedEVMK
exportedKeys = append(exportedKeys, exportedKey)
}
}
- log.Info().
+ c.l.Info().
Str(NodeURL, c.Config.URL).
Str("Password", ChainlinkKeyPassword).
Msg("Exported EVM Keys")
@@ -646,7 +650,7 @@ func (c *ChainlinkClient) ExportEVMKeysForChain(chainid string) ([]*ExportedEVMK
// CreateTxKey creates a tx key on the Chainlink node
func (c *ChainlinkClient) CreateTxKey(chain string, chainId string) (*TxKey, *http.Response, error) {
txKey := &TxKey{}
- log.Info().Str(NodeURL, c.Config.URL).Msg("Creating Tx Key")
+ c.l.Info().Str(NodeURL, c.Config.URL).Msg("Creating Tx Key")
resp, err := c.APIClient.R().
SetPathParams(map[string]string{
"chain": chain,
@@ -663,7 +667,7 @@ func (c *ChainlinkClient) CreateTxKey(chain string, chainId string) (*TxKey, *ht
// ReadTxKeys reads all tx keys from the Chainlink node
func (c *ChainlinkClient) ReadTxKeys(chain string) (*TxKeys, *http.Response, error) {
txKeys := &TxKeys{}
- log.Info().Str(NodeURL, c.Config.URL).Msg("Reading Tx Keys")
+ c.l.Info().Str(NodeURL, c.Config.URL).Msg("Reading Tx Keys")
resp, err := c.APIClient.R().
SetPathParams(map[string]string{
"chain": chain,
@@ -678,7 +682,7 @@ func (c *ChainlinkClient) ReadTxKeys(chain string) (*TxKeys, *http.Response, err
// DeleteTxKey deletes an tx key based on the provided ID
func (c *ChainlinkClient) DeleteTxKey(chain string, id string) (*http.Response, error) {
- log.Info().Str(NodeURL, c.Config.URL).Str("ID", id).Msg("Deleting Tx Key")
+ c.l.Info().Str(NodeURL, c.Config.URL).Str("ID", id).Msg("Deleting Tx Key")
resp, err := c.APIClient.R().
SetPathParams(map[string]string{
"chain": chain,
@@ -695,7 +699,7 @@ func (c *ChainlinkClient) DeleteTxKey(chain string, id string) (*http.Response,
// and returns error if the request is unsuccessful
func (c *ChainlinkClient) MustReadTransactionAttempts() (*TransactionsData, error) {
txsData := &TransactionsData{}
- log.Info().Str(NodeURL, c.Config.URL).Msg("Reading Transaction Attempts")
+ c.l.Info().Str(NodeURL, c.Config.URL).Msg("Reading Transaction Attempts")
resp, err := c.APIClient.R().
SetResult(txsData).
Get("/v2/tx_attempts")
@@ -709,7 +713,7 @@ func (c *ChainlinkClient) MustReadTransactionAttempts() (*TransactionsData, erro
// ReadTransactions reads all transactions made by the Chainlink node
func (c *ChainlinkClient) ReadTransactions() (*TransactionsData, *http.Response, error) {
txsData := &TransactionsData{}
- log.Info().Str(NodeURL, c.Config.URL).Msg("Reading Transactions")
+ c.l.Info().Str(NodeURL, c.Config.URL).Msg("Reading Transactions")
resp, err := c.APIClient.R().
SetResult(txsData).
Get("/v2/transactions")
@@ -735,7 +739,7 @@ func (c *ChainlinkClient) MustSendNativeToken(amount *big.Int, fromAddress, toAd
SetResult(txData).
Post("/v2/transfers")
- log.Info().
+ c.l.Info().
Str(NodeURL, c.Config.URL).
Str("From", fromAddress).
Str("To", toAddress).
@@ -751,7 +755,7 @@ func (c *ChainlinkClient) MustSendNativeToken(amount *big.Int, fromAddress, toAd
// ReadVRFKeys reads all VRF keys from the Chainlink node
func (c *ChainlinkClient) ReadVRFKeys() (*VRFKeys, *http.Response, error) {
vrfKeys := &VRFKeys{}
- log.Info().Str(NodeURL, c.Config.URL).Msg("Reading VRF Keys")
+ c.l.Info().Str(NodeURL, c.Config.URL).Msg("Reading VRF Keys")
resp, err := c.APIClient.R().
SetResult(vrfKeys).
Get("/v2/keys/vrf")
@@ -759,7 +763,7 @@ func (c *ChainlinkClient) ReadVRFKeys() (*VRFKeys, *http.Response, error) {
return nil, nil, err
}
if len(vrfKeys.Data) == 0 {
- log.Warn().Str(NodeURL, c.Config.URL).Msg("Found no VRF Keys on the node")
+ c.l.Warn().Str(NodeURL, c.Config.URL).Msg("Found no VRF Keys on the node")
}
return vrfKeys, resp.RawResponse, err
}
@@ -768,7 +772,7 @@ func (c *ChainlinkClient) ReadVRFKeys() (*VRFKeys, *http.Response, error) {
// and returns error if the request is unsuccessful
func (c *ChainlinkClient) MustCreateVRFKey() (*VRFKey, error) {
vrfKey := &VRFKey{}
- log.Info().Str(NodeURL, c.Config.URL).Msg("Creating VRF Key")
+ c.l.Info().Str(NodeURL, c.Config.URL).Msg("Creating VRF Key")
resp, err := c.APIClient.R().
SetResult(vrfKey).
Post("/v2/keys/vrf")
@@ -781,7 +785,7 @@ func (c *ChainlinkClient) MustCreateVRFKey() (*VRFKey, error) {
// ExportVRFKey exports a vrf key by key id
func (c *ChainlinkClient) ExportVRFKey(keyId string) (*VRFExportKey, *http.Response, error) {
vrfExportKey := &VRFExportKey{}
- log.Info().Str(NodeURL, c.Config.URL).Str("ID", keyId).Msg("Exporting VRF Key")
+ c.l.Info().Str(NodeURL, c.Config.URL).Str("ID", keyId).Msg("Exporting VRF Key")
resp, err := c.APIClient.R().
SetPathParams(map[string]string{
"keyId": keyId,
@@ -797,7 +801,7 @@ func (c *ChainlinkClient) ExportVRFKey(keyId string) (*VRFExportKey, *http.Respo
// ImportVRFKey import vrf key
func (c *ChainlinkClient) ImportVRFKey(vrfExportKey *VRFExportKey) (*VRFKey, *http.Response, error) {
vrfKey := &VRFKey{}
- log.Info().Str(NodeURL, c.Config.URL).Str("ID", vrfExportKey.VrfKey.Address).Msg("Importing VRF Key")
+ c.l.Info().Str(NodeURL, c.Config.URL).Str("ID", vrfExportKey.VrfKey.Address).Msg("Importing VRF Key")
resp, err := c.APIClient.R().
SetBody(vrfExportKey).
SetResult(vrfKey).
@@ -812,7 +816,7 @@ func (c *ChainlinkClient) ImportVRFKey(vrfExportKey *VRFExportKey) (*VRFKey, *ht
// and returns error if the request is unsuccessful
func (c *ChainlinkClient) MustCreateDkgSignKey() (*DKGSignKey, error) {
dkgSignKey := &DKGSignKey{}
- log.Info().Str(NodeURL, c.Config.URL).Msg("Creating DKG Sign Key")
+ c.l.Info().Str(NodeURL, c.Config.URL).Msg("Creating DKG Sign Key")
resp, err := c.APIClient.R().
SetResult(dkgSignKey).
Post("/v2/keys/dkgsign")
@@ -826,7 +830,7 @@ func (c *ChainlinkClient) MustCreateDkgSignKey() (*DKGSignKey, error) {
// and returns error if the request is unsuccessful
func (c *ChainlinkClient) MustCreateDkgEncryptKey() (*DKGEncryptKey, error) {
dkgEncryptKey := &DKGEncryptKey{}
- log.Info().Str(NodeURL, c.Config.URL).Msg("Creating DKG Encrypt Key")
+ c.l.Info().Str(NodeURL, c.Config.URL).Msg("Creating DKG Encrypt Key")
resp, err := c.APIClient.R().
SetResult(dkgEncryptKey).
Post("/v2/keys/dkgencrypt")
@@ -839,7 +843,7 @@ func (c *ChainlinkClient) MustCreateDkgEncryptKey() (*DKGEncryptKey, error) {
// MustReadDKGSignKeys reads all DKG Sign Keys from the Chainlink node returns err if response not 200
func (c *ChainlinkClient) MustReadDKGSignKeys() (*DKGSignKeys, error) {
dkgSignKeys := &DKGSignKeys{}
- log.Info().Str(NodeURL, c.Config.URL).Msg("Reading DKG Sign Keys")
+ c.l.Info().Str(NodeURL, c.Config.URL).Msg("Reading DKG Sign Keys")
resp, err := c.APIClient.R().
SetResult(dkgSignKeys).
Get("/v2/keys/dkgsign")
@@ -853,7 +857,7 @@ func (c *ChainlinkClient) MustReadDKGSignKeys() (*DKGSignKeys, error) {
// MustReadDKGEncryptKeys reads all DKG Encrypt Keys from the Chainlink node returns err if response not 200
func (c *ChainlinkClient) MustReadDKGEncryptKeys() (*DKGEncryptKeys, error) {
dkgEncryptKeys := &DKGEncryptKeys{}
- log.Info().Str(NodeURL, c.Config.URL).Msg("Reading DKG Encrypt Keys")
+ c.l.Info().Str(NodeURL, c.Config.URL).Msg("Reading DKG Encrypt Keys")
resp, err := c.APIClient.R().
SetResult(dkgEncryptKeys).
Get("/v2/keys/dkgencrypt")
@@ -867,7 +871,7 @@ func (c *ChainlinkClient) MustReadDKGEncryptKeys() (*DKGEncryptKeys, error) {
// CreateCSAKey creates a CSA key on the Chainlink node, only 1 CSA key per noe
func (c *ChainlinkClient) CreateCSAKey() (*CSAKey, *http.Response, error) {
csaKey := &CSAKey{}
- log.Info().Str(NodeURL, c.Config.URL).Msg("Creating CSA Key")
+ c.l.Info().Str(NodeURL, c.Config.URL).Msg("Creating CSA Key")
resp, err := c.APIClient.R().
SetResult(csaKey).
Post("/v2/keys/csa")
@@ -880,12 +884,12 @@ func (c *ChainlinkClient) CreateCSAKey() (*CSAKey, *http.Response, error) {
// ReadCSAKeys reads CSA keys from the Chainlink node
func (c *ChainlinkClient) ReadCSAKeys() (*CSAKeys, *http.Response, error) {
csaKeys := &CSAKeys{}
- log.Info().Str(NodeURL, c.Config.URL).Msg("Reading CSA Keys")
+ c.l.Info().Str(NodeURL, c.Config.URL).Msg("Reading CSA Keys")
resp, err := c.APIClient.R().
SetResult(csaKeys).
Get("/v2/keys/csa")
if len(csaKeys.Data) == 0 {
- log.Warn().Str(NodeURL, c.Config.URL).Msg("Found no CSA Keys on the node")
+ c.l.Warn().Str(NodeURL, c.Config.URL).Msg("Found no CSA Keys on the node")
}
if err != nil {
return nil, nil, err
@@ -896,7 +900,7 @@ func (c *ChainlinkClient) ReadCSAKeys() (*CSAKeys, *http.Response, error) {
// CreateEI creates an EI on the Chainlink node based on the provided attributes and returns the respective secrets
func (c *ChainlinkClient) CreateEI(eia *EIAttributes) (*EIKeyCreate, *http.Response, error) {
ei := EIKeyCreate{}
- log.Info().Str(NodeURL, c.Config.URL).Str("Name", eia.Name).Msg("Creating External Initiator")
+ c.l.Info().Str(NodeURL, c.Config.URL).Str("Name", eia.Name).Msg("Creating External Initiator")
resp, err := c.APIClient.R().
SetBody(eia).
SetResult(&ei).
@@ -910,7 +914,7 @@ func (c *ChainlinkClient) CreateEI(eia *EIAttributes) (*EIKeyCreate, *http.Respo
// ReadEIs reads all of the configured EIs from the Chainlink node
func (c *ChainlinkClient) ReadEIs() (*EIKeys, *http.Response, error) {
ei := EIKeys{}
- log.Info().Str(NodeURL, c.Config.URL).Msg("Reading EI Keys")
+ c.l.Info().Str(NodeURL, c.Config.URL).Msg("Reading EI Keys")
resp, err := c.APIClient.R().
SetResult(&ei).
Get("/v2/external_initiators")
@@ -922,7 +926,7 @@ func (c *ChainlinkClient) ReadEIs() (*EIKeys, *http.Response, error) {
// DeleteEI deletes an external initiator in the Chainlink node based on the provided name
func (c *ChainlinkClient) DeleteEI(name string) (*http.Response, error) {
- log.Info().Str(NodeURL, c.Config.URL).Str("Name", name).Msg("Deleting EI")
+ c.l.Info().Str(NodeURL, c.Config.URL).Str("Name", name).Msg("Deleting EI")
resp, err := c.APIClient.R().
SetPathParams(map[string]string{
"name": name,
@@ -937,7 +941,7 @@ func (c *ChainlinkClient) DeleteEI(name string) (*http.Response, error) {
// CreateCosmosChain creates a cosmos chain
func (c *ChainlinkClient) CreateCosmosChain(chain *CosmosChainAttributes) (*CosmosChainCreate, *http.Response, error) {
response := CosmosChainCreate{}
- log.Info().Str(NodeURL, c.Config.URL).Str("Chain ID", chain.ChainID).Msg("Creating Cosmos Chain")
+ c.l.Info().Str(NodeURL, c.Config.URL).Str("Chain ID", chain.ChainID).Msg("Creating Cosmos Chain")
resp, err := c.APIClient.R().
SetBody(chain).
SetResult(&response).
@@ -951,7 +955,7 @@ func (c *ChainlinkClient) CreateCosmosChain(chain *CosmosChainAttributes) (*Cosm
// CreateCosmosNode creates a cosmos node
func (c *ChainlinkClient) CreateCosmosNode(node *CosmosNodeAttributes) (*CosmosNodeCreate, *http.Response, error) {
response := CosmosNodeCreate{}
- log.Info().Str(NodeURL, c.Config.URL).Str("Name", node.Name).Msg("Creating Cosmos Node")
+ c.l.Info().Str(NodeURL, c.Config.URL).Str("Name", node.Name).Msg("Creating Cosmos Node")
resp, err := c.APIClient.R().
SetBody(node).
SetResult(&response).
@@ -965,7 +969,7 @@ func (c *ChainlinkClient) CreateCosmosNode(node *CosmosNodeAttributes) (*CosmosN
// CreateSolanaChain creates a solana chain
func (c *ChainlinkClient) CreateSolanaChain(chain *SolanaChainAttributes) (*SolanaChainCreate, *http.Response, error) {
response := SolanaChainCreate{}
- log.Info().Str(NodeURL, c.Config.URL).Str("Chain ID", chain.ChainID).Msg("Creating Solana Chain")
+ c.l.Info().Str(NodeURL, c.Config.URL).Str("Chain ID", chain.ChainID).Msg("Creating Solana Chain")
resp, err := c.APIClient.R().
SetBody(chain).
SetResult(&response).
@@ -979,7 +983,7 @@ func (c *ChainlinkClient) CreateSolanaChain(chain *SolanaChainAttributes) (*Sola
// CreateSolanaNode creates a solana node
func (c *ChainlinkClient) CreateSolanaNode(node *SolanaNodeAttributes) (*SolanaNodeCreate, *http.Response, error) {
response := SolanaNodeCreate{}
- log.Info().Str(NodeURL, c.Config.URL).Str("Name", node.Name).Msg("Creating Solana Node")
+ c.l.Info().Str(NodeURL, c.Config.URL).Str("Name", node.Name).Msg("Creating Solana Node")
resp, err := c.APIClient.R().
SetBody(node).
SetResult(&response).
@@ -993,7 +997,7 @@ func (c *ChainlinkClient) CreateSolanaNode(node *SolanaNodeAttributes) (*SolanaN
// CreateStarkNetChain creates a starknet chain
func (c *ChainlinkClient) CreateStarkNetChain(chain *StarkNetChainAttributes) (*StarkNetChainCreate, *http.Response, error) {
response := StarkNetChainCreate{}
- log.Info().Str(NodeURL, c.Config.URL).Str("Chain ID", chain.ChainID).Msg("Creating StarkNet Chain")
+ c.l.Info().Str(NodeURL, c.Config.URL).Str("Chain ID", chain.ChainID).Msg("Creating StarkNet Chain")
resp, err := c.APIClient.R().
SetBody(chain).
SetResult(&response).
@@ -1007,7 +1011,7 @@ func (c *ChainlinkClient) CreateStarkNetChain(chain *StarkNetChainAttributes) (*
// CreateStarkNetNode creates a starknet node
func (c *ChainlinkClient) CreateStarkNetNode(node *StarkNetNodeAttributes) (*StarkNetNodeCreate, *http.Response, error) {
response := StarkNetNodeCreate{}
- log.Info().Str(NodeURL, c.Config.URL).Str("Name", node.Name).Msg("Creating StarkNet Node")
+ c.l.Info().Str(NodeURL, c.Config.URL).Str("Name", node.Name).Msg("Creating StarkNet Node")
resp, err := c.APIClient.R().
SetBody(node).
SetResult(&response).
@@ -1030,14 +1034,14 @@ func (c *ChainlinkClient) Profile(profileTime time.Duration, profileFunction fun
profileResults := NewBlankChainlinkProfileResults()
profileErrorGroup := new(errgroup.Group)
var profileExecutedGroup sync.WaitGroup
- log.Info().Int("Seconds to Profile", profileSeconds).Str(NodeURL, c.Config.URL).Msg("Starting Node PPROF session")
+ c.l.Info().Int("Seconds to Profile", profileSeconds).Str(NodeURL, c.Config.URL).Msg("Starting Node PPROF session")
for _, rep := range profileResults.Reports {
profileExecutedGroup.Add(1)
profileReport := rep
// The profile function returns with the profile results after the profile time frame has concluded
// e.g. a profile API call of 5 seconds will start profiling, wait for 5 seconds, then send back results
profileErrorGroup.Go(func() error {
- log.Debug().Str("Type", profileReport.Type).Msg("PROFILING")
+ c.l.Debug().Str("Type", profileReport.Type).Msg("PROFILING")
profileExecutedGroup.Done()
resp, err := c.APIClient.R().
SetPathParams(map[string]string{
@@ -1054,7 +1058,7 @@ func (c *ChainlinkClient) Profile(profileTime time.Duration, profileFunction fun
if err != nil {
return err
}
- log.Debug().Str("Type", profileReport.Type).Msg("DONE PROFILING")
+ c.l.Debug().Str("Type", profileReport.Type).Msg("DONE PROFILING")
profileReport.Data = resp.Body()
return err
})
@@ -1070,12 +1074,12 @@ func (c *ChainlinkClient) Profile(profileTime time.Duration, profileFunction fun
actualSeconds := int(actualRunTime.Seconds())
if actualSeconds > profileSeconds {
- log.Warn().
+ c.l.Warn().
Int("Actual Seconds", actualSeconds).
Int("Profile Seconds", profileSeconds).
Msg("Your profile function took longer than expected to run, increase profileTime")
} else if actualSeconds < profileSeconds && actualSeconds > 0 {
- log.Warn().
+ c.l.Warn().
Int("Actual Seconds", actualSeconds).
Int("Profile Seconds", profileSeconds).
Msg("Your profile function took shorter than expected to run, you can decrease profileTime")
@@ -1174,7 +1178,7 @@ func (c *ChainlinkClient) TrackForwarder(chainID *big.Int, address common.Addres
ChainID: chainID.String(),
Address: address.Hex(),
}
- log.Debug().Str(NodeURL, c.Config.URL).
+ c.l.Debug().Str(NodeURL, c.Config.URL).
Str("Forwarder address", (address).Hex()).
Str("Chain ID", chainID.String()).
Msg("Track forwarder")
@@ -1196,7 +1200,7 @@ func (c *ChainlinkClient) TrackForwarder(chainID *big.Int, address common.Addres
// GetForwarders get list of tracked forwarders
func (c *ChainlinkClient) GetForwarders() (*Forwarders, *http.Response, error) {
response := &Forwarders{}
- log.Info().Str(NodeURL, c.Config.URL).Msg("Reading Tracked Forwarders")
+ c.l.Info().Str(NodeURL, c.Config.URL).Msg("Reading Tracked Forwarders")
resp, err := c.APIClient.R().
SetResult(response).
Get("/v2/nodes/evm/forwarders")
diff --git a/integration-tests/client/chainlink_models.go b/integration-tests/client/chainlink_models.go
index 881b2d125e8..6013e13e0fa 100644
--- a/integration-tests/client/chainlink_models.go
+++ b/integration-tests/client/chainlink_models.go
@@ -620,6 +620,43 @@ func (d *PipelineSpec) String() (string, error) {
return MarshallTemplate(d, "API call pipeline template", sourceString)
}
+// VRFV2TxPipelineSpec VRFv2 request with tx callback
+type VRFV2PlusTxPipelineSpec struct {
+ Address string
+}
+
+// Type returns the type of the pipeline
+func (d *VRFV2PlusTxPipelineSpec) Type() string {
+ return "vrf_pipeline_v2plus"
+}
+
+// String representation of the pipeline
+func (d *VRFV2PlusTxPipelineSpec) String() (string, error) {
+ sourceString := `
+decode_log [type=ethabidecodelog
+ abi="RandomWordsRequested(bytes32 indexed keyHash,uint256 requestId,uint256 preSeed,uint256 indexed subId,uint16 minimumRequestConfirmations,uint32 callbackGasLimit,uint32 numWords,bytes extraArgs,address indexed sender)"
+ data="$(jobRun.logData)"
+ topics="$(jobRun.logTopics)"]
+generate_proof [type=vrfv2plus
+ publicKey="$(jobSpec.publicKey)"
+ requestBlockHash="$(jobRun.logBlockHash)"
+ requestBlockNumber="$(jobRun.logBlockNumber)"
+ topics="$(jobRun.logTopics)"]
+estimate_gas [type=estimategaslimit
+ to="{{ .Address }}"
+ multiplier="1.1"
+ data="$(generate_proof.output)"]
+simulate_fulfillment [type=ethcall
+ to="{{ .Address }}"
+ gas="$(estimate_gas)"
+ gasPrice="$(jobSpec.maxGasPrice)"
+ extractRevertReason=true
+ contract="{{ .Address }}"
+ data="$(generate_proof.output)"]
+decode_log->generate_proof->estimate_gas->simulate_fulfillment`
+ return MarshallTemplate(d, "VRFV2 Plus pipeline template", sourceString)
+}
+
// VRFV2TxPipelineSpec VRFv2 request with tx callback
type VRFV2TxPipelineSpec struct {
Address string
@@ -725,6 +762,7 @@ func (d *DirectRequestTxPipelineSpec) String() (string, error) {
type DirectRequestJobSpec struct {
Name string `toml:"name"`
ContractAddress string `toml:"contractAddress"`
+ EVMChainID string `toml:"evmChainID"`
ExternalJobID string `toml:"externalJobID"`
MinIncomingConfirmations string `toml:"minIncomingConfirmations"`
ObservationSource string `toml:"observationSource"` // List of commands for the Chainlink node
@@ -740,6 +778,7 @@ schemaVersion = 1
name = "{{.Name}}"
maxTaskDuration = "99999s"
contractAddress = "{{.ContractAddress}}"
+evmChainID = "{{.EVMChainID}}"
externalJobID = "{{.ExternalJobID}}"
minIncomingConfirmations = {{.MinIncomingConfirmations}}
observationSource = """
@@ -752,6 +791,7 @@ observationSource = """
type FluxMonitorJobSpec struct {
Name string `toml:"name"`
ContractAddress string `toml:"contractAddress"` // Address of the Flux Monitor script
+ EVMChainID string `toml:"evmChainID"` // Not optional
Precision int `toml:"precision"` // Optional
Threshold float32 `toml:"threshold"` // Optional
AbsoluteThreshold float32 `toml:"absoluteThreshold"` // Optional
@@ -772,6 +812,7 @@ func (f *FluxMonitorJobSpec) String() (string, error) {
schemaVersion = 1
name = "{{.Name}}"
contractAddress = "{{.ContractAddress}}"
+evmChainID = "{{.EVMChainID}}"
precision ={{if not .Precision}} 0 {{else}} {{.Precision}} {{end}}
threshold ={{if not .Threshold}} 0.5 {{else}} {{.Threshold}} {{end}}
absoluteThreshold ={{if not .AbsoluteThreshold}} 0.1 {{else}} {{.AbsoluteThreshold}} {{end}}
@@ -795,6 +836,7 @@ type KeeperJobSpec struct {
Name string `toml:"name"`
ContractAddress string `toml:"contractAddress"`
FromAddress string `toml:"fromAddress"` // Hex representation of the from address
+ EVMChainID string `toml:"evmChainID"` // Not optional
MinIncomingConfirmations int `toml:"minIncomingConfirmations"`
}
@@ -809,6 +851,7 @@ schemaVersion = 1
name = "{{.Name}}"
contractAddress = "{{.ContractAddress}}"
fromAddress = "{{.FromAddress}}"
+evmChainID = "{{.EVMChainID}}"
minIncomingConfirmations = {{.MinIncomingConfirmations}}
`
return MarshallTemplate(k, "Keeper Job", keeperTemplateString)
@@ -823,8 +866,9 @@ type OCRBootstrapJobSpec struct {
TrackerPollInterval time.Duration `toml:"contractConfigTrackerPollInterval"` // Optional
TrackerSubscribeInterval time.Duration `toml:"contractConfigTrackerSubscribeInterval"` // Optional
ContractAddress string `toml:"contractAddress"` // Address of the OCR contract
- IsBootstrapPeer bool `toml:"isBootstrapPeer"` // Typically true
- P2PPeerID string `toml:"p2pPeerID"` // This node's P2P ID
+ EVMChainID string `toml:"evmChainID"`
+ IsBootstrapPeer bool `toml:"isBootstrapPeer"` // Typically true
+ P2PPeerID string `toml:"p2pPeerID"` // This node's P2P ID
}
// Type returns the type of the job
@@ -839,6 +883,7 @@ contractConfigConfirmations ={{if not .ContractConfirmations}} 3 {{el
contractConfigTrackerPollInterval ={{if not .TrackerPollInterval}} "1m" {{else}} {{.TrackerPollInterval}} {{end}}
contractConfigTrackerSubscribeInterval ={{if not .TrackerSubscribeInterval}} "2m" {{else}} {{.TrackerSubscribeInterval}} {{end}}
contractAddress = "{{.ContractAddress}}"
+evmChainID = "{{.EVMChainID}}"
p2pBootstrapPeers = []
isBootstrapPeer = {{.IsBootstrapPeer}}
p2pPeerID = "{{.P2PPeerID}}"`
@@ -855,13 +900,14 @@ type OCRTaskJobSpec struct {
TrackerSubscribeInterval time.Duration `toml:"contractConfigTrackerSubscribeInterval"` // Optional
ForwardingAllowed bool `toml:"forwardingAllowed"` // Optional, by default false
ContractAddress string `toml:"contractAddress"` // Address of the OCR contract
- P2PBootstrapPeers []*ChainlinkClient `toml:"p2pBootstrapPeers"` // P2P ID of the bootstrap node
- IsBootstrapPeer bool `toml:"isBootstrapPeer"` // Typically false
- P2PPeerID string `toml:"p2pPeerID"` // This node's P2P ID
- KeyBundleID string `toml:"keyBundleID"` // ID of this node's OCR key bundle
- MonitoringEndpoint string `toml:"monitoringEndpoint"` // Typically "chain.link:4321"
- TransmitterAddress string `toml:"transmitterAddress"` // ETH address this node will use to transmit its answer
- ObservationSource string `toml:"observationSource"` // List of commands for the Chainlink node
+ EVMChainID string `toml:"evmChainID"`
+ P2PBootstrapPeers []*ChainlinkClient `toml:"p2pBootstrapPeers"` // P2P ID of the bootstrap node
+ IsBootstrapPeer bool `toml:"isBootstrapPeer"` // Typically false
+ P2PPeerID string `toml:"p2pPeerID"` // This node's P2P ID
+ KeyBundleID string `toml:"keyBundleID"` // ID of this node's OCR key bundle
+ MonitoringEndpoint string `toml:"monitoringEndpoint"` // Typically "chain.link:4321"
+ TransmitterAddress string `toml:"transmitterAddress"` // ETH address this node will use to transmit its answer
+ ObservationSource string `toml:"observationSource"` // List of commands for the Chainlink node
}
// P2PData holds the remote ip and the peer id and port
@@ -902,6 +948,7 @@ func (o *OCRTaskJobSpec) String() (string, error) {
TrackerPollInterval time.Duration
TrackerSubscribeInterval time.Duration
ContractAddress string
+ EVMChainID string
P2PBootstrapPeers []P2PData
IsBootstrapPeer bool
P2PPeerID string
@@ -917,6 +964,7 @@ func (o *OCRTaskJobSpec) String() (string, error) {
TrackerPollInterval: o.TrackerPollInterval,
TrackerSubscribeInterval: o.TrackerSubscribeInterval,
ContractAddress: o.ContractAddress,
+ EVMChainID: o.EVMChainID,
P2PBootstrapPeers: peers,
IsBootstrapPeer: o.IsBootstrapPeer,
P2PPeerID: o.P2PPeerID,
@@ -934,6 +982,7 @@ contractConfigConfirmations ={{if not .ContractConfirmations}} 3 {{el
contractConfigTrackerPollInterval ={{if not .TrackerPollInterval}} "1m" {{else}} {{.TrackerPollInterval}} {{end}}
contractConfigTrackerSubscribeInterval ={{if not .TrackerSubscribeInterval}} "2m" {{else}} {{.TrackerSubscribeInterval}} {{end}}
contractAddress = "{{.ContractAddress}}"
+evmChainID = "{{.EVMChainID}}"
{{if .P2PBootstrapPeers}}
p2pBootstrapPeers = [
{{range $peer := .P2PBootstrapPeers}}
@@ -1064,6 +1113,46 @@ observationSource = """
return MarshallTemplate(specWrap, "OCR2 Job", ocr2TemplateString)
}
+// VRFV2PlusJobSpec represents a VRFV2 job
+type VRFV2PlusJobSpec struct {
+ Name string `toml:"name"`
+ CoordinatorAddress string `toml:"coordinatorAddress"` // Address of the VRF CoordinatorV2 contract
+ PublicKey string `toml:"publicKey"` // Public key of the proving key
+ ExternalJobID string `toml:"externalJobID"`
+ ObservationSource string `toml:"observationSource"` // List of commands for the Chainlink node
+ MinIncomingConfirmations int `toml:"minIncomingConfirmations"`
+ FromAddresses []string `toml:"fromAddresses"`
+ EVMChainID string `toml:"evmChainID"`
+ BatchFulfillmentEnabled bool `toml:"batchFulfillmentEnabled"`
+ BackOffInitialDelay time.Duration `toml:"backOffInitialDelay"`
+ BackOffMaxDelay time.Duration `toml:"backOffMaxDelay"`
+}
+
+// Type returns the type of the job
+func (v *VRFV2PlusJobSpec) Type() string { return "vrf" }
+
+// String representation of the job
+func (v *VRFV2PlusJobSpec) String() (string, error) {
+ vrfTemplateString := `
+type = "vrf"
+schemaVersion = 1
+name = "{{.Name}}"
+coordinatorAddress = "{{.CoordinatorAddress}}"
+fromAddresses = [{{range .FromAddresses}}"{{.}}",{{end}}]
+evmChainID = "{{.EVMChainID}}"
+minIncomingConfirmations = {{.MinIncomingConfirmations}}
+publicKey = "{{.PublicKey}}"
+externalJobID = "{{.ExternalJobID}}"
+batchFulfillmentEnabled = {{.BatchFulfillmentEnabled}}
+backoffInitialDelay = "{{.BackOffInitialDelay}}"
+backoffMaxDelay = "{{.BackOffMaxDelay}}"
+observationSource = """
+{{.ObservationSource}}
+"""
+`
+ return MarshallTemplate(v, "VRFV2 PLUS Job", vrfTemplateString)
+}
+
// VRFV2JobSpec represents a VRFV2 job
type VRFV2JobSpec struct {
Name string `toml:"name"`
@@ -1109,6 +1198,7 @@ type VRFJobSpec struct {
Name string `toml:"name"`
CoordinatorAddress string `toml:"coordinatorAddress"` // Address of the VRF CoordinatorV2 contract
PublicKey string `toml:"publicKey"` // Public key of the proving key
+ EVMChainID string `toml:"evmChainID"`
ExternalJobID string `toml:"externalJobID"`
ObservationSource string `toml:"observationSource"` // List of commands for the Chainlink node
MinIncomingConfirmations int `toml:"minIncomingConfirmations"`
@@ -1126,6 +1216,7 @@ name = "{{.Name}}"
coordinatorAddress = "{{.CoordinatorAddress}}"
minIncomingConfirmations = {{.MinIncomingConfirmations}}
publicKey = "{{.PublicKey}}"
+evmChainID = "{{.EVMChainID}}"
externalJobID = "{{.ExternalJobID}}"
observationSource = """
{{.ObservationSource}}
diff --git a/integration-tests/contracts/contract_deployer.go b/integration-tests/contracts/contract_deployer.go
index 578ca1ea549..dcf81edede7 100644
--- a/integration-tests/contracts/contract_deployer.go
+++ b/integration-tests/contracts/contract_deployer.go
@@ -9,6 +9,7 @@ import (
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
+ "github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"github.com/smartcontractkit/chainlink-testing-framework/blockchain"
"github.com/smartcontractkit/libocr/gethwrappers/offchainaggregator"
@@ -17,6 +18,7 @@ import (
eth_contracts "github.com/smartcontractkit/chainlink/integration-tests/contracts/ethereum"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/functions/generated/functions_load_test_client"
+ "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/functions/generated/functions_v1_events_mock"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/automation_consumer_benchmark"
automationForwarderLogic "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/automation_forwarder_logic"
registrar21 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/automation_registrar_wrapper2_1"
@@ -88,8 +90,13 @@ type ContractDeployer interface {
DeployVRFConsumerV2(linkAddr string, coordinatorAddr string) (VRFConsumerV2, error)
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)
+ 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)
@@ -102,6 +109,7 @@ type ContractDeployer interface {
DeployFunctionsOracleEventsMock() (FunctionsOracleEventsMock, error)
DeployFunctionsBillingRegistryEventsMock() (FunctionsBillingRegistryEventsMock, error)
DeployStakingEventsMock() (StakingEventsMock, error)
+ DeployFunctionsV1EventsMock() (FunctionsV1EventsMock, error)
DeployOffchainAggregatorEventsMock() (OffchainAggregatorEventsMock, error)
DeployMockAggregatorProxy(aggregatorAddr string) (MockAggregatorProxy, error)
DeployOffchainAggregatorV2(linkAddr string, offchainOptions OffchainOptions) (OffchainAggregatorV2, error)
@@ -112,30 +120,30 @@ type ContractDeployer interface {
}
// NewContractDeployer returns an instance of a contract deployer based on the client type
-func NewContractDeployer(bcClient blockchain.EVMClient) (ContractDeployer, error) {
+func NewContractDeployer(bcClient blockchain.EVMClient, logger zerolog.Logger) (ContractDeployer, error) {
switch clientImpl := bcClient.Get().(type) {
case *blockchain.EthereumClient:
- return NewEthereumContractDeployer(clientImpl), nil
+ return NewEthereumContractDeployer(clientImpl, logger), nil
case *blockchain.KlaytnClient:
- return &KlaytnContractDeployer{NewEthereumContractDeployer(clientImpl)}, nil
+ return &KlaytnContractDeployer{NewEthereumContractDeployer(clientImpl, logger)}, nil
case *blockchain.MetisClient:
- return &MetisContractDeployer{NewEthereumContractDeployer(clientImpl)}, nil
+ return &MetisContractDeployer{NewEthereumContractDeployer(clientImpl, logger)}, nil
case *blockchain.ArbitrumClient:
- return &MetisContractDeployer{NewEthereumContractDeployer(clientImpl)}, nil
+ return &MetisContractDeployer{NewEthereumContractDeployer(clientImpl, logger)}, nil
case *blockchain.OptimismClient:
- return &OptimismContractDeployer{NewEthereumContractDeployer(clientImpl)}, nil
+ return &OptimismContractDeployer{NewEthereumContractDeployer(clientImpl, logger)}, nil
case *blockchain.RSKClient:
- return &RSKContractDeployer{NewEthereumContractDeployer(clientImpl)}, nil
+ return &RSKContractDeployer{NewEthereumContractDeployer(clientImpl, logger)}, nil
case *blockchain.PolygonClient:
- return &PolygonContractDeployer{NewEthereumContractDeployer(clientImpl)}, nil
+ return &PolygonContractDeployer{NewEthereumContractDeployer(clientImpl, logger)}, nil
case *blockchain.CeloClient:
- return &CeloContractDeployer{NewEthereumContractDeployer(clientImpl)}, nil
+ return &CeloContractDeployer{NewEthereumContractDeployer(clientImpl, logger)}, nil
case *blockchain.QuorumClient:
- return &QuorumContractDeployer{NewEthereumContractDeployer(clientImpl)}, nil
+ return &QuorumContractDeployer{NewEthereumContractDeployer(clientImpl, logger)}, nil
case *blockchain.BSCClient:
- return &BSCContractDeployer{NewEthereumContractDeployer(clientImpl)}, nil
+ return &BSCContractDeployer{NewEthereumContractDeployer(clientImpl, logger)}, nil
case *blockchain.ScrollClient:
- return &ScrollContractDeployer{NewEthereumContractDeployer(clientImpl)}, nil
+ return &ScrollContractDeployer{NewEthereumContractDeployer(clientImpl, logger)}, nil
}
return nil, errors.New("unknown blockchain client implementation for contract deployer, register blockchain client in NewContractDeployer")
}
@@ -143,6 +151,7 @@ func NewContractDeployer(bcClient blockchain.EVMClient) (ContractDeployer, error
// EthereumContractDeployer provides the implementations for deploying ETH (EVM) based contracts
type EthereumContractDeployer struct {
client blockchain.EVMClient
+ l zerolog.Logger
}
// KlaytnContractDeployer wraps ethereum contract deployments for Klaytn
@@ -191,9 +200,10 @@ type ScrollContractDeployer struct {
}
// NewEthereumContractDeployer returns an instantiated instance of the ETH contract deployer
-func NewEthereumContractDeployer(ethClient blockchain.EVMClient) *EthereumContractDeployer {
+func NewEthereumContractDeployer(ethClient blockchain.EVMClient, logger zerolog.Logger) *EthereumContractDeployer {
return &EthereumContractDeployer{
client: ethClient,
+ l: logger,
}
}
@@ -346,6 +356,23 @@ func (e *EthereumContractDeployer) DeployStakingEventsMock() (StakingEventsMock,
}, nil
}
+func (e *EthereumContractDeployer) DeployFunctionsV1EventsMock() (FunctionsV1EventsMock, error) {
+ address, _, instance, err := e.client.DeployContract("FunctionsV1EventsMock", func(
+ auth *bind.TransactOpts,
+ backend bind.ContractBackend,
+ ) (common.Address, *types.Transaction, interface{}, error) {
+ return functions_v1_events_mock.DeployFunctionsV1EventsMock(auth, backend)
+ })
+ if err != nil {
+ return nil, err
+ }
+ return &EthereumFunctionsV1EventsMock{
+ client: e.client,
+ eventsMock: instance.(*functions_v1_events_mock.FunctionsV1EventsMock),
+ address: address,
+ }, nil
+}
+
func (e *EthereumContractDeployer) DeployKeeperRegistry11Mock() (KeeperRegistry11Mock, error) {
address, _, instance, err := e.client.DeployContract("KeeperRegistry11Mock", func(
auth *bind.TransactOpts,
@@ -430,6 +457,7 @@ func (e *EthereumContractDeployer) DeployLinkTokenContract() (LinkToken, error)
client: e.client,
instance: instance.(*link_token_interface.LinkToken),
address: *linkTokenAddress,
+ l: e.l,
}, err
}
@@ -448,6 +476,7 @@ func (e *EthereumContractDeployer) LoadLinkToken(address common.Address) (LinkTo
address: address,
client: e.client,
instance: instance.(*link_token_interface.LinkToken),
+ l: e.l,
}, err
}
@@ -530,6 +559,7 @@ func (e *EthereumContractDeployer) DeployOffChainAggregator(
client: e.client,
ocr: instance.(*offchainaggregator.OffchainAggregator),
address: address,
+ l: e.l,
}, err
}
@@ -548,6 +578,7 @@ func (e *EthereumContractDeployer) LoadOffChainAggregator(address *common.Addres
address: address,
client: e.client,
ocr: instance.(*offchainaggregator.OffchainAggregator),
+ l: e.l,
}, err
}
@@ -1402,5 +1433,6 @@ func (e *EthereumContractDeployer) DeployOffchainAggregatorV2(
client: e.client,
contract: instance.(*ocr2aggregator.OCR2Aggregator),
address: address,
+ l: e.l,
}, err
}
diff --git a/integration-tests/contracts/contract_loader.go b/integration-tests/contracts/contract_loader.go
index 7517ef7ba7e..a790747e38d 100644
--- a/integration-tests/contracts/contract_loader.go
+++ b/integration-tests/contracts/contract_loader.go
@@ -2,8 +2,10 @@ package contracts
import (
"errors"
+
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
+ "github.com/rs/zerolog"
"github.com/smartcontractkit/chainlink-testing-framework/blockchain"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/functions/generated/functions_coordinator"
@@ -12,6 +14,8 @@ 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/verifier"
+ "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/llo-feeds/generated/verifier_proxy"
)
// ContractLoader is an interface for abstracting the contract loading methods across network implementations
@@ -24,23 +28,27 @@ type ContractLoader interface {
LoadFunctionsCoordinator(addr string) (FunctionsCoordinator, error)
LoadFunctionsRouter(addr string) (FunctionsRouter, error)
LoadFunctionsLoadTestClient(addr string) (FunctionsLoadTestClient, error)
+
+ // Mercury
+ LoadMercuryVerifier(addr string) (MercuryVerifier, error)
+ LoadMercuryVerifierProxy(addr string) (MercuryVerifierProxy, error)
}
// NewContractLoader returns an instance of a contract Loader based on the client type
-func NewContractLoader(bcClient blockchain.EVMClient) (ContractLoader, error) {
+func NewContractLoader(bcClient blockchain.EVMClient, logger zerolog.Logger) (ContractLoader, error) {
switch clientImpl := bcClient.Get().(type) {
case *blockchain.EthereumClient:
- return NewEthereumContractLoader(clientImpl), nil
+ return NewEthereumContractLoader(clientImpl, logger), nil
case *blockchain.KlaytnClient:
- return &KlaytnContractLoader{NewEthereumContractLoader(clientImpl)}, nil
+ return &KlaytnContractLoader{NewEthereumContractLoader(clientImpl, logger)}, nil
case *blockchain.MetisClient:
- return &MetisContractLoader{NewEthereumContractLoader(clientImpl)}, nil
+ return &MetisContractLoader{NewEthereumContractLoader(clientImpl, logger)}, nil
case *blockchain.ArbitrumClient:
- return &ArbitrumContractLoader{NewEthereumContractLoader(clientImpl)}, nil
+ return &ArbitrumContractLoader{NewEthereumContractLoader(clientImpl, logger)}, nil
case *blockchain.PolygonClient:
- return &PolygonContractLoader{NewEthereumContractLoader(clientImpl)}, nil
+ return &PolygonContractLoader{NewEthereumContractLoader(clientImpl, logger)}, nil
case *blockchain.OptimismClient:
- return &OptimismContractLoader{NewEthereumContractLoader(clientImpl)}, nil
+ return &OptimismContractLoader{NewEthereumContractLoader(clientImpl, logger)}, nil
}
return nil, errors.New("unknown blockchain client implementation for contract Loader, register blockchain client in NewContractLoader")
}
@@ -48,6 +56,7 @@ func NewContractLoader(bcClient blockchain.EVMClient) (ContractLoader, error) {
// EthereumContractLoader provides the implementations for deploying ETH (EVM) based contracts
type EthereumContractLoader struct {
client blockchain.EVMClient
+ l zerolog.Logger
}
// KlaytnContractLoader wraps ethereum contract deployments for Klaytn
@@ -76,9 +85,10 @@ type OptimismContractLoader struct {
}
// NewEthereumContractLoader returns an instantiated instance of the ETH contract Loader
-func NewEthereumContractLoader(ethClient blockchain.EVMClient) *EthereumContractLoader {
+func NewEthereumContractLoader(ethClient blockchain.EVMClient, logger zerolog.Logger) *EthereumContractLoader {
return &EthereumContractLoader{
client: ethClient,
+ l: logger,
}
}
@@ -97,6 +107,7 @@ func (e *EthereumContractLoader) LoadLINKToken(addr string) (LinkToken, error) {
client: e.client,
instance: instance.(*link_token_interface.LinkToken),
address: common.HexToAddress(addr),
+ l: e.l,
}, err
}
@@ -133,6 +144,7 @@ func (e *EthereumContractLoader) LoadFunctionsRouter(addr string) (FunctionsRout
client: e.client,
instance: instance.(*functions_router.FunctionsRouter),
address: common.HexToAddress(addr),
+ l: e.l,
}, err
}
@@ -169,6 +181,7 @@ func (e *EthereumContractLoader) LoadOperatorContract(address common.Address) (O
address: address,
client: e.client,
operator: instance.(*operator_wrapper.Operator),
+ l: e.l,
}, err
}
@@ -189,3 +202,39 @@ func (e *EthereumContractLoader) LoadAuthorizedForwarder(address common.Address)
authorizedForwarder: instance.(*authorized_forwarder.AuthorizedForwarder),
}, err
}
+
+// 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(
+ address common.Address,
+ backend bind.ContractBackend,
+ ) (interface{}, error) {
+ return verifier.NewVerifier(address, backend)
+ })
+ if err != nil {
+ return nil, err
+ }
+ return &EthereumMercuryVerifier{
+ client: e.client,
+ instance: instance.(*verifier.Verifier),
+ address: common.HexToAddress(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(
+ address common.Address,
+ backend bind.ContractBackend,
+ ) (interface{}, error) {
+ return verifier_proxy.NewVerifierProxy(address, backend)
+ })
+ if err != nil {
+ return nil, err
+ }
+ return &EthereumMercuryVerifierProxy{
+ client: e.client,
+ instance: instance.(*verifier_proxy.VerifierProxy),
+ address: common.HexToAddress(addr),
+ }, err
+}
diff --git a/integration-tests/contracts/contract_models.go b/integration-tests/contracts/contract_models.go
index 9af61d7d880..9f1130dce9f 100644
--- a/integration-tests/contracts/contract_models.go
+++ b/integration-tests/contracts/contract_models.go
@@ -286,6 +286,21 @@ type KeeperGasWrapperMock interface {
SetMeasureCheckGasResult(result bool, payload []byte, gas *big.Int) error
}
+type FunctionsV1EventsMock interface {
+ Address() string
+ EmitRequestProcessed(requestId [32]byte, subscriptionId uint64, totalCostJuels *big.Int, transmitter common.Address, resultCode uint8, response []byte, errByte []byte, callbackReturnData []byte) error
+ EmitRequestStart(requestId [32]byte, donId [32]byte, subscriptionId uint64, subscriptionOwner common.Address, requestingContract common.Address, requestInitiator common.Address, data []byte, dataVersion uint16, callbackGasLimit uint32, estimatedTotalCostJuels *big.Int) error
+ EmitSubscriptionCanceled(subscriptionId uint64, fundsRecipient common.Address, fundsAmount *big.Int) error
+ EmitSubscriptionConsumerAdded(subscriptionId uint64, consumer common.Address) error
+ EmitSubscriptionConsumerRemoved(subscriptionId uint64, consumer common.Address) error
+ EmitSubscriptionCreated(subscriptionId uint64, owner common.Address) error
+ EmitSubscriptionFunded(subscriptionId uint64, oldBalance *big.Int, newBalance *big.Int) error
+ EmitSubscriptionOwnerTransferred(subscriptionId uint64, from common.Address, to common.Address) error
+ EmitSubscriptionOwnerTransferRequested(subscriptionId uint64, from common.Address, to common.Address) error
+ EmitRequestNotProcessed(requestId [32]byte, coordinator common.Address, transmitter common.Address, resultCode uint8) error
+ EmitContractUpdated(id [32]byte, from common.Address, to common.Address) error
+}
+
type MockAggregatorProxy interface {
Address() string
UpdateAggregator(aggregator common.Address) error
@@ -336,6 +351,8 @@ type AuthorizedForwarder interface {
type FunctionsCoordinator interface {
Address() string
+ GetThresholdPublicKey() ([]byte, error)
+ GetDONPublicKey() ([]byte, error)
}
type FunctionsRouter interface {
@@ -345,5 +362,19 @@ type FunctionsRouter interface {
type FunctionsLoadTestClient interface {
Address() string
- SendRequest(source string, encryptedSecretsReferences []byte, args []string, subscriptionId uint64, jobId [32]byte) error
+ ResetStats() error
+ GetStats() (*EthereumFunctionsLoadStats, error)
+ SendRequest(times uint32, source string, encryptedSecretsReferences []byte, args []string, subscriptionId uint64, jobId [32]byte) error
+ SendRequestWithDONHostedSecrets(times uint32, source string, slotID uint8, slotVersion uint64, args []string, subscriptionId uint64, donID [32]byte) error
+}
+
+type MercuryVerifier interface {
+ Address() string
+ Verify(signedReport []byte, sender common.Address) error
+}
+
+type MercuryVerifierProxy interface {
+ Address() string
+ Verify(signedReport []byte, parameterPayload []byte, value *big.Int) (*types.Transaction, error)
+ VerifyBulk(signedReports [][]byte, parameterPayload []byte, value *big.Int) (*types.Transaction, error)
}
diff --git a/integration-tests/contracts/contract_vrf_models.go b/integration-tests/contracts/contract_vrf_models.go
index 93ced8a3ea0..0d302215bea 100644
--- a/integration-tests/contracts/contract_vrf_models.go
+++ b/integration-tests/contracts/contract_vrf_models.go
@@ -2,9 +2,15 @@ package contracts
import (
"context"
+
"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"
@@ -50,6 +56,80 @@ type VRFCoordinatorV2 interface {
GetSubscription(ctx context.Context, subID uint64) (vrf_coordinator_v2.GetSubscription, error)
}
+type VRFCoordinatorV2_5 interface {
+ SetLINKAndLINKNativeFeed(
+ link string,
+ linkNativeFeed string,
+ ) error
+ SetConfig(
+ minimumRequestConfirmations uint16,
+ maxGasLimit uint32,
+ stalenessSeconds uint32,
+ gasAfterPaymentCalculation uint32,
+ fallbackWeiPerUnitLink *big.Int,
+ feeConfig vrf_coordinator_v2_5.VRFCoordinatorV25FeeConfig,
+ ) error
+ RegisterProvingKey(
+ oracleAddr string,
+ publicProvingKey [2]*big.Int,
+ ) error
+ HashOfKey(ctx context.Context, pubKey [2]*big.Int) ([32]byte, error)
+ CreateSubscription() error
+ GetActiveSubscriptionIds(ctx context.Context, startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error)
+ Migrate(subId *big.Int, coordinatorAddress string) error
+ RegisterMigratableCoordinator(migratableCoordinatorAddress string) error
+ AddConsumer(subId *big.Int, consumerAddress string) error
+ FundSubscriptionWithNative(subId *big.Int, nativeTokenAmount *big.Int) error
+ Address() string
+ 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_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 {
+ SetLINKAndLINKNativeFeed(
+ link string,
+ linkNativeFeed string,
+ ) error
+ SetConfig(
+ minimumRequestConfirmations uint16,
+ maxGasLimit uint32,
+ stalenessSeconds uint32,
+ gasAfterPaymentCalculation uint32,
+ fallbackWeiPerUnitLink *big.Int,
+ feeConfig vrf_v2plus_upgraded_version.VRFCoordinatorV2PlusUpgradedVersionFeeConfig,
+ ) error
+ RegisterProvingKey(
+ oracleAddr string,
+ publicProvingKey [2]*big.Int,
+ ) error
+ HashOfKey(ctx context.Context, pubKey [2]*big.Int) ([32]byte, error)
+ CreateSubscription() error
+ GetNativeTokenTotalBalance(ctx context.Context) (*big.Int, error)
+ GetLinkTotalBalance(ctx context.Context) (*big.Int, error)
+ Migrate(subId *big.Int, coordinatorAddress string) error
+ RegisterMigratableCoordinator(migratableCoordinatorAddress string) error
+ AddConsumer(subId *big.Int, consumerAddress string) 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)
+ FindSubscriptionID() (*big.Int, error)
+ WaitForRandomWordsFulfilledEvent(subID []*big.Int, requestID []*big.Int, timeout time.Duration) (*vrf_v2plus_upgraded_version.VRFCoordinatorV2PlusUpgradedVersionRandomWordsFulfilled, error)
+ WaitForMigrationCompletedEvent(timeout time.Duration) (*vrf_v2plus_upgraded_version.VRFCoordinatorV2PlusUpgradedVersionMigrationCompleted, error)
+ 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) error
+ GetSubID(ctx context.Context) (*big.Int, error)
+}
+
type VRFConsumer interface {
Address() string
RequestRandomness(hash [32]byte, fee *big.Int) error
@@ -85,6 +165,26 @@ type VRFv2LoadTestConsumer interface {
GetLoadTestMetrics(ctx context.Context) (*VRFLoadTestMetrics, error)
}
+type VRFv2PlusLoadTestConsumer interface {
+ Address() string
+ RequestRandomness(keyHash [32]byte, subID *big.Int, requestConfirmations uint16, callbackGasLimit uint32, nativePayment bool, numWords uint32, requestCount uint16) (*types.Transaction, error)
+ GetRequestStatus(ctx context.Context, requestID *big.Int) (vrf_v2plus_load_test_with_metrics.GetRequestStatus, error)
+ GetLastRequestId(ctx context.Context) (*big.Int, error)
+ GetLoadTestMetrics(ctx context.Context) (*VRFLoadTestMetrics, error)
+ 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 e419a02e578..d3db6913c50 100644
--- a/integration-tests/contracts/ethereum_contracts.go
+++ b/integration-tests/contracts/ethereum_contracts.go
@@ -11,6 +11,7 @@ import (
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
+ "github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"github.com/smartcontractkit/chainlink-testing-framework/blockchain"
"github.com/smartcontractkit/libocr/gethwrappers/offchainaggregator"
@@ -18,14 +19,17 @@ import (
ocrConfigHelper "github.com/smartcontractkit/libocr/offchainreporting/confighelper"
ocrTypes "github.com/smartcontractkit/libocr/offchainreporting/types"
+ "strings"
+
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/pkg/errors"
+
"github.com/smartcontractkit/chainlink/integration-tests/client"
eth_contracts "github.com/smartcontractkit/chainlink/integration-tests/contracts/ethereum"
- "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/functions/generated/functions_client_example"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/functions/generated/functions_coordinator"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/functions/generated/functions_load_test_client"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/functions/generated/functions_router"
+ "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/functions/generated/functions_v1_events_mock"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/authorized_forwarder"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/flags_wrapper"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/flux_aggregator_wrapper"
@@ -43,7 +47,8 @@ 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"
- "strings"
+ "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/llo-feeds/generated/verifier"
+ "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/llo-feeds/generated/verifier_proxy"
)
// EthereumOracle oracle for "directrequest" job tests
@@ -738,6 +743,149 @@ func (f *EthereumKeeperGasWrapperMock) SetMeasureCheckGasResult(result bool, pay
return f.client.ProcessTransaction(tx)
}
+// EthereumFunctionsV1EventsMock represents the basic functions v1 events mock contract
+type EthereumFunctionsV1EventsMock struct {
+ client blockchain.EVMClient
+ eventsMock *functions_v1_events_mock.FunctionsV1EventsMock
+ address *common.Address
+}
+
+func (f *EthereumFunctionsV1EventsMock) Address() string {
+ return f.address.Hex()
+}
+
+func (f *EthereumFunctionsV1EventsMock) EmitRequestProcessed(requestId [32]byte, subscriptionId uint64, totalCostJuels *big.Int, transmitter common.Address, resultCode uint8, response []byte, errByte []byte, callbackReturnData []byte) error {
+ opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet())
+ if err != nil {
+ return err
+ }
+ tx, err := f.eventsMock.EmitRequestProcessed(opts, requestId, subscriptionId, totalCostJuels, transmitter, resultCode, response, errByte, callbackReturnData)
+ if err != nil {
+ return err
+ }
+ return f.client.ProcessTransaction(tx)
+}
+
+func (f *EthereumFunctionsV1EventsMock) EmitRequestStart(requestId [32]byte, donId [32]byte, subscriptionId uint64, subscriptionOwner common.Address, requestingContract common.Address, requestInitiator common.Address, data []byte, dataVersion uint16, callbackGasLimit uint32, estimatedTotalCostJuels *big.Int) error {
+ opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet())
+ if err != nil {
+ return err
+ }
+ tx, err := f.eventsMock.EmitRequestStart(opts, requestId, donId, subscriptionId, subscriptionOwner, requestingContract, requestInitiator, data, dataVersion, callbackGasLimit, estimatedTotalCostJuels)
+ if err != nil {
+ return err
+ }
+ return f.client.ProcessTransaction(tx)
+}
+
+func (f *EthereumFunctionsV1EventsMock) EmitSubscriptionCanceled(subscriptionId uint64, fundsRecipient common.Address, fundsAmount *big.Int) error {
+ opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet())
+ if err != nil {
+ return err
+ }
+ tx, err := f.eventsMock.EmitSubscriptionCanceled(opts, subscriptionId, fundsRecipient, fundsAmount)
+ if err != nil {
+ return err
+ }
+ return f.client.ProcessTransaction(tx)
+}
+
+func (f *EthereumFunctionsV1EventsMock) EmitSubscriptionConsumerAdded(subscriptionId uint64, consumer common.Address) error {
+ opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet())
+ if err != nil {
+ return err
+ }
+ tx, err := f.eventsMock.EmitSubscriptionConsumerAdded(opts, subscriptionId, consumer)
+ if err != nil {
+ return err
+ }
+ return f.client.ProcessTransaction(tx)
+}
+
+func (f *EthereumFunctionsV1EventsMock) EmitSubscriptionConsumerRemoved(subscriptionId uint64, consumer common.Address) error {
+ opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet())
+ if err != nil {
+ return err
+ }
+ tx, err := f.eventsMock.EmitSubscriptionConsumerRemoved(opts, subscriptionId, consumer)
+ if err != nil {
+ return err
+ }
+ return f.client.ProcessTransaction(tx)
+}
+
+func (f *EthereumFunctionsV1EventsMock) EmitSubscriptionCreated(subscriptionId uint64, owner common.Address) error {
+ opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet())
+ if err != nil {
+ return err
+ }
+ tx, err := f.eventsMock.EmitSubscriptionCreated(opts, subscriptionId, owner)
+ if err != nil {
+ return err
+ }
+ return f.client.ProcessTransaction(tx)
+}
+
+func (f *EthereumFunctionsV1EventsMock) EmitSubscriptionFunded(subscriptionId uint64, oldBalance *big.Int, newBalance *big.Int) error {
+ opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet())
+ if err != nil {
+ return err
+ }
+ tx, err := f.eventsMock.EmitSubscriptionFunded(opts, subscriptionId, oldBalance, newBalance)
+ if err != nil {
+ return err
+ }
+ return f.client.ProcessTransaction(tx)
+}
+
+func (f *EthereumFunctionsV1EventsMock) EmitSubscriptionOwnerTransferred(subscriptionId uint64, from common.Address, to common.Address) error {
+ opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet())
+ if err != nil {
+ return err
+ }
+ tx, err := f.eventsMock.EmitSubscriptionOwnerTransferred(opts, subscriptionId, from, to)
+ if err != nil {
+ return err
+ }
+ return f.client.ProcessTransaction(tx)
+}
+
+func (f *EthereumFunctionsV1EventsMock) EmitSubscriptionOwnerTransferRequested(subscriptionId uint64, from common.Address, to common.Address) error {
+ opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet())
+ if err != nil {
+ return err
+ }
+ tx, err := f.eventsMock.EmitSubscriptionOwnerTransferRequested(opts, subscriptionId, from, to)
+ if err != nil {
+ return err
+ }
+ return f.client.ProcessTransaction(tx)
+}
+
+func (f *EthereumFunctionsV1EventsMock) EmitRequestNotProcessed(requestId [32]byte, coordinator common.Address, transmitter common.Address, resultCode uint8) error {
+ opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet())
+ if err != nil {
+ return err
+ }
+ tx, err := f.eventsMock.EmitRequestNotProcessed(opts, requestId, coordinator, transmitter, resultCode)
+ if err != nil {
+ return err
+ }
+ return f.client.ProcessTransaction(tx)
+}
+
+func (f *EthereumFunctionsV1EventsMock) EmitContractUpdated(id [32]byte, from common.Address, to common.Address) error {
+ opts, err := f.client.TransactionOpts(f.client.GetDefaultWallet())
+ if err != nil {
+ return err
+ }
+ tx, err := f.eventsMock.EmitContractUpdated(opts, id, from, to)
+ if err != nil {
+ return err
+ }
+ return f.client.ProcessTransaction(tx)
+}
+
// EthereumFluxAggregator represents the basic flux aggregation contract
type EthereumFluxAggregator struct {
client blockchain.EVMClient
@@ -968,6 +1116,7 @@ type FluxAggregatorRoundConfirmer struct {
context context.Context
cancel context.CancelFunc
complete bool
+ l zerolog.Logger
}
// NewFluxAggregatorRoundConfirmer provides a new instance of a FluxAggregatorRoundConfirmer
@@ -975,6 +1124,7 @@ func NewFluxAggregatorRoundConfirmer(
contract FluxAggregator,
roundID *big.Int,
timeout time.Duration,
+ logger zerolog.Logger,
) *FluxAggregatorRoundConfirmer {
ctx, ctxCancel := context.WithTimeout(context.Background(), timeout)
return &FluxAggregatorRoundConfirmer{
@@ -983,6 +1133,7 @@ func NewFluxAggregatorRoundConfirmer(
doneChan: make(chan struct{}),
context: ctx,
cancel: ctxCancel,
+ l: logger,
}
}
@@ -1002,11 +1153,11 @@ func (f *FluxAggregatorRoundConfirmer) ReceiveHeader(header blockchain.NodeHeade
"Header Number": header.Number.Uint64(),
}
if lr.Cmp(f.roundID) >= 0 {
- log.Info().Fields(logFields).Msg("FluxAggregator round completed")
+ f.l.Info().Fields(logFields).Msg("FluxAggregator round completed")
f.complete = true
f.doneChan <- struct{}{}
} else {
- log.Debug().Fields(logFields).Msg("Waiting for FluxAggregator round")
+ f.l.Debug().Fields(logFields).Msg("Waiting for FluxAggregator round")
}
return nil
}
@@ -1034,6 +1185,7 @@ type EthereumLinkToken struct {
client blockchain.EVMClient
instance *link_token_interface.LinkToken
address common.Address
+ l zerolog.Logger
}
// Fund the LINK Token contract with ETH to distribute the token
@@ -1075,7 +1227,7 @@ func (l *EthereumLinkToken) Approve(to string, amount *big.Int) error {
if err != nil {
return err
}
- log.Info().
+ l.l.Info().
Str("From", l.client.GetDefaultWallet().Address()).
Str("To", to).
Str("Amount", amount.String()).
@@ -1093,7 +1245,7 @@ func (l *EthereumLinkToken) Transfer(to string, amount *big.Int) error {
if err != nil {
return err
}
- log.Info().
+ l.l.Info().
Str("From", l.client.GetDefaultWallet().Address()).
Str("To", to).
Str("Amount", amount.String()).
@@ -1115,7 +1267,7 @@ func (l *EthereumLinkToken) TransferAndCall(to string, amount *big.Int, data []b
if err != nil {
return nil, err
}
- log.Info().
+ l.l.Info().
Str("From", l.client.GetDefaultWallet().Address()).
Str("To", to).
Str("Amount", amount.String()).
@@ -1130,6 +1282,7 @@ type EthereumOffchainAggregator struct {
client blockchain.EVMClient
ocr *offchainaggregator.OffchainAggregator
address *common.Address
+ l zerolog.Logger
}
// Fund sends specified currencies to the contract
@@ -1175,7 +1328,7 @@ func (o *EthereumOffchainAggregator) SetPayees(
payeesAddr = append(payeesAddr, common.HexToAddress(p))
}
- log.Info().
+ o.l.Info().
Str("Transmitters", fmt.Sprintf("%v", transmitters)).
Str("Payees", fmt.Sprintf("%v", payees)).
Str("OCR Address", o.Address()).
@@ -1283,7 +1436,7 @@ func (o *EthereumOffchainAggregator) RequestNewRound() error {
if err != nil {
return err
}
- log.Info().Str("Contract Address", o.address.Hex()).Msg("New OCR round requested")
+ o.l.Info().Str("Contract Address", o.address.Hex()).Msg("New OCR round requested")
return o.client.ProcessTransaction(tx)
}
@@ -1365,6 +1518,7 @@ type RunlogRoundConfirmer struct {
doneChan chan struct{}
context context.Context
cancel context.CancelFunc
+ l zerolog.Logger
}
// NewRunlogRoundConfirmer provides a new instance of a RunlogRoundConfirmer
@@ -1372,6 +1526,7 @@ func NewRunlogRoundConfirmer(
contract APIConsumer,
roundID *big.Int,
timeout time.Duration,
+ logger zerolog.Logger,
) *RunlogRoundConfirmer {
ctx, ctxCancel := context.WithTimeout(context.Background(), timeout)
return &RunlogRoundConfirmer{
@@ -1380,6 +1535,7 @@ func NewRunlogRoundConfirmer(
doneChan: make(chan struct{}),
context: ctx,
cancel: ctxCancel,
+ l: logger,
}
}
@@ -1395,10 +1551,10 @@ func (o *RunlogRoundConfirmer) ReceiveHeader(_ blockchain.NodeHeader) error {
"Waiting for Round": o.roundID.Int64(),
}
if currentRoundID.Cmp(o.roundID) >= 0 {
- log.Info().Fields(logFields).Msg("Runlog round completed")
+ o.l.Info().Fields(logFields).Msg("Runlog round completed")
o.doneChan <- struct{}{}
} else {
- log.Debug().Fields(logFields).Msg("Waiting for Runlog round")
+ o.l.Debug().Fields(logFields).Msg("Waiting for Runlog round")
}
return nil
}
@@ -1425,6 +1581,7 @@ type OffchainAggregatorRoundConfirmer struct {
cancel context.CancelFunc
blocksSinceAnswer uint
complete bool
+ l zerolog.Logger
}
// NewOffchainAggregatorRoundConfirmer provides a new instance of a OffchainAggregatorRoundConfirmer
@@ -1432,6 +1589,7 @@ func NewOffchainAggregatorRoundConfirmer(
contract OffchainAggregator,
roundID *big.Int,
timeout time.Duration,
+ logger zerolog.Logger,
) *OffchainAggregatorRoundConfirmer {
ctx, ctxCancel := context.WithTimeout(context.Background(), timeout)
return &OffchainAggregatorRoundConfirmer{
@@ -1441,6 +1599,7 @@ func NewOffchainAggregatorRoundConfirmer(
context: ctx,
cancel: ctxCancel,
complete: false,
+ l: logger,
}
}
@@ -1462,11 +1621,11 @@ func (o *OffchainAggregatorRoundConfirmer) ReceiveHeader(_ blockchain.NodeHeader
"Waiting for Round": o.roundID.Int64(),
}
if currRound.Cmp(o.roundID) >= 0 {
- log.Info().Fields(logFields).Msg("OCR round completed")
+ o.l.Info().Fields(logFields).Msg("OCR round completed")
o.doneChan <- struct{}{}
o.complete = true
} else {
- log.Debug().Fields(logFields).Msg("Waiting on OCR Round")
+ o.l.Debug().Fields(logFields).Msg("Waiting on OCR Round")
}
return nil
}
@@ -1499,6 +1658,7 @@ type OffchainAggregatorV2RoundConfirmer struct {
cancel context.CancelFunc
blocksSinceAnswer uint
complete bool
+ l zerolog.Logger
}
// NewOffchainAggregatorRoundConfirmer provides a new instance of a OffchainAggregatorRoundConfirmer
@@ -1506,6 +1666,7 @@ func NewOffchainAggregatorV2RoundConfirmer(
contract OffchainAggregatorV2,
roundID *big.Int,
timeout time.Duration,
+ logger zerolog.Logger,
) *OffchainAggregatorV2RoundConfirmer {
ctx, ctxCancel := context.WithTimeout(context.Background(), timeout)
return &OffchainAggregatorV2RoundConfirmer{
@@ -1515,6 +1676,7 @@ func NewOffchainAggregatorV2RoundConfirmer(
context: ctx,
cancel: ctxCancel,
complete: false,
+ l: logger,
}
}
@@ -1536,11 +1698,11 @@ func (o *OffchainAggregatorV2RoundConfirmer) ReceiveHeader(_ blockchain.NodeHead
"Waiting for Round": o.roundID.Int64(),
}
if currRound.Cmp(o.roundID) >= 0 {
- log.Info().Fields(logFields).Msg("OCR round completed")
+ o.l.Info().Fields(logFields).Msg("OCR round completed")
o.doneChan <- struct{}{}
o.complete = true
} else {
- log.Debug().Fields(logFields).Msg("Waiting on OCR Round")
+ o.l.Debug().Fields(logFields).Msg("Waiting on OCR Round")
}
return nil
}
@@ -1668,6 +1830,7 @@ type EthereumOperator struct {
address common.Address
client blockchain.EVMClient
operator *operator_wrapper.Operator
+ l zerolog.Logger
}
func (e *EthereumOperator) Address() string {
@@ -1679,7 +1842,7 @@ func (e *EthereumOperator) AcceptAuthorizedReceivers(forwarders []common.Address
if err != nil {
return err
}
- log.Info().
+ e.l.Info().
Str("ForwardersAddresses", fmt.Sprint(forwarders)).
Str("EoaAddresses", fmt.Sprint(eoa)).
Msg("Accepting Authorized Receivers")
@@ -1776,6 +1939,7 @@ type EthereumOffchainAggregatorV2 struct {
address *common.Address
client blockchain.EVMClient
contract *ocr2aggregator.OCR2Aggregator
+ l zerolog.Logger
}
// OCRv2Config represents the config for the OCRv2 contract
@@ -1861,7 +2025,7 @@ func (e *EthereumOffchainAggregatorV2) SetPayees(transmitters, payees []string)
if err != nil {
return err
}
- log.Info().
+ e.l.Info().
Str("Transmitters", fmt.Sprintf("%v", transmitters)).
Str("Payees", fmt.Sprintf("%v", payees)).
Str("OCRv2 Address", e.Address()).
@@ -1887,7 +2051,7 @@ func (e *EthereumOffchainAggregatorV2) SetConfig(ocrConfig *OCRv2Config) error {
if err != nil {
return err
}
- log.Info().
+ e.l.Info().
Str("Address", e.Address()).
Interface("Signers", ocrConfig.Signers).
Interface("Transmitters", ocrConfig.Transmitters).
@@ -1944,6 +2108,7 @@ type EthereumFunctionsRouter struct {
address common.Address
client blockchain.EVMClient
instance *functions_router.FunctionsRouter
+ l zerolog.Logger
}
func (e *EthereumFunctionsRouter) Address() string {
@@ -1967,7 +2132,7 @@ func (e *EthereumFunctionsRouter) CreateSubscriptionWithConsumer(consumer string
return 0, err
}
for _, l := range r.Logs {
- log.Warn().Interface("Log", common.Bytes2Hex(l.Data)).Send()
+ e.l.Info().Interface("Log", common.Bytes2Hex(l.Data)).Send()
}
topicsMap := map[string]interface{}{}
@@ -1976,14 +2141,14 @@ func (e *EthereumFunctionsRouter) CreateSubscriptionWithConsumer(consumer string
return 0, err
}
for _, ev := range fabi.Events {
- log.Warn().Str("EventName", ev.Name).Send()
+ e.l.Info().Str("EventName", ev.Name).Send()
}
topicOneInputs := abi.Arguments{fabi.Events["SubscriptionCreated"].Inputs[0]}
topicOneHash := []common.Hash{r.Logs[0].Topics[1:][0]}
if err := abi.ParseTopicsIntoMap(topicsMap, topicOneInputs, topicOneHash); err != nil {
return 0, errors.Wrap(err, "failed to decode topic value")
}
- log.Warn().Interface("NewTopicsDecoded", topicsMap).Send()
+ e.l.Info().Interface("NewTopicsDecoded", topicsMap).Send()
if topicsMap["subscriptionId"] == 0 {
return 0, errors.New("failed to decode subscription ID after creation")
}
@@ -1996,6 +2161,22 @@ type EthereumFunctionsCoordinator struct {
instance *functions_coordinator.FunctionsCoordinator
}
+func (e *EthereumFunctionsCoordinator) GetThresholdPublicKey() ([]byte, error) {
+ opts := &bind.CallOpts{
+ From: common.HexToAddress(e.client.GetDefaultWallet().Address()),
+ Context: context.Background(),
+ }
+ return e.instance.GetThresholdPublicKey(opts)
+}
+
+func (e *EthereumFunctionsCoordinator) GetDONPublicKey() ([]byte, error) {
+ opts := &bind.CallOpts{
+ From: common.HexToAddress(e.client.GetDefaultWallet().Address()),
+ Context: context.Background(),
+ }
+ return e.instance.GetDONPublicKey(opts)
+}
+
func (e *EthereumFunctionsCoordinator) Address() string {
return e.address.Hex()
}
@@ -2010,19 +2191,138 @@ func (e *EthereumFunctionsLoadTestClient) Address() string {
return e.address.Hex()
}
-func (e *EthereumFunctionsLoadTestClient) SendRequest(source string, encryptedSecretsReferences []byte, args []string, subscriptionId uint64, jobId [32]byte) error {
+type EthereumFunctionsLoadStats struct {
+ LastRequestID string
+ LastResponse string
+ LastError string
+ Total uint32
+ Succeeded uint32
+ Errored uint32
+ Empty uint32
+}
+
+func Bytes32ToSlice(a [32]byte) (r []byte) {
+ r = append(r, a[:]...)
+ return
+}
+
+func (e *EthereumFunctionsLoadTestClient) GetStats() (*EthereumFunctionsLoadStats, error) {
+ opts := &bind.CallOpts{
+ From: common.HexToAddress(e.client.GetDefaultWallet().Address()),
+ Context: context.Background(),
+ }
+ lr, lbody, lerr, total, succeeded, errored, empty, err := e.instance.GetStats(opts)
+ if err != nil {
+ return nil, err
+ }
+ return &EthereumFunctionsLoadStats{
+ LastRequestID: string(Bytes32ToSlice(lr)),
+ LastResponse: string(lbody),
+ LastError: string(lerr),
+ Total: total,
+ Succeeded: succeeded,
+ Errored: errored,
+ Empty: empty,
+ }, nil
+}
+
+func (e *EthereumFunctionsLoadTestClient) ResetStats() error {
opts, err := e.client.TransactionOpts(e.client.GetDefaultWallet())
if err != nil {
return err
}
- tx, err := e.instance.SendRequest(opts, source, encryptedSecretsReferences, args, subscriptionId, jobId)
+ tx, err := e.instance.ResetStats(opts)
if err != nil {
return err
}
if err := e.client.ProcessTransaction(tx); err != nil {
return err
}
- revertReason, _, _ := e.client.RevertReasonFromTx(tx.Hash(), functions_client_example.FunctionsClientExampleABI)
- log.Debug().Str("RevertReason", revertReason).Send()
return nil
}
+
+func (e *EthereumFunctionsLoadTestClient) SendRequest(times uint32, source string, encryptedSecretsReferences []byte, args []string, subscriptionId uint64, jobId [32]byte) error {
+ opts, err := e.client.TransactionOpts(e.client.GetDefaultWallet())
+ if err != nil {
+ return err
+ }
+ tx, err := e.instance.SendRequest(opts, times, source, encryptedSecretsReferences, args, subscriptionId, jobId)
+ if err != nil {
+ return err
+ }
+ return e.client.ProcessTransaction(tx)
+}
+
+func (e *EthereumFunctionsLoadTestClient) SendRequestWithDONHostedSecrets(times uint32, source string, slotID uint8, slotVersion uint64, args []string, subscriptionId uint64, donID [32]byte) error {
+ opts, err := e.client.TransactionOpts(e.client.GetDefaultWallet())
+ if err != nil {
+ return err
+ }
+ tx, err := e.instance.SendRequestWithDONHostedSecrets(opts, times, source, slotID, slotVersion, args, subscriptionId, donID)
+ if err != nil {
+ return err
+ }
+ return e.client.ProcessTransaction(tx)
+}
+
+type EthereumMercuryVerifier struct {
+ address common.Address
+ client blockchain.EVMClient
+ instance *verifier.Verifier
+}
+
+func (e *EthereumMercuryVerifier) Address() string {
+ return e.address.Hex()
+}
+
+func (e *EthereumMercuryVerifier) Verify(signedReport []byte, sender common.Address) error {
+ opts, err := e.client.TransactionOpts(e.client.GetDefaultWallet())
+ if err != nil {
+ return err
+ }
+ tx, err := e.instance.Verify(opts, signedReport, sender)
+ if err != nil {
+ return err
+ }
+ return e.client.ProcessTransaction(tx)
+}
+
+type EthereumMercuryVerifierProxy struct {
+ address common.Address
+ client blockchain.EVMClient
+ instance *verifier_proxy.VerifierProxy
+}
+
+func (e *EthereumMercuryVerifierProxy) Address() string {
+ return e.address.Hex()
+}
+
+func (e *EthereumMercuryVerifierProxy) Verify(signedReport []byte, parameterPayload []byte, value *big.Int) (*types.Transaction, error) {
+ opts, err := e.client.TransactionOpts(e.client.GetDefaultWallet())
+ if value != nil {
+ opts.Value = value
+ }
+ if err != nil {
+ return nil, err
+ }
+ tx, err := e.instance.Verify(opts, parameterPayload, signedReport)
+ if err != nil {
+ return nil, err
+ }
+ return tx, e.client.ProcessTransaction(tx)
+}
+
+func (e *EthereumMercuryVerifierProxy) VerifyBulk(signedReports [][]byte, parameterPayload []byte, value *big.Int) (*types.Transaction, error) {
+ opts, err := e.client.TransactionOpts(e.client.GetDefaultWallet())
+ if value != nil {
+ opts.Value = value
+ }
+ if err != nil {
+ return nil, err
+ }
+ tx, err := e.instance.VerifyBulk(opts, signedReports, parameterPayload)
+ if err != nil {
+ return nil, err
+ }
+ return tx, e.client.ProcessTransaction(tx)
+}
diff --git a/integration-tests/contracts/ethereum_keeper_contracts.go b/integration-tests/contracts/ethereum_keeper_contracts.go
index 0d21fd9e739..afb6550bd2c 100644
--- a/integration-tests/contracts/ethereum_keeper_contracts.go
+++ b/integration-tests/contracts/ethereum_keeper_contracts.go
@@ -15,7 +15,7 @@ import (
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
- "github.com/rs/zerolog/log"
+ "github.com/rs/zerolog"
"github.com/smartcontractkit/chainlink-testing-framework/blockchain"
goabi "github.com/umbracle/ethgo/abi"
@@ -68,6 +68,7 @@ type KeeperRegistry interface {
CancelUpkeep(id *big.Int) error
SetUpkeepGasLimit(id *big.Int, gas uint32) error
ParseUpkeepPerformedLog(log *types.Log) (*UpkeepPerformedLog, error)
+ ParseStaleUpkeepReportLog(log *types.Log) (*StaleUpkeepReportLog, error)
ParseUpkeepIdFromRegisteredLog(log *types.Log) (*big.Int, error)
Pause() error
Migrate(upkeepIDs []*big.Int, destinationAddress common.Address) error
@@ -75,6 +76,7 @@ type KeeperRegistry interface {
PauseUpkeep(id *big.Int) error
UnpauseUpkeep(id *big.Int) error
UpdateCheckData(id *big.Int, newCheckData []byte) error
+ SetUpkeepTriggerConfig(id *big.Int, triggerConfig []byte) error
}
type KeeperConsumer interface {
@@ -130,6 +132,10 @@ type UpkeepPerformedLog struct {
From common.Address
}
+type StaleUpkeepReportLog struct {
+ Id *big.Int
+}
+
// KeeperRegistryOpts opts to deploy keeper registry version
type KeeperRegistryOpts struct {
RegistryVersion ethereum.KeeperRegistryVersion
@@ -198,6 +204,7 @@ type EthereumKeeperRegistry struct {
registry2_0 *keeper_registry_wrapper2_0.KeeperRegistry
registry2_1 *i_keeper_registry_master_wrapper_2_1.IKeeperRegistryMaster
address *common.Address
+ l zerolog.Logger
}
func (v *EthereumKeeperRegistry) Address() string {
@@ -396,6 +403,12 @@ func (v *EthereumKeeperRegistry) Pause() error {
return err
}
return v.client.ProcessTransaction(tx)
+ case ethereum.RegistryVersion_2_1:
+ tx, err = v.registry2_1.Pause(txOpts)
+ if err != nil {
+ return err
+ }
+ return v.client.ProcessTransaction(tx)
}
return fmt.Errorf("keeper registry version %d is not supported", v.version)
@@ -507,6 +520,8 @@ func (v *EthereumKeeperRegistry) AddUpkeepFunds(id *big.Int, amount *big.Int) er
tx, err = v.registry1_3.AddFunds(opts, id, amount)
case ethereum.RegistryVersion_2_0:
tx, err = v.registry2_0.AddFunds(opts, id, amount)
+ case ethereum.RegistryVersion_2_1:
+ tx, err = v.registry2_1.AddFunds(opts, id, amount)
}
if err != nil {
@@ -582,6 +597,23 @@ func (v *EthereumKeeperRegistry) GetUpkeepInfo(ctx context.Context, id *big.Int)
Paused: uk.Paused,
OffchainConfig: uk.OffchainConfig,
}, nil
+ case ethereum.RegistryVersion_2_1:
+ uk, err := v.registry2_1.GetUpkeep(opts, id)
+ if err != nil {
+ return nil, err
+ }
+ return &UpkeepInfo{
+ Target: uk.Target.Hex(),
+ ExecuteGas: uk.PerformGas,
+ CheckData: uk.CheckData,
+ Balance: uk.Balance,
+ Admin: uk.Admin.Hex(),
+ MaxValidBlocknumber: uk.MaxValidBlocknumber,
+ LastPerformBlockNumber: uk.LastPerformedBlockNumber,
+ AmountSpent: uk.AmountSpent,
+ Paused: uk.Paused,
+ OffchainConfig: uk.OffchainConfig,
+ }, nil
}
return nil, fmt.Errorf("keeper registry version %d is not supported", v.version)
@@ -746,7 +778,7 @@ func (v *EthereumKeeperRegistry) CancelUpkeep(id *big.Int) error {
}
}
- log.Info().
+ v.l.Info().
Str("Upkeep ID", strconv.FormatInt(id.Int64(), 10)).
Str("From", v.client.GetDefaultWallet().Address()).
Str("TX Hash", tx.Hash().String()).
@@ -778,6 +810,11 @@ func (v *EthereumKeeperRegistry) SetUpkeepGasLimit(id *big.Int, gas uint32) erro
if err != nil {
return err
}
+ case ethereum.RegistryVersion_2_1:
+ tx, err = v.registry2_1.SetUpkeepGasLimit(opts, id, gas)
+ if err != nil {
+ return err
+ }
default:
return fmt.Errorf("keeper registry version %d is not supported for SetUpkeepGasLimit", v.version)
}
@@ -852,11 +889,42 @@ func (v *EthereumKeeperRegistry) UpdateCheckData(id *big.Int, newCheckData []byt
return err
}
return v.client.ProcessTransaction(tx)
+ case ethereum.RegistryVersion_2_1:
+ opts, err := v.client.TransactionOpts(v.client.GetDefaultWallet())
+ if err != nil {
+ return err
+ }
+
+ tx, err := v.registry2_1.SetUpkeepCheckData(opts, id, newCheckData)
+ if err != nil {
+ return err
+ }
+ return v.client.ProcessTransaction(tx)
default:
return fmt.Errorf("UpdateCheckData is not supported by keeper registry version %d", v.version)
}
}
+// SetUpkeepTriggerConfig updates the trigger config of an upkeep (only for version 2.1)
+func (v *EthereumKeeperRegistry) SetUpkeepTriggerConfig(id *big.Int, triggerConfig []byte) error {
+
+ switch v.version {
+ case ethereum.RegistryVersion_2_1:
+ opts, err := v.client.TransactionOpts(v.client.GetDefaultWallet())
+ if err != nil {
+ return err
+ }
+
+ tx, err := v.registry2_1.SetUpkeepTriggerConfig(opts, id, triggerConfig)
+ if err != nil {
+ return err
+ }
+ return v.client.ProcessTransaction(tx)
+ default:
+ return fmt.Errorf("SetUpkeepTriggerConfig is not supported by keeper registry version %d", v.version)
+ }
+}
+
// PauseUpkeep stops an upkeep from an upkeep
func (v *EthereumKeeperRegistry) PauseUpkeep(id *big.Int) error {
switch v.version {
@@ -882,6 +950,17 @@ func (v *EthereumKeeperRegistry) PauseUpkeep(id *big.Int) error {
return err
}
return v.client.ProcessTransaction(tx)
+ case ethereum.RegistryVersion_2_1:
+ opts, err := v.client.TransactionOpts(v.client.GetDefaultWallet())
+ if err != nil {
+ return err
+ }
+
+ tx, err := v.registry2_1.PauseUpkeep(opts, id)
+ if err != nil {
+ return err
+ }
+ return v.client.ProcessTransaction(tx)
default:
return fmt.Errorf("PauseUpkeep is not supported by keeper registry version %d", v.version)
}
@@ -912,6 +991,17 @@ func (v *EthereumKeeperRegistry) UnpauseUpkeep(id *big.Int) error {
return err
}
return v.client.ProcessTransaction(tx)
+ case ethereum.RegistryVersion_2_1:
+ opts, err := v.client.TransactionOpts(v.client.GetDefaultWallet())
+ if err != nil {
+ return err
+ }
+
+ tx, err := v.registry2_1.UnpauseUpkeep(opts, id)
+ if err != nil {
+ return err
+ }
+ return v.client.ProcessTransaction(tx)
default:
return fmt.Errorf("UnpauseUpkeep is not supported by keeper registry version %d", v.version)
}
@@ -960,6 +1050,40 @@ func (v *EthereumKeeperRegistry) ParseUpkeepPerformedLog(log *types.Log) (*Upkee
Success: parsedLog.Success,
From: utils.ZeroAddress,
}, nil
+ case ethereum.RegistryVersion_2_1:
+ parsedLog, err := v.registry2_1.ParseUpkeepPerformed(*log)
+ if err != nil {
+ return nil, err
+ }
+ return &UpkeepPerformedLog{
+ Id: parsedLog.Id,
+ Success: parsedLog.Success,
+ From: utils.ZeroAddress,
+ }, nil
+ }
+ return nil, fmt.Errorf("keeper registry version %d is not supported", v.version)
+}
+
+// ParseStaleUpkeepReportLog Parses Stale upkeep report log
+func (v *EthereumKeeperRegistry) ParseStaleUpkeepReportLog(log *types.Log) (*StaleUpkeepReportLog, error) {
+ switch v.version {
+ case ethereum.RegistryVersion_2_0:
+ parsedLog, err := v.registry2_0.ParseStaleUpkeepReport(*log)
+ if err != nil {
+ return nil, err
+ }
+ return &StaleUpkeepReportLog{
+ Id: parsedLog.Id,
+ }, nil
+ case ethereum.RegistryVersion_2_1:
+ parsedLog, err := v.registry2_1.ParseStaleUpkeepReport(*log)
+ if err != nil {
+ return nil, err
+ }
+ return &StaleUpkeepReportLog{
+ Id: parsedLog.Id,
+ }, nil
+
}
return nil, fmt.Errorf("keeper registry version %d is not supported", v.version)
}
@@ -1009,6 +1133,7 @@ type KeeperConsumerRoundConfirmer struct {
doneChan chan struct{}
context context.Context
cancel context.CancelFunc
+ l zerolog.Logger
}
// NewKeeperConsumerRoundConfirmer provides a new instance of a KeeperConsumerRoundConfirmer
@@ -1016,6 +1141,7 @@ func NewKeeperConsumerRoundConfirmer(
contract KeeperConsumer,
counterValue int,
timeout time.Duration,
+ logger zerolog.Logger,
) *KeeperConsumerRoundConfirmer {
ctx, ctxCancel := context.WithTimeout(context.Background(), timeout)
return &KeeperConsumerRoundConfirmer{
@@ -1024,6 +1150,7 @@ func NewKeeperConsumerRoundConfirmer(
doneChan: make(chan struct{}),
context: ctx,
cancel: ctxCancel,
+ l: logger,
}
}
@@ -1033,7 +1160,7 @@ func (o *KeeperConsumerRoundConfirmer) ReceiveHeader(_ blockchain.NodeHeader) er
if err != nil {
return err
}
- l := log.Info().
+ l := o.l.Info().
Str("Contract Address", o.instance.Address()).
Int64("Upkeeps", upkeeps.Int64()).
Int("Required upkeeps", o.upkeepsValue)
@@ -1077,6 +1204,7 @@ type KeeperConsumerPerformanceRoundConfirmer struct {
metricsReporter *testreporters.KeeperBlockTimeTestReporter // Testreporter to track results
complete bool
+ l zerolog.Logger
}
// NewKeeperConsumerPerformanceRoundConfirmer provides a new instance of a KeeperConsumerPerformanceRoundConfirmer
@@ -1086,6 +1214,7 @@ func NewKeeperConsumerPerformanceRoundConfirmer(
expectedBlockCadence int64, // Expected to upkeep every 5/10/20 blocks, for example
blockRange int64,
metricsReporter *testreporters.KeeperBlockTimeTestReporter,
+ logger zerolog.Logger,
) *KeeperConsumerPerformanceRoundConfirmer {
ctx, cancelFunc := context.WithCancel(context.Background())
return &KeeperConsumerPerformanceRoundConfirmer{
@@ -1103,6 +1232,7 @@ func NewKeeperConsumerPerformanceRoundConfirmer(
metricsReporter: metricsReporter,
complete: false,
lastBlockNum: 0,
+ l: logger,
}
}
@@ -1125,22 +1255,22 @@ func (o *KeeperConsumerPerformanceRoundConfirmer) ReceiveHeader(receivedHeader b
return err
}
if isEligible {
- log.Trace().
+ o.l.Trace().
Str("Contract Address", o.instance.Address()).
Int64("Upkeeps Performed", upkeepCount.Int64()).
Msg("Upkeep Now Eligible")
}
if upkeepCount.Int64() >= o.expectedUpkeepCount { // Upkeep was successful
if o.blocksSinceSuccessfulUpkeep < o.blockCadence { // If there's an early upkeep, that's weird
- log.Error().
+ o.l.Error().
Str("Contract Address", o.instance.Address()).
Int64("Upkeeps Performed", upkeepCount.Int64()).
Int64("Expected Cadence", o.blockCadence).
Int64("Actual Cadence", o.blocksSinceSuccessfulUpkeep).
- Err(errors.New("Found an early Upkeep"))
- return fmt.Errorf("Found an early Upkeep on contract %s", o.instance.Address())
+ Err(errors.New("found an early Upkeep"))
+ return fmt.Errorf("found an early Upkeep on contract %s", o.instance.Address())
} else if o.blocksSinceSuccessfulUpkeep == o.blockCadence { // Perfectly timed upkeep
- log.Info().
+ o.l.Info().
Str("Contract Address", o.instance.Address()).
Int64("Upkeeps Performed", upkeepCount.Int64()).
Int64("Expected Cadence", o.blockCadence).
@@ -1148,7 +1278,7 @@ func (o *KeeperConsumerPerformanceRoundConfirmer) ReceiveHeader(receivedHeader b
Msg("Successful Upkeep on Expected Cadence")
o.totalSuccessfulUpkeeps++
} else { // Late upkeep
- log.Warn().
+ o.l.Warn().
Str("Contract Address", o.instance.Address()).
Int64("Upkeeps Performed", upkeepCount.Int64()).
Int64("Expected Cadence", o.blockCadence).
@@ -1163,7 +1293,7 @@ func (o *KeeperConsumerPerformanceRoundConfirmer) ReceiveHeader(receivedHeader b
if o.blocksSinceSubscription > o.blockRange {
if o.blocksSinceSuccessfulUpkeep > o.blockCadence {
- log.Warn().
+ o.l.Warn().
Str("Contract Address", o.instance.Address()).
Int64("Upkeeps Performed", upkeepCount.Int64()).
Int64("Expected Cadence", o.blockCadence).
@@ -1173,7 +1303,7 @@ func (o *KeeperConsumerPerformanceRoundConfirmer) ReceiveHeader(receivedHeader b
Msg("Finished Watching for Upkeeps While Waiting on a Late Upkeep")
o.allMissedUpkeeps = append(o.allMissedUpkeeps, o.blocksSinceSuccessfulUpkeep-o.blockCadence)
} else {
- log.Info().
+ o.l.Info().
Str("Contract Address", o.instance.Address()).
Int64("Upkeeps Performed", upkeepCount.Int64()).
Int64("Total Blocks Watched", o.blocksSinceSubscription).
@@ -1242,6 +1372,7 @@ type KeeperConsumerBenchmarkRoundConfirmer struct {
upkeepCount int64 // The count of upkeeps done so far
allCheckDelays []int64 // Tracks the amount of blocks missed before an upkeep since it became eligible
complete bool
+ l zerolog.Logger
}
// NewKeeperConsumerBenchmarkRoundConfirmer provides a new instance of a KeeperConsumerBenchmarkRoundConfirmer
@@ -1255,6 +1386,7 @@ func NewKeeperConsumerBenchmarkRoundConfirmer(
metricsReporter *testreporters.KeeperBenchmarkTestReporter,
upkeepIndex int64,
firstEligibleuffer int64,
+ logger zerolog.Logger,
) *KeeperConsumerBenchmarkRoundConfirmer {
ctx, cancelFunc := context.WithCancel(context.Background())
return &KeeperConsumerBenchmarkRoundConfirmer{
@@ -1276,6 +1408,7 @@ func NewKeeperConsumerBenchmarkRoundConfirmer(
upkeepIndex: upkeepIndex,
firstBlockNum: 0,
firstEligibleuffer: firstEligibleuffer,
+ l: logger,
}
}
@@ -1300,7 +1433,7 @@ func (o *KeeperConsumerBenchmarkRoundConfirmer) ReceiveHeader(receivedHeader blo
if upkeepCount.Int64() != o.upkeepCount+1 {
return errors.New("upkeep count increased by more than 1 in a single block")
}
- log.Info().
+ o.l.Info().
Uint64("Block_Number", receivedHeader.Number.Uint64()).
Str("Upkeep_ID", o.upkeepID.String()).
Str("Contract_Address", o.instance.Address()).
@@ -1310,7 +1443,7 @@ func (o *KeeperConsumerBenchmarkRoundConfirmer) ReceiveHeader(receivedHeader blo
Msg("Upkeep Performed")
if o.blocksSinceEligible > o.upkeepSLA {
- log.Warn().
+ o.l.Warn().
Uint64("Block_Number", receivedHeader.Number.Uint64()).
Str("Upkeep_ID", o.upkeepID.String()).
Str("Contract_Address", o.instance.Address()).
@@ -1333,7 +1466,7 @@ func (o *KeeperConsumerBenchmarkRoundConfirmer) ReceiveHeader(receivedHeader blo
if o.blocksSinceEligible == 0 {
// First time this upkeep became eligible
o.countEligible++
- log.Info().
+ o.l.Info().
Uint64("Block_Number", receivedHeader.Number.Uint64()).
Str("Upkeep_ID", o.upkeepID.String()).
Str("Contract_Address", o.instance.Address()).
@@ -1346,7 +1479,7 @@ func (o *KeeperConsumerBenchmarkRoundConfirmer) ReceiveHeader(receivedHeader blo
if o.blocksSinceSubscription >= o.blockRange || int64(o.lastBlockNum-o.firstBlockNum) >= o.blockRange {
if o.blocksSinceEligible > 0 {
if o.blocksSinceEligible > o.upkeepSLA {
- log.Warn().
+ o.l.Warn().
Uint64("Block_Number", receivedHeader.Number.Uint64()).
Str("Upkeep_ID", o.upkeepID.String()).
Str("Contract_Address", o.instance.Address()).
@@ -1355,7 +1488,7 @@ func (o *KeeperConsumerBenchmarkRoundConfirmer) ReceiveHeader(receivedHeader blo
Msg("Upkeep remained eligible at end of test and missed SLA")
o.countMissed++
} else {
- log.Info().
+ o.l.Info().
Uint64("Block_Number", receivedHeader.Number.Uint64()).
Str("Upkeep_ID", o.upkeepID.String()).
Str("Contract_Address", o.instance.Address()).
@@ -1367,7 +1500,7 @@ func (o *KeeperConsumerBenchmarkRoundConfirmer) ReceiveHeader(receivedHeader blo
o.allCheckDelays = append(o.allCheckDelays, o.blocksSinceEligible)
}
- log.Info().
+ o.l.Info().
Uint64("Block_Number", receivedHeader.Number.Uint64()).
Str("Upkeep_ID", o.upkeepID.String()).
Str("Contract_Address", o.instance.Address()).
diff --git a/integration-tests/contracts/ethereum_ocr2vrf_contracts.go b/integration-tests/contracts/ethereum_ocr2vrf_contracts.go
new file mode 100644
index 00000000000..11606de53e5
--- /dev/null
+++ b/integration-tests/contracts/ethereum_ocr2vrf_contracts.go
@@ -0,0 +1,572 @@
+package contracts
+
+import (
+ "context"
+ "encoding/hex"
+ "fmt"
+ "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/rs/zerolog/log"
+ "github.com/smartcontractkit/chainlink-testing-framework/blockchain"
+ "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/batch_blockhash_store"
+ "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/solidity_vrf_coordinator_interface"
+ "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/dkg"
+ "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/vrf_beacon"
+ "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/vrf_beacon_consumer"
+ "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/vrf_coordinator"
+ "math/big"
+ "time"
+)
+
+// EthereumDKG represents DKG contract
+type EthereumDKG struct {
+ address *common.Address
+ client blockchain.EVMClient
+ dkg *dkg.DKG
+}
+
+// EthereumVRFCoordinatorV3 represents VRFCoordinatorV3 contract
+type EthereumVRFCoordinatorV3 struct {
+ address *common.Address
+ client blockchain.EVMClient
+ vrfCoordinatorV3 *vrf_coordinator.VRFCoordinator
+}
+
+// EthereumVRFBeacon represents VRFBeacon contract
+type EthereumVRFBeacon struct {
+ address *common.Address
+ client blockchain.EVMClient
+ vrfBeacon *vrf_beacon.VRFBeacon
+}
+
+// EthereumVRFBeaconConsumer represents VRFBeaconConsumer contract
+type EthereumVRFBeaconConsumer struct {
+ address *common.Address
+ client blockchain.EVMClient
+ vrfBeaconConsumer *vrf_beacon_consumer.BeaconVRFConsumer
+}
+
+// EthereumVRFCoordinator represents VRF coordinator contract
+type EthereumVRFCoordinator struct {
+ address *common.Address
+ client blockchain.EVMClient
+ coordinator *solidity_vrf_coordinator_interface.VRFCoordinator
+}
+
+// DeployDKG deploys DKG contract
+func (e *EthereumContractDeployer) DeployDKG() (DKG, error) {
+ address, _, instance, err := e.client.DeployContract("DKG", func(
+ auth *bind.TransactOpts,
+ backend bind.ContractBackend,
+ ) (common.Address, *types.Transaction, interface{}, error) {
+ return dkg.DeployDKG(auth, backend)
+ })
+ if err != nil {
+ return nil, err
+ }
+ return &EthereumDKG{
+ client: e.client,
+ dkg: instance.(*dkg.DKG),
+ address: address,
+ }, err
+}
+
+// DeployOCR2VRFCoordinator deploys CR2VRFCoordinator contract
+func (e *EthereumContractDeployer) DeployOCR2VRFCoordinator(beaconPeriodBlocksCount *big.Int, linkAddress string) (VRFCoordinatorV3, error) {
+ address, _, instance, err := e.client.DeployContract("VRFCoordinatorV3", func(
+ auth *bind.TransactOpts,
+ backend bind.ContractBackend,
+ ) (common.Address, *types.Transaction, interface{}, error) {
+ return vrf_coordinator.DeployVRFCoordinator(auth, backend, beaconPeriodBlocksCount, common.HexToAddress(linkAddress))
+ })
+ if err != nil {
+ return nil, err
+ }
+ return &EthereumVRFCoordinatorV3{
+ client: e.client,
+ vrfCoordinatorV3: instance.(*vrf_coordinator.VRFCoordinator),
+ address: address,
+ }, err
+}
+
+// DeployVRFBeacon deploys DeployVRFBeacon contract
+func (e *EthereumContractDeployer) DeployVRFBeacon(vrfCoordinatorAddress string, linkAddress string, dkgAddress string, keyId string) (VRFBeacon, error) {
+ keyIDBytes, err := DecodeHexTo32ByteArray(keyId)
+ if err != nil {
+ return nil, err
+ }
+ address, _, instance, err := e.client.DeployContract("VRFBeacon", func(
+ auth *bind.TransactOpts,
+ backend bind.ContractBackend,
+ ) (common.Address, *types.Transaction, interface{}, error) {
+ return vrf_beacon.DeployVRFBeacon(auth, backend, common.HexToAddress(linkAddress), common.HexToAddress(vrfCoordinatorAddress), common.HexToAddress(dkgAddress), keyIDBytes)
+ })
+ if err != nil {
+ return nil, err
+ }
+ return &EthereumVRFBeacon{
+ client: e.client,
+ vrfBeacon: instance.(*vrf_beacon.VRFBeacon),
+ address: address,
+ }, err
+}
+
+// DeployBatchBlockhashStore deploys DeployBatchBlockhashStore contract
+func (e *EthereumContractDeployer) DeployBatchBlockhashStore(blockhashStoreAddr string) (BatchBlockhashStore, error) {
+ address, _, instance, err := e.client.DeployContract("BatchBlockhashStore", func(
+ auth *bind.TransactOpts,
+ backend bind.ContractBackend,
+ ) (common.Address, *types.Transaction, interface{}, error) {
+ return batch_blockhash_store.DeployBatchBlockhashStore(auth, backend, common.HexToAddress(blockhashStoreAddr))
+ })
+ if err != nil {
+ return nil, err
+ }
+ return &EthereumBatchBlockhashStore{
+ client: e.client,
+ batchBlockhashStore: instance.(*batch_blockhash_store.BatchBlockhashStore),
+ address: address,
+ }, err
+}
+
+// todo - solve import cycle
+func DecodeHexTo32ByteArray(val string) ([32]byte, error) {
+ var byteArray [32]byte
+ decoded, err := hex.DecodeString(val)
+ if err != nil {
+ return [32]byte{}, err
+ }
+ if len(decoded) != 32 {
+ return [32]byte{}, fmt.Errorf("expected value to be 32 bytes but received %d bytes", len(decoded))
+ }
+ copy(byteArray[:], decoded)
+ return byteArray, err
+}
+
+// DeployVRFBeaconConsumer deploys VRFv@ consumer contract
+func (e *EthereumContractDeployer) DeployVRFBeaconConsumer(vrfCoordinatorAddress string, beaconPeriodBlockCount *big.Int) (VRFBeaconConsumer, error) {
+ address, _, instance, err := e.client.DeployContract("VRFBeaconConsumer", func(
+ auth *bind.TransactOpts,
+ backend bind.ContractBackend,
+ ) (common.Address, *types.Transaction, interface{}, error) {
+ return vrf_beacon_consumer.DeployBeaconVRFConsumer(auth, backend, common.HexToAddress(vrfCoordinatorAddress), false, beaconPeriodBlockCount)
+ })
+ if err != nil {
+ return nil, err
+ }
+ return &EthereumVRFBeaconConsumer{
+ client: e.client,
+ vrfBeaconConsumer: instance.(*vrf_beacon_consumer.BeaconVRFConsumer),
+ address: address,
+ }, err
+}
+
+func (dkgContract *EthereumDKG) Address() string {
+ return dkgContract.address.Hex()
+}
+
+func (dkgContract *EthereumDKG) AddClient(keyID string, clientAddress string) error {
+ keyIDBytes, err := DecodeHexTo32ByteArray(keyID)
+ if err != nil {
+ return err
+ }
+ opts, err := dkgContract.client.TransactionOpts(dkgContract.client.GetDefaultWallet())
+ if err != nil {
+ return err
+ }
+ tx, err := dkgContract.dkg.AddClient(
+ opts,
+ keyIDBytes,
+ common.HexToAddress(clientAddress),
+ )
+ if err != nil {
+ return err
+ }
+ return dkgContract.client.ProcessTransaction(tx)
+
+}
+
+func (dkgContract *EthereumDKG) SetConfig(
+ signerAddresses []common.Address,
+ transmitterAddresses []common.Address,
+ f uint8,
+ onchainConfig []byte,
+ offchainConfigVersion uint64,
+ offchainConfig []byte,
+) error {
+ opts, err := dkgContract.client.TransactionOpts(dkgContract.client.GetDefaultWallet())
+ if err != nil {
+ return err
+ }
+ tx, err := dkgContract.dkg.SetConfig(
+ opts,
+ signerAddresses,
+ transmitterAddresses,
+ f,
+ onchainConfig,
+ offchainConfigVersion,
+ offchainConfig,
+ )
+ if err != nil {
+ return err
+ }
+ return dkgContract.client.ProcessTransaction(tx)
+}
+
+func (dkgContract *EthereumDKG) WaitForTransmittedEvent(timeout time.Duration) (*dkg.DKGTransmitted, error) {
+ transmittedEventsChannel := make(chan *dkg.DKGTransmitted)
+ subscription, err := dkgContract.dkg.WatchTransmitted(nil, transmittedEventsChannel)
+ if err != nil {
+ return nil, err
+ }
+ defer subscription.Unsubscribe()
+
+ for {
+ select {
+ case err = <-subscription.Err():
+ return nil, err
+ case <-time.After(timeout):
+ return nil, errors.New("timeout waiting for DKGTransmitted event")
+ case transmittedEvent := <-transmittedEventsChannel:
+ return transmittedEvent, nil
+ }
+ }
+}
+
+func (dkgContract *EthereumDKG) WaitForConfigSetEvent(timeout time.Duration) (*dkg.DKGConfigSet, error) {
+ configSetEventsChannel := make(chan *dkg.DKGConfigSet)
+ subscription, err := dkgContract.dkg.WatchConfigSet(nil, configSetEventsChannel)
+ if err != nil {
+ return nil, err
+ }
+ defer subscription.Unsubscribe()
+
+ for {
+ select {
+ case err = <-subscription.Err():
+ return nil, err
+ case <-time.After(timeout):
+ return nil, errors.New("timeout waiting for DKGConfigSet event")
+ case configSetEvent := <-configSetEventsChannel:
+ return configSetEvent, nil
+ }
+ }
+}
+
+func (coordinator *EthereumVRFCoordinatorV3) Address() string {
+ return coordinator.address.Hex()
+}
+
+func (coordinator *EthereumVRFCoordinatorV3) SetProducer(producerAddress string) error {
+ opts, err := coordinator.client.TransactionOpts(coordinator.client.GetDefaultWallet())
+ if err != nil {
+ return err
+ }
+ tx, err := coordinator.vrfCoordinatorV3.SetProducer(
+ opts,
+ common.HexToAddress(producerAddress),
+ )
+ if err != nil {
+ return err
+ }
+ return coordinator.client.ProcessTransaction(tx)
+}
+
+func (coordinator *EthereumVRFCoordinatorV3) CreateSubscription() error {
+ opts, err := coordinator.client.TransactionOpts(coordinator.client.GetDefaultWallet())
+ if err != nil {
+ return err
+ }
+ tx, err := coordinator.vrfCoordinatorV3.CreateSubscription(
+ opts,
+ )
+ if err != nil {
+ return err
+ }
+ return coordinator.client.ProcessTransaction(tx)
+}
+
+func (coordinator *EthereumVRFCoordinatorV3) FindSubscriptionID() (*big.Int, error) {
+ fopts := &bind.FilterOpts{}
+ owner := coordinator.client.GetDefaultWallet().Address()
+
+ subscriptionIterator, err := coordinator.vrfCoordinatorV3.FilterSubscriptionCreated(
+ fopts,
+ nil,
+ []common.Address{common.HexToAddress(owner)},
+ )
+ if err != nil {
+ return nil, err
+ }
+
+ if !subscriptionIterator.Next() {
+ return nil, fmt.Errorf("expected at least 1 subID for the given owner %s", owner)
+ }
+
+ return subscriptionIterator.Event.SubId, nil
+}
+
+func (coordinator *EthereumVRFCoordinatorV3) AddConsumer(subId *big.Int, consumerAddress string) error {
+ opts, err := coordinator.client.TransactionOpts(coordinator.client.GetDefaultWallet())
+ if err != nil {
+ return err
+ }
+ tx, err := coordinator.vrfCoordinatorV3.AddConsumer(
+ opts,
+ subId,
+ common.HexToAddress(consumerAddress),
+ )
+ if err != nil {
+ return err
+ }
+ return coordinator.client.ProcessTransaction(tx)
+}
+
+func (coordinator *EthereumVRFCoordinatorV3) SetConfig(maxCallbackGasLimit uint32, maxCallbackArgumentsLength uint32) error {
+ opts, err := coordinator.client.TransactionOpts(coordinator.client.GetDefaultWallet())
+ if err != nil {
+ return err
+ }
+ tx, err := coordinator.vrfCoordinatorV3.SetCallbackConfig(
+ opts,
+ vrf_coordinator.VRFCoordinatorCallbackConfig{
+ MaxCallbackGasLimit: maxCallbackGasLimit,
+ MaxCallbackArgumentsLength: maxCallbackArgumentsLength, // 5 EVM words
+ },
+ )
+ if err != nil {
+ return err
+ }
+ return coordinator.client.ProcessTransaction(tx)
+}
+
+func (beacon *EthereumVRFBeacon) Address() string {
+ return beacon.address.Hex()
+}
+
+func (beacon *EthereumVRFBeacon) SetPayees(transmitterAddresses []common.Address, payeesAddresses []common.Address) error {
+ opts, err := beacon.client.TransactionOpts(beacon.client.GetDefaultWallet())
+ if err != nil {
+ return err
+ }
+
+ tx, err := beacon.vrfBeacon.SetPayees(
+ opts,
+ transmitterAddresses,
+ payeesAddresses,
+ )
+ if err != nil {
+ return err
+ }
+ return beacon.client.ProcessTransaction(tx)
+}
+
+func (beacon *EthereumVRFBeacon) SetConfig(
+ signerAddresses []common.Address,
+ transmitterAddresses []common.Address,
+ f uint8,
+ onchainConfig []byte,
+ offchainConfigVersion uint64,
+ offchainConfig []byte,
+) error {
+ opts, err := beacon.client.TransactionOpts(beacon.client.GetDefaultWallet())
+ if err != nil {
+ return err
+ }
+ tx, err := beacon.vrfBeacon.SetConfig(
+ opts,
+ signerAddresses,
+ transmitterAddresses,
+ f,
+ onchainConfig,
+ offchainConfigVersion,
+ offchainConfig,
+ )
+ if err != nil {
+ return err
+ }
+ return beacon.client.ProcessTransaction(tx)
+}
+
+func (beacon *EthereumVRFBeacon) WaitForConfigSetEvent(timeout time.Duration) (*vrf_beacon.VRFBeaconConfigSet, error) {
+ configSetEventsChannel := make(chan *vrf_beacon.VRFBeaconConfigSet)
+ subscription, err := beacon.vrfBeacon.WatchConfigSet(nil, configSetEventsChannel)
+ if err != nil {
+ return nil, err
+ }
+ defer subscription.Unsubscribe()
+
+ for {
+ select {
+ case err := <-subscription.Err():
+ return nil, err
+ case <-time.After(timeout):
+ return nil, fmt.Errorf("timeout waiting for config set event")
+ case configSetEvent := <-configSetEventsChannel:
+ return configSetEvent, nil
+ }
+ }
+}
+
+func (beacon *EthereumVRFBeacon) WaitForNewTransmissionEvent(timeout time.Duration) (*vrf_beacon.VRFBeaconNewTransmission, error) {
+ newTransmissionEventsChannel := make(chan *vrf_beacon.VRFBeaconNewTransmission)
+ subscription, err := beacon.vrfBeacon.WatchNewTransmission(nil, newTransmissionEventsChannel, nil)
+ if err != nil {
+ return nil, err
+ }
+ defer subscription.Unsubscribe()
+
+ for {
+ select {
+ case err := <-subscription.Err():
+ return nil, err
+ case <-time.After(timeout):
+ return nil, fmt.Errorf("timeout waiting for new transmission event")
+ case newTransmissionEvent := <-newTransmissionEventsChannel:
+ return newTransmissionEvent, nil
+ }
+ }
+}
+
+func (beacon *EthereumVRFBeacon) LatestConfigDigestAndEpoch(ctx context.Context) (vrf_beacon.LatestConfigDigestAndEpoch,
+ error) {
+ opts := &bind.CallOpts{
+ From: common.HexToAddress(beacon.client.GetDefaultWallet().Address()),
+ Context: ctx,
+ }
+ return beacon.vrfBeacon.LatestConfigDigestAndEpoch(opts)
+}
+
+func (consumer *EthereumVRFBeaconConsumer) Address() string {
+ return consumer.address.Hex()
+}
+
+func (consumer *EthereumVRFBeaconConsumer) RequestRandomness(
+ numWords uint16,
+ subID, confirmationDelayArg *big.Int,
+) (*types.Receipt, error) {
+ opts, err := consumer.client.TransactionOpts(consumer.client.GetDefaultWallet())
+ if err != nil {
+ return nil, errors.Wrap(err, "TransactionOpts failed")
+ }
+ tx, err := consumer.vrfBeaconConsumer.TestRequestRandomness(
+ opts,
+ numWords,
+ subID,
+ confirmationDelayArg,
+ )
+ if err != nil {
+ return nil, errors.Wrap(err, "TestRequestRandomness failed")
+ }
+ err = consumer.client.ProcessTransaction(tx)
+ if err != nil {
+ return nil, errors.Wrap(err, "ProcessTransaction failed")
+ }
+ err = consumer.client.WaitForEvents()
+
+ if err != nil {
+ return nil, errors.Wrap(err, "WaitForEvents failed")
+ }
+ receipt, err := consumer.client.GetTxReceipt(tx.Hash())
+ if err != nil {
+ return nil, errors.Wrap(err, "GetTxReceipt failed")
+ }
+ log.Info().Interface("Sub ID", subID).
+ Interface("Number of Words", numWords).
+ Interface("Number of Confirmations", confirmationDelayArg).
+ Msg("RequestRandomness called")
+ return receipt, nil
+}
+
+func (consumer *EthereumVRFBeaconConsumer) RedeemRandomness(
+ subID, requestID *big.Int,
+) error {
+ opts, err := consumer.client.TransactionOpts(consumer.client.GetDefaultWallet())
+ if err != nil {
+ return err
+ }
+ tx, err := consumer.vrfBeaconConsumer.TestRedeemRandomness(
+ opts,
+ subID,
+ requestID,
+ )
+ if err != nil {
+ return err
+ }
+ log.Info().Interface("Sub ID", subID).
+ Interface("Request ID", requestID).
+ Msg("RedeemRandomness called")
+ return consumer.client.ProcessTransaction(tx)
+}
+
+func (consumer *EthereumVRFBeaconConsumer) RequestRandomnessFulfillment(
+ numWords uint16,
+ subID, confirmationDelayArg *big.Int,
+ requestGasLimit uint32,
+ callbackGasLimit uint32,
+ arguments []byte,
+) (*types.Receipt, error) {
+ opts, err := consumer.client.TransactionOpts(consumer.client.GetDefaultWallet())
+ if err != nil {
+ return nil, err
+ }
+ // overriding gas limit because gas estimated by TestRequestRandomnessFulfillment
+ // is incorrect
+ opts.GasLimit = uint64(requestGasLimit)
+ tx, err := consumer.vrfBeaconConsumer.TestRequestRandomnessFulfillment(
+ opts,
+ subID,
+ numWords,
+ confirmationDelayArg,
+ callbackGasLimit,
+ arguments,
+ )
+ if err != nil {
+ return nil, errors.Wrap(err, "TestRequestRandomnessFulfillment failed")
+ }
+ err = consumer.client.ProcessTransaction(tx)
+ if err != nil {
+ return nil, errors.Wrap(err, "ProcessTransaction failed")
+ }
+ err = consumer.client.WaitForEvents()
+
+ if err != nil {
+ return nil, errors.Wrap(err, "WaitForEvents failed")
+ }
+ receipt, err := consumer.client.GetTxReceipt(tx.Hash())
+ if err != nil {
+ return nil, errors.Wrap(err, "GetTxReceipt failed")
+ }
+ log.Info().Interface("Sub ID", subID).
+ Interface("Number of Words", numWords).
+ Interface("Number of Confirmations", confirmationDelayArg).
+ Interface("Callback Gas Limit", callbackGasLimit).
+ Msg("RequestRandomnessFulfillment called")
+ return receipt, nil
+}
+
+func (consumer *EthereumVRFBeaconConsumer) IBeaconPeriodBlocks(ctx context.Context) (*big.Int, error) {
+ opts := &bind.CallOpts{
+ From: common.HexToAddress(consumer.client.GetDefaultWallet().Address()),
+ Context: ctx,
+ }
+ return consumer.vrfBeaconConsumer.IBeaconPeriodBlocks(opts)
+}
+
+func (consumer *EthereumVRFBeaconConsumer) GetRequestIdsBy(ctx context.Context, nextBeaconOutputHeight *big.Int, confDelay *big.Int) (*big.Int, error) {
+ opts := &bind.CallOpts{
+ From: common.HexToAddress(consumer.client.GetDefaultWallet().Address()),
+ Context: ctx,
+ }
+ return consumer.vrfBeaconConsumer.SRequestsIDs(opts, nextBeaconOutputHeight, confDelay)
+}
+
+func (consumer *EthereumVRFBeaconConsumer) GetRandomnessByRequestId(ctx context.Context, requestID *big.Int, numWordIndex *big.Int) (*big.Int, error) {
+ opts := &bind.CallOpts{
+ From: common.HexToAddress(consumer.client.GetDefaultWallet().Address()),
+ Context: ctx,
+ }
+ return consumer.vrfBeaconConsumer.SReceivedRandomnessByRequestID(opts, requestID, numWordIndex)
+}
diff --git a/integration-tests/contracts/ethereum_vrf_contracts.go b/integration-tests/contracts/ethereum_vrf_contracts.go
index eb7605e3ee8..f97ba86d975 100644
--- a/integration-tests/contracts/ethereum_vrf_contracts.go
+++ b/integration-tests/contracts/ethereum_vrf_contracts.go
@@ -2,7 +2,6 @@ package contracts
import (
"context"
- "encoding/hex"
"fmt"
"math/big"
"time"
@@ -11,7 +10,6 @@ import (
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
- "github.com/pkg/errors"
"github.com/rs/zerolog/log"
"github.com/smartcontractkit/chainlink-testing-framework/blockchain"
@@ -21,17 +19,46 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/solidity_vrf_consumer_interface"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/solidity_vrf_coordinator_interface"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/solidity_vrf_wrapper"
- "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/ocr2vrf/generated/dkg"
- "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/vrf_beacon"
- "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/vrf_beacon_consumer"
- "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ocr2vrf/generated/vrf_coordinator"
-
- eth_contracts "github.com/smartcontractkit/chainlink/integration-tests/contracts/ethereum"
)
+// EthereumBatchBlockhashStore represents BatchBlockhashStore contract
+type EthereumBatchBlockhashStore struct {
+ address *common.Address
+ client blockchain.EVMClient
+ batchBlockhashStore *batch_blockhash_store.BatchBlockhashStore
+}
+
+// EthereumBlockhashStore represents a blockhash store for VRF contract
+type EthereumBlockhashStore struct {
+ address *common.Address
+ client blockchain.EVMClient
+ blockHashStore *blockhash_store.BlockhashStore
+}
+
+// EthereumVRFConsumer represents VRF consumer contract
+type EthereumVRFConsumer struct {
+ address *common.Address
+ client blockchain.EVMClient
+ consumer *solidity_vrf_consumer_interface.VRFConsumer
+}
+
+// VRFConsumerRoundConfirmer is a header subscription that awaits for a certain VRF round to be completed
+type VRFConsumerRoundConfirmer struct {
+ consumer VRFConsumer
+ roundID *big.Int
+ doneChan chan struct{}
+ context context.Context
+ cancel context.CancelFunc
+ done bool
+}
+
+// EthereumVRF represents a VRF contract
+type EthereumVRF struct {
+ client blockchain.EVMClient
+ vrf *solidity_vrf_wrapper.VRF
+ address *common.Address
+}
+
// DeployVRFContract deploy VRF contract
func (e *EthereumContractDeployer) DeployVRFContract() (VRF, error) {
address, _, instance, err := e.client.DeployContract("VRF", func(
@@ -68,24 +95,6 @@ func (e *EthereumContractDeployer) DeployBlockhashStore() (BlockHashStore, error
}, err
}
-// DeployVRFCoordinatorV2 deploys VRFV2 coordinator contract
-func (e *EthereumContractDeployer) DeployVRFCoordinatorV2(linkAddr string, bhsAddr string, linkEthFeedAddr string) (VRFCoordinatorV2, error) {
- address, _, instance, err := e.client.DeployContract("VRFCoordinatorV2", func(
- auth *bind.TransactOpts,
- backend bind.ContractBackend,
- ) (common.Address, *types.Transaction, interface{}, error) {
- return vrf_coordinator_v2.DeployVRFCoordinatorV2(auth, backend, common.HexToAddress(linkAddr), common.HexToAddress(bhsAddr), common.HexToAddress(linkEthFeedAddr))
- })
- if err != nil {
- return nil, err
- }
- return &EthereumVRFCoordinatorV2{
- client: e.client,
- coordinator: instance.(*vrf_coordinator_v2.VRFCoordinatorV2),
- address: address,
- }, err
-}
-
// DeployVRFCoordinator deploys VRF coordinator contract
func (e *EthereumContractDeployer) DeployVRFCoordinator(linkAddr string, bhsAddr string) (VRFCoordinator, error) {
address, _, instance, err := e.client.DeployContract("VRFCoordinator", func(
@@ -122,573 +131,43 @@ func (e *EthereumContractDeployer) DeployVRFConsumer(linkAddr string, coordinato
}, err
}
-// DeployVRFConsumerV2 deploys VRFv@ consumer contract
-func (e *EthereumContractDeployer) DeployVRFConsumerV2(linkAddr string, coordinatorAddr string) (VRFConsumerV2, error) {
- address, _, instance, err := e.client.DeployContract("VRFConsumerV2", func(
- auth *bind.TransactOpts,
- backend bind.ContractBackend,
- ) (common.Address, *types.Transaction, interface{}, error) {
- return vrf_consumer_v2.DeployVRFConsumerV2(auth, backend, common.HexToAddress(coordinatorAddr), common.HexToAddress(linkAddr))
- })
- if err != nil {
- return nil, err
- }
- return &EthereumVRFConsumerV2{
- client: e.client,
- consumer: instance.(*vrf_consumer_v2.VRFConsumerV2),
- address: address,
- }, err
-}
-
-func (e *EthereumContractDeployer) DeployVRFv2Consumer(coordinatorAddr string) (VRFv2Consumer, error) {
- address, _, instance, err := e.client.DeployContract("VRFv2Consumer", func(
- auth *bind.TransactOpts,
- backend bind.ContractBackend,
- ) (common.Address, *types.Transaction, interface{}, error) {
- return eth_contracts.DeployVRFv2Consumer(auth, backend, common.HexToAddress(coordinatorAddr))
- })
- if err != nil {
- return nil, err
- }
- return &EthereumVRFv2Consumer{
- client: e.client,
- consumer: instance.(*eth_contracts.VRFv2Consumer),
- address: address,
- }, err
-}
-
-//DeployVRFv2LoadTestConsumer(coordinatorAddr string) (VRFv2Consumer, error)
-
-func (e *EthereumContractDeployer) DeployVRFv2LoadTestConsumer(coordinatorAddr string) (VRFv2LoadTestConsumer, error) {
- address, _, instance, err := e.client.DeployContract("VRFV2LoadTestWithMetrics", func(
- auth *bind.TransactOpts,
- backend bind.ContractBackend,
- ) (common.Address, *types.Transaction, interface{}, error) {
- return vrf_load_test_with_metrics.DeployVRFV2LoadTestWithMetrics(auth, backend, common.HexToAddress(coordinatorAddr))
- })
- if err != nil {
- return nil, err
- }
- return &EthereumVRFv2LoadTestConsumer{
- client: e.client,
- consumer: instance.(*vrf_load_test_with_metrics.VRFV2LoadTestWithMetrics),
- address: address,
- }, err
-}
-
-// DeployDKG deploys DKG contract
-func (e *EthereumContractDeployer) DeployDKG() (DKG, error) {
- address, _, instance, err := e.client.DeployContract("DKG", func(
- auth *bind.TransactOpts,
- backend bind.ContractBackend,
- ) (common.Address, *types.Transaction, interface{}, error) {
- return dkg.DeployDKG(auth, backend)
- })
- if err != nil {
- return nil, err
- }
- return &EthereumDKG{
- client: e.client,
- dkg: instance.(*dkg.DKG),
- address: address,
- }, err
-}
-
-// DeployOCR2VRFCoordinator deploys CR2VRFCoordinator contract
-func (e *EthereumContractDeployer) DeployOCR2VRFCoordinator(beaconPeriodBlocksCount *big.Int, linkAddress string) (VRFCoordinatorV3, error) {
- address, _, instance, err := e.client.DeployContract("VRFCoordinatorV3", func(
- auth *bind.TransactOpts,
- backend bind.ContractBackend,
- ) (common.Address, *types.Transaction, interface{}, error) {
- return vrf_coordinator.DeployVRFCoordinator(auth, backend, beaconPeriodBlocksCount, common.HexToAddress(linkAddress))
- })
- if err != nil {
- return nil, err
- }
- return &EthereumVRFCoordinatorV3{
- client: e.client,
- vrfCoordinatorV3: instance.(*vrf_coordinator.VRFCoordinator),
- address: address,
- }, err
-}
-
-// DeployVRFBeacon deploys DeployVRFBeacon contract
-func (e *EthereumContractDeployer) DeployVRFBeacon(vrfCoordinatorAddress string, linkAddress string, dkgAddress string, keyId string) (VRFBeacon, error) {
- keyIDBytes, err := decodeHexTo32ByteArray(keyId)
- if err != nil {
- return nil, err
- }
- address, _, instance, err := e.client.DeployContract("VRFBeacon", func(
- auth *bind.TransactOpts,
- backend bind.ContractBackend,
- ) (common.Address, *types.Transaction, interface{}, error) {
- return vrf_beacon.DeployVRFBeacon(auth, backend, common.HexToAddress(linkAddress), common.HexToAddress(vrfCoordinatorAddress), common.HexToAddress(dkgAddress), keyIDBytes)
- })
- if err != nil {
- return nil, err
- }
- return &EthereumVRFBeacon{
- client: e.client,
- vrfBeacon: instance.(*vrf_beacon.VRFBeacon),
- address: address,
- }, err
-}
-
-// DeployBatchBlockhashStore deploys DeployBatchBlockhashStore contract
-func (e *EthereumContractDeployer) DeployBatchBlockhashStore(blockhashStoreAddr string) (BatchBlockhashStore, error) {
- address, _, instance, err := e.client.DeployContract("BatchBlockhashStore", func(
- auth *bind.TransactOpts,
- backend bind.ContractBackend,
- ) (common.Address, *types.Transaction, interface{}, error) {
- return batch_blockhash_store.DeployBatchBlockhashStore(auth, backend, common.HexToAddress(blockhashStoreAddr))
- })
- if err != nil {
- return nil, err
- }
- return &EthereumBatchBlockhashStore{
- client: e.client,
- batchBlockhashStore: instance.(*batch_blockhash_store.BatchBlockhashStore),
- address: address,
- }, err
-}
-
-// todo - solve import cycle
-func decodeHexTo32ByteArray(val string) ([32]byte, error) {
- var byteArray [32]byte
- decoded, err := hex.DecodeString(val)
- if err != nil {
- return [32]byte{}, err
- }
- if len(decoded) != 32 {
- return [32]byte{}, fmt.Errorf("expected value to be 32 bytes but received %d bytes", len(decoded))
- }
- copy(byteArray[:], decoded)
- return byteArray, err
-}
-
-// DeployVRFBeaconConsumer deploys VRFv@ consumer contract
-func (e *EthereumContractDeployer) DeployVRFBeaconConsumer(vrfCoordinatorAddress string, beaconPeriodBlockCount *big.Int) (VRFBeaconConsumer, error) {
- address, _, instance, err := e.client.DeployContract("VRFBeaconConsumer", func(
- auth *bind.TransactOpts,
- backend bind.ContractBackend,
- ) (common.Address, *types.Transaction, interface{}, error) {
- return vrf_beacon_consumer.DeployBeaconVRFConsumer(auth, backend, common.HexToAddress(vrfCoordinatorAddress), false, beaconPeriodBlockCount)
- })
- if err != nil {
- return nil, err
- }
- return &EthereumVRFBeaconConsumer{
- client: e.client,
- vrfBeaconConsumer: instance.(*vrf_beacon_consumer.BeaconVRFConsumer),
- address: address,
- }, err
-}
-
-// EthereumBlockhashStore represents a blockhash store for VRF contract
-type EthereumBlockhashStore struct {
- address *common.Address
- client blockchain.EVMClient
- blockHashStore *blockhash_store.BlockhashStore
-}
-
func (v *EthereumBlockhashStore) Address() string {
return v.address.Hex()
}
-// EthereumVRFCoordinatorV2 represents VRFV2 coordinator contract
-type EthereumVRFCoordinatorV2 struct {
- address *common.Address
- client blockchain.EVMClient
- coordinator *vrf_coordinator_v2.VRFCoordinatorV2
-}
-
-func (v *EthereumVRFCoordinatorV2) Address() string {
- return v.address.Hex()
-}
-
-func (v *EthereumVRFCoordinatorV2) HashOfKey(ctx context.Context, pubKey [2]*big.Int) ([32]byte, error) {
- opts := &bind.CallOpts{
- From: common.HexToAddress(v.client.GetDefaultWallet().Address()),
- Context: ctx,
- }
- hash, err := v.coordinator.HashOfKey(opts, pubKey)
- if err != nil {
- return [32]byte{}, err
- }
- return hash, nil
-}
-
-func (v *EthereumVRFCoordinatorV2) GetSubscription(ctx context.Context, subID uint64) (vrf_coordinator_v2.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_v2.GetSubscription{}, err
- }
- return subscription, nil
-}
-
-func (v *EthereumVRFCoordinatorV2) SetConfig(minimumRequestConfirmations uint16, maxGasLimit uint32, stalenessSeconds uint32, gasAfterPaymentCalculation uint32, fallbackWeiPerUnitLink *big.Int, feeConfig vrf_coordinator_v2.VRFCoordinatorV2FeeConfig) error {
- opts, err := v.client.TransactionOpts(v.client.GetDefaultWallet())
- if err != nil {
- return err
- }
- tx, err := v.coordinator.SetConfig(
- opts,
- minimumRequestConfirmations,
- maxGasLimit,
- stalenessSeconds,
- gasAfterPaymentCalculation,
- fallbackWeiPerUnitLink,
- feeConfig,
- )
- if err != nil {
- return err
- }
- return v.client.ProcessTransaction(tx)
-}
-
-func (v *EthereumVRFCoordinatorV2) RegisterProvingKey(
- oracleAddr string,
- publicProvingKey [2]*big.Int,
-) error {
- opts, err := v.client.TransactionOpts(v.client.GetDefaultWallet())
- if err != nil {
- return err
- }
- tx, err := v.coordinator.RegisterProvingKey(opts, common.HexToAddress(oracleAddr), publicProvingKey)
- if err != nil {
- return err
- }
- return v.client.ProcessTransaction(tx)
-}
-
-func (v *EthereumVRFCoordinatorV2) CreateSubscription() error {
- opts, err := v.client.TransactionOpts(v.client.GetDefaultWallet())
- if err != nil {
- return err
- }
- tx, err := v.coordinator.CreateSubscription(opts)
- if err != nil {
- return err
- }
- return v.client.ProcessTransaction(tx)
-}
-
-func (v *EthereumVRFCoordinatorV2) AddConsumer(subId uint64, consumerAddress string) error {
- opts, err := v.client.TransactionOpts(v.client.GetDefaultWallet())
- if err != nil {
- return err
- }
- tx, err := v.coordinator.AddConsumer(
- opts,
- subId,
- common.HexToAddress(consumerAddress),
- )
- if err != nil {
- return err
- }
- return v.client.ProcessTransaction(tx)
-}
-
-// EthereumVRFCoordinator represents VRF coordinator contract
-type EthereumVRFCoordinator struct {
- address *common.Address
- client blockchain.EVMClient
- coordinator *solidity_vrf_coordinator_interface.VRFCoordinator
-}
-
-func (v *EthereumVRFCoordinator) Address() string {
- return v.address.Hex()
-}
-
-// HashOfKey get a hash of proving key to use it as a request ID part for VRF
-func (v *EthereumVRFCoordinator) HashOfKey(ctx context.Context, pubKey [2]*big.Int) ([32]byte, error) {
- opts := &bind.CallOpts{
- From: common.HexToAddress(v.client.GetDefaultWallet().Address()),
- Context: ctx,
- }
- hash, err := v.coordinator.HashOfKey(opts, pubKey)
- if err != nil {
- return [32]byte{}, err
- }
- return hash, nil
-}
-
-// RegisterProvingKey register VRF proving key
-func (v *EthereumVRFCoordinator) RegisterProvingKey(
- fee *big.Int,
- oracleAddr string,
- publicProvingKey [2]*big.Int,
- jobID [32]byte,
-) error {
- opts, err := v.client.TransactionOpts(v.client.GetDefaultWallet())
- if err != nil {
- return err
- }
- tx, err := v.coordinator.RegisterProvingKey(opts, fee, common.HexToAddress(oracleAddr), publicProvingKey, jobID)
- if err != nil {
- return err
- }
- return v.client.ProcessTransaction(tx)
-}
-
-// EthereumVRFConsumerV2 represents VRFv2 consumer contract
-type EthereumVRFConsumerV2 struct {
- address *common.Address
- client blockchain.EVMClient
- consumer *vrf_consumer_v2.VRFConsumerV2
-}
-
-// EthereumVRFv2Consumer represents VRFv2 consumer contract
-type EthereumVRFv2Consumer struct {
- address *common.Address
- client blockchain.EVMClient
- consumer *eth_contracts.VRFv2Consumer
-}
-
-// EthereumVRFv2LoadTestConsumer represents VRFv2 consumer contract for performing Load Tests
-type EthereumVRFv2LoadTestConsumer struct {
- address *common.Address
- client blockchain.EVMClient
- consumer *vrf_load_test_with_metrics.VRFV2LoadTestWithMetrics
-}
-
-// CurrentSubscription get current VRFv2 subscription
-func (v *EthereumVRFConsumerV2) CurrentSubscription() (uint64, error) {
- return v.consumer.SSubId(&bind.CallOpts{
- From: common.HexToAddress(v.client.GetDefaultWallet().Address()),
- Context: context.Background(),
- })
-}
-
-// CreateFundedSubscription create funded subscription for VRFv2 randomness
-func (v *EthereumVRFConsumerV2) CreateFundedSubscription(funds *big.Int) error {
- opts, err := v.client.TransactionOpts(v.client.GetDefaultWallet())
- if err != nil {
- return err
- }
- tx, err := v.consumer.CreateSubscriptionAndFund(opts, funds)
- if err != nil {
- return err
- }
- return v.client.ProcessTransaction(tx)
-}
-
-// TopUpSubscriptionFunds add funds to a VRFv2 subscription
-func (v *EthereumVRFConsumerV2) TopUpSubscriptionFunds(funds *big.Int) error {
- opts, err := v.client.TransactionOpts(v.client.GetDefaultWallet())
- if err != nil {
- return err
- }
- tx, err := v.consumer.TopUpSubscription(opts, funds)
- if err != nil {
- return err
- }
- return v.client.ProcessTransaction(tx)
-}
-
-func (v *EthereumVRFConsumerV2) Address() string {
- return v.address.Hex()
-}
-
-func (v *EthereumVRFv2Consumer) Address() string {
- return v.address.Hex()
-}
-
-// GasAvailable get available gas after randomness fulfilled
-func (v *EthereumVRFConsumerV2) GasAvailable() (*big.Int, error) {
- return v.consumer.SGasAvailable(&bind.CallOpts{
- From: common.HexToAddress(v.client.GetDefaultWallet().Address()),
- Context: context.Background(),
- })
-}
-
-func (v *EthereumVRFConsumerV2) 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)
-}
-
-// RequestRandomness request VRFv2 random words
-func (v *EthereumVRFConsumerV2) RequestRandomness(hash [32]byte, subID uint64, confs uint16, gasLimit uint32, numWords uint32) error {
- opts, err := v.client.TransactionOpts(v.client.GetDefaultWallet())
- if err != nil {
- return err
- }
- tx, err := v.consumer.RequestRandomness(opts, hash, subID, confs, gasLimit, numWords)
- if err != nil {
- return err
- }
- log.Info().Interface("Sub ID", subID).
- Interface("Number of Words", numWords).
- Interface("Number of Confirmations", confs).
- Interface("Callback Gas Limit", gasLimit).
- Interface("KeyHash", hex.EncodeToString(hash[:])).
- Interface("Consumer Contract", v.address).
- Msg("RequestRandomness called")
- return v.client.ProcessTransaction(tx)
-}
-
-// RequestRandomness request VRFv2 random words
-func (v *EthereumVRFv2Consumer) RequestRandomness(hash [32]byte, subID uint64, confs uint16, gasLimit uint32, numWords uint32) error {
- opts, err := v.client.TransactionOpts(v.client.GetDefaultWallet())
- if err != nil {
- return err
- }
- tx, err := v.consumer.RequestRandomWords(opts, subID, gasLimit, confs, numWords, hash)
- if err != nil {
- return err
- }
- log.Info().Interface("Sub ID", subID).
- Interface("Number of Words", numWords).
- Interface("Number of Confirmations", confs).
- Interface("Callback Gas Limit", gasLimit).
- Interface("KeyHash", hex.EncodeToString(hash[:])).
- Interface("Consumer Contract", v.address).
- Msg("RequestRandomness called")
- return v.client.ProcessTransaction(tx)
-}
-
-// RandomnessOutput get VRFv2 randomness output (word)
-func (v *EthereumVRFConsumerV2) RandomnessOutput(ctx context.Context, arg0 *big.Int) (*big.Int, error) {
- return v.consumer.SRandomWords(&bind.CallOpts{
- From: common.HexToAddress(v.client.GetDefaultWallet().Address()),
- Context: ctx,
- }, arg0)
-}
-
-func (v *EthereumVRFv2LoadTestConsumer) Address() string {
- return v.address.Hex()
-}
-
-func (v *EthereumVRFv2LoadTestConsumer) RequestRandomness(keyHash [32]byte, subID uint64, requestConfirmations uint16, callbackGasLimit uint32, numWords uint32, requestCount uint16) error {
- opts, err := v.client.TransactionOpts(v.client.GetDefaultWallet())
- if err != nil {
- return err
- }
-
- tx, err := v.consumer.RequestRandomWords(opts, subID, requestConfirmations, keyHash, callbackGasLimit, numWords, requestCount)
- if err != nil {
- return err
- }
- return v.client.ProcessTransaction(tx)
-}
-
-func (v *EthereumVRFv2Consumer) GetRequestStatus(ctx context.Context, requestID *big.Int) (RequestStatus, error) {
- return v.consumer.GetRequestStatus(&bind.CallOpts{
- From: common.HexToAddress(v.client.GetDefaultWallet().Address()),
- Context: ctx,
- }, requestID)
-}
-
-func (v *EthereumVRFv2Consumer) GetLastRequestId(ctx context.Context) (*big.Int, error) {
- return v.consumer.LastRequestId(&bind.CallOpts{
- From: common.HexToAddress(v.client.GetDefaultWallet().Address()),
- Context: ctx,
- })
-}
-
-func (v *EthereumVRFv2LoadTestConsumer) GetRequestStatus(ctx context.Context, requestID *big.Int) (vrf_load_test_with_metrics.GetRequestStatus, error) {
- return v.consumer.GetRequestStatus(&bind.CallOpts{
- From: common.HexToAddress(v.client.GetDefaultWallet().Address()),
- Context: ctx,
- }, requestID)
-}
-
-func (v *EthereumVRFv2LoadTestConsumer) GetLastRequestId(ctx context.Context) (*big.Int, error) {
- return v.consumer.SLastRequestId(&bind.CallOpts{
- From: common.HexToAddress(v.client.GetDefaultWallet().Address()),
- Context: ctx,
- })
-}
-
-func (v *EthereumVRFv2LoadTestConsumer) 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 &VRFLoadTestMetrics{}, err
- }
- fulfilmentCount, err := v.consumer.SResponseCount(&bind.CallOpts{
- From: common.HexToAddress(v.client.GetDefaultWallet().Address()),
- Context: ctx,
- })
-
- if err != nil {
- return &VRFLoadTestMetrics{}, err
- }
- averageFulfillmentInMillions, err := v.consumer.SAverageFulfillmentInMillions(&bind.CallOpts{
- From: common.HexToAddress(v.client.GetDefaultWallet().Address()),
- Context: ctx,
- })
- if err != nil {
- return &VRFLoadTestMetrics{}, err
- }
- slowestFulfillment, err := v.consumer.SSlowestFulfillment(&bind.CallOpts{
- From: common.HexToAddress(v.client.GetDefaultWallet().Address()),
- Context: ctx,
- })
+func (v *EthereumVRFCoordinator) Address() string {
+ return v.address.Hex()
+}
- if err != nil {
- return &VRFLoadTestMetrics{}, err
- }
- fastestFulfillment, err := v.consumer.SFastestFulfillment(&bind.CallOpts{
+// HashOfKey get a hash of proving key to use it as a request ID part for VRF
+func (v *EthereumVRFCoordinator) HashOfKey(ctx context.Context, pubKey [2]*big.Int) ([32]byte, error) {
+ opts := &bind.CallOpts{
From: common.HexToAddress(v.client.GetDefaultWallet().Address()),
Context: ctx,
- })
+ }
+ hash, err := v.coordinator.HashOfKey(opts, pubKey)
if err != nil {
- return &VRFLoadTestMetrics{}, err
+ return [32]byte{}, err
}
-
- return &VRFLoadTestMetrics{
- requestCount,
- fulfilmentCount,
- averageFulfillmentInMillions,
- slowestFulfillment,
- fastestFulfillment,
- }, nil
+ return hash, nil
}
-// GetAllRandomWords get all VRFv2 randomness output words
-func (v *EthereumVRFConsumerV2) GetAllRandomWords(ctx context.Context, num int) ([]*big.Int, error) {
- words := make([]*big.Int, 0)
- for i := 0; i < num; i++ {
- word, err := v.consumer.SRandomWords(&bind.CallOpts{
- From: common.HexToAddress(v.client.GetDefaultWallet().Address()),
- Context: ctx,
- }, big.NewInt(int64(i)))
- if err != nil {
- return nil, err
- }
- words = append(words, word)
+// RegisterProvingKey register VRF proving key
+func (v *EthereumVRFCoordinator) RegisterProvingKey(
+ fee *big.Int,
+ oracleAddr string,
+ publicProvingKey [2]*big.Int,
+ jobID [32]byte,
+) error {
+ opts, err := v.client.TransactionOpts(v.client.GetDefaultWallet())
+ if err != nil {
+ return err
}
- return words, nil
-}
-
-// LoadExistingConsumer loads an EthereumVRFConsumerV2 with a specified address
-func (v *EthereumVRFConsumerV2) LoadExistingConsumer(address string, client blockchain.EVMClient) error {
- a := common.HexToAddress(address)
- consumer, err := vrf_consumer_v2.NewVRFConsumerV2(a, client.(*blockchain.EthereumClient).Client)
+ tx, err := v.coordinator.RegisterProvingKey(opts, fee, common.HexToAddress(oracleAddr), publicProvingKey, jobID)
if err != nil {
return err
}
- v.client = client
- v.consumer = consumer
- v.address = &a
- return nil
-}
-
-// EthereumVRFConsumer represents VRF consumer contract
-type EthereumVRFConsumer struct {
- address *common.Address
- client blockchain.EVMClient
- consumer *solidity_vrf_consumer_interface.VRFConsumer
+ return v.client.ProcessTransaction(tx)
}
func (v *EthereumVRFConsumer) Address() string {
@@ -738,16 +217,6 @@ func (v *EthereumVRFConsumer) RandomnessOutput(ctx context.Context) (*big.Int, e
return out, nil
}
-// VRFConsumerRoundConfirmer is a header subscription that awaits for a certain VRF round to be completed
-type VRFConsumerRoundConfirmer struct {
- consumer VRFConsumer
- roundID *big.Int
- doneChan chan struct{}
- context context.Context
- cancel context.CancelFunc
- done bool
-}
-
// NewVRFConsumerRoundConfirmer provides a new instance of a NewVRFConsumerRoundConfirmer
func NewVRFConsumerRoundConfirmer(
contract VRFConsumer,
@@ -806,13 +275,6 @@ func (f *VRFConsumerRoundConfirmer) Wait() error {
}
}
-// EthereumVRF represents a VRF contract
-type EthereumVRF struct {
- client blockchain.EVMClient
- vrf *solidity_vrf_wrapper.VRF
- address *common.Address
-}
-
// Fund sends specified currencies to the contract
func (v *EthereumVRF) Fund(ethAmount *big.Float) error {
gasEstimates, err := v.client.EstimateGas(ethereum.CallMsg{})
@@ -831,449 +293,6 @@ func (v *EthereumVRF) ProofLength(ctxt context.Context) (*big.Int, error) {
return v.vrf.PROOFLENGTH(opts)
}
-// EthereumDKG represents DKG contract
-type EthereumDKG struct {
- address *common.Address
- client blockchain.EVMClient
- dkg *dkg.DKG
-}
-
-func (dkgContract *EthereumDKG) Address() string {
- return dkgContract.address.Hex()
-}
-
-func (dkgContract *EthereumDKG) AddClient(keyID string, clientAddress string) error {
- keyIDBytes, err := decodeHexTo32ByteArray(keyID)
- if err != nil {
- return err
- }
- opts, err := dkgContract.client.TransactionOpts(dkgContract.client.GetDefaultWallet())
- if err != nil {
- return err
- }
- tx, err := dkgContract.dkg.AddClient(
- opts,
- keyIDBytes,
- common.HexToAddress(clientAddress),
- )
- if err != nil {
- return err
- }
- return dkgContract.client.ProcessTransaction(tx)
-
-}
-
-func (dkgContract *EthereumDKG) SetConfig(
- signerAddresses []common.Address,
- transmitterAddresses []common.Address,
- f uint8,
- onchainConfig []byte,
- offchainConfigVersion uint64,
- offchainConfig []byte,
-) error {
- opts, err := dkgContract.client.TransactionOpts(dkgContract.client.GetDefaultWallet())
- if err != nil {
- return err
- }
- tx, err := dkgContract.dkg.SetConfig(
- opts,
- signerAddresses,
- transmitterAddresses,
- f,
- onchainConfig,
- offchainConfigVersion,
- offchainConfig,
- )
- if err != nil {
- return err
- }
- return dkgContract.client.ProcessTransaction(tx)
-}
-
-func (dkgContract *EthereumDKG) WaitForTransmittedEvent(timeout time.Duration) (*dkg.DKGTransmitted, error) {
- transmittedEventsChannel := make(chan *dkg.DKGTransmitted)
- subscription, err := dkgContract.dkg.WatchTransmitted(nil, transmittedEventsChannel)
- if err != nil {
- return nil, err
- }
- defer subscription.Unsubscribe()
-
- for {
- select {
- case err = <-subscription.Err():
- return nil, err
- case <-time.After(timeout):
- return nil, errors.New("timeout waiting for DKGTransmitted event")
- case transmittedEvent := <-transmittedEventsChannel:
- return transmittedEvent, nil
- }
- }
-}
-
-func (dkgContract *EthereumDKG) WaitForConfigSetEvent(timeout time.Duration) (*dkg.DKGConfigSet, error) {
- configSetEventsChannel := make(chan *dkg.DKGConfigSet)
- subscription, err := dkgContract.dkg.WatchConfigSet(nil, configSetEventsChannel)
- if err != nil {
- return nil, err
- }
- defer subscription.Unsubscribe()
-
- for {
- select {
- case err = <-subscription.Err():
- return nil, err
- case <-time.After(timeout):
- return nil, errors.New("timeout waiting for DKGConfigSet event")
- case configSetEvent := <-configSetEventsChannel:
- return configSetEvent, nil
- }
- }
-}
-
-// EthereumVRFCoordinatorV3 represents VRFCoordinatorV3 contract
-type EthereumVRFCoordinatorV3 struct {
- address *common.Address
- client blockchain.EVMClient
- vrfCoordinatorV3 *vrf_coordinator.VRFCoordinator
-}
-
-func (coordinator *EthereumVRFCoordinatorV3) Address() string {
- return coordinator.address.Hex()
-}
-
-func (coordinator *EthereumVRFCoordinatorV3) SetProducer(producerAddress string) error {
- opts, err := coordinator.client.TransactionOpts(coordinator.client.GetDefaultWallet())
- if err != nil {
- return err
- }
- tx, err := coordinator.vrfCoordinatorV3.SetProducer(
- opts,
- common.HexToAddress(producerAddress),
- )
- if err != nil {
- return err
- }
- return coordinator.client.ProcessTransaction(tx)
-}
-
-func (coordinator *EthereumVRFCoordinatorV3) CreateSubscription() error {
- opts, err := coordinator.client.TransactionOpts(coordinator.client.GetDefaultWallet())
- if err != nil {
- return err
- }
- tx, err := coordinator.vrfCoordinatorV3.CreateSubscription(
- opts,
- )
- if err != nil {
- return err
- }
- return coordinator.client.ProcessTransaction(tx)
-}
-
-func (coordinator *EthereumVRFCoordinatorV3) FindSubscriptionID() (*big.Int, error) {
- fopts := &bind.FilterOpts{}
- owner := coordinator.client.GetDefaultWallet().Address()
-
- subscriptionIterator, err := coordinator.vrfCoordinatorV3.FilterSubscriptionCreated(
- fopts,
- nil,
- []common.Address{common.HexToAddress(owner)},
- )
- if err != nil {
- return nil, err
- }
-
- if !subscriptionIterator.Next() {
- return nil, fmt.Errorf("expected at least 1 subID for the given owner %s", owner)
- }
-
- return subscriptionIterator.Event.SubId, nil
-}
-
-func (coordinator *EthereumVRFCoordinatorV3) AddConsumer(subId *big.Int, consumerAddress string) error {
- opts, err := coordinator.client.TransactionOpts(coordinator.client.GetDefaultWallet())
- if err != nil {
- return err
- }
- tx, err := coordinator.vrfCoordinatorV3.AddConsumer(
- opts,
- subId,
- common.HexToAddress(consumerAddress),
- )
- if err != nil {
- return err
- }
- return coordinator.client.ProcessTransaction(tx)
-}
-
-func (coordinator *EthereumVRFCoordinatorV3) SetConfig(maxCallbackGasLimit uint32, maxCallbackArgumentsLength uint32) error {
- opts, err := coordinator.client.TransactionOpts(coordinator.client.GetDefaultWallet())
- if err != nil {
- return err
- }
- tx, err := coordinator.vrfCoordinatorV3.SetCallbackConfig(
- opts,
- vrf_coordinator.VRFCoordinatorCallbackConfig{
- MaxCallbackGasLimit: maxCallbackGasLimit,
- MaxCallbackArgumentsLength: maxCallbackArgumentsLength, // 5 EVM words
- },
- )
- if err != nil {
- return err
- }
- return coordinator.client.ProcessTransaction(tx)
-}
-
-// EthereumVRFBeacon represents VRFBeacon contract
-type EthereumVRFBeacon struct {
- address *common.Address
- client blockchain.EVMClient
- vrfBeacon *vrf_beacon.VRFBeacon
-}
-
-func (beacon *EthereumVRFBeacon) Address() string {
- return beacon.address.Hex()
-}
-
-func (beacon *EthereumVRFBeacon) SetPayees(transmitterAddresses []common.Address, payeesAddresses []common.Address) error {
- opts, err := beacon.client.TransactionOpts(beacon.client.GetDefaultWallet())
- if err != nil {
- return err
- }
-
- tx, err := beacon.vrfBeacon.SetPayees(
- opts,
- transmitterAddresses,
- payeesAddresses,
- )
- if err != nil {
- return err
- }
- return beacon.client.ProcessTransaction(tx)
-}
-
-func (beacon *EthereumVRFBeacon) SetConfig(
- signerAddresses []common.Address,
- transmitterAddresses []common.Address,
- f uint8,
- onchainConfig []byte,
- offchainConfigVersion uint64,
- offchainConfig []byte,
-) error {
- opts, err := beacon.client.TransactionOpts(beacon.client.GetDefaultWallet())
- if err != nil {
- return err
- }
- tx, err := beacon.vrfBeacon.SetConfig(
- opts,
- signerAddresses,
- transmitterAddresses,
- f,
- onchainConfig,
- offchainConfigVersion,
- offchainConfig,
- )
- if err != nil {
- return err
- }
- return beacon.client.ProcessTransaction(tx)
-}
-
-func (beacon *EthereumVRFBeacon) WaitForConfigSetEvent(timeout time.Duration) (*vrf_beacon.VRFBeaconConfigSet, error) {
- configSetEventsChannel := make(chan *vrf_beacon.VRFBeaconConfigSet)
- subscription, err := beacon.vrfBeacon.WatchConfigSet(nil, configSetEventsChannel)
- if err != nil {
- return nil, err
- }
- defer subscription.Unsubscribe()
-
- for {
- select {
- case err := <-subscription.Err():
- return nil, err
- case <-time.After(timeout):
- return nil, fmt.Errorf("timeout waiting for config set event")
- case configSetEvent := <-configSetEventsChannel:
- return configSetEvent, nil
- }
- }
-}
-
-func (beacon *EthereumVRFBeacon) WaitForNewTransmissionEvent(timeout time.Duration) (*vrf_beacon.VRFBeaconNewTransmission, error) {
- newTransmissionEventsChannel := make(chan *vrf_beacon.VRFBeaconNewTransmission)
- subscription, err := beacon.vrfBeacon.WatchNewTransmission(nil, newTransmissionEventsChannel, nil)
- if err != nil {
- return nil, err
- }
- defer subscription.Unsubscribe()
-
- for {
- select {
- case err := <-subscription.Err():
- return nil, err
- case <-time.After(timeout):
- return nil, fmt.Errorf("timeout waiting for new transmission event")
- case newTransmissionEvent := <-newTransmissionEventsChannel:
- return newTransmissionEvent, nil
- }
- }
-}
-
-func (beacon *EthereumVRFBeacon) LatestConfigDigestAndEpoch(ctx context.Context) (vrf_beacon.LatestConfigDigestAndEpoch,
- error) {
- opts := &bind.CallOpts{
- From: common.HexToAddress(beacon.client.GetDefaultWallet().Address()),
- Context: ctx,
- }
- return beacon.vrfBeacon.LatestConfigDigestAndEpoch(opts)
-}
-
-// EthereumVRFBeaconConsumer represents VRFBeaconConsumer contract
-type EthereumVRFBeaconConsumer struct {
- address *common.Address
- client blockchain.EVMClient
- vrfBeaconConsumer *vrf_beacon_consumer.BeaconVRFConsumer
-}
-
-func (consumer *EthereumVRFBeaconConsumer) Address() string {
- return consumer.address.Hex()
-}
-
-func (consumer *EthereumVRFBeaconConsumer) RequestRandomness(
- numWords uint16,
- subID, confirmationDelayArg *big.Int,
-) (*types.Receipt, error) {
- opts, err := consumer.client.TransactionOpts(consumer.client.GetDefaultWallet())
- if err != nil {
- return nil, errors.Wrap(err, "TransactionOpts failed")
- }
- tx, err := consumer.vrfBeaconConsumer.TestRequestRandomness(
- opts,
- numWords,
- subID,
- confirmationDelayArg,
- )
- if err != nil {
- return nil, errors.Wrap(err, "TestRequestRandomness failed")
- }
- err = consumer.client.ProcessTransaction(tx)
- if err != nil {
- return nil, errors.Wrap(err, "ProcessTransaction failed")
- }
- err = consumer.client.WaitForEvents()
-
- if err != nil {
- return nil, errors.Wrap(err, "WaitForEvents failed")
- }
- receipt, err := consumer.client.GetTxReceipt(tx.Hash())
- if err != nil {
- return nil, errors.Wrap(err, "GetTxReceipt failed")
- }
- log.Info().Interface("Sub ID", subID).
- Interface("Number of Words", numWords).
- Interface("Number of Confirmations", confirmationDelayArg).
- Msg("RequestRandomness called")
- return receipt, nil
-}
-
-func (consumer *EthereumVRFBeaconConsumer) RedeemRandomness(
- subID, requestID *big.Int,
-) error {
- opts, err := consumer.client.TransactionOpts(consumer.client.GetDefaultWallet())
- if err != nil {
- return err
- }
- tx, err := consumer.vrfBeaconConsumer.TestRedeemRandomness(
- opts,
- subID,
- requestID,
- )
- if err != nil {
- return err
- }
- log.Info().Interface("Sub ID", subID).
- Interface("Request ID", requestID).
- Msg("RedeemRandomness called")
- return consumer.client.ProcessTransaction(tx)
-}
-
-func (consumer *EthereumVRFBeaconConsumer) RequestRandomnessFulfillment(
- numWords uint16,
- subID, confirmationDelayArg *big.Int,
- requestGasLimit uint32,
- callbackGasLimit uint32,
- arguments []byte,
-) (*types.Receipt, error) {
- opts, err := consumer.client.TransactionOpts(consumer.client.GetDefaultWallet())
- if err != nil {
- return nil, err
- }
- // overriding gas limit because gas estimated by TestRequestRandomnessFulfillment
- // is incorrect
- opts.GasLimit = uint64(requestGasLimit)
- tx, err := consumer.vrfBeaconConsumer.TestRequestRandomnessFulfillment(
- opts,
- subID,
- numWords,
- confirmationDelayArg,
- callbackGasLimit,
- arguments,
- )
- if err != nil {
- return nil, errors.Wrap(err, "TestRequestRandomnessFulfillment failed")
- }
- err = consumer.client.ProcessTransaction(tx)
- if err != nil {
- return nil, errors.Wrap(err, "ProcessTransaction failed")
- }
- err = consumer.client.WaitForEvents()
-
- if err != nil {
- return nil, errors.Wrap(err, "WaitForEvents failed")
- }
- receipt, err := consumer.client.GetTxReceipt(tx.Hash())
- if err != nil {
- return nil, errors.Wrap(err, "GetTxReceipt failed")
- }
- log.Info().Interface("Sub ID", subID).
- Interface("Number of Words", numWords).
- Interface("Number of Confirmations", confirmationDelayArg).
- Interface("Callback Gas Limit", callbackGasLimit).
- Msg("RequestRandomnessFulfillment called")
- return receipt, nil
-}
-
-func (consumer *EthereumVRFBeaconConsumer) IBeaconPeriodBlocks(ctx context.Context) (*big.Int, error) {
- opts := &bind.CallOpts{
- From: common.HexToAddress(consumer.client.GetDefaultWallet().Address()),
- Context: ctx,
- }
- return consumer.vrfBeaconConsumer.IBeaconPeriodBlocks(opts)
-}
-
-func (consumer *EthereumVRFBeaconConsumer) GetRequestIdsBy(ctx context.Context, nextBeaconOutputHeight *big.Int, confDelay *big.Int) (*big.Int, error) {
- opts := &bind.CallOpts{
- From: common.HexToAddress(consumer.client.GetDefaultWallet().Address()),
- Context: ctx,
- }
- return consumer.vrfBeaconConsumer.SRequestsIDs(opts, nextBeaconOutputHeight, confDelay)
-}
-
-func (consumer *EthereumVRFBeaconConsumer) GetRandomnessByRequestId(ctx context.Context, requestID *big.Int, numWordIndex *big.Int) (*big.Int, error) {
- opts := &bind.CallOpts{
- From: common.HexToAddress(consumer.client.GetDefaultWallet().Address()),
- Context: ctx,
- }
- return consumer.vrfBeaconConsumer.SReceivedRandomnessByRequestID(opts, requestID, numWordIndex)
-}
-
-// EthereumBatchBlockhashStore represents BatchBlockhashStore contract
-type EthereumBatchBlockhashStore struct {
- address *common.Address
- client blockchain.EVMClient
- batchBlockhashStore *batch_blockhash_store.BatchBlockhashStore
-}
-
func (v *EthereumBatchBlockhashStore) Address() string {
return v.address.Hex()
}
diff --git a/integration-tests/contracts/ethereum_vrfv2_contracts.go b/integration-tests/contracts/ethereum_vrfv2_contracts.go
new file mode 100644
index 00000000000..88dfe58eb2f
--- /dev/null
+++ b/integration-tests/contracts/ethereum_vrfv2_contracts.go
@@ -0,0 +1,435 @@
+package contracts
+
+import (
+ "context"
+ "encoding/hex"
+ "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/rs/zerolog/log"
+ "github.com/smartcontractkit/chainlink-testing-framework/blockchain"
+ eth_contracts "github.com/smartcontractkit/chainlink/integration-tests/contracts/ethereum"
+ "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"
+ "math/big"
+)
+
+// EthereumVRFCoordinatorV2 represents VRFV2 coordinator contract
+type EthereumVRFCoordinatorV2 struct {
+ address *common.Address
+ client blockchain.EVMClient
+ coordinator *vrf_coordinator_v2.VRFCoordinatorV2
+}
+
+// EthereumVRFConsumerV2 represents VRFv2 consumer contract
+type EthereumVRFConsumerV2 struct {
+ address *common.Address
+ client blockchain.EVMClient
+ consumer *vrf_consumer_v2.VRFConsumerV2
+}
+
+// EthereumVRFv2Consumer represents VRFv2 consumer contract
+type EthereumVRFv2Consumer struct {
+ address *common.Address
+ client blockchain.EVMClient
+ consumer *eth_contracts.VRFv2Consumer
+}
+
+// EthereumVRFv2LoadTestConsumer represents VRFv2 consumer contract for performing Load Tests
+type EthereumVRFv2LoadTestConsumer struct {
+ address *common.Address
+ client blockchain.EVMClient
+ consumer *vrf_load_test_with_metrics.VRFV2LoadTestWithMetrics
+}
+
+// DeployVRFCoordinatorV2 deploys VRFV2 coordinator contract
+func (e *EthereumContractDeployer) DeployVRFCoordinatorV2(linkAddr string, bhsAddr string, linkEthFeedAddr string) (VRFCoordinatorV2, error) {
+ address, _, instance, err := e.client.DeployContract("VRFCoordinatorV2", func(
+ auth *bind.TransactOpts,
+ backend bind.ContractBackend,
+ ) (common.Address, *types.Transaction, interface{}, error) {
+ return vrf_coordinator_v2.DeployVRFCoordinatorV2(auth, backend, common.HexToAddress(linkAddr), common.HexToAddress(bhsAddr), common.HexToAddress(linkEthFeedAddr))
+ })
+ if err != nil {
+ return nil, err
+ }
+ return &EthereumVRFCoordinatorV2{
+ client: e.client,
+ coordinator: instance.(*vrf_coordinator_v2.VRFCoordinatorV2),
+ address: address,
+ }, err
+}
+
+// DeployVRFConsumerV2 deploys VRFv@ consumer contract
+func (e *EthereumContractDeployer) DeployVRFConsumerV2(linkAddr string, coordinatorAddr string) (VRFConsumerV2, error) {
+ address, _, instance, err := e.client.DeployContract("VRFConsumerV2", func(
+ auth *bind.TransactOpts,
+ backend bind.ContractBackend,
+ ) (common.Address, *types.Transaction, interface{}, error) {
+ return vrf_consumer_v2.DeployVRFConsumerV2(auth, backend, common.HexToAddress(coordinatorAddr), common.HexToAddress(linkAddr))
+ })
+ if err != nil {
+ return nil, err
+ }
+ return &EthereumVRFConsumerV2{
+ client: e.client,
+ consumer: instance.(*vrf_consumer_v2.VRFConsumerV2),
+ address: address,
+ }, err
+}
+
+func (e *EthereumContractDeployer) DeployVRFv2Consumer(coordinatorAddr string) (VRFv2Consumer, error) {
+ address, _, instance, err := e.client.DeployContract("VRFv2Consumer", func(
+ auth *bind.TransactOpts,
+ backend bind.ContractBackend,
+ ) (common.Address, *types.Transaction, interface{}, error) {
+ return eth_contracts.DeployVRFv2Consumer(auth, backend, common.HexToAddress(coordinatorAddr))
+ })
+ if err != nil {
+ return nil, err
+ }
+ return &EthereumVRFv2Consumer{
+ client: e.client,
+ consumer: instance.(*eth_contracts.VRFv2Consumer),
+ address: address,
+ }, err
+}
+
+// DeployVRFv2LoadTestConsumer(coordinatorAddr string) (VRFv2Consumer, error)
+func (e *EthereumContractDeployer) DeployVRFv2LoadTestConsumer(coordinatorAddr string) (VRFv2LoadTestConsumer, error) {
+ address, _, instance, err := e.client.DeployContract("VRFV2LoadTestWithMetrics", func(
+ auth *bind.TransactOpts,
+ backend bind.ContractBackend,
+ ) (common.Address, *types.Transaction, interface{}, error) {
+ return vrf_load_test_with_metrics.DeployVRFV2LoadTestWithMetrics(auth, backend, common.HexToAddress(coordinatorAddr))
+ })
+ if err != nil {
+ return nil, err
+ }
+ return &EthereumVRFv2LoadTestConsumer{
+ client: e.client,
+ consumer: instance.(*vrf_load_test_with_metrics.VRFV2LoadTestWithMetrics),
+ address: address,
+ }, err
+}
+
+func (v *EthereumVRFCoordinatorV2) Address() string {
+ return v.address.Hex()
+}
+
+func (v *EthereumVRFCoordinatorV2) HashOfKey(ctx context.Context, pubKey [2]*big.Int) ([32]byte, error) {
+ opts := &bind.CallOpts{
+ From: common.HexToAddress(v.client.GetDefaultWallet().Address()),
+ Context: ctx,
+ }
+ hash, err := v.coordinator.HashOfKey(opts, pubKey)
+ if err != nil {
+ return [32]byte{}, err
+ }
+ return hash, nil
+}
+
+func (v *EthereumVRFCoordinatorV2) GetSubscription(ctx context.Context, subID uint64) (vrf_coordinator_v2.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_v2.GetSubscription{}, err
+ }
+ return subscription, nil
+}
+
+func (v *EthereumVRFCoordinatorV2) SetConfig(minimumRequestConfirmations uint16, maxGasLimit uint32, stalenessSeconds uint32, gasAfterPaymentCalculation uint32, fallbackWeiPerUnitLink *big.Int, feeConfig vrf_coordinator_v2.VRFCoordinatorV2FeeConfig) error {
+ opts, err := v.client.TransactionOpts(v.client.GetDefaultWallet())
+ if err != nil {
+ return err
+ }
+ tx, err := v.coordinator.SetConfig(
+ opts,
+ minimumRequestConfirmations,
+ maxGasLimit,
+ stalenessSeconds,
+ gasAfterPaymentCalculation,
+ fallbackWeiPerUnitLink,
+ feeConfig,
+ )
+ if err != nil {
+ return err
+ }
+ return v.client.ProcessTransaction(tx)
+}
+
+func (v *EthereumVRFCoordinatorV2) RegisterProvingKey(
+ oracleAddr string,
+ publicProvingKey [2]*big.Int,
+) error {
+ opts, err := v.client.TransactionOpts(v.client.GetDefaultWallet())
+ if err != nil {
+ return err
+ }
+ tx, err := v.coordinator.RegisterProvingKey(opts, common.HexToAddress(oracleAddr), publicProvingKey)
+ if err != nil {
+ return err
+ }
+ return v.client.ProcessTransaction(tx)
+}
+
+func (v *EthereumVRFCoordinatorV2) CreateSubscription() error {
+ opts, err := v.client.TransactionOpts(v.client.GetDefaultWallet())
+ if err != nil {
+ return err
+ }
+ tx, err := v.coordinator.CreateSubscription(opts)
+ if err != nil {
+ return err
+ }
+ return v.client.ProcessTransaction(tx)
+}
+
+func (v *EthereumVRFCoordinatorV2) AddConsumer(subId uint64, consumerAddress string) error {
+ opts, err := v.client.TransactionOpts(v.client.GetDefaultWallet())
+ if err != nil {
+ return err
+ }
+ tx, err := v.coordinator.AddConsumer(
+ opts,
+ subId,
+ common.HexToAddress(consumerAddress),
+ )
+ if err != nil {
+ return err
+ }
+ return v.client.ProcessTransaction(tx)
+}
+
+// GetAllRandomWords get all VRFv2 randomness output words
+func (v *EthereumVRFConsumerV2) GetAllRandomWords(ctx context.Context, num int) ([]*big.Int, error) {
+ words := make([]*big.Int, 0)
+ for i := 0; i < num; i++ {
+ word, err := v.consumer.SRandomWords(&bind.CallOpts{
+ From: common.HexToAddress(v.client.GetDefaultWallet().Address()),
+ Context: ctx,
+ }, big.NewInt(int64(i)))
+ if err != nil {
+ return nil, err
+ }
+ words = append(words, word)
+ }
+ return words, nil
+}
+
+// LoadExistingConsumer loads an EthereumVRFConsumerV2 with a specified address
+func (v *EthereumVRFConsumerV2) LoadExistingConsumer(address string, client blockchain.EVMClient) error {
+ a := common.HexToAddress(address)
+ consumer, err := vrf_consumer_v2.NewVRFConsumerV2(a, client.(*blockchain.EthereumClient).Client)
+ if err != nil {
+ return err
+ }
+ v.client = client
+ v.consumer = consumer
+ v.address = &a
+ return nil
+}
+
+// CreateFundedSubscription create funded subscription for VRFv2 randomness
+func (v *EthereumVRFConsumerV2) CreateFundedSubscription(funds *big.Int) error {
+ opts, err := v.client.TransactionOpts(v.client.GetDefaultWallet())
+ if err != nil {
+ return err
+ }
+ tx, err := v.consumer.CreateSubscriptionAndFund(opts, funds)
+ if err != nil {
+ return err
+ }
+ return v.client.ProcessTransaction(tx)
+}
+
+// TopUpSubscriptionFunds add funds to a VRFv2 subscription
+func (v *EthereumVRFConsumerV2) TopUpSubscriptionFunds(funds *big.Int) error {
+ opts, err := v.client.TransactionOpts(v.client.GetDefaultWallet())
+ if err != nil {
+ return err
+ }
+ tx, err := v.consumer.TopUpSubscription(opts, funds)
+ if err != nil {
+ return err
+ }
+ return v.client.ProcessTransaction(tx)
+}
+
+func (v *EthereumVRFConsumerV2) Address() string {
+ return v.address.Hex()
+}
+
+func (v *EthereumVRFv2Consumer) Address() string {
+ return v.address.Hex()
+}
+
+// CurrentSubscription get current VRFv2 subscription
+func (v *EthereumVRFConsumerV2) CurrentSubscription() (uint64, error) {
+ return v.consumer.SSubId(&bind.CallOpts{
+ From: common.HexToAddress(v.client.GetDefaultWallet().Address()),
+ Context: context.Background(),
+ })
+}
+
+// GasAvailable get available gas after randomness fulfilled
+func (v *EthereumVRFConsumerV2) GasAvailable() (*big.Int, error) {
+ return v.consumer.SGasAvailable(&bind.CallOpts{
+ From: common.HexToAddress(v.client.GetDefaultWallet().Address()),
+ Context: context.Background(),
+ })
+}
+
+func (v *EthereumVRFConsumerV2) 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)
+}
+
+// RequestRandomness request VRFv2 random words
+func (v *EthereumVRFConsumerV2) RequestRandomness(hash [32]byte, subID uint64, confs uint16, gasLimit uint32, numWords uint32) error {
+ opts, err := v.client.TransactionOpts(v.client.GetDefaultWallet())
+ if err != nil {
+ return err
+ }
+ tx, err := v.consumer.RequestRandomness(opts, hash, subID, confs, gasLimit, numWords)
+ if err != nil {
+ return err
+ }
+ log.Info().Interface("Sub ID", subID).
+ Interface("Number of Words", numWords).
+ Interface("Number of Confirmations", confs).
+ Interface("Callback Gas Limit", gasLimit).
+ Interface("KeyHash", hex.EncodeToString(hash[:])).
+ Interface("Consumer Contract", v.address).
+ Msg("RequestRandomness called")
+ return v.client.ProcessTransaction(tx)
+}
+
+// RequestRandomness request VRFv2 random words
+func (v *EthereumVRFv2Consumer) RequestRandomness(hash [32]byte, subID uint64, confs uint16, gasLimit uint32, numWords uint32) error {
+ opts, err := v.client.TransactionOpts(v.client.GetDefaultWallet())
+ if err != nil {
+ return err
+ }
+ tx, err := v.consumer.RequestRandomWords(opts, subID, gasLimit, confs, numWords, hash)
+ if err != nil {
+ return err
+ }
+ log.Info().Interface("Sub ID", subID).
+ Interface("Number of Words", numWords).
+ Interface("Number of Confirmations", confs).
+ Interface("Callback Gas Limit", gasLimit).
+ Interface("KeyHash", hex.EncodeToString(hash[:])).
+ Interface("Consumer Contract", v.address).
+ Msg("RequestRandomness called")
+ return v.client.ProcessTransaction(tx)
+}
+
+// RandomnessOutput get VRFv2 randomness output (word)
+func (v *EthereumVRFConsumerV2) RandomnessOutput(ctx context.Context, arg0 *big.Int) (*big.Int, error) {
+ return v.consumer.SRandomWords(&bind.CallOpts{
+ From: common.HexToAddress(v.client.GetDefaultWallet().Address()),
+ Context: ctx,
+ }, arg0)
+}
+
+func (v *EthereumVRFv2LoadTestConsumer) Address() string {
+ return v.address.Hex()
+}
+
+func (v *EthereumVRFv2LoadTestConsumer) RequestRandomness(keyHash [32]byte, subID uint64, requestConfirmations uint16, callbackGasLimit uint32, numWords uint32, requestCount uint16) error {
+ opts, err := v.client.TransactionOpts(v.client.GetDefaultWallet())
+ if err != nil {
+ return err
+ }
+
+ tx, err := v.consumer.RequestRandomWords(opts, subID, requestConfirmations, keyHash, callbackGasLimit, numWords, requestCount)
+ if err != nil {
+ return err
+ }
+ return v.client.ProcessTransaction(tx)
+}
+
+func (v *EthereumVRFv2Consumer) GetRequestStatus(ctx context.Context, requestID *big.Int) (RequestStatus, error) {
+ return v.consumer.GetRequestStatus(&bind.CallOpts{
+ From: common.HexToAddress(v.client.GetDefaultWallet().Address()),
+ Context: ctx,
+ }, requestID)
+}
+
+func (v *EthereumVRFv2Consumer) GetLastRequestId(ctx context.Context) (*big.Int, error) {
+ return v.consumer.LastRequestId(&bind.CallOpts{
+ From: common.HexToAddress(v.client.GetDefaultWallet().Address()),
+ Context: ctx,
+ })
+}
+
+func (v *EthereumVRFv2LoadTestConsumer) GetRequestStatus(ctx context.Context, requestID *big.Int) (vrf_load_test_with_metrics.GetRequestStatus, error) {
+ return v.consumer.GetRequestStatus(&bind.CallOpts{
+ From: common.HexToAddress(v.client.GetDefaultWallet().Address()),
+ Context: ctx,
+ }, requestID)
+}
+
+func (v *EthereumVRFv2LoadTestConsumer) GetLastRequestId(ctx context.Context) (*big.Int, error) {
+ return v.consumer.SLastRequestId(&bind.CallOpts{
+ From: common.HexToAddress(v.client.GetDefaultWallet().Address()),
+ Context: ctx,
+ })
+}
+
+func (v *EthereumVRFv2LoadTestConsumer) 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 &VRFLoadTestMetrics{}, err
+ }
+ fulfilmentCount, err := v.consumer.SResponseCount(&bind.CallOpts{
+ From: common.HexToAddress(v.client.GetDefaultWallet().Address()),
+ Context: ctx,
+ })
+
+ if err != nil {
+ return &VRFLoadTestMetrics{}, err
+ }
+ averageFulfillmentInMillions, err := v.consumer.SAverageFulfillmentInMillions(&bind.CallOpts{
+ From: common.HexToAddress(v.client.GetDefaultWallet().Address()),
+ Context: ctx,
+ })
+ if err != nil {
+ return &VRFLoadTestMetrics{}, err
+ }
+ slowestFulfillment, err := v.consumer.SSlowestFulfillment(&bind.CallOpts{
+ From: common.HexToAddress(v.client.GetDefaultWallet().Address()),
+ Context: ctx,
+ })
+
+ if err != nil {
+ return &VRFLoadTestMetrics{}, err
+ }
+ fastestFulfillment, err := v.consumer.SFastestFulfillment(&bind.CallOpts{
+ From: common.HexToAddress(v.client.GetDefaultWallet().Address()),
+ Context: ctx,
+ })
+ if err != nil {
+ return &VRFLoadTestMetrics{}, err
+ }
+
+ return &VRFLoadTestMetrics{
+ requestCount,
+ fulfilmentCount,
+ averageFulfillmentInMillions,
+ slowestFulfillment,
+ fastestFulfillment,
+ }, nil
+}
diff --git a/integration-tests/contracts/ethereum_vrfv2plus_contracts.go b/integration-tests/contracts/ethereum_vrfv2plus_contracts.go
new file mode 100644
index 00000000000..d07492d0df1
--- /dev/null
+++ b/integration-tests/contracts/ethereum_vrfv2plus_contracts.go
@@ -0,0 +1,875 @@
+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_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"
+ "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrfv2plus_wrapper_load_test_consumer"
+)
+
+type EthereumVRFCoordinatorV2_5 struct {
+ address *common.Address
+ client blockchain.EVMClient
+ coordinator vrf_coordinator_v2_5.VRFCoordinatorV25Interface
+}
+
+type EthereumVRFCoordinatorV2PlusUpgradedVersion struct {
+ address *common.Address
+ client blockchain.EVMClient
+ coordinator *vrf_v2plus_upgraded_version.VRFCoordinatorV2PlusUpgradedVersion
+}
+
+// EthereumVRFv2PlusLoadTestConsumer represents VRFv2Plus consumer contract for performing Load Tests
+type EthereumVRFv2PlusLoadTestConsumer struct {
+ address *common.Address
+ client blockchain.EVMClient
+ consumer *vrf_v2plus_load_test_with_metrics.VRFV2PlusLoadTestWithMetrics
+}
+
+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_v2_5.DeployVRFCoordinatorV25(auth, backend, common.HexToAddress(bhsAddr))
+ })
+ if err != nil {
+ return nil, err
+ }
+ return &EthereumVRFCoordinatorV2_5{
+ client: e.client,
+ coordinator: instance.(*vrf_coordinator_v2_5.VRFCoordinatorV25),
+ address: address,
+ }, err
+}
+
+func (v *EthereumVRFCoordinatorV2_5) Address() string {
+ return v.address.Hex()
+}
+
+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,
+ }
+ hash, err := v.coordinator.HashOfKey(opts, pubKey)
+ if err != nil {
+ return [32]byte{}, err
+ }
+ return hash, nil
+}
+
+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,
+ }
+ activeSubscriptionIds, err := v.coordinator.GetActiveSubscriptionIds(opts, startIndex, maxCount)
+ if err != nil {
+ return nil, err
+ }
+ return activeSubscriptionIds, nil
+}
+
+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_v2_5.GetSubscription{}, err
+ }
+ return subscription, nil
+}
+
+func (v *EthereumVRFCoordinatorV2_5) GetLinkTotalBalance(ctx context.Context) (*big.Int, error) {
+ opts := &bind.CallOpts{
+ From: common.HexToAddress(v.client.GetDefaultWallet().Address()),
+ Context: ctx,
+ }
+ totalBalance, err := v.coordinator.STotalBalance(opts)
+ if err != nil {
+ return nil, err
+ }
+ return totalBalance, nil
+}
+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.STotalNativeBalance(opts)
+ if err != nil {
+ return nil, err
+ }
+ return totalBalance, nil
+}
+
+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
+ }
+ tx, err := v.coordinator.SetConfig(
+ opts,
+ minimumRequestConfirmations,
+ maxGasLimit,
+ stalenessSeconds,
+ gasAfterPaymentCalculation,
+ fallbackWeiPerUnitLink,
+ feeConfig,
+ )
+ if err != nil {
+ return err
+ }
+ return v.client.ProcessTransaction(tx)
+}
+
+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.SetLINKAndLINKNativeFeed(
+ opts,
+ common.HexToAddress(linkAddress),
+ common.HexToAddress(linkNativeFeedAddress),
+ )
+ if err != nil {
+ return err
+ }
+ return v.client.ProcessTransaction(tx)
+}
+
+func (v *EthereumVRFCoordinatorV2_5) RegisterProvingKey(
+ oracleAddr string,
+ publicProvingKey [2]*big.Int,
+) error {
+ opts, err := v.client.TransactionOpts(v.client.GetDefaultWallet())
+ if err != nil {
+ return err
+ }
+ tx, err := v.coordinator.RegisterProvingKey(opts, common.HexToAddress(oracleAddr), publicProvingKey)
+ if err != nil {
+ return err
+ }
+ return v.client.ProcessTransaction(tx)
+}
+
+func (v *EthereumVRFCoordinatorV2_5) CreateSubscription() error {
+ opts, err := v.client.TransactionOpts(v.client.GetDefaultWallet())
+ if err != nil {
+ return err
+ }
+ tx, err := v.coordinator.CreateSubscription(opts)
+ if err != nil {
+ return err
+ }
+ return v.client.ProcessTransaction(tx)
+}
+
+func (v *EthereumVRFCoordinatorV2_5) Migrate(subId *big.Int, coordinatorAddress string) error {
+ opts, err := v.client.TransactionOpts(v.client.GetDefaultWallet())
+ if err != nil {
+ return err
+ }
+ tx, err := v.coordinator.Migrate(opts, subId, common.HexToAddress(coordinatorAddress))
+ if err != nil {
+ return err
+ }
+ return v.client.ProcessTransaction(tx)
+}
+
+func (v *EthereumVRFCoordinatorV2_5) RegisterMigratableCoordinator(migratableCoordinatorAddress string) error {
+ opts, err := v.client.TransactionOpts(v.client.GetDefaultWallet())
+ if err != nil {
+ return err
+ }
+ tx, err := v.coordinator.RegisterMigratableCoordinator(opts, common.HexToAddress(migratableCoordinatorAddress))
+ if err != nil {
+ return err
+ }
+ return v.client.ProcessTransaction(tx)
+}
+
+func (v *EthereumVRFCoordinatorV2_5) AddConsumer(subId *big.Int, consumerAddress string) error {
+ opts, err := v.client.TransactionOpts(v.client.GetDefaultWallet())
+ if err != nil {
+ return err
+ }
+ tx, err := v.coordinator.AddConsumer(
+ opts,
+ subId,
+ common.HexToAddress(consumerAddress),
+ )
+ if err != nil {
+ return err
+ }
+ return v.client.ProcessTransaction(tx)
+}
+
+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.FundSubscriptionWithNative(
+ opts,
+ subId,
+ )
+ if err != nil {
+ return err
+ }
+ return v.client.ProcessTransaction(tx)
+}
+
+func (v *EthereumVRFCoordinatorV2_5) FindSubscriptionID() (*big.Int, error) {
+ owner := v.client.GetDefaultWallet().Address()
+ subscriptionIterator, err := v.coordinator.FilterSubscriptionCreated(
+ nil,
+ nil,
+ )
+ if err != nil {
+ return nil, err
+ }
+
+ if !subscriptionIterator.Next() {
+ return nil, fmt.Errorf("expected at least 1 subID for the given owner %s", owner)
+ }
+
+ return subscriptionIterator.Event.SubId, nil
+}
+
+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
+ }
+ defer subscription.Unsubscribe()
+
+ for {
+ select {
+ case err := <-subscription.Err():
+ return nil, err
+ case <-time.After(timeout):
+ return nil, fmt.Errorf("timeout waiting for RandomWordsFulfilled event")
+ case randomWordsFulfilledEvent := <-randomWordsFulfilledEventsChannel:
+ return randomWordsFulfilledEvent, nil
+ }
+ }
+}
+
+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
+ }
+ defer subscription.Unsubscribe()
+
+ for {
+ select {
+ case err := <-subscription.Err():
+ return nil, err
+ case <-time.After(timeout):
+ return nil, fmt.Errorf("timeout waiting for RandomWordsRequested event")
+ case randomWordsFulfilledEvent := <-randomWordsFulfilledEventsChannel:
+ return randomWordsFulfilledEvent, nil
+ }
+ }
+}
+
+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
+ }
+ defer subscription.Unsubscribe()
+
+ for {
+ select {
+ case err := <-subscription.Err():
+ return nil, err
+ case <-time.After(timeout):
+ return nil, fmt.Errorf("timeout waiting for MigrationCompleted event")
+ case migrationCompletedEvent := <-eventsChannel:
+ return migrationCompletedEvent, nil
+ }
+ }
+}
+
+func (v *EthereumVRFv2PlusLoadTestConsumer) Address() string {
+ return v.address.Hex()
+}
+func (v *EthereumVRFv2PlusLoadTestConsumer) RequestRandomness(keyHash [32]byte, subID *big.Int, requestConfirmations uint16, callbackGasLimit uint32, nativePayment bool, 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.RequestRandomWords(opts, subID, requestConfirmations, keyHash, callbackGasLimit, nativePayment, numWords, requestCount)
+ if err != nil {
+ return nil, err
+ }
+
+ return tx, v.client.ProcessTransaction(tx)
+}
+
+func (v *EthereumVRFv2PlusLoadTestConsumer) GetCoordinator(ctx context.Context) (common.Address, error) {
+ return v.consumer.SVrfCoordinator(&bind.CallOpts{
+ From: common.HexToAddress(v.client.GetDefaultWallet().Address()),
+ Context: ctx,
+ })
+}
+func (v *EthereumVRFv2PlusLoadTestConsumer) GetRequestStatus(ctx context.Context, requestID *big.Int) (vrf_v2plus_load_test_with_metrics.GetRequestStatus, error) {
+ return v.consumer.GetRequestStatus(&bind.CallOpts{
+ From: common.HexToAddress(v.client.GetDefaultWallet().Address()),
+ Context: ctx,
+ }, requestID)
+}
+
+func (v *EthereumVRFv2PlusLoadTestConsumer) GetLastRequestId(ctx context.Context) (*big.Int, error) {
+ return v.consumer.SLastRequestId(&bind.CallOpts{
+ From: common.HexToAddress(v.client.GetDefaultWallet().Address()),
+ Context: ctx,
+ })
+}
+
+func (v *EthereumVRFv2PlusLoadTestConsumer) 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
+}
+
+func (e *EthereumContractDeployer) DeployVRFCoordinatorV2PlusUpgradedVersion(bhsAddr string) (VRFCoordinatorV2PlusUpgradedVersion, error) {
+ address, _, instance, err := e.client.DeployContract("VRFCoordinatorV2PlusUpgradedVersion", func(
+ auth *bind.TransactOpts,
+ backend bind.ContractBackend,
+ ) (common.Address, *types.Transaction, interface{}, error) {
+ return vrf_v2plus_upgraded_version.DeployVRFCoordinatorV2PlusUpgradedVersion(auth, backend, common.HexToAddress(bhsAddr))
+ })
+ if err != nil {
+ return nil, err
+ }
+ return &EthereumVRFCoordinatorV2PlusUpgradedVersion{
+ client: e.client,
+ coordinator: instance.(*vrf_v2plus_upgraded_version.VRFCoordinatorV2PlusUpgradedVersion),
+ address: address,
+ }, err
+}
+
+func (v *EthereumVRFCoordinatorV2PlusUpgradedVersion) Address() string {
+ return v.address.Hex()
+}
+
+func (v *EthereumVRFCoordinatorV2PlusUpgradedVersion) HashOfKey(ctx context.Context, pubKey [2]*big.Int) ([32]byte, error) {
+ opts := &bind.CallOpts{
+ From: common.HexToAddress(v.client.GetDefaultWallet().Address()),
+ Context: ctx,
+ }
+ hash, err := v.coordinator.HashOfKey(opts, pubKey)
+ if err != nil {
+ return [32]byte{}, err
+ }
+ return hash, nil
+}
+
+func (v *EthereumVRFCoordinatorV2PlusUpgradedVersion) 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,
+ }
+ activeSubscriptionIds, err := v.coordinator.GetActiveSubscriptionIds(opts, startIndex, maxCount)
+ if err != nil {
+ return nil, err
+ }
+ return activeSubscriptionIds, nil
+}
+
+func (v *EthereumVRFCoordinatorV2PlusUpgradedVersion) GetSubscription(ctx context.Context, subID *big.Int) (vrf_v2plus_upgraded_version.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_v2plus_upgraded_version.GetSubscription{}, err
+ }
+ return subscription, nil
+}
+
+func (v *EthereumVRFCoordinatorV2PlusUpgradedVersion) SetConfig(minimumRequestConfirmations uint16, maxGasLimit uint32, stalenessSeconds uint32, gasAfterPaymentCalculation uint32, fallbackWeiPerUnitLink *big.Int, feeConfig vrf_v2plus_upgraded_version.VRFCoordinatorV2PlusUpgradedVersionFeeConfig) error {
+ opts, err := v.client.TransactionOpts(v.client.GetDefaultWallet())
+ if err != nil {
+ return err
+ }
+ tx, err := v.coordinator.SetConfig(
+ opts,
+ minimumRequestConfirmations,
+ maxGasLimit,
+ stalenessSeconds,
+ gasAfterPaymentCalculation,
+ fallbackWeiPerUnitLink,
+ feeConfig,
+ )
+ if err != nil {
+ return err
+ }
+ return v.client.ProcessTransaction(tx)
+}
+
+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.SetLINKAndLINKNativeFeed(
+ opts,
+ common.HexToAddress(linkAddress),
+ common.HexToAddress(linkNativeFeedAddress),
+ )
+ if err != nil {
+ return err
+ }
+ return v.client.ProcessTransaction(tx)
+}
+
+func (v *EthereumVRFCoordinatorV2PlusUpgradedVersion) RegisterProvingKey(
+ oracleAddr string,
+ publicProvingKey [2]*big.Int,
+) error {
+ opts, err := v.client.TransactionOpts(v.client.GetDefaultWallet())
+ if err != nil {
+ return err
+ }
+ tx, err := v.coordinator.RegisterProvingKey(opts, common.HexToAddress(oracleAddr), publicProvingKey)
+ if err != nil {
+ return err
+ }
+ return v.client.ProcessTransaction(tx)
+}
+
+func (v *EthereumVRFCoordinatorV2PlusUpgradedVersion) CreateSubscription() error {
+ opts, err := v.client.TransactionOpts(v.client.GetDefaultWallet())
+ if err != nil {
+ return err
+ }
+ tx, err := v.coordinator.CreateSubscription(opts)
+ if err != nil {
+ return err
+ }
+ return v.client.ProcessTransaction(tx)
+}
+
+func (v *EthereumVRFCoordinatorV2PlusUpgradedVersion) GetLinkTotalBalance(ctx context.Context) (*big.Int, error) {
+ opts := &bind.CallOpts{
+ From: common.HexToAddress(v.client.GetDefaultWallet().Address()),
+ Context: ctx,
+ }
+ totalBalance, err := v.coordinator.STotalBalance(opts)
+ if err != nil {
+ return nil, err
+ }
+ return totalBalance, nil
+}
+func (v *EthereumVRFCoordinatorV2PlusUpgradedVersion) GetNativeTokenTotalBalance(ctx context.Context) (*big.Int, error) {
+ opts := &bind.CallOpts{
+ From: common.HexToAddress(v.client.GetDefaultWallet().Address()),
+ Context: ctx,
+ }
+ totalBalance, err := v.coordinator.STotalNativeBalance(opts)
+ if err != nil {
+ return nil, err
+ }
+ return totalBalance, nil
+}
+
+func (v *EthereumVRFCoordinatorV2PlusUpgradedVersion) Migrate(subId *big.Int, coordinatorAddress string) error {
+ opts, err := v.client.TransactionOpts(v.client.GetDefaultWallet())
+ if err != nil {
+ return err
+ }
+ tx, err := v.coordinator.Migrate(opts, subId, common.HexToAddress(coordinatorAddress))
+ if err != nil {
+ return err
+ }
+ return v.client.ProcessTransaction(tx)
+}
+
+func (v *EthereumVRFCoordinatorV2PlusUpgradedVersion) RegisterMigratableCoordinator(migratableCoordinatorAddress string) error {
+ opts, err := v.client.TransactionOpts(v.client.GetDefaultWallet())
+ if err != nil {
+ return err
+ }
+ tx, err := v.coordinator.RegisterMigratableCoordinator(opts, common.HexToAddress(migratableCoordinatorAddress))
+ if err != nil {
+ return err
+ }
+ return v.client.ProcessTransaction(tx)
+}
+
+func (v *EthereumVRFCoordinatorV2PlusUpgradedVersion) AddConsumer(subId *big.Int, consumerAddress string) error {
+ opts, err := v.client.TransactionOpts(v.client.GetDefaultWallet())
+ if err != nil {
+ return err
+ }
+ tx, err := v.coordinator.AddConsumer(
+ opts,
+ subId,
+ common.HexToAddress(consumerAddress),
+ )
+ if err != nil {
+ return err
+ }
+ return v.client.ProcessTransaction(tx)
+}
+
+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.FundSubscriptionWithNative(
+ opts,
+ subId,
+ )
+ if err != nil {
+ return err
+ }
+ return v.client.ProcessTransaction(tx)
+}
+
+func (v *EthereumVRFCoordinatorV2PlusUpgradedVersion) FindSubscriptionID() (*big.Int, error) {
+ owner := v.client.GetDefaultWallet().Address()
+ subscriptionIterator, err := v.coordinator.FilterSubscriptionCreated(
+ nil,
+ nil,
+ )
+ if err != nil {
+ return nil, err
+ }
+
+ if !subscriptionIterator.Next() {
+ return nil, fmt.Errorf("expected at least 1 subID for the given owner %s", owner)
+ }
+
+ return subscriptionIterator.Event.SubId, nil
+}
+
+func (v *EthereumVRFCoordinatorV2PlusUpgradedVersion) WaitForRandomWordsFulfilledEvent(subID []*big.Int, requestID []*big.Int, timeout time.Duration) (*vrf_v2plus_upgraded_version.VRFCoordinatorV2PlusUpgradedVersionRandomWordsFulfilled, error) {
+ randomWordsFulfilledEventsChannel := make(chan *vrf_v2plus_upgraded_version.VRFCoordinatorV2PlusUpgradedVersionRandomWordsFulfilled)
+ subscription, err := v.coordinator.WatchRandomWordsFulfilled(nil, randomWordsFulfilledEventsChannel, requestID, subID)
+ if err != nil {
+ return nil, err
+ }
+ defer subscription.Unsubscribe()
+
+ for {
+ select {
+ case err := <-subscription.Err():
+ return nil, err
+ case <-time.After(timeout):
+ return nil, fmt.Errorf("timeout waiting for RandomWordsFulfilled event")
+ case randomWordsFulfilledEvent := <-randomWordsFulfilledEventsChannel:
+ return randomWordsFulfilledEvent, nil
+ }
+ }
+}
+
+func (v *EthereumVRFCoordinatorV2PlusUpgradedVersion) WaitForMigrationCompletedEvent(timeout time.Duration) (*vrf_v2plus_upgraded_version.VRFCoordinatorV2PlusUpgradedVersionMigrationCompleted, error) {
+ eventsChannel := make(chan *vrf_v2plus_upgraded_version.VRFCoordinatorV2PlusUpgradedVersionMigrationCompleted)
+ subscription, err := v.coordinator.WatchMigrationCompleted(nil, eventsChannel)
+ if err != nil {
+ return nil, err
+ }
+ defer subscription.Unsubscribe()
+
+ for {
+ select {
+ case err := <-subscription.Err():
+ return nil, err
+ case <-time.After(timeout):
+ return nil, fmt.Errorf("timeout waiting for MigrationCompleted event")
+ case migrationCompletedEvent := <-eventsChannel:
+ return migrationCompletedEvent, nil
+ }
+ }
+}
+
+func (v *EthereumVRFCoordinatorV2PlusUpgradedVersion) WaitForRandomWordsRequestedEvent(keyHash [][32]byte, subID []*big.Int, sender []common.Address, timeout time.Duration) (*vrf_v2plus_upgraded_version.VRFCoordinatorV2PlusUpgradedVersionRandomWordsRequested, error) {
+ eventsChannel := make(chan *vrf_v2plus_upgraded_version.VRFCoordinatorV2PlusUpgradedVersionRandomWordsRequested)
+ subscription, err := v.coordinator.WatchRandomWordsRequested(nil, eventsChannel, keyHash, subID, sender)
+ if err != nil {
+ return nil, err
+ }
+ defer subscription.Unsubscribe()
+
+ for {
+ select {
+ case err := <-subscription.Err():
+ return nil, err
+ case <-time.After(timeout):
+ return nil, fmt.Errorf("timeout waiting for RandomWordsRequested event")
+ case randomWordsRequestedEvent := <-eventsChannel:
+ return randomWordsRequestedEvent, nil
+ }
+ }
+}
+
+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) 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,
+ )
+ 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/docker.go b/integration-tests/docker/docker.go
deleted file mode 100644
index d5803e0a163..00000000000
--- a/integration-tests/docker/docker.go
+++ /dev/null
@@ -1,30 +0,0 @@
-package docker
-
-import (
- "context"
- "fmt"
-
- "github.com/google/uuid"
- "github.com/rs/zerolog/log"
- tc "github.com/testcontainers/testcontainers-go"
-)
-
-func CreateNetwork() (*tc.DockerNetwork, error) {
- uuidObj, _ := uuid.NewRandom()
- var networkName = fmt.Sprintf("network-%s", uuidObj.String())
- network, err := tc.GenericNetwork(context.Background(), tc.GenericNetworkRequest{
- NetworkRequest: tc.NetworkRequest{
- Name: networkName,
- CheckDuplicate: true,
- },
- })
- if err != nil {
- return nil, err
- }
- dockerNetwork, ok := network.(*tc.DockerNetwork)
- if !ok {
- return nil, fmt.Errorf("failed to cast network to *dockertest.Network")
- }
- log.Trace().Any("network", dockerNetwork).Msgf("created network")
- return dockerNetwork, nil
-}
diff --git a/integration-tests/docker/test_env/cl_node.go b/integration-tests/docker/test_env/cl_node.go
index 4d690e9dd76..e4182ca4c36 100644
--- a/integration-tests/docker/test_env/cl_node.go
+++ b/integration-tests/docker/test_env/cl_node.go
@@ -10,6 +10,7 @@ import (
"os"
"strings"
"sync"
+ "testing"
"time"
"github.com/ethereum/go-ethereum"
@@ -17,11 +18,15 @@ import (
"github.com/google/uuid"
"github.com/pelletier/go-toml/v2"
"github.com/pkg/errors"
+ "github.com/rs/zerolog"
"github.com/rs/zerolog/log"
tc "github.com/testcontainers/testcontainers-go"
tcwait "github.com/testcontainers/testcontainers-go/wait"
"github.com/smartcontractkit/chainlink-testing-framework/blockchain"
+ "github.com/smartcontractkit/chainlink-testing-framework/docker"
+ "github.com/smartcontractkit/chainlink-testing-framework/docker/test_env"
+ "github.com/smartcontractkit/chainlink-testing-framework/logging"
"github.com/smartcontractkit/chainlink-testing-framework/logwatch"
"github.com/smartcontractkit/chainlink/v2/core/services/chainlink"
"github.com/smartcontractkit/chainlink/v2/core/services/keystore/chaintype"
@@ -39,12 +44,16 @@ var (
)
type ClNode struct {
- EnvComponent
+ test_env.EnvComponent
API *client.ChainlinkClient
NodeConfig *chainlink.Config
NodeSecretsConfigTOML string
- PostgresDb *PostgresDb
+ PostgresDb *test_env.PostgresDb
lw *logwatch.LogWatch
+ ContainerImage string
+ ContainerVersion string
+ t *testing.T
+ l zerolog.Logger
}
type ClNodeOption = func(c *ClNode)
@@ -76,14 +85,15 @@ func WithLogWatch(lw *logwatch.LogWatch) ClNodeOption {
func NewClNode(networks []string, nodeConfig *chainlink.Config, opts ...ClNodeOption) *ClNode {
nodeDefaultCName := fmt.Sprintf("%s-%s", "cl-node", uuid.NewString()[0:8])
pgDefaultCName := fmt.Sprintf("pg-%s", nodeDefaultCName)
- pgDb := NewPostgresDb(networks, WithPostgresDbContainerName(pgDefaultCName))
+ pgDb := test_env.NewPostgresDb(networks, test_env.WithPostgresDbContainerName(pgDefaultCName))
n := &ClNode{
- EnvComponent: EnvComponent{
+ EnvComponent: test_env.EnvComponent{
ContainerName: nodeDefaultCName,
Networks: networks,
},
NodeConfig: nodeConfig,
PostgresDb: pgDb,
+ l: log.Logger,
}
for _, opt := range opts {
opt(n)
@@ -91,6 +101,13 @@ func NewClNode(networks []string, nodeConfig *chainlink.Config, opts ...ClNodeOp
return n
}
+func (n *ClNode) WithTestLogger(t *testing.T) *ClNode {
+ n.l = logging.GetTestLogger(t)
+ n.t = t
+ n.PostgresDb.WithTestLogger(t)
+ return n
+}
+
// Restart restarts only CL node, DB container is reused
func (n *ClNode) Restart(cfg *chainlink.Config) error {
if err := n.Container.Terminate(context.Background()); err != nil {
@@ -100,6 +117,19 @@ func (n *ClNode) Restart(cfg *chainlink.Config) error {
return n.StartContainer()
}
+// UpgradeVersion restarts the cl node with new image and version
+func (n *ClNode) UpgradeVersion(cfg *chainlink.Config, newImage, newVersion string) error {
+ if newVersion == "" {
+ return fmt.Errorf("new version is empty")
+ }
+ if newImage == "" {
+ newImage = os.Getenv("CHAINLINK_IMAGE")
+ }
+ n.ContainerImage = newImage
+ n.ContainerVersion = newVersion
+ return n.Restart(n.NodeConfig)
+}
+
func (n *ClNode) PrimaryETHAddress() (string, error) {
return n.API.PrimaryEthAddress()
}
@@ -135,8 +165,8 @@ func (n *ClNode) AddMercuryOCRJob(verifierAddr common.Address, fromBlock uint64,
}
bridges := utils.BuildBridges(eaUrls)
- for _, b := range bridges {
- err = n.API.MustCreateBridge(&b)
+ for index := range bridges {
+ err = n.API.MustCreateBridge(&bridges[index])
if err != nil {
return nil, err
}
@@ -202,7 +232,6 @@ func (n *ClNode) Fund(evmClient blockchain.EVMClient, amount *big.Float) error {
}
return evmClient.Fund(toAddress, amount, gasEstimates)
}
-
func (n *ClNode) StartContainer() error {
err := n.PostgresDb.StartContainer()
if err != nil {
@@ -222,10 +251,19 @@ func (n *ClNode) StartContainer() error {
if err != nil {
return err
}
- container, err := tc.GenericContainer(context.Background(), tc.GenericContainerRequest{
+
+ l := tc.Logger
+ if n.t != nil {
+ l = logging.CustomT{
+ T: n.t,
+ L: n.l,
+ }
+ }
+ container, err := docker.StartContainerWithRetry(n.l, tc.GenericContainerRequest{
ContainerRequest: *cReq,
Started: true,
Reuse: true,
+ Logger: l,
})
if err != nil {
return errors.Wrap(err, ErrStartCLNodeContainer)
@@ -243,7 +281,7 @@ func (n *ClNode) StartContainer() error {
if err != nil {
return err
}
- log.Info().Str("containerName", n.ContainerName).
+ n.l.Info().Str("containerName", n.ContainerName).
Str("clEndpoint", clEndpoint).
Str("clInternalIP", ip).
Msg("Started Chainlink Node container")
@@ -252,11 +290,11 @@ func (n *ClNode) StartContainer() error {
Email: "local@local.com",
Password: "localdevpassword",
InternalIP: ip,
- })
+ },
+ n.l)
if err != nil {
return errors.Wrap(err, ErrConnectNodeClient)
}
-
clClient.Config.InternalIP = n.ContainerName
n.Container = container
n.API = clClient
@@ -312,18 +350,24 @@ func (n *ClNode) getContainerRequest() (
adminCredsPath := "/home/admin-credentials.txt"
apiCredsPath := "/home/api-credentials.txt"
- image, ok := os.LookupEnv("CHAINLINK_IMAGE")
- if !ok {
- return nil, errors.New("CHAINLINK_IMAGE env must be set")
+ if n.ContainerImage == "" {
+ image, ok := os.LookupEnv("CHAINLINK_IMAGE")
+ if !ok {
+ return nil, errors.New("CHAINLINK_IMAGE env must be set")
+ }
+ n.ContainerImage = image
}
- tag, ok := os.LookupEnv("CHAINLINK_VERSION")
- if !ok {
- return nil, errors.New("CHAINLINK_VERSION env must be set")
+ if n.ContainerVersion == "" {
+ version, ok := os.LookupEnv("CHAINLINK_VERSION")
+ if !ok {
+ return nil, errors.New("CHAINLINK_VERSION env must be set")
+ }
+ n.ContainerVersion = version
}
return &tc.ContainerRequest{
Name: n.ContainerName,
- Image: fmt.Sprintf("%s:%s", image, tag),
+ Image: fmt.Sprintf("%s:%s", n.ContainerImage, n.ContainerVersion),
ExposedPorts: []string{"6688/tcp"},
Entrypoint: []string{"chainlink",
"-c", configPath,
diff --git a/integration-tests/docker/test_env/env_component.go b/integration-tests/docker/test_env/env_component.go
deleted file mode 100644
index e6f6fc4b8a6..00000000000
--- a/integration-tests/docker/test_env/env_component.go
+++ /dev/null
@@ -1,21 +0,0 @@
-package test_env
-
-import (
- tc "github.com/testcontainers/testcontainers-go"
-)
-
-type EnvComponent struct {
- ContainerName string
- Container tc.Container
- Networks []string
-}
-
-type EnvComponentOption = func(c *EnvComponent)
-
-func WithContainerName(name string) EnvComponentOption {
- return func(c *EnvComponent) {
- if name != "" {
- c.ContainerName = name
- }
- }
-}
diff --git a/integration-tests/docker/test_env/geth.go b/integration-tests/docker/test_env/geth.go
deleted file mode 100644
index 764f7acf418..00000000000
--- a/integration-tests/docker/test_env/geth.go
+++ /dev/null
@@ -1,233 +0,0 @@
-package test_env
-
-import (
- "context"
- "fmt"
- "os"
- "time"
-
- "github.com/ethereum/go-ethereum/accounts"
- "github.com/ethereum/go-ethereum/accounts/keystore"
- "github.com/google/uuid"
- "github.com/pkg/errors"
- "github.com/rs/zerolog/log"
- tc "github.com/testcontainers/testcontainers-go"
- tcwait "github.com/testcontainers/testcontainers-go/wait"
-
- "github.com/smartcontractkit/chainlink-testing-framework/blockchain"
-
- "github.com/smartcontractkit/chainlink/integration-tests/utils/templates"
-)
-
-const (
- // RootFundingAddr is the static key that hardhat is using
- // https://hardhat.org/hardhat-runner/docs/getting-started
- // if you need more keys, keep them compatible, so we can swap Geth to Ganache/Hardhat in the future
- RootFundingAddr = `0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266`
- RootFundingWallet = `{"address":"f39fd6e51aad88f6f4ce6ab8827279cfffb92266","crypto":{"cipher":"aes-128-ctr","ciphertext":"c36afd6e60b82d6844530bd6ab44dbc3b85a53e826c3a7f6fc6a75ce38c1e4c6","cipherparams":{"iv":"f69d2bb8cd0cb6274535656553b61806"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"80d5f5e38ba175b6b89acfc8ea62a6f163970504af301292377ff7baafedab53"},"mac":"f2ecec2c4d05aacc10eba5235354c2fcc3776824f81ec6de98022f704efbf065"},"id":"e5c124e9-e280-4b10-a27b-d7f3e516b408","version":3}`
-)
-
-type Geth struct {
- EnvComponent
- ExternalHttpUrl string
- InternalHttpUrl string
- ExternalWsUrl string
- InternalWsUrl string
-}
-
-func NewGeth(networks []string, opts ...EnvComponentOption) *Geth {
- g := &Geth{
- EnvComponent: EnvComponent{
- ContainerName: fmt.Sprintf("%s-%s", "geth", uuid.NewString()[0:8]),
- Networks: networks,
- },
- }
- for _, opt := range opts {
- opt(&g.EnvComponent)
- }
- return g
-}
-
-func (g *Geth) StartContainer() (blockchain.EVMNetwork, InternalDockerUrls, error) {
- r, _, _, err := g.getGethContainerRequest(g.Networks)
- if err != nil {
- return blockchain.EVMNetwork{}, InternalDockerUrls{}, err
- }
- ct, err := tc.GenericContainer(context.Background(),
- tc.GenericContainerRequest{
- ContainerRequest: *r,
- Started: true,
- Reuse: true,
- })
- if err != nil {
- return blockchain.EVMNetwork{}, InternalDockerUrls{}, errors.Wrapf(err, "cannot start geth container")
- }
- host, err := ct.Host(context.Background())
- if err != nil {
- return blockchain.EVMNetwork{}, InternalDockerUrls{}, err
- }
- httpPort, err := ct.MappedPort(context.Background(), "8544/tcp")
- if err != nil {
- return blockchain.EVMNetwork{}, InternalDockerUrls{}, err
- }
- wsPort, err := ct.MappedPort(context.Background(), "8545/tcp")
- if err != nil {
- return blockchain.EVMNetwork{}, InternalDockerUrls{}, err
- }
-
- g.Container = ct
- g.ExternalHttpUrl = fmt.Sprintf("http://%s:%s", host, httpPort.Port())
- g.InternalHttpUrl = fmt.Sprintf("http://%s:8544", g.ContainerName)
- g.ExternalWsUrl = fmt.Sprintf("ws://%s:%s", host, wsPort.Port())
- g.InternalWsUrl = fmt.Sprintf("ws://%s:8545", g.ContainerName)
-
- networkConfig := blockchain.SimulatedEVMNetwork
- networkConfig.Name = "geth"
- networkConfig.URLs = []string{g.ExternalWsUrl}
- networkConfig.HTTPURLs = []string{g.ExternalHttpUrl}
-
- internalDockerUrls := InternalDockerUrls{
- HttpUrl: g.InternalHttpUrl,
- WsUrl: g.InternalWsUrl,
- }
-
- log.Info().Str("containerName", g.ContainerName).
- Str("internalHttpUrl", g.InternalHttpUrl).
- Str("externalHttpUrl", g.ExternalHttpUrl).
- Str("externalWsUrl", g.ExternalWsUrl).
- Str("internalWsUrl", g.InternalWsUrl).
- Msg("Started Geth container")
-
- return networkConfig, internalDockerUrls, nil
-}
-
-func (g *Geth) getGethContainerRequest(networks []string) (*tc.ContainerRequest, *keystore.KeyStore, *accounts.Account, error) {
- chainId := "1337"
- blocktime := "1"
-
- initScriptFile, err := os.CreateTemp("", "init_script")
- if err != nil {
- return nil, nil, nil, err
- }
- _, err = initScriptFile.WriteString(templates.InitGethScript)
- if err != nil {
- return nil, nil, nil, err
- }
- keystoreDir, err := os.MkdirTemp("", "keystore")
- if err != nil {
- return nil, nil, nil, err
- }
- // Create keystore and ethereum account
- ks := keystore.NewKeyStore(keystoreDir, keystore.StandardScryptN, keystore.StandardScryptP)
- account, err := ks.NewAccount("")
- if err != nil {
- return nil, ks, &account, err
- }
- genesisJsonStr, err := templates.GenesisJsonTemplate{
- ChainId: chainId,
- AccountAddr: account.Address.Hex(),
- }.String()
- if err != nil {
- return nil, ks, &account, err
- }
- genesisFile, err := os.CreateTemp("", "genesis_json")
- if err != nil {
- return nil, ks, &account, err
- }
- _, err = genesisFile.WriteString(genesisJsonStr)
- if err != nil {
- return nil, ks, &account, err
- }
- key1File, err := os.CreateTemp(keystoreDir, "key1")
- if err != nil {
- return nil, ks, &account, err
- }
- _, err = key1File.WriteString(RootFundingWallet)
- if err != nil {
- return nil, ks, &account, err
- }
- configDir, err := os.MkdirTemp("", "config")
- if err != nil {
- return nil, ks, &account, err
- }
- err = os.WriteFile(configDir+"/password.txt", []byte(""), 0600)
- if err != nil {
- return nil, ks, &account, err
- }
-
- return &tc.ContainerRequest{
- Name: g.ContainerName,
- AlwaysPullImage: true,
- Image: "ethereum/client-go:stable",
- ExposedPorts: []string{"8544/tcp", "8545/tcp"},
- Networks: networks,
- WaitingFor: tcwait.ForLog("Chain head was updated").
- WithStartupTimeout(120 * time.Second).
- WithPollInterval(1 * time.Second),
- Entrypoint: []string{"sh", "./root/init.sh",
- "--dev",
- "--password", "/root/config/password.txt",
- "--datadir",
- "/root/.ethereum/devchain",
- "--unlock",
- RootFundingAddr,
- "--mine",
- "--miner.etherbase",
- RootFundingAddr,
- "--ipcdisable",
- "--http",
- "--http.vhosts",
- "*",
- "--http.addr",
- "0.0.0.0",
- "--http.port=8544",
- "--ws",
- "--ws.origins",
- "*",
- "--ws.addr",
- "0.0.0.0",
- "--ws.port=8545",
- "--graphql",
- "-graphql.corsdomain",
- "*",
- "--allow-insecure-unlock",
- "--rpc.allow-unprotected-txs",
- "--http.api",
- "eth,web3,debug",
- "--http.corsdomain",
- "*",
- "--vmdebug",
- fmt.Sprintf("--networkid=%s", chainId),
- "--rpc.txfeecap",
- "0",
- "--dev.period",
- blocktime,
- },
- Files: []tc.ContainerFile{
- {
- HostFilePath: initScriptFile.Name(),
- ContainerFilePath: "/root/init.sh",
- FileMode: 0644,
- },
- {
- HostFilePath: genesisFile.Name(),
- ContainerFilePath: "/root/genesis.json",
- FileMode: 0644,
- },
- },
- Mounts: tc.ContainerMounts{
- tc.ContainerMount{
- Source: tc.GenericBindMountSource{
- HostPath: keystoreDir,
- },
- Target: "/root/.ethereum/devchain/keystore/",
- },
- tc.ContainerMount{
- Source: tc.GenericBindMountSource{
- HostPath: configDir,
- },
- Target: "/root/config/",
- },
- },
- }, ks, &account, nil
-}
diff --git a/integration-tests/docker/test_env/mockserver.go b/integration-tests/docker/test_env/mockserver.go
deleted file mode 100644
index 8a8f966678c..00000000000
--- a/integration-tests/docker/test_env/mockserver.go
+++ /dev/null
@@ -1,106 +0,0 @@
-package test_env
-
-import (
- "context"
- "fmt"
- "net/url"
- "strings"
- "time"
-
- "github.com/google/uuid"
- "github.com/pkg/errors"
- "github.com/rs/zerolog/log"
- tc "github.com/testcontainers/testcontainers-go"
- tcwait "github.com/testcontainers/testcontainers-go/wait"
-
- ctfClient "github.com/smartcontractkit/chainlink-testing-framework/client"
-)
-
-type MockServer struct {
- EnvComponent
- Client *ctfClient.MockserverClient
- Endpoint string
- InternalEndpoint string
- EAMockUrls []*url.URL
-}
-
-func NewMockServer(networks []string, opts ...EnvComponentOption) *MockServer {
- ms := &MockServer{
- EnvComponent: EnvComponent{
- ContainerName: fmt.Sprintf("%s-%s", "mockserver", uuid.NewString()[0:8]),
- Networks: networks,
- },
- }
- for _, opt := range opts {
- opt(&ms.EnvComponent)
- }
- return ms
-}
-
-func (ms *MockServer) SetExternalAdapterMocks(count int) error {
- for i := 0; i < count; i++ {
- path := fmt.Sprintf("/ea-%d", i)
- err := ms.Client.SetRandomValuePath(path)
- if err != nil {
- return err
- }
- cName, err := ms.Container.Name(context.Background())
- if err != nil {
- return err
- }
- cName = strings.Replace(cName, "/", "", -1)
- eaUrl, err := url.Parse(fmt.Sprintf("http://%s:%s%s",
- cName, "1080", path))
- if err != nil {
- return err
- }
- ms.EAMockUrls = append(ms.EAMockUrls, eaUrl)
- }
- return nil
-}
-
-func (ms *MockServer) StartContainer() error {
- c, err := tc.GenericContainer(context.Background(), tc.GenericContainerRequest{
- ContainerRequest: ms.getContainerRequest(),
- Started: true,
- Reuse: true,
- })
- if err != nil {
- return errors.Wrapf(err, "cannot start MockServer container")
- }
- ms.Container = c
- endpoint, err := c.Endpoint(context.Background(), "http")
- if err != nil {
- return err
- }
- log.Info().Any("endpoint", endpoint).Str("containerName", ms.ContainerName).
- Msgf("Started MockServer container")
- ms.Endpoint = endpoint
- ms.InternalEndpoint = fmt.Sprintf("http://%s:%s", ms.ContainerName, "1080")
-
- client := ctfClient.NewMockserverClient(&ctfClient.MockserverConfig{
- LocalURL: endpoint,
- ClusterURL: ms.InternalEndpoint,
- })
- if err != nil {
- return errors.Wrapf(err, "cannot connect to MockServer client")
- }
- ms.Client = client
-
- return nil
-}
-
-func (ms *MockServer) getContainerRequest() tc.ContainerRequest {
- return tc.ContainerRequest{
- Name: ms.ContainerName,
- Image: "mockserver/mockserver:5.15.0",
- ExposedPorts: []string{"1080/tcp"},
- Env: map[string]string{
- "SERVER_PORT": "1080",
- },
- Networks: ms.Networks,
- WaitingFor: tcwait.ForLog("INFO 1080 started on port: 1080").
- WithStartupTimeout(30 * time.Second).
- WithPollInterval(100 * time.Millisecond),
- }
-}
diff --git a/integration-tests/docker/test_env/postgres.go b/integration-tests/docker/test_env/postgres.go
deleted file mode 100644
index 64b48235989..00000000000
--- a/integration-tests/docker/test_env/postgres.go
+++ /dev/null
@@ -1,83 +0,0 @@
-package test_env
-
-import (
- "context"
- "fmt"
- "time"
-
- "github.com/google/uuid"
- "github.com/rs/zerolog/log"
- tc "github.com/testcontainers/testcontainers-go"
- tcwait "github.com/testcontainers/testcontainers-go/wait"
-)
-
-type PostgresDb struct {
- EnvComponent
- User string
- Password string
- DbName string
- Port string
-}
-
-type PostgresDbOption = func(c *PostgresDb)
-
-// Sets custom container name if name is not empty
-func WithPostgresDbContainerName(name string) PostgresDbOption {
- return func(c *PostgresDb) {
- if name != "" {
- c.ContainerName = name
- }
- }
-}
-
-func NewPostgresDb(networks []string, opts ...PostgresDbOption) *PostgresDb {
- pg := &PostgresDb{
- EnvComponent: EnvComponent{
- ContainerName: fmt.Sprintf("%s-%s", "postgres-db", uuid.NewString()[0:8]),
- Networks: networks,
- },
- User: "postgres",
- Password: "mysecretpassword",
- DbName: "testdb",
- Port: "5432",
- }
- for _, opt := range opts {
- opt(pg)
- }
- return pg
-}
-
-func (pg *PostgresDb) StartContainer() error {
- req := pg.getContainerRequest()
- c, err := tc.GenericContainer(context.Background(), tc.GenericContainerRequest{
- ContainerRequest: *req,
- Started: true,
- Reuse: true,
- })
- if err != nil {
- return err
- }
- pg.Container = c
-
- log.Info().Str("containerName", pg.ContainerName).
- Msg("Started Postgres DB container")
-
- return nil
-}
-
-func (pg *PostgresDb) getContainerRequest() *tc.ContainerRequest {
- return &tc.ContainerRequest{
- Name: pg.ContainerName,
- Image: "postgres:15.3",
- ExposedPorts: []string{fmt.Sprintf("%s/tcp", pg.Port)},
- Env: map[string]string{
- "POSTGRES_USER": pg.User,
- "POSTGRES_DB": pg.DbName,
- "POSTGRES_PASSWORD": pg.Password,
- },
- Networks: pg.Networks,
- WaitingFor: tcwait.ForExec([]string{"psql", "-h", "localhost",
- "-U", pg.User, "-c", "select", "1", "-d", pg.DbName}).
- WithStartupTimeout(10 * time.Second),
- }
-}
diff --git a/integration-tests/docker/test_env/test_env.go b/integration-tests/docker/test_env/test_env.go
index 40e4c27bd2a..8c4faadbd2b 100644
--- a/integration-tests/docker/test_env/test_env.go
+++ b/integration-tests/docker/test_env/test_env.go
@@ -1,22 +1,33 @@
package test_env
import (
+ "context"
+ "encoding/json"
+ "fmt"
+ "io"
"math/big"
+ "os"
+ "path/filepath"
+ "testing"
+ "time"
+ "github.com/ethereum/go-ethereum/accounts/keystore"
"github.com/ethereum/go-ethereum/common"
"github.com/pkg/errors"
+ "github.com/rs/zerolog"
"github.com/rs/zerolog/log"
tc "github.com/testcontainers/testcontainers-go"
"golang.org/x/sync/errgroup"
"github.com/smartcontractkit/chainlink-testing-framework/blockchain"
+ "github.com/smartcontractkit/chainlink-testing-framework/docker"
"github.com/smartcontractkit/chainlink-testing-framework/docker/test_env"
+ "github.com/smartcontractkit/chainlink-testing-framework/logging"
"github.com/smartcontractkit/chainlink-testing-framework/logwatch"
"github.com/smartcontractkit/chainlink/v2/core/services/chainlink"
"github.com/smartcontractkit/chainlink/integration-tests/client"
"github.com/smartcontractkit/chainlink/integration-tests/contracts"
- "github.com/smartcontractkit/chainlink/integration-tests/docker"
"github.com/smartcontractkit/chainlink/integration-tests/utils"
)
@@ -32,41 +43,53 @@ type CLClusterTestEnv struct {
/* components */
CLNodes []*ClNode
- Geth *Geth // for tests using --dev networks
- PrivateGethChain []test_env.PrivateGethChain // for tests using non-dev networks
- MockServer *MockServer
+ Geth *test_env.Geth // for tests using --dev networks
+ PrivateChain []test_env.PrivateChain // for tests using non-dev networks
+ MockServer *test_env.MockServer
EVMClient blockchain.EVMClient
ContractDeployer contracts.ContractDeployer
ContractLoader contracts.ContractLoader
+ l zerolog.Logger
+ t *testing.T
}
func NewTestEnv() (*CLClusterTestEnv, error) {
utils.SetupCoreDockerEnvLogger()
- network, err := docker.CreateNetwork()
+ network, err := docker.CreateNetwork(log.Logger)
if err != nil {
return nil, err
}
networks := []string{network.Name}
return &CLClusterTestEnv{
Network: network,
- Geth: NewGeth(networks),
- MockServer: NewMockServer(networks),
+ Geth: test_env.NewGeth(networks),
+ MockServer: test_env.NewMockServer(networks),
+ l: log.Logger,
}, nil
}
-func NewTestEnvFromCfg(cfg *TestEnvConfig) (*CLClusterTestEnv, error) {
+func (te *CLClusterTestEnv) WithTestLogger(t *testing.T) *CLClusterTestEnv {
+ te.t = t
+ te.l = logging.GetTestLogger(t)
+ te.Geth.WithTestLogger(t)
+ te.MockServer.WithTestLogger(t)
+ return te
+}
+
+func NewTestEnvFromCfg(l zerolog.Logger, cfg *TestEnvConfig) (*CLClusterTestEnv, error) {
utils.SetupCoreDockerEnvLogger()
- network, err := docker.CreateNetwork()
+ network, err := docker.CreateNetwork(log.Logger)
if err != nil {
return nil, err
}
networks := []string{network.Name}
- log.Info().Interface("Cfg", cfg).Send()
+ l.Info().Interface("Cfg", cfg).Send()
return &CLClusterTestEnv{
Cfg: cfg,
Network: network,
- Geth: NewGeth(networks, WithContainerName(cfg.Geth.ContainerName)),
- MockServer: NewMockServer(networks, WithContainerName(cfg.MockServer.ContainerName)),
+ 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
}
@@ -74,23 +97,39 @@ func (te *CLClusterTestEnv) ParallelTransactions(enabled bool) {
te.EVMClient.ParallelTransactions(enabled)
}
-func (te *CLClusterTestEnv) WithPrivateGethChain(evmNetworks []blockchain.EVMNetwork) *CLClusterTestEnv {
- var chains []test_env.PrivateGethChain
+func (te *CLClusterTestEnv) WithPrivateChain(evmNetworks []blockchain.EVMNetwork) *CLClusterTestEnv {
+ var chains []test_env.PrivateChain
for _, evmNetwork := range evmNetworks {
n := evmNetwork
- chains = append(chains, test_env.NewPrivateGethChain(&n, []string{te.Network.Name}))
+ pgc := test_env.NewPrivateGethChain(&n, []string{te.Network.Name})
+ if te.t != nil {
+ pgc.GetPrimaryNode().WithTestLogger(te.t)
+ }
+ chains = append(chains, pgc)
+ var privateChain test_env.PrivateChain
+ switch n.SimulationType {
+ case "besu":
+ privateChain = test_env.NewPrivateBesuChain(&n, []string{te.Network.Name})
+ default:
+ privateChain = test_env.NewPrivateGethChain(&n, []string{te.Network.Name})
+ }
+ chains = append(chains, privateChain)
}
- te.PrivateGethChain = chains
+ te.PrivateChain = chains
return te
}
-func (te *CLClusterTestEnv) StartPrivateGethChain() error {
- for _, chain := range te.PrivateGethChain {
- err := chain.PrimaryNode.Start()
+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"))
+ }
+ err := primaryNode.Start()
if err != nil {
return err
}
- err = chain.PrimaryNode.ConnectToClient()
+ err = primaryNode.ConnectToClient()
if err != nil {
return err
}
@@ -98,7 +137,7 @@ func (te *CLClusterTestEnv) StartPrivateGethChain() error {
return nil
}
-func (te *CLClusterTestEnv) StartGeth() (blockchain.EVMNetwork, InternalDockerUrls, error) {
+func (te *CLClusterTestEnv) StartGeth() (blockchain.EVMNetwork, test_env.InternalDockerUrls, error) {
return te.Geth.StartContainer()
}
@@ -132,6 +171,9 @@ func (te *CLClusterTestEnv) StartClNodes(nodeConfig *chainlink.Config, count int
WithNodeContainerName(nodeContainerName),
WithDbContainerName(dbContainerName),
)
+ if te.t != nil {
+ n.WithTestLogger(te.t)
+ }
err := n.StartContainer()
if err != nil {
return err
@@ -193,3 +235,86 @@ func (te *CLClusterTestEnv) Terminate() error {
// the containers and the Network
return nil
}
+
+// Cleanup cleans the environment up after it's done being used, mainly for returning funds when on live networks.
+// Intended to be used as part of t.Cleanup() in tests.
+func (te *CLClusterTestEnv) Cleanup(t *testing.T) error {
+ if te.EVMClient == nil {
+ return errors.New("blockchain client is nil, unable to return funds from chainlink nodes")
+ }
+ if te.CLNodes == nil {
+ return errors.New("chainlink nodes are nil, unable to return funds from chainlink nodes")
+ }
+
+ // Check if we need to return funds
+ if te.EVMClient.NetworkSimulated() {
+ te.l.Info().Str("Network Name", te.EVMClient.GetNetworkName()).
+ Msg("Network is a simulated network. Skipping fund return.")
+ } else {
+ te.l.Info().Msg("Attempting to return Chainlink node funds to default network wallets")
+ for _, chainlinkNode := range te.CLNodes {
+ fundedKeys, err := chainlinkNode.API.ExportEVMKeysForChain(te.EVMClient.GetChainID().String())
+ if err != nil {
+ return err
+ }
+ for _, key := range fundedKeys {
+ keyToDecrypt, err := json.Marshal(key)
+ if err != nil {
+ return err
+ }
+ // This can take up a good bit of RAM and time. When running on the remote-test-runner, this can lead to OOM
+ // issues. So we avoid running in parallel; slower, but safer.
+ decryptedKey, err := keystore.DecryptKey(keyToDecrypt, client.ChainlinkKeyPassword)
+ if err != nil {
+ return err
+ }
+ if err = te.EVMClient.ReturnFunds(decryptedKey.PrivateKey); err != nil {
+ return err
+ }
+ }
+ }
+ }
+
+ // 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 04b9f44f3f7..f3944b0ba96 100644
--- a/integration-tests/docker/test_env/test_env_builder.go
+++ b/integration-tests/docker/test_env/test_env_builder.go
@@ -1,18 +1,23 @@
package test_env
import (
+ "fmt"
"math/big"
"os"
+ "testing"
"github.com/pkg/errors"
+ "github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"github.com/smartcontractkit/chainlink-testing-framework/blockchain"
+ "github.com/smartcontractkit/chainlink-testing-framework/docker/test_env"
+ "github.com/smartcontractkit/chainlink-testing-framework/logging"
"github.com/smartcontractkit/chainlink-testing-framework/logwatch"
+ "github.com/smartcontractkit/chainlink-testing-framework/networks"
"github.com/smartcontractkit/chainlink/v2/core/services/chainlink"
"github.com/smartcontractkit/chainlink/integration-tests/contracts"
- "github.com/smartcontractkit/chainlink/integration-tests/networks"
"github.com/smartcontractkit/chainlink/integration-tests/types/config/node"
)
@@ -27,22 +32,26 @@ type CLTestEnvBuilder struct {
externalAdapterCount int
customNodeCsaKeys []string
defaultNodeCsaKeys []string
+ l zerolog.Logger
+ t *testing.T
/* funding */
ETHFunds *big.Float
}
-type InternalDockerUrls struct {
- HttpUrl string
- WsUrl string
-}
-
func NewCLTestEnvBuilder() *CLTestEnvBuilder {
return &CLTestEnvBuilder{
externalAdapterCount: 1,
+ l: log.Logger,
}
}
+func (b *CLTestEnvBuilder) WithTestLogger(t *testing.T) *CLTestEnvBuilder {
+ b.t = t
+ b.l = logging.GetTestLogger(t)
+ return b
+}
+
func (b *CLTestEnvBuilder) WithLogWatcher() *CLTestEnvBuilder {
b.hasLogWatch = true
return b
@@ -98,7 +107,7 @@ func (b *CLTestEnvBuilder) Build() (*CLClusterTestEnv, error) {
}
func (b *CLTestEnvBuilder) buildNewEnv(cfg *TestEnvConfig) (*CLClusterTestEnv, error) {
- log.Info().
+ b.l.Info().
Bool("hasGeth", b.hasGeth).
Bool("hasMockServer", b.hasMockServer).
Int("externalAdapterCount", b.externalAdapterCount).
@@ -110,7 +119,7 @@ func (b *CLTestEnvBuilder) buildNewEnv(cfg *TestEnvConfig) (*CLClusterTestEnv, e
var te *CLClusterTestEnv
var err error
if cfg != nil {
- te, err = NewTestEnvFromCfg(cfg)
+ te, err = NewTestEnvFromCfg(b.l, cfg)
if err != nil {
return nil, err
}
@@ -121,6 +130,10 @@ func (b *CLTestEnvBuilder) buildNewEnv(cfg *TestEnvConfig) (*CLClusterTestEnv, e
}
}
+ if b.t != nil {
+ te.WithTestLogger(b.t)
+ }
+
if b.hasLogWatch {
te.LogWatch, err = logwatch.NewLogWatch(nil, nil)
if err != nil {
@@ -139,19 +152,23 @@ func (b *CLTestEnvBuilder) buildNewEnv(cfg *TestEnvConfig) (*CLClusterTestEnv, e
}
}
if b.nonDevGethNetworks != nil {
- te.WithPrivateGethChain(b.nonDevGethNetworks)
- err := te.StartPrivateGethChain()
+ te.WithPrivateChain(b.nonDevGethNetworks)
+ err := te.StartPrivateChain()
if err != nil {
return te, err
}
- var nonDevGethNetworks []blockchain.EVMNetwork
- for i, n := range te.PrivateGethChain {
- nonDevGethNetworks = append(nonDevGethNetworks, *n.NetworkConfig)
- nonDevGethNetworks[i].URLs = []string{n.PrimaryNode.InternalWsUrl}
- nonDevGethNetworks[i].HTTPURLs = []string{n.PrimaryNode.InternalHttpUrl}
+ var nonDevNetworks []blockchain.EVMNetwork
+ for i, n := range te.PrivateChain {
+ primaryNode := n.GetPrimaryNode()
+ if primaryNode == nil {
+ return te, errors.WithStack(fmt.Errorf("Primary node is nil in PrivateChain interface"))
+ }
+ nonDevNetworks = append(nonDevNetworks, *n.GetNetworkConfig())
+ nonDevNetworks[i].URLs = []string{primaryNode.GetInternalWsUrl()}
+ nonDevNetworks[i].HTTPURLs = []string{primaryNode.GetInternalHttpUrl()}
}
- if nonDevGethNetworks == nil {
- return nil, errors.New("cannot create nodes with custom config without nonDevGethNetworks")
+ if nonDevNetworks == nil {
+ return nil, errors.New("cannot create nodes with custom config without nonDevNetworks")
}
err = te.StartClNodes(b.clNodeConfig, b.clNodesCount)
@@ -161,7 +178,7 @@ func (b *CLTestEnvBuilder) buildNewEnv(cfg *TestEnvConfig) (*CLClusterTestEnv, e
return te, nil
}
networkConfig := networks.SelectedNetwork
- var internalDockerUrls InternalDockerUrls
+ var internalDockerUrls test_env.InternalDockerUrls
if b.hasGeth && networkConfig.Simulated {
networkConfig, internalDockerUrls, err = te.StartGeth()
if err != nil {
@@ -170,20 +187,20 @@ func (b *CLTestEnvBuilder) buildNewEnv(cfg *TestEnvConfig) (*CLClusterTestEnv, e
}
- bc, err := blockchain.NewEVMClientFromNetwork(networkConfig)
+ bc, err := blockchain.NewEVMClientFromNetwork(networkConfig, b.l)
if err != nil {
return nil, err
}
te.EVMClient = bc
- cd, err := contracts.NewContractDeployer(bc)
+ cd, err := contracts.NewContractDeployer(bc, b.l)
if err != nil {
return nil, err
}
te.ContractDeployer = cd
- cl, err := contracts.NewContractLoader(bc)
+ cl, err := contracts.NewContractLoader(bc, b.l)
if err != nil {
return nil, err
}
@@ -197,7 +214,7 @@ func (b *CLTestEnvBuilder) buildNewEnv(cfg *TestEnvConfig) (*CLClusterTestEnv, e
if b.clNodeConfig != nil {
cfg = b.clNodeConfig
} else {
- cfg = node.NewConfig(node.BaseConf,
+ cfg = node.NewConfig(node.NewBaseConfig(),
node.WithOCR1(),
node.WithP2Pv1(),
)
diff --git a/integration-tests/example.env b/integration-tests/example.env
index 8570fa86e1e..428f76b914e 100644
--- a/integration-tests/example.env
+++ b/integration-tests/example.env
@@ -4,7 +4,7 @@
########## 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="1.13.0" # Version of the Chainlink image to pull
+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
diff --git a/integration-tests/go.mod b/integration-tests/go.mod
index 9ad8b7164ce..9aa09350013 100644
--- a/integration-tests/go.mod
+++ b/integration-tests/go.mod
@@ -1,6 +1,6 @@
module github.com/smartcontractkit/chainlink/integration-tests
-go 1.20
+go 1.21
// Make sure we're working with the latest chainlink libs
replace github.com/smartcontractkit/chainlink/v2 => ../
@@ -10,21 +10,22 @@ require (
github.com/cli/go-gh/v2 v2.0.0
github.com/ethereum/go-ethereum v1.12.0
github.com/go-resty/resty/v2 v2.7.0
- github.com/google/uuid v1.3.0
+ github.com/google/uuid v1.3.1
github.com/kelseyhightower/envconfig v1.4.0
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/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/chainlink-env v0.36.0
- github.com/smartcontractkit/chainlink-testing-framework v1.16.0
+ github.com/smartcontractkit/chainlink-testing-framework v1.17.0
github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000
- github.com/smartcontractkit/libocr v0.0.0-20230816220705-665e93233ae5
- github.com/smartcontractkit/ocr2keepers v0.7.17
+ 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/spf13/cobra v1.6.1
github.com/stretchr/testify v1.8.4
@@ -68,7 +69,7 @@ require (
github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129 // indirect
github.com/armon/go-metrics v0.4.1 // indirect
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
- github.com/avast/retry-go/v4 v4.3.4 // indirect
+ github.com/avast/retry-go/v4 v4.5.0 // indirect
github.com/aws/aws-sdk-go v1.44.276 // indirect
github.com/aws/constructs-go/constructs/v10 v10.1.255 // indirect
github.com/aws/jsii-runtime-go v1.75.0 // indirect
@@ -130,6 +131,7 @@ require (
github.com/dvsekhvalnov/jose2go v1.5.0 // indirect
github.com/edsrzf/mmap-go v1.1.0 // indirect
github.com/emicklei/go-restful/v3 v3.10.1 // indirect
+ github.com/esote/minmaxheap v1.0.0 // indirect
github.com/evanphx/json-patch v5.6.0+incompatible // indirect
github.com/evanphx/json-patch/v5 v5.6.0 // indirect
github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f // indirect
@@ -158,12 +160,12 @@ require (
github.com/go-ole/go-ole v1.2.6 // indirect
github.com/go-openapi/analysis v0.21.4 // indirect
github.com/go-openapi/errors v0.20.3 // indirect
- github.com/go-openapi/jsonpointer v0.19.6 // indirect
+ github.com/go-openapi/jsonpointer v0.20.0 // indirect
github.com/go-openapi/jsonreference v0.20.2 // indirect
github.com/go-openapi/loads v0.21.2 // indirect
- github.com/go-openapi/spec v0.20.8 // indirect
+ github.com/go-openapi/spec v0.20.9 // indirect
github.com/go-openapi/strfmt v0.21.7 // indirect
- github.com/go-openapi/swag v0.22.3 // indirect
+ github.com/go-openapi/swag v0.22.4 // indirect
github.com/go-openapi/validate v0.22.1 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
@@ -189,7 +191,7 @@ require (
github.com/google/go-tpm v0.3.3 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/gopacket v1.1.19 // indirect
- github.com/google/pprof v0.0.0-20230602150820-91b7bce49751 // indirect
+ github.com/google/pprof v0.0.0-20230705174524-200ffdc848b8 // indirect
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
github.com/gorilla/context v1.1.1 // indirect
github.com/gorilla/mux v1.8.0 // indirect
@@ -201,6 +203,8 @@ require (
github.com/grafana/dskit v0.0.0-20230201083518-528d8a7d52f2 // indirect
github.com/grafana/loki v1.6.2-0.20230403212622-90888a0cc737 // indirect
github.com/grafana/loki/pkg/push v0.0.0-20230127102416-571f88bc5765 // indirect
+ github.com/grafana/pyroscope-go v1.0.2 // indirect
+ github.com/grafana/pyroscope-go/godeltaprof v0.1.3 // indirect
github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd // indirect
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect
@@ -227,7 +231,7 @@ require (
github.com/hashicorp/yamux v0.0.0-20200609203250-aecfd211c9ce // indirect
github.com/hdevalence/ed25519consensus v0.1.0 // indirect
github.com/holiman/bloomfilter/v2 v2.0.3 // indirect
- github.com/holiman/uint256 v1.2.2 // indirect
+ github.com/holiman/uint256 v1.2.3 // indirect
github.com/huandu/skiplist v1.2.0 // indirect
github.com/huin/goupnp v1.0.3 // indirect
github.com/imdario/mergo v0.3.16 // indirect
@@ -239,7 +243,7 @@ require (
github.com/ipfs/go-log v1.0.4 // indirect
github.com/ipfs/go-log/v2 v2.1.1 // indirect
github.com/jackc/chunkreader/v2 v2.0.1 // indirect
- github.com/jackc/pgconn v1.14.0 // indirect
+ github.com/jackc/pgconn v1.14.1 // indirect
github.com/jackc/pgio v1.0.0 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgproto3/v2 v2.3.2 // indirect
@@ -356,37 +360,35 @@ require (
github.com/petermattis/goid v0.0.0-20230317030725-371a4b8eda08 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
- github.com/prometheus/alertmanager v0.25.0 // indirect
+ github.com/prometheus/alertmanager v0.25.1 // indirect
github.com/prometheus/client_golang v1.16.0 // indirect
github.com/prometheus/client_model v0.4.0 // indirect
github.com/prometheus/common v0.44.0 // indirect
github.com/prometheus/common/sigv4 v0.1.0 // indirect
github.com/prometheus/exporter-toolkit v0.10.0 // indirect
github.com/prometheus/procfs v0.11.0 // indirect
- github.com/prometheus/prometheus v0.45.0 // indirect
+ github.com/prometheus/prometheus v0.46.0 // indirect
github.com/pyroscope-io/client v0.7.1 // indirect
- github.com/pyroscope-io/godeltaprof v0.1.2 // indirect
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect
github.com/rivo/uniseg v0.4.4 // indirect
github.com/robfig/cron/v3 v3.0.1 // indirect
- github.com/rogpeppe/go-internal v1.10.0 // indirect
+ github.com/rogpeppe/go-internal v1.11.0 // indirect
github.com/russross/blackfriday v1.6.0 // indirect
github.com/sasha-s/go-deadlock v0.3.1 // indirect
github.com/scylladb/go-reflectx v1.0.1 // indirect
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 // indirect
github.com/sercand/kuberesolver v2.4.0+incompatible // indirect
github.com/shirou/gopsutil v3.21.11+incompatible // indirect
- github.com/shirou/gopsutil/v3 v3.22.12 // indirect
+ github.com/shirou/gopsutil/v3 v3.23.8 // indirect
github.com/shopspring/decimal v1.3.1 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704 // indirect
- github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20230824124058-9b063c470048 // indirect
- github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230824125819-215fd09979a2 // indirect
- github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230802143301-165000751a85 // indirect
- github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20230802150127-d2c95679d61a // indirect
+ github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20230913032705-f924d753cc47 // 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
- github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230823081604-f2a0e6b108bb // indirect
- github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230823081604-f2a0e6b108bb // indirect
+ github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 // indirect
github.com/smartcontractkit/wsrpc v0.7.2 // indirect
github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 // indirect
github.com/spaolacci/murmur3 v1.1.0 // indirect
@@ -404,10 +406,10 @@ require (
github.com/teris-io/shortid v0.0.0-20201117134242-e59966efd125 // indirect
github.com/theodesp/go-heaps v0.0.0-20190520121037-88e35354fe0a // indirect
github.com/tidwall/btree v1.6.0 // indirect
- github.com/tidwall/gjson v1.14.4 // indirect
+ github.com/tidwall/gjson v1.16.0 // indirect
github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.0 // indirect
- github.com/tklauser/go-sysconf v0.3.11 // indirect
+ github.com/tklauser/go-sysconf v0.3.12 // indirect
github.com/tklauser/numcpus v0.6.1 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/tyler-smith/go-bip39 v1.1.0 // indirect
@@ -459,9 +461,9 @@ require (
gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect
gonum.org/v1/gonum v0.13.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
- google.golang.org/genproto v0.0.0-20230706204954-ccb25ca9f130 // indirect
- google.golang.org/genproto/googleapis/api v0.0.0-20230629202037-9506855d4529 // indirect
- google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 // indirect
+ google.golang.org/genproto v0.0.0-20230717213848-3f92550aa753 // indirect
+ google.golang.org/genproto/googleapis/api v0.0.0-20230717213848-3f92550aa753 // indirect
+ google.golang.org/genproto/googleapis/rpc v0.0.0-20230717213848-3f92550aa753 // indirect
google.golang.org/grpc v1.57.0 // indirect
google.golang.org/protobuf v1.31.0 // indirect
gopkg.in/guregu/null.v2 v2.1.2 // indirect
diff --git a/integration-tests/go.sum b/integration-tests/go.sum
index 187291d8510..bd4a8b977c0 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=
@@ -270,7 +272,8 @@ cloud.google.com/go/iam v0.7.0/go.mod h1:H5Br8wRaDGNc8XP3keLc4unfUUZeyH3Sfl9XpQE
cloud.google.com/go/iam v0.8.0/go.mod h1:lga0/y3iH6CX7sYqypWJ33hf7kkfXJag67naqGESjkE=
cloud.google.com/go/iam v0.11.0/go.mod h1:9PiLDanza5D+oWFZiH1uG+RnRCfEGKoyl6yo4cgWZGY=
cloud.google.com/go/iam v0.12.0/go.mod h1:knyHGviacl11zrtZUoDuYpDgLjvr28sLQaG0YB2GYAY=
-cloud.google.com/go/iam v1.1.0 h1:67gSqaPukx7O8WLLHMa0PNs3EBGd2eE4d+psbO/CO94=
+cloud.google.com/go/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,23 +550,34 @@ 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.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak=
+github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d h1:nalkkPQcITbvhmL4+C4cKA87NW0tfm3Kl9VXRoPywFg=
github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d/go.mod h1:URdX5+vg25ts3aCh8H5IFZybJYKWhJHYMTnf+ULtoC4=
@@ -574,9 +591,11 @@ github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3
github.com/DataDog/zstd v1.5.2 h1:vUG4lAyuPCXO0TLbXvPv7EB7cNK1QV/luu55UHLrrn8=
github.com/DataDog/zstd v1.5.2/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw=
github.com/Depado/ginprom v1.7.11 h1:qOhxW/NJZkNkkG4TQrzAZklX8SUTjTfLA73zIUNIpww=
+github.com/Depado/ginprom v1.7.11/go.mod h1:49mxL3NTQwDrhpDbY4V1mAIB3us9B+b2hP1+ph+Sla8=
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=
@@ -592,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=
@@ -610,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=
@@ -619,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=
@@ -637,8 +662,8 @@ github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkY
github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so=
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
-github.com/avast/retry-go/v4 v4.3.4 h1:pHLkL7jvCvP317I8Ge+Km2Yhntv3SdkJm7uekkqbKhM=
-github.com/avast/retry-go/v4 v4.3.4/go.mod h1:rv+Nla6Vk3/ilU0H51VHddWHiwimzX66yZ0JT6T+UvE=
+github.com/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.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
@@ -660,6 +685,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=
@@ -673,6 +699,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=
@@ -683,8 +710,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=
@@ -700,6 +729,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=
@@ -729,6 +759,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=
@@ -744,10 +775,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=
@@ -762,6 +796,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.7.0 h1:uBjbrBx4QzU0zOEnU8KxoDl18dMNgDh+zZRUE0ucsbo=
@@ -771,6 +806,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=
@@ -794,6 +830,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=
@@ -805,6 +842,7 @@ github.com/cosmos/ics23/go v0.9.1-0.20221207100636-b1abd8678aab/go.mod h1:2Cwqas
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 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk=
@@ -813,16 +851,22 @@ 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=
github.com/danielkov/gin-helmet v0.0.0-20171108135313-1387e224435e h1:5jVSh2l/ho6ajWhSPNN84eHEdq3dp0T7+f6r3Tc6hsk=
+github.com/danielkov/gin-helmet v0.0.0-20171108135313-1387e224435e/go.mod h1:IJgIiGUARc4aOr4bOQ85klmjsShkEEfiRc6q/yBSfo8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
@@ -833,12 +877,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=
@@ -859,6 +905,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=
@@ -877,6 +924,7 @@ github.com/edsrzf/mmap-go v1.1.0 h1:6EUwBLQ/Mcr1EYLE4Tn1VdW1A4ckqCQWZBw8Hr0kjpQ=
github.com/edsrzf/mmap-go v1.1.0/go.mod h1:19H/e8pUPLicwkyNgOykDXkJ9F0MHE+Z52B8EIth78Q=
github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM=
github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153 h1:yUdfgN0XgIJw7foRItutHYUIhlcKzcSf5vDpdhQAKTc=
+github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
github.com/emicklei/go-restful/v3 v3.10.1 h1:rc42Y5YTp7Am7CS630D7JmhRjq4UlEUuEKfrDac4bSQ=
github.com/emicklei/go-restful/v3 v3.10.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
@@ -891,11 +939,15 @@ 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=
github.com/ethereum/go-ethereum v1.12.0 h1:bdnhLPtqETd4m3mS8BGMNvBTf36bO5bx/hxE2zljOa0=
github.com/ethereum/go-ethereum v1.12.0/go.mod h1:/oo2X/dZLJjf2mJ6YT9wcWxa4nNJDBKDBU6sFIpx1Gs=
@@ -907,8 +959,11 @@ github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2Vvl
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/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c h1:8ISkoahWXwZR41ois5lSJBSVw4D0OV19Ht/JSTzvSv0=
+github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c/go.mod h1:Yg+htXGokKKdzcwhuNDwVvN+uBxDGXJ7G/VN1d8fa64=
github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 h1:JWuenKqqX8nojtoVVWjGfOF9635RETekkoH6Cc9SX0A=
+github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg=
github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4 h1:7HZCaLC5+BZpmbhCOZJ293Lz68O7PYrF2EzeiFMwCLk=
+github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4/go.mod h1:5tD+neXqOorC30/tWg0LCSkrqj/AR6gu8yY8/fpw1q0=
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=
@@ -922,13 +977,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=
@@ -953,15 +1011,19 @@ github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv
github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 h1:f6D9Hr8xV8uYKlyuj8XIruxlh9WjVjdh1gIicAS7ays=
github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww=
github.com/gedex/inflector v0.0.0-20170307190818-16278e9db813 h1:Uc+IZ7gYqAf/rSGFplbWBSHaGolEQlNLgMgSE3ccnIQ=
+github.com/gedex/inflector v0.0.0-20170307190818-16278e9db813/go.mod h1:P+oSoE9yhSRvsmYyZsshflcR6ePWYLql6UU1amW13IM=
github.com/getsentry/sentry-go v0.12.0/go.mod h1:NSap0JBYWzHND8oMbyi0+XZhUalc1TBdRL1M71JZW2c=
github.com/getsentry/sentry-go v0.19.0 h1:BcCH3CN5tXt5aML+gwmbFwVptLLQA+eT866fCO9wVOM=
github.com/getsentry/sentry-go v0.19.0/go.mod h1:y3+lGEFEFexZtpbG1GUE2WD/f9zGyKYwpEqryTOC/nE=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/gin-contrib/cors v1.4.0 h1:oJ6gwtUl3lqV0WEIwM/LxPF1QZ5qe2lGWdY2+bz7y0g=
+github.com/gin-contrib/cors v1.4.0/go.mod h1:bs9pNM0x/UsmHPBWT2xZz9ROh8xYjYkiURUfmBoMlcs=
github.com/gin-contrib/expvar v0.0.1 h1:IuU5ArEgihz50vG8Onrwz22kJr7Mcvgv9xSSpfU5g+w=
+github.com/gin-contrib/expvar v0.0.1/go.mod h1:8o2CznfQi1JjktORdHr2/abg3wSV6OCnXh0yGypvvVw=
github.com/gin-contrib/sessions v0.0.5 h1:CATtfHmLMQrMNpJRgzjWXD7worTh7g7ritsQfmF+0jE=
github.com/gin-contrib/sessions v0.0.5/go.mod h1:vYAuaUPqie3WUSsft6HUlCjlwwoJQs97miaG2+7neKY=
github.com/gin-contrib/size v0.0.0-20230212012657-e14a14094dc4 h1:Z9J0PVIt1PuibOShaOw1jH8hUYz+Ak8NLsR/GI0Hv5I=
+github.com/gin-contrib/size v0.0.0-20230212012657-e14a14094dc4/go.mod h1:CEPcgZiz8998l9E8fDm16h8UfHRL7b+5oG0j/0koeVw=
github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s=
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
@@ -1001,6 +1063,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=
@@ -1014,8 +1077,9 @@ github.com/go-openapi/errors v0.20.3 h1:rz6kiC84sqNQoqrtulzaL/VERgkoCyB6WdEkc2uj
github.com/go-openapi/errors v0.20.3/go.mod h1:Z3FlZ4I8jEGxjUK+bugx3on2mIAk4txuAOhlsB1FSgk=
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
-github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE=
github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs=
+github.com/go-openapi/jsonpointer v0.20.0 h1:ESKJdU9ASRfaPNOPRx12IUyA1vn3R9GiE3KYD14BXdQ=
+github.com/go-openapi/jsonpointer v0.20.0/go.mod h1:6PGzBjjIIumbLYysB73Klnms1mwnU4G3YHOECG3CedA=
github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns=
github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo=
github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE=
@@ -1025,8 +1089,8 @@ github.com/go-openapi/loads v0.21.2 h1:r2a/xFIYeZ4Qd2TnGpWDIQNcP80dIaZgf704za8en
github.com/go-openapi/loads v0.21.2/go.mod h1:Jq58Os6SSGz0rzh62ptiu8Z31I+OTHqmULx5e/gJbNw=
github.com/go-openapi/spec v0.20.4/go.mod h1:faYFR1CvsJZ0mNsmsphTMSoRrNV3TEDoAM7FOEWeq8I=
github.com/go-openapi/spec v0.20.6/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA=
-github.com/go-openapi/spec v0.20.8 h1:ubHmXNY3FCIOinT8RNrrPfGc9t7I1qhPtdOGoG2AxRU=
-github.com/go-openapi/spec v0.20.8/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA=
+github.com/go-openapi/spec v0.20.9 h1:xnlYNQAwKd2VQRRfwTEI0DcK+2cbuvI/0c7jx3gA8/8=
+github.com/go-openapi/spec v0.20.9/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA=
github.com/go-openapi/strfmt v0.21.0/go.mod h1:ZRQ409bWMj+SOgXofQAGTIo2Ebu72Gs+WaRADcS5iNg=
github.com/go-openapi/strfmt v0.21.1/go.mod h1:I/XVKeLc5+MM5oPNN7P6urMOpuLXEcNrCX/rPGuWb0k=
github.com/go-openapi/strfmt v0.21.3/go.mod h1:k+RzNO0Da+k3FrrynSNN8F7n/peCmQQqbbXjtDfvmGg=
@@ -1035,14 +1099,16 @@ github.com/go-openapi/strfmt v0.21.7/go.mod h1:adeGTkxE44sPyLk0JV235VQAO/ZXUr8KA
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
github.com/go-openapi/swag v0.21.1/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
-github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g=
github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
+github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU=
+github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
github.com/go-openapi/validate v0.22.1 h1:G+c2ub6q47kfX1sOBLwIQwzBVt8qmOAARyo/9Fqs9NU=
github.com/go-openapi/validate v0.22.1/go.mod h1:rjnrwK57VJ7A8xqfpAOEKRH8yQSGUriMu5/zuPSQ1hg=
github.com/go-pdf/fpdf v0.5.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M=
github.com/go-pdf/fpdf v0.6.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M=
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
+github.com/go-playground/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.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
@@ -1061,6 +1127,7 @@ 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=
@@ -1068,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=
@@ -1108,6 +1176,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=
@@ -1213,6 +1282,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=
@@ -1229,17 +1299,19 @@ github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLe
github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
-github.com/google/pprof v0.0.0-20230602150820-91b7bce49751 h1:hR7/MlvK23p6+lIw9SN1TigNLn9ZnF3W4SYRKq2gAHs=
-github.com/google/pprof v0.0.0-20230602150820-91b7bce49751/go.mod h1:Jh3hGz2jkYak8qXPD19ryItVnUgpgeqzdkY/D0EaeuA=
+github.com/google/pprof v0.0.0-20230705174524-200ffdc848b8 h1:n6vlPhxsA+BW/XsS5+uqi7GyzaLa5MH7qlSLBZtRdiA=
+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.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.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.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8=
github.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8=
github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg=
@@ -1257,13 +1329,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=
@@ -1287,10 +1362,16 @@ github.com/grafana/loki v1.6.2-0.20230403212622-90888a0cc737 h1:o45+fZAYRtTjx+9f
github.com/grafana/loki v1.6.2-0.20230403212622-90888a0cc737/go.mod h1:kxNnWCr4EMobhndjy7a2Qpm7jkLPnJW2ariYvY77hLE=
github.com/grafana/loki/pkg/push v0.0.0-20230127102416-571f88bc5765 h1:VXitROTlmZtLzvokNe8ZbUKpmwldM4Hy1zdNRO32jKU=
github.com/grafana/loki/pkg/push v0.0.0-20230127102416-571f88bc5765/go.mod h1:DhJMrd2QInI/1CNtTN43BZuTmkccdizW1jZ+F6aHkhY=
+github.com/grafana/pyroscope-go v1.0.2 h1:dEFgO9VbhYTwuwpCC5coTpuW0JjISEWDZtvRAW9v5Tw=
+github.com/grafana/pyroscope-go v1.0.2/go.mod h1:bShDKsVZdzxq+Ol6no0JKigU9y5FTWUcFditMXaH09o=
+github.com/grafana/pyroscope-go/godeltaprof v0.1.3 h1:eunWpv1B3Z7ZK9o4499EmQGlY+CsDmSZ4FbxjRx37uk=
+github.com/grafana/pyroscope-go/godeltaprof v0.1.3/go.mod h1:1HSPtjU8vLG0jE9JrTdzjgFqdJ/VgN7fvxBNq3luJko=
github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd h1:PpuIBO5P3e9hpqBD0O/HjhShYuM6XE0i/lbE6J94kww=
github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd/go.mod h1:M5qHK+eWfAv8VR/265dIuEpL3fNfeC21tXXp9itM24A=
github.com/graph-gophers/dataloader v5.0.0+incompatible h1:R+yjsbrNq1Mo3aPG+Z/EKYrXrXXUNJHOgbRt+U6jOug=
+github.com/graph-gophers/dataloader v5.0.0+incompatible/go.mod h1:jk4jk0c5ZISbKaMe8WsVopGB5/15GvGHMdMdPtwlRp4=
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=
@@ -1322,16 +1403,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=
@@ -1346,10 +1431,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=
@@ -1357,8 +1444,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=
@@ -1375,6 +1464,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=
@@ -1383,11 +1473,13 @@ 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.2 h1:TXKcSGc2WaxPD2+bmzAsVthL4+pEN0YwXcL5qED83vk=
-github.com/holiman/uint256 v1.2.2/go.mod h1:SC8Ryt4n+UBbPbIBKaG9zbbDlp4jOru9xFZmPzLUTxw=
+github.com/holiman/uint256 v1.2.3 h1:K8UWO1HUJpRMXBxbmaY1Y8IAMZC/RsKB+ArEnnK4l5o=
+github.com/holiman/uint256 v1.2.3/go.mod h1:SC8Ryt4n+UBbPbIBKaG9zbbDlp4jOru9xFZmPzLUTxw=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/huandu/go-assert v1.1.5 h1:fjemmA7sSfYHJD7CUqs9qTwwfdNAx7/j2/ZlHXzNB3c=
github.com/huandu/go-assert v1.1.5/go.mod h1:yOLvuqZwmcHIC5rIzrBhT7D3Q9c3GFnd0JrPVhn/06U=
@@ -1405,11 +1497,13 @@ 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.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/ionos-cloud/sdk-go/v6 v6.1.4 h1:BJHhFA8Q1SZC7VOXqKKr2BV2ysQ2/4hlk1e4hZte7GY=
+github.com/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=
@@ -1468,8 +1562,9 @@ github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsU
github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o=
github.com/jackc/pgconn v1.9.0/go.mod h1:YctiPyvzfU11JFxoXokUOOKQXQmDMoJL9vJzHH8/2JY=
github.com/jackc/pgconn v1.9.1-0.20210724152538-d89c8390a530/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI=
-github.com/jackc/pgconn v1.14.0 h1:vrbA9Ud87g6JdFWkHTJXppVce58qPIdP7N8y0Ml/A7Q=
github.com/jackc/pgconn v1.14.0/go.mod h1:9mBNlny0UvkgJdCDvdVHYSjI+8tD2rnKK69Wz8ti++E=
+github.com/jackc/pgconn v1.14.1 h1:smbxIaZA08n6YuxEX1sDyjV/qkbtUtkH20qLkR9MUR4=
+github.com/jackc/pgconn v1.14.1/go.mod h1:9mBNlny0UvkgJdCDvdVHYSjI+8tD2rnKK69Wz8ti++E=
github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE=
github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8=
github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE=
@@ -1522,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=
@@ -1533,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=
@@ -1584,6 +1681,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=
@@ -1604,6 +1702,7 @@ github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
+github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/labstack/echo/v4 v4.5.0/go.mod h1:czIriw4a0C1dFun+ObrXp7ok03xON0N1awStJ6ArI7Y=
github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k=
github.com/leanovate/gopter v0.2.10-0.20210127095200-9abe2343507a h1:dHCfT5W7gghzPtfsW488uPmEOm85wewI+ypUwibyTdU=
@@ -1825,9 +1924,11 @@ 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/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=
@@ -1845,6 +1946,7 @@ github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJ
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/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE=
github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
@@ -1876,6 +1978,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=
@@ -1899,6 +2002,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=
@@ -1926,6 +2030,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=
@@ -1958,7 +2063,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=
@@ -2024,6 +2131,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=
@@ -2044,6 +2152,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=
@@ -2071,7 +2180,9 @@ 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/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=
@@ -2081,8 +2192,8 @@ github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/9
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.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=
@@ -2109,8 +2220,9 @@ github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSg
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw=
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
github.com/pressly/goose/v3 v3.15.0 h1:6tY5aDqFknY6VZkorFGgZtWygodZQxfmmEF4rqyJW9k=
-github.com/prometheus/alertmanager v0.25.0 h1:vbXKUR6PYRiZPRIKfmXaG+dmCKG52RtPL4Btl8hQGvg=
-github.com/prometheus/alertmanager v0.25.0/go.mod h1:MEZ3rFVHqKZsw7IcNS/m4AWZeXThmJhumpiWR4eHU/w=
+github.com/pressly/goose/v3 v3.15.0/go.mod h1:LlIo3zGccjb/YUgG+Svdb9Er14vefRdlDI7URCDrwYo=
+github.com/prometheus/alertmanager v0.25.1 h1:LGBNMspOfv8h7brb+LWj2wnwBCg2ZuuKWTh6CAVw2/Y=
+github.com/prometheus/alertmanager v0.25.1/go.mod h1:MEZ3rFVHqKZsw7IcNS/m4AWZeXThmJhumpiWR4eHU/w=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
@@ -2166,9 +2278,11 @@ github.com/pyroscope-io/client v0.7.1/go.mod h1:4h21iOU4pUOq0prKyDlvYRL+SCKsBc5w
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=
@@ -2185,9 +2299,10 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
-github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
-github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
+github.com/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=
@@ -2208,6 +2323,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=
@@ -2217,10 +2333,13 @@ 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.22.12 h1:oG0ns6poeUSxf78JtOsfygNWuEHYYz8hnnNg7P04TJs=
-github.com/shirou/gopsutil/v3 v3.22.12/go.mod h1:Xd7P1kwZcp5VW52+9XsirIKd/BROzbb2wdX3Kqlz9uI=
+github.com/shirou/gopsutil/v3 v3.23.8 h1:xnATPiybo6GgdRoC4YoGnxXZFRc3dqQTGi73oLvvBrE=
+github.com/shirou/gopsutil/v3 v3.23.8/go.mod h1:7hmCaBn+2ZwaZOr6jmPBZDfawwMGuo1id3C6aM8EDqQ=
+github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ=
+github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k=
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8=
@@ -2237,34 +2356,34 @@ github.com/slack-go/slack v0.12.2 h1:x3OppyMyGIbbiyFhsBmpf9pwkUzMhthJMRNmNlA4LaQ
github.com/slack-go/slack v0.12.2/go.mod h1:hlGi5oXA+Gt+yWTPP0plCdRKmjsDxecdHxYQdlMQKOw=
github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704 h1:T3lFWumvbfM1u/etVq42Afwq/jtNSBSOA8n5jntnNPo=
github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704/go.mod h1:2QuJdEouTWjh5BDy5o/vgGXQtR4Gz8yH1IYB5eT7u4M=
-github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20230824124058-9b063c470048 h1:OHj8qzXajBAIT9TBnHN5LVGoCxvso/4JgCeg/l76Tgk=
-github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20230824124058-9b063c470048/go.mod h1:xMwqRdj5vqYhCJXgKVqvyAwdcqM6ZAEhnwEQ4Khsop8=
+github.com/smartcontractkit/chainlink-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-env v0.36.0/go.mod h1:NbRExHmJGnKSYXmvNuJx5VErSx26GtE1AEN/CRzYOg8=
-github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230824125819-215fd09979a2 h1:z9PIgm0klhunwPy+KZYR4E9vCpjgJaMOyQRLCYgfoLk=
-github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230824125819-215fd09979a2/go.mod h1:gWclxGW7rLkbjXn7FGizYlyKhp/boekto4MEYGyiMG4=
-github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230802143301-165000751a85 h1:/fm02hYSUdhbSh7xPn7os9yHj7dnl8aLs2+nFXPiB4g=
-github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230802143301-165000751a85/go.mod h1:H3/j2l84FsxYevCLNERdVasI7FVr+t2mkpv+BCJLSVw=
-github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20230802150127-d2c95679d61a h1:b3rjvZLpTV45TmCV+ALX+EDDslf91pnDUugP54Lu9FA=
-github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20230802150127-d2c95679d61a/go.mod h1:LL+FLf10gOUHrF3aUsRGEZlT/w8DaW5T/eEo/54W68c=
-github.com/smartcontractkit/chainlink-testing-framework v1.16.0 h1:jLpqwqaTpJXQvTJ1IXTomcCToOdrSCe4+IGcLXGsmD0=
-github.com/smartcontractkit/chainlink-testing-framework v1.16.0/go.mod h1:t6FJX3akEfAO31p96ru0ilNPfE9P2UshUlXTIkI58LM=
+github.com/smartcontractkit/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.0 h1:JcJwfawW7jfLBG+By5hGTVcNgKQ7bJCqvN9TEF3qBis=
+github.com/smartcontractkit/chainlink-testing-framework v1.17.0/go.mod h1:Ry6fRPr8TwrIsYVNEF1pguAgzE3QW1s54tbLWnFtfI4=
github.com/smartcontractkit/go-plugin v0.0.0-20230605132010-0f4d515d1472 h1:x3kNwgFlDmbE/n0gTSRMt9GBDfsfGrs4X9b9arPZtFI=
github.com/smartcontractkit/go-plugin v0.0.0-20230605132010-0f4d515d1472/go.mod h1:6/1TEzT0eQznvI/gV2CM29DLSkAK/e58mUWKVsPaph0=
github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f h1:hgJif132UCdjo8u43i7iPN1/MFnu49hv7lFGFftCHKU=
github.com/smartcontractkit/grpc-proxy v0.0.0-20230731113816-f1be6620749f/go.mod h1:MvMXoufZAtqExNexqi4cjrNYE9MefKddKylxjS+//n0=
-github.com/smartcontractkit/libocr v0.0.0-20230816220705-665e93233ae5 h1:rzbqGoScs9VHGnyCKF7AoQEuUfwJnzcKmGIfaczeanA=
-github.com/smartcontractkit/libocr v0.0.0-20230816220705-665e93233ae5/go.mod h1:2lyRkw/qLQgUWlrWWmq5nj0y90rWeO6Y+v+fCakRgb0=
-github.com/smartcontractkit/ocr2keepers v0.7.17 h1:847GG2SHyHIPc3yu+dhB+1HfeLRhSjyiKnhw3umpoJw=
-github.com/smartcontractkit/ocr2keepers v0.7.17/go.mod h1:AjcIEKeNnU7NRlvnuMCTjBIQ1kpW0YHhlFdeDa/3hs0=
+github.com/smartcontractkit/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=
github.com/smartcontractkit/sqlx v1.3.5-0.20210805004948-4be295aacbeb/go.mod h1:HNUu4cJekUdsJbwRBCiOybtkPJEfGRELQPe2tkoDEyk=
-github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230823081604-f2a0e6b108bb h1:xNLGJcARfz9HCUKla6wH0gmwsG1/FTAWWeOplW2J72A=
-github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230823081604-f2a0e6b108bb/go.mod h1:q6f4fe39oZPdsh1i57WznEZgxd8siidMaSFq3wdPmVg=
-github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230823081604-f2a0e6b108bb h1:jyhgdafuZsex+kEHDIgq8o8wuVoPTr9wsGmuBtcFbEk=
-github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230823081604-f2a0e6b108bb/go.mod h1:G5Sd/yzHWf26rQ+X0nG9E0buKPqRGPMJAfk2gwCzOOw=
+github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 h1:yiKnypAqP8l0OX0P3klzZ7SCcBUxy5KqTAKZmQOvSQE=
+github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1/go.mod h1:q6f4fe39oZPdsh1i57WznEZgxd8siidMaSFq3wdPmVg=
+github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 h1:Dai1bn+Q5cpeGMQwRdjOdVjG8mmFFROVkSKuUgBErRQ=
+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/wsrpc v0.7.2 h1:iBXzMeg7vc5YoezIQBq896y25BARw7OKbhrb6vPbtRQ=
@@ -2349,19 +2468,19 @@ 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=
-github.com/tidwall/gjson v1.14.4 h1:uo0p8EbA09J7RQaflQ1aBRffTR7xedD2bcIVSYxLnkM=
-github.com/tidwall/gjson v1.14.4/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
+github.com/tidwall/gjson v1.16.0 h1:SyXa+dsSPpUlcwEDuKuEBJEz5vzTvOea+9rjyYodQFg=
+github.com/tidwall/gjson v1.16.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
-github.com/tklauser/go-sysconf v0.3.11 h1:89WgdJhk5SNwJfu+GKyYveZ4IaJ7xAkecBo+KdJV0CM=
-github.com/tklauser/go-sysconf v0.3.11/go.mod h1:GqXfhXY3kiPa0nAXPDIQIWzJbMCB7AmcWpGR8lSZfqI=
-github.com/tklauser/numcpus v0.6.0/go.mod h1:FEZLMke0lhOUG6w2JadTzp0a+Nl8PF/GFkQ5UVIcaL4=
+github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU=
+github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk=
github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
@@ -2383,14 +2502,19 @@ github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLY
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=
github.com/umbracle/ethgo v0.1.3/go.mod h1:g9zclCLixH8liBI27Py82klDkW7Oo33AxUOr+M9lzrU=
github.com/umbracle/fastrlp v0.0.0-20220527094140-59d5dd30e722 h1:10Nbw6cACsnQm7r34zlpJky+IzxVLRk6MKTS2d3Vp0E=
github.com/umbracle/fastrlp v0.0.0-20220527094140-59d5dd30e722/go.mod h1:c8J0h9aULj2i3umrfyestM6jCq0LK0U6ly6bWy96nd4=
github.com/unrolled/secure v1.13.0 h1:sdr3Phw2+f8Px8HE5sd1EHdj1aV3yUwed/uZXChLFsk=
+github.com/unrolled/secure v1.13.0/go.mod h1:BmF5hyM6tXczk3MpQkFf1hpKSRqCyhqcbiQtiAF7+40=
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=
@@ -2400,6 +2524,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=
@@ -2429,6 +2554,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=
@@ -2442,7 +2568,6 @@ github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
-github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw=
github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0=
@@ -3111,6 +3236,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=
@@ -3253,12 +3379,12 @@ google.golang.org/genproto v0.0.0-20230209215440-0dfe4f8abfcc/go.mod h1:RGgjbofJ
google.golang.org/genproto v0.0.0-20230216225411-c8e22ba71e44/go.mod h1:8B0gmkoRebU8ukX6HP+4wrVQUY1+6PkQ44BSyIlflHA=
google.golang.org/genproto v0.0.0-20230222225845-10f96fb3dbec/go.mod h1:3Dl5ZL0q0isWJt+FVcfpQyirqemEuLAK/iFvg1UP1Hw=
google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s=
-google.golang.org/genproto v0.0.0-20230706204954-ccb25ca9f130 h1:Au6te5hbKUV8pIYWHqOUZ1pva5qK/rwbIhoXEUB9Lu8=
-google.golang.org/genproto v0.0.0-20230706204954-ccb25ca9f130/go.mod h1:O9kGHb51iE/nOGvQaDUuadVYqovW56s5emA88lQnj6Y=
-google.golang.org/genproto/googleapis/api v0.0.0-20230629202037-9506855d4529 h1:s5YSX+ZH5b5vS9rnpGymvIyMpLRJizowqDlOuyjXnTk=
-google.golang.org/genproto/googleapis/api v0.0.0-20230629202037-9506855d4529/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 h1:bVf09lpb+OJbByTj913DRJioFFAjf/ZGxEz7MajTp2U=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM=
+google.golang.org/genproto v0.0.0-20230717213848-3f92550aa753 h1:+VoAg+OKmWaommL56xmZSE2sUK8A7m6SUO7X89F2tbw=
+google.golang.org/genproto v0.0.0-20230717213848-3f92550aa753/go.mod h1:iqkVr8IRpZ53gx1dEnWlCUIEwDWqWARWrbzpasaTNYM=
+google.golang.org/genproto/googleapis/api v0.0.0-20230717213848-3f92550aa753 h1:lCbbUxUDD+DiXx9Q6F/ttL0aAu7N2pz8XnmMm8ZW4NE=
+google.golang.org/genproto/googleapis/api v0.0.0-20230717213848-3f92550aa753/go.mod h1:rsr7RhLuwsDKL7RmgDDCUc6yaGr1iqceVb5Wv6f6YvQ=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20230717213848-3f92550aa753 h1:XUODHrpzJEUeWmVo/jfNTLj0YyVveOo28oE6vkFbkO4=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20230717213848-3f92550aa753/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM=
google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
@@ -3378,6 +3504,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=
diff --git a/integration-tests/load/functions/README.md b/integration-tests/load/functions/README.md
index ec94b9ded0a..65a87b897ac 100644
--- a/integration-tests/load/functions/README.md
+++ b/integration-tests/load/functions/README.md
@@ -1,11 +1,68 @@
-### Functions Load tests
+### Functions & S4 Gateway Load tests
-## Usage
+## Setup
+Export vars
```
+export SELECTED_NETWORKS=MUMBAI
+export MUMBAI_KEYS=...
+export MUMBAI_URLS=...
export LOKI_TOKEN=...
export LOKI_URL=...
+```
+See more config options in [config.toml](./config.toml)
+
+## Usage
+
+All tests are split by network and in 3 groups:
+- HTTP payload only
+- Secrets decoding payload only
+- Realistic payload with args/http/secrets
+
+Load test client is [here](../../../contracts/src/v0.8/functions/tests/v1_0_0/testhelpers/FunctionsLoadTestClient.sol)
+
+Load is controlled with 2 params:
+- RPS
+- requests_per_call (generating more events in a loop in the contract)
+
+`Soak` is a stable workload for which there **must** be no issues
+
+`Stress` is a peak workload for which issues **must** be analyzed
+
+Load test client can execute `78 calls per request` at max (gas limit)
+
+Functions tests:
+```
+go test -v -run TestFunctionsLoad/mumbai_functions_soak_test_http
+go test -v -run TestFunctionsLoad/mumbai_functions_stress_test_http
+go test -v -run TestFunctionsLoad/mumbai_functions_soak_test_only_secrets
+go test -v -run TestFunctionsLoad/mumbai_functions_stress_test_only_secrets
+go test -v -run TestFunctionsLoad/mumbai_functions_soak_test_real
+go test -v -run TestFunctionsLoad/mumbai_functions_stress_test_real
+```
+
+Gateway tests:
+```
+go test -v -run TestGatewayLoad/gateway_secrets_list_soak_test
+go test -v -run TestGatewayLoad/gateway_secrets_set_soak_test
+```
+
+Chaos suite can be combined with any test, can be found [here](../../chaos/functions/full.yaml)
-go test -v -run TestFunctionsLoad/functions_soak_test
+Default [dashboard](https://chainlinklabs.grafana.net/d/FunctionsV1/functionsv1?orgId=1&from=now-5m&to=now&var-go_test_name=All&var-gen_name=All&var-branch=All&var-commit=All&var-call_group=All&refresh=5s)
+
+## Redeploying client and funding a new sub
+When contracts got redeployed on `Mumbai` just comment these lines in config
+```
+# comment both client and sub to automatically create a new pair
+client_addr = "0x64a351fbAa61681A5a7e569Cc5A691150c4D73D2"
+subscription_id = 23
+```
+Then insert new client addr and subscription number back
+
+## Debug
+Show more logs
+```
+export WASP_LOG_LEVEL=debug
```
### Dashboards
diff --git a/integration-tests/load/functions/config.go b/integration-tests/load/functions/config.go
index baba37d2c82..5c622401aba 100644
--- a/integration-tests/load/functions/config.go
+++ b/integration-tests/load/functions/config.go
@@ -17,21 +17,35 @@ const (
)
type PerformanceConfig struct {
- Soak *Soak `toml:"Soak"`
- Load *Load `toml:"Load"`
- SoakVolume *SoakVolume `toml:"SoakVolume"`
- LoadVolume *LoadVolume `toml:"LoadVolume"`
- Common *Common `toml:"Common"`
+ Soak *Soak `toml:"Soak"`
+ SecretsSoak *SecretsSoak `toml:"SecretsSoak"`
+ RealSoak *RealSoak `toml:"RealSoak"`
+ Stress *Stress `toml:"Stress"`
+ SecretsStress *SecretsStress `toml:"SecretsStress"`
+ RealStress *RealStress `toml:"RealStress"`
+ GatewayListSoak *GatewayListSoak `toml:"GatewayListSoak"`
+ GatewaySetSoak *GatewaySetSoak `toml:"GatewaySetSoak"`
+ Common *Common `toml:"Common"`
+ MumbaiPrivateKey string
}
type Common struct {
Funding
- LINKTokenAddr string `toml:"link_token_addr"`
- Coordinator string `toml:"coordinator_addr"`
- Router string `toml:"router_addr"`
- LoadTestClient string `toml:"client_example_addr"`
- SubscriptionID uint64 `toml:"subscription_id"`
- DONID string `toml:"don_id"`
+ LINKTokenAddr string `toml:"link_token_addr"`
+ Coordinator string `toml:"coordinator_addr"`
+ Router string `toml:"router_addr"`
+ LoadTestClient string `toml:"client_addr"`
+ SubscriptionID uint64 `toml:"subscription_id"`
+ DONID string `toml:"don_id"`
+ GatewayURL string `toml:"gateway_url"`
+ Receiver string `toml:"receiver"`
+ FunctionsCallPayloadHTTP string `toml:"functions_call_payload_http"`
+ FunctionsCallPayloadWithSecrets string `toml:"functions_call_payload_with_secrets"`
+ FunctionsCallPayloadReal string `toml:"functions_call_payload_real"`
+ SecretsSlotID uint8 `toml:"secrets_slot_id"`
+ SecretsVersionID uint64 `toml:"secrets_version_id"`
+ // Secrets these are for CI secrets
+ Secrets string `toml:"secrets"`
}
type Funding struct {
@@ -40,29 +54,49 @@ type Funding struct {
}
type Soak struct {
- RPS int64 `toml:"rps"`
- Duration *models.Duration `toml:"duration"`
+ RPS int64 `toml:"rps"`
+ RequestsPerCall uint32 `toml:"requests_per_call"`
+ Duration *models.Duration `toml:"duration"`
}
-type SoakVolume struct {
- Products int64 `toml:"products"`
- Pace *models.Duration `toml:"pace"`
- Duration *models.Duration `toml:"duration"`
+type SecretsSoak struct {
+ RPS int64 `toml:"rps"`
+ RequestsPerCall uint32 `toml:"requests_per_call"`
+ Duration *models.Duration `toml:"duration"`
+}
+
+type RealSoak struct {
+ RPS int64 `toml:"rps"`
+ RequestsPerCall uint32 `toml:"requests_per_call"`
+ Duration *models.Duration `toml:"duration"`
+}
+
+type Stress struct {
+ RPS int64 `toml:"rps"`
+ RequestsPerCall uint32 `toml:"requests_per_call"`
+ Duration *models.Duration `toml:"duration"`
+}
+
+type SecretsStress struct {
+ RPS int64 `toml:"rps"`
+ RequestsPerCall uint32 `toml:"requests_per_call"`
+ Duration *models.Duration `toml:"duration"`
+}
+
+type RealStress struct {
+ RPS int64 `toml:"rps"`
+ RequestsPerCall uint32 `toml:"requests_per_call"`
+ Duration *models.Duration `toml:"duration"`
}
-type Load struct {
- RPSFrom int64 `toml:"rps_from"`
- RPSIncrease int64 `toml:"rps_increase"`
- RPSSteps int `toml:"rps_steps"`
- Duration *models.Duration `toml:"duration"`
+type GatewayListSoak struct {
+ RPS int64 `toml:"rps"`
+ Duration *models.Duration `toml:"duration"`
}
-type LoadVolume struct {
- ProductsFrom int64 `toml:"products_from"`
- ProductsIncrease int64 `toml:"products_increase"`
- ProductsSteps int `toml:"products_steps"`
- Pace *models.Duration `toml:"pace"`
- Duration *models.Duration `toml:"duration"`
+type GatewaySetSoak struct {
+ RPS int64 `toml:"rps"`
+ Duration *models.Duration `toml:"duration"`
}
func ReadConfig() (*PerformanceConfig, error) {
@@ -76,5 +110,15 @@ func ReadConfig() (*PerformanceConfig, error) {
return nil, errors.Wrap(err, ErrUnmarshalPerfConfig)
}
log.Debug().Interface("PerformanceConfig", cfg).Msg("Parsed performance config")
+ mpk := os.Getenv("MUMBAI_KEYS")
+ murls := os.Getenv("MUMBAI_URLS")
+ snet := os.Getenv("SELECTED_NETWORKS")
+ if mpk == "" || murls == "" || snet == "" {
+ return nil, errors.New(
+ "ensure variables are set:\nMUMBAI_KEYS variable, private keys, comma separated\nSELECTED_NETWORKS=MUMBAI\nMUMBAI_URLS variable, websocket urls, comma separated",
+ )
+ } else {
+ cfg.MumbaiPrivateKey = mpk
+ }
return cfg, nil
}
diff --git a/integration-tests/load/functions/config.toml b/integration-tests/load/functions/config.toml
index 14cedcd9a5d..2de3ba9282c 100644
--- a/integration-tests/load/functions/config.toml
+++ b/integration-tests/load/functions/config.toml
@@ -1,34 +1,73 @@
[Soak]
rps = 1
-duration = "1h"
-
-[Load]
-rps_from = 1
-rps_increase = 1
-rps_steps = 10
-duration = "3m"
-
-[SoakVolume]
-products = 5
-pace = "1s"
-duration = "3m"
-
-[LoadVolume]
-products_from = 1
-products_increase = 1
-products_steps = 10
-pace = "1s"
-duration = "3m"
+requests_per_call = 40
+duration = "10m"
+
+[Stress]
+rps = 1
+requests_per_call = 78
+duration = "10m"
+
+[SecretsSoak]
+rps = 1
+requests_per_call = 20
+duration = "10m"
+
+[SecretsStress]
+rps = 1
+requests_per_call = 40
+duration = "10m"
+
+[RealSoak]
+rps = 1
+requests_per_call = 20
+duration = "10m"
+
+[RealStress]
+rps = 1
+requests_per_call = 40
+duration = "10m"
+
+[GatewayListSoak]
+rps = 95
+duration = "10m"
+
+[GatewaySetSoak]
+rps = 95
+duration = "10m"
[Common]
# Polygon Mumbai only for now
+receiver = "0x3098B6665589959711A48a6bAe5B7F2908f6a3bE"
+don_id = "fun-staging-mumbai-1"
+gateway_url = "https://gateway-stg-one.main.stage.cldev.sh"
link_token_addr = "0x326C977E6efc84E512bB9C30f76E30c160eD06FB"
-coordinator_addr = "0x69b4C680209737B877c93327fC2144ec39eaC423"
-router_addr = "0xa4Ac8b863A6b4fB064B6bdF87aD61d389d97748d"
-client_example_addr = "0x2720cC3a112d33B5C1D40270f7c7BE7CADec1690"
-don_id = "functions_staging_mumbai"
-# comment it to automatically create and fund a new one
-subscription_id = 48
-# not used until we have full DON setup
-# node_funds = 10
-sub_funds = 7
\ No newline at end of file
+coordinator_addr = "0x6D6a83BB356b7242E88C1A2b290102fde26590D0"
+router_addr = "0x2673266D3Cd08b53494B5a92B66DEec7F1408E7A"
+
+# comment "client_addr" and "subscription_id" and test will create a new pair
+# get it from logs and save
+client_addr = "0x89D4b58D859a536D0B888ecD5093eF5FF9e4F977"
+subscription_id = 47
+sub_funds = 10
+
+functions_call_payload_with_secrets = "return Functions.encodeString(JSON.stringify(secrets))"
+functions_call_payload_http = """
+const response = await Functions.makeHttpRequest({ url: 'http://dummyjson.com/products/1' });
+return Functions.encodeUint256(response.data.id);
+"""
+functions_call_payload_real = """
+const arg1 = args[0];
+const arg2 = args[1];
+const arg3 = args[2];
+const arg4 = args[3];
+
+const response = await Functions.makeHttpRequest({ url: 'http://dummyjson.com/products/${arg1}' });
+return Functions.encodeString(JSON.stringify(secrets));
+"""
+secrets_slot_id = 0
+secrets_version = 1693945705
+
+# uncomment to upload new secrets to s4 and use it in your run
+# TODO: not working now
+#secrets = "{\"secrets\": \"secretValue\"}"
\ No newline at end of file
diff --git a/integration-tests/load/functions/functions_test.go b/integration-tests/load/functions/functions_test.go
index 656c3b80ec1..7822035208e 100644
--- a/integration-tests/load/functions/functions_test.go
+++ b/integration-tests/load/functions/functions_test.go
@@ -10,52 +10,193 @@ import (
func TestFunctionsLoad(t *testing.T) {
cfg, err := ReadConfig()
require.NoError(t, err)
- env, functionContracts, err := SetupLocalLoadTestEnv(cfg)
+ ft, err := SetupLocalLoadTestEnv(cfg)
require.NoError(t, err)
- env.ParallelTransactions(true)
+ ft.EVMClient.ParallelTransactions(false)
labels := map[string]string{
"branch": "functions_healthcheck",
"commit": "functions_healthcheck",
}
- singleFeedConfig := &wasp.Config{
- T: t,
- LoadType: wasp.RPS,
- GenName: "gun",
- CallTimeout: 2 * time.Minute,
- Gun: NewSingleFunctionCallGun(
- functionContracts,
- "const response = await Functions.makeHttpRequest({ url: 'http://dummyjson.com/products/1' }); return Functions.encodeUint256(response.data.id)",
- []byte{},
- []string{},
- cfg.Common.SubscriptionID,
- StringToByte32(cfg.Common.DONID),
- ),
- Labels: labels,
- LokiConfig: wasp.NewEnvLokiConfig(),
- }
+ MonitorLoadStats(t, ft, labels)
+
+ t.Run("mumbai functions soak test http", func(t *testing.T) {
+ _, err := wasp.NewProfile().
+ Add(wasp.NewGenerator(&wasp.Config{
+ T: t,
+ LoadType: wasp.RPS,
+ GenName: "functions_soak_gen",
+ RateLimitUnitDuration: 5 * time.Second,
+ CallTimeout: 3 * time.Minute,
+ Schedule: wasp.Plain(
+ cfg.Soak.RPS,
+ cfg.Soak.Duration.Duration(),
+ ),
+ Gun: NewSingleFunctionCallGun(
+ ft,
+ ModeHTTPPayload,
+ cfg.Soak.RequestsPerCall,
+ cfg.Common.FunctionsCallPayloadHTTP,
+ cfg.Common.SecretsSlotID,
+ cfg.Common.SecretsVersionID,
+ []string{},
+ cfg.Common.SubscriptionID,
+ StringToByte32(cfg.Common.DONID),
+ ),
+ Labels: labels,
+ LokiConfig: wasp.NewEnvLokiConfig(),
+ })).
+ Run(true)
+ require.NoError(t, err)
+ })
+
+ t.Run("mumbai functions stress test http", func(t *testing.T) {
+ _, err = wasp.NewProfile().
+ Add(wasp.NewGenerator(&wasp.Config{
+ T: t,
+ LoadType: wasp.RPS,
+ GenName: "functions_stress_gen",
+ RateLimitUnitDuration: 5 * time.Second,
+ CallTimeout: 3 * time.Minute,
+ Schedule: wasp.Plain(
+ cfg.Stress.RPS,
+ cfg.Stress.Duration.Duration(),
+ ),
+ Gun: NewSingleFunctionCallGun(
+ ft,
+ ModeHTTPPayload,
+ cfg.Stress.RequestsPerCall,
+ cfg.Common.FunctionsCallPayloadHTTP,
+ cfg.Common.SecretsSlotID,
+ cfg.Common.SecretsVersionID,
+ []string{},
+ cfg.Common.SubscriptionID,
+ StringToByte32(cfg.Common.DONID),
+ ),
+ Labels: labels,
+ LokiConfig: wasp.NewEnvLokiConfig(),
+ })).
+ Run(true)
+ require.NoError(t, err)
+ })
+
+ t.Run("mumbai functions soak test only secrets", func(t *testing.T) {
+ _, err := wasp.NewProfile().
+ Add(wasp.NewGenerator(&wasp.Config{
+ T: t,
+ LoadType: wasp.RPS,
+ GenName: "functions_soak_gen",
+ RateLimitUnitDuration: 5 * time.Second,
+ CallTimeout: 3 * time.Minute,
+ Schedule: wasp.Plain(
+ cfg.SecretsSoak.RPS,
+ cfg.SecretsSoak.Duration.Duration(),
+ ),
+ Gun: NewSingleFunctionCallGun(
+ ft,
+ ModeSecretsOnlyPayload,
+ cfg.SecretsSoak.RequestsPerCall,
+ cfg.Common.FunctionsCallPayloadWithSecrets,
+ cfg.Common.SecretsSlotID,
+ cfg.Common.SecretsVersionID,
+ []string{},
+ cfg.Common.SubscriptionID,
+ StringToByte32(cfg.Common.DONID),
+ ),
+ Labels: labels,
+ LokiConfig: wasp.NewEnvLokiConfig(),
+ })).
+ Run(true)
+ require.NoError(t, err)
+ })
+
+ t.Run("mumbai functions stress test only secrets", func(t *testing.T) {
+ _, err = wasp.NewProfile().
+ Add(wasp.NewGenerator(&wasp.Config{
+ T: t,
+ LoadType: wasp.RPS,
+ GenName: "functions_stress_gen",
+ RateLimitUnitDuration: 5 * time.Second,
+ CallTimeout: 3 * time.Minute,
+ Schedule: wasp.Plain(
+ cfg.SecretsStress.RPS,
+ cfg.SecretsStress.Duration.Duration(),
+ ),
+ Gun: NewSingleFunctionCallGun(
+ ft,
+ ModeSecretsOnlyPayload,
+ cfg.SecretsStress.RequestsPerCall,
+ cfg.Common.FunctionsCallPayloadWithSecrets,
+ cfg.Common.SecretsSlotID,
+ cfg.Common.SecretsVersionID,
+ []string{},
+ cfg.Common.SubscriptionID,
+ StringToByte32(cfg.Common.DONID),
+ ),
+ Labels: labels,
+ LokiConfig: wasp.NewEnvLokiConfig(),
+ })).
+ Run(true)
+ require.NoError(t, err)
+ })
- t.Run("functions soak test", func(t *testing.T) {
- singleFeedConfig.Schedule = wasp.Plain(
- cfg.Soak.RPS,
- cfg.Soak.Duration.Duration(),
- )
+ t.Run("mumbai functions soak test real", func(t *testing.T) {
_, err := wasp.NewProfile().
- Add(wasp.NewGenerator(singleFeedConfig)).
+ Add(wasp.NewGenerator(&wasp.Config{
+ T: t,
+ LoadType: wasp.RPS,
+ GenName: "functions_soak_gen",
+ RateLimitUnitDuration: 5 * time.Second,
+ CallTimeout: 3 * time.Minute,
+ Schedule: wasp.Plain(
+ cfg.RealSoak.RPS,
+ cfg.RealSoak.Duration.Duration(),
+ ),
+ Gun: NewSingleFunctionCallGun(
+ ft,
+ ModeReal,
+ cfg.RealSoak.RequestsPerCall,
+ cfg.Common.FunctionsCallPayloadReal,
+ cfg.Common.SecretsSlotID,
+ cfg.Common.SecretsVersionID,
+ []string{"1", "2", "3", "4"},
+ cfg.Common.SubscriptionID,
+ StringToByte32(cfg.Common.DONID),
+ ),
+ Labels: labels,
+ LokiConfig: wasp.NewEnvLokiConfig(),
+ })).
Run(true)
require.NoError(t, err)
})
- t.Run("functions load test", func(t *testing.T) {
- singleFeedConfig.Schedule = wasp.Steps(
- cfg.Load.RPSFrom,
- cfg.Load.RPSIncrease,
- cfg.Load.RPSSteps,
- cfg.Load.Duration.Duration(),
- )
+ t.Run("mumbai functions stress test real", func(t *testing.T) {
_, err = wasp.NewProfile().
- Add(wasp.NewGenerator(singleFeedConfig)).
+ Add(wasp.NewGenerator(&wasp.Config{
+ T: t,
+ LoadType: wasp.RPS,
+ GenName: "functions_stress_gen",
+ RateLimitUnitDuration: 5 * time.Second,
+ CallTimeout: 3 * time.Minute,
+ Schedule: wasp.Plain(
+ cfg.RealStress.RPS,
+ cfg.RealStress.Duration.Duration(),
+ ),
+ Gun: NewSingleFunctionCallGun(
+ ft,
+ ModeReal,
+ cfg.RealStress.RequestsPerCall,
+ cfg.Common.FunctionsCallPayloadReal,
+ cfg.Common.SecretsSlotID,
+ cfg.Common.SecretsVersionID,
+ []string{"1", "2", "3", "4"},
+ cfg.Common.SubscriptionID,
+ StringToByte32(cfg.Common.DONID),
+ ),
+ Labels: labels,
+ LokiConfig: wasp.NewEnvLokiConfig(),
+ })).
Run(true)
require.NoError(t, err)
})
diff --git a/integration-tests/load/functions/gateway.go b/integration-tests/load/functions/gateway.go
new file mode 100644
index 00000000000..aefe4fbedc2
--- /dev/null
+++ b/integration-tests/load/functions/gateway.go
@@ -0,0 +1,225 @@
+package loadfunctions
+
+import (
+ "bytes"
+ "crypto/ecdsa"
+ "crypto/rand"
+ "encoding/base64"
+ "encoding/hex"
+ "encoding/json"
+ "fmt"
+ "github.com/ethereum/go-ethereum/crypto"
+ "github.com/ethereum/go-ethereum/crypto/ecies"
+ "github.com/go-resty/resty/v2"
+ "github.com/pkg/errors"
+ "github.com/rs/zerolog/log"
+ "github.com/smartcontractkit/chainlink/v2/core/services/gateway/api"
+ "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/functions"
+ "github.com/smartcontractkit/chainlink/v2/core/services/s4"
+ "github.com/smartcontractkit/tdh2/go/tdh2/tdh2easy"
+ "time"
+)
+
+type RPCResponse struct {
+ ID string `json:"id"`
+ Jsonrpc string `json:"jsonrpc"`
+ Result struct {
+ Body struct {
+ DonID string `json:"don_id"`
+ MessageID string `json:"message_id"`
+ Method string `json:"method"`
+ Payload struct {
+ NodeResponses []struct {
+ Body struct {
+ DonID string `json:"don_id"`
+ MessageID string `json:"message_id"`
+ Method string `json:"method"`
+ Payload struct {
+ Success bool `json:"success"`
+ } `json:"payload"`
+ Receiver string `json:"receiver"`
+ } `json:"body"`
+ Signature string `json:"signature"`
+ } `json:"node_responses"`
+ Success bool `json:"success"`
+ } `json:"payload"`
+ Receiver string `json:"receiver"`
+ } `json:"body"`
+ Signature string `json:"signature"`
+ } `json:"result"`
+}
+
+func UploadS4Secrets(rc *resty.Client, s4Cfg *S4SecretsCfg) (uint8, uint64, error) {
+ key, err := crypto.HexToECDSA(s4Cfg.PrivateKey)
+ if err != nil {
+ return 0, 0, err
+ }
+ address := crypto.PubkeyToAddress(key.PublicKey)
+ var payloadJSON []byte
+ envelope := s4.Envelope{
+ Address: address.Bytes(),
+ SlotID: s4Cfg.S4SetSlotID,
+ Version: s4Cfg.S4SetVersion,
+ Payload: []byte(s4Cfg.S4SetPayload),
+ Expiration: time.Now().UnixMilli() + s4Cfg.S4SetExpirationPeriod,
+ }
+ signature, err := envelope.Sign(key)
+ if err != nil {
+ return 0, 0, err
+ }
+
+ s4SetPayload := functions.SecretsSetRequest{
+ SlotID: envelope.SlotID,
+ Version: envelope.Version,
+ Expiration: envelope.Expiration,
+ Payload: []byte(s4Cfg.S4SetPayload),
+ Signature: signature,
+ }
+
+ payloadJSON, err = json.Marshal(s4SetPayload)
+ if err != nil {
+ return 0, 0, err
+ }
+
+ msg := &api.Message{
+ Body: api.MessageBody{
+ MessageId: s4Cfg.MessageID,
+ Method: s4Cfg.Method,
+ DonId: s4Cfg.DonID,
+ Payload: json.RawMessage(payloadJSON),
+ },
+ }
+
+ err = msg.Sign(key)
+ if err != nil {
+ return 0, 0, err
+ }
+ codec := api.JsonRPCCodec{}
+ rawMsg, err := codec.EncodeRequest(msg)
+ if err != nil {
+ return 0, 0, err
+ }
+ var result *RPCResponse
+ resp, err := rc.R().
+ SetBody(rawMsg).
+ Post(s4Cfg.GatewayURL)
+ if err != nil {
+ return 0, 0, err
+ }
+ if resp.StatusCode() != 200 {
+ return 0, 0, fmt.Errorf("status code was %d, expected 200", resp.StatusCode())
+ }
+ if err := json.Unmarshal(resp.Body(), &result); err != nil {
+ return 0, 0, err
+ }
+ log.Debug().Interface("Result", result).Msg("S4 secrets_set response result")
+ for _, nodeResponse := range result.Result.Body.Payload.NodeResponses {
+ if !nodeResponse.Body.Payload.Success {
+ return 0, 0, fmt.Errorf("node response was not succesful")
+ }
+ }
+ return uint8(envelope.SlotID), envelope.Version, nil
+}
+
+func ListS4Secrets(rc *resty.Client, s4Cfg *S4SecretsCfg) error {
+ key, err := crypto.HexToECDSA(s4Cfg.PrivateKey)
+ if err != nil {
+ return err
+ }
+
+ msg := &api.Message{
+ Body: api.MessageBody{
+ MessageId: s4Cfg.MessageID,
+ Method: s4Cfg.Method,
+ DonId: s4Cfg.DonID,
+ Receiver: s4Cfg.RecieverAddr,
+ },
+ }
+
+ err = msg.Sign(key)
+ if err != nil {
+ return err
+ }
+ codec := api.JsonRPCCodec{}
+ rawMsg, err := codec.EncodeRequest(msg)
+ if err != nil {
+ return err
+ }
+ msgdec, err := codec.DecodeRequest(rawMsg)
+ if err != nil {
+ return err
+ }
+ log.Debug().Interface("Request", msgdec).Msg("Sending RPC request")
+ var result map[string]interface{}
+ resp, err := rc.R().
+ SetBody(rawMsg).
+ Post(s4Cfg.GatewayURL)
+ if err != nil {
+ return err
+ }
+ if err := json.Unmarshal(resp.Body(), &result); err != nil {
+ return err
+ }
+ log.Debug().Interface("Result", result).Msg("S4 secrets_list response result")
+ if resp.StatusCode() != 200 {
+ return fmt.Errorf("status code was %d, expected 200", resp.StatusCode())
+ }
+ return nil
+}
+
+func ParseTDH2Key(data []byte) (*tdh2easy.PublicKey, error) {
+ pk := &tdh2easy.PublicKey{}
+ if err := pk.Unmarshal(data); err != nil {
+ return nil, err
+ }
+ return pk, nil
+}
+
+func EncryptS4Secrets(deployerPk *ecdsa.PrivateKey, tdh2Pk *tdh2easy.PublicKey, donKey []byte, msgJSON string) (string, error) {
+ // 65 bytes PublicKey format, should start with 0x04 to be processed by crypto.UnmarshalPubkey()
+ b := make([]byte, 1)
+ b[0] = 0x04
+ donKey = bytes.Join([][]byte{b, donKey}, nil)
+ donPubKey, err := crypto.UnmarshalPubkey(donKey)
+ if err != nil {
+ return "", errors.Wrap(err, "failed to unmarshal DON key")
+ }
+ eciesDONPubKey := ecies.ImportECDSAPublic(donPubKey)
+ signature, err := deployerPk.Sign(rand.Reader, []byte(msgJSON), nil)
+ if err != nil {
+ return "", errors.Wrap(err, "failed to sign the msg with Ethereum key")
+ }
+ signedSecrets, err := json.Marshal(struct {
+ Signature []byte `json:"signature"`
+ Message string `json:"message"`
+ }{
+ Signature: signature,
+ Message: msgJSON,
+ })
+ if err != nil {
+ return "", errors.Wrap(err, "failed to marshal signed secrets")
+ }
+ ct, err := ecies.Encrypt(rand.Reader, eciesDONPubKey, signedSecrets, nil, nil)
+ if err != nil {
+ return "", errors.Wrap(err, "failed to encrypt with DON key")
+ }
+ ct0xFormat, err := json.Marshal(map[string]interface{}{"0x0": base64.StdEncoding.EncodeToString(ct)})
+ if err != nil {
+ return "", errors.Wrap(err, "failed to marshal DON key encrypted format")
+ }
+ ctTDH2Format, err := tdh2easy.Encrypt(tdh2Pk, ct0xFormat)
+ if err != nil {
+ return "", errors.Wrap(err, "failed to encrypt with TDH2 public key")
+ }
+ tdh2Message, err := ctTDH2Format.Marshal()
+ if err != nil {
+ return "", errors.Wrap(err, "failed to marshal TDH2 encrypted msg")
+ }
+ finalMsg, err := json.Marshal(map[string]interface{}{
+ "encryptedSecrets": "0x" + hex.EncodeToString(tdh2Message),
+ })
+ if err != nil {
+ return "", errors.Wrap(err, "failed to marshal secrets msg")
+ }
+ return string(finalMsg), nil
+}
diff --git a/integration-tests/load/functions/gateway_gun.go b/integration-tests/load/functions/gateway_gun.go
new file mode 100644
index 00000000000..fd13922d0a7
--- /dev/null
+++ b/integration-tests/load/functions/gateway_gun.go
@@ -0,0 +1,111 @@
+package loadfunctions
+
+import (
+ "crypto/ecdsa"
+ "fmt"
+ "github.com/go-resty/resty/v2"
+ "github.com/rs/zerolog/log"
+ "github.com/smartcontractkit/tdh2/go/tdh2/tdh2easy"
+ "github.com/smartcontractkit/wasp"
+ "math/rand"
+ "os"
+ "strconv"
+ "time"
+)
+
+/* SingleFunctionCallGun is a gun that constantly requests randomness for one feed */
+
+type GatewaySecretsSetGun struct {
+ Cfg *PerformanceConfig
+ Resty *resty.Client
+ SlotID uint
+ Method string
+ EthereumPrivateKey *ecdsa.PrivateKey
+ ThresholdPublicKey *tdh2easy.PublicKey
+ DONPublicKey []byte
+}
+
+func NewGatewaySecretsSetGun(cfg *PerformanceConfig, method string, pKey *ecdsa.PrivateKey, tdh2PubKey *tdh2easy.PublicKey, donPubKey []byte) *GatewaySecretsSetGun {
+ return &GatewaySecretsSetGun{
+ Cfg: cfg,
+ Resty: resty.New(),
+ Method: method,
+ EthereumPrivateKey: pKey,
+ ThresholdPublicKey: tdh2PubKey,
+ DONPublicKey: donPubKey,
+ }
+}
+
+func callSecretsSet(m *GatewaySecretsSetGun) *wasp.CallResult {
+ randNum := strconv.Itoa(rand.Intn(100000))
+ randSlot := uint(rand.Intn(5))
+ version := uint64(time.Now().UnixNano())
+ expiration := int64(60 * 60 * 1000)
+ secret := fmt.Sprintf("{\"ltsecret\": \"%s\"}", randNum)
+ log.Debug().
+ Uint("SlotID", randSlot).
+ Str("MessageID", randNum).
+ Uint64("Version", version).
+ Int64("Expiration", expiration).
+ Str("Secret", secret).
+ Msg("Sending S4 envelope")
+ secrets, err := EncryptS4Secrets(
+ m.EthereumPrivateKey,
+ m.ThresholdPublicKey,
+ m.DONPublicKey,
+ secret,
+ )
+ if err != nil {
+ return &wasp.CallResult{Error: err.Error(), Failed: true}
+ }
+ _, _, err = UploadS4Secrets(m.Resty, &S4SecretsCfg{
+ GatewayURL: m.Cfg.Common.GatewayURL,
+ PrivateKey: os.Getenv("MUMBAI_KEYS"),
+ MessageID: randNum,
+ Method: "secrets_set",
+ DonID: m.Cfg.Common.DONID,
+ S4SetSlotID: randSlot,
+ S4SetVersion: version,
+ S4SetExpirationPeriod: expiration,
+ S4SetPayload: secrets,
+ })
+ if err != nil {
+ return &wasp.CallResult{Error: err.Error(), Failed: true}
+ }
+ return &wasp.CallResult{}
+}
+
+func callSecretsList(m *GatewaySecretsSetGun) *wasp.CallResult {
+ randNum := strconv.Itoa(rand.Intn(100000))
+ randSlot := uint(rand.Intn(5))
+ version := uint64(time.Now().UnixNano())
+ expiration := int64(60 * 60 * 1000)
+ if err := ListS4Secrets(m.Resty, &S4SecretsCfg{
+ GatewayURL: fmt.Sprintf(m.Cfg.Common.GatewayURL),
+ RecieverAddr: m.Cfg.Common.Receiver,
+ PrivateKey: os.Getenv("MUMBAI_KEYS"),
+ MessageID: randNum,
+ Method: m.Method,
+ DonID: m.Cfg.Common.DONID,
+ S4SetSlotID: randSlot,
+ S4SetVersion: version,
+ S4SetExpirationPeriod: expiration,
+ }); err != nil {
+ return &wasp.CallResult{Error: err.Error(), Failed: true}
+ }
+ return &wasp.CallResult{}
+}
+
+// Call implements example gun call, assertions on response bodies should be done here
+func (m *GatewaySecretsSetGun) Call(_ *wasp.Generator) *wasp.CallResult {
+ var res *wasp.CallResult
+ switch m.Method {
+ case "secrets_set":
+ res = callSecretsSet(m)
+ case "secrets_list":
+ res = callSecretsList(m)
+ default:
+ panic("gateway gun must use either 'secrets_set' or 'list' methods")
+ }
+ return res
+}
diff --git a/integration-tests/load/functions/gateway_test.go b/integration-tests/load/functions/gateway_test.go
new file mode 100644
index 00000000000..c8e63f92f2b
--- /dev/null
+++ b/integration-tests/load/functions/gateway_test.go
@@ -0,0 +1,75 @@
+package loadfunctions
+
+import (
+ "testing"
+
+ "github.com/smartcontractkit/wasp"
+ "github.com/stretchr/testify/require"
+
+ "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/functions"
+)
+
+func TestGatewayLoad(t *testing.T) {
+ cfg, err := ReadConfig()
+ require.NoError(t, err)
+ ft, err := SetupLocalLoadTestEnv(cfg)
+ require.NoError(t, err)
+ ft.EVMClient.ParallelTransactions(false)
+
+ labels := map[string]string{
+ "branch": "gateway_healthcheck",
+ "commit": "gateway_healthcheck",
+ }
+
+ secretsListCfg := &wasp.Config{
+ LoadType: wasp.RPS,
+ GenName: functions.MethodSecretsList,
+ Schedule: wasp.Plain(
+ cfg.GatewayListSoak.RPS,
+ cfg.GatewayListSoak.Duration.Duration(),
+ ),
+ Gun: NewGatewaySecretsSetGun(
+ cfg,
+ functions.MethodSecretsList,
+ ft.EthereumPrivateKey,
+ ft.ThresholdPublicKey,
+ ft.DONPublicKey,
+ ),
+ Labels: labels,
+ LokiConfig: wasp.NewEnvLokiConfig(),
+ }
+
+ secretsSetCfg := &wasp.Config{
+ LoadType: wasp.RPS,
+ GenName: functions.MethodSecretsSet,
+ Schedule: wasp.Plain(
+ cfg.GatewaySetSoak.RPS,
+ cfg.GatewaySetSoak.Duration.Duration(),
+ ),
+ Gun: NewGatewaySecretsSetGun(
+ cfg,
+ functions.MethodSecretsSet,
+ ft.EthereumPrivateKey,
+ ft.ThresholdPublicKey,
+ ft.DONPublicKey,
+ ),
+ Labels: labels,
+ LokiConfig: wasp.NewEnvLokiConfig(),
+ }
+
+ t.Run("gateway secrets list soak test", func(t *testing.T) {
+ secretsListCfg.T = t
+ _, err := wasp.NewProfile().
+ Add(wasp.NewGenerator(secretsListCfg)).
+ Run(true)
+ require.NoError(t, err)
+ })
+
+ t.Run("gateway secrets set soak test", func(t *testing.T) {
+ secretsListCfg.T = t
+ _, err := wasp.NewProfile().
+ Add(wasp.NewGenerator(secretsSetCfg)).
+ Run(true)
+ require.NoError(t, err)
+ })
+}
diff --git a/integration-tests/load/functions/gun.go b/integration-tests/load/functions/gun.go
deleted file mode 100644
index 358e0acb986..00000000000
--- a/integration-tests/load/functions/gun.go
+++ /dev/null
@@ -1,36 +0,0 @@
-package loadfunctions
-
-import (
- "github.com/smartcontractkit/wasp"
-)
-
-/* SingleFunctionCallGun is a gun that constantly requests randomness for one feed */
-
-type SingleFunctionCallGun struct {
- contracts *Contracts
- source string
- encryptedSecretsReferences []byte
- args []string
- subscriptionId uint64
- jobId [32]byte
-}
-
-func NewSingleFunctionCallGun(contracts *Contracts, source string, encryptedSecretsReferences []byte, args []string, subscriptionId uint64, jobId [32]byte) *SingleFunctionCallGun {
- return &SingleFunctionCallGun{
- contracts: contracts,
- source: source,
- encryptedSecretsReferences: encryptedSecretsReferences,
- args: args,
- subscriptionId: subscriptionId,
- jobId: jobId,
- }
-}
-
-// Call implements example gun call, assertions on response bodies should be done here
-func (m *SingleFunctionCallGun) Call(l *wasp.Generator) *wasp.CallResult {
- err := m.contracts.LoadTestClient.SendRequest(m.source, m.encryptedSecretsReferences, m.args, m.subscriptionId, m.jobId)
- if err != nil {
- return &wasp.CallResult{Error: err.Error(), Failed: true}
- }
- return &wasp.CallResult{}
-}
diff --git a/integration-tests/load/functions/onchain_monitoring.go b/integration-tests/load/functions/onchain_monitoring.go
new file mode 100644
index 00000000000..0a8b4cef46a
--- /dev/null
+++ b/integration-tests/load/functions/onchain_monitoring.go
@@ -0,0 +1,61 @@
+package loadfunctions
+
+import (
+ "github.com/rs/zerolog/log"
+ "github.com/smartcontractkit/wasp"
+ "testing"
+ "time"
+)
+
+/* Monitors on-chain stats of LoadConsumer and pushes them to Loki every second */
+
+const (
+ LokiTypeLabel = "functions_contracts_load_summary"
+ ErrMetrics = "failed to get Functions load test metrics"
+ ErrLokiClient = "failed to create Loki client for monitoring"
+ ErrLokiPush = "failed to push monitoring metrics to Loki"
+)
+
+type LoadStats struct {
+ Succeeded uint32
+ Errored uint32
+ Empty uint32
+}
+
+func MonitorLoadStats(t *testing.T, ft *FunctionsTest, labels map[string]string) {
+ go func() {
+ updatedLabels := make(map[string]string)
+ for k, v := range labels {
+ updatedLabels[k] = v
+ }
+ updatedLabels["type"] = LokiTypeLabel
+ updatedLabels["go_test_name"] = t.Name()
+ updatedLabels["gen_name"] = "performance"
+ lc, err := wasp.NewLokiClient(wasp.NewEnvLokiConfig())
+ if err != nil {
+ log.Error().Err(err).Msg(ErrLokiClient)
+ return
+ }
+ if err := ft.LoadTestClient.ResetStats(); err != nil {
+ log.Error().Err(err).Msg("failed to reset load test client stats")
+ }
+ for {
+ time.Sleep(5 * time.Second)
+ stats, err := ft.LoadTestClient.GetStats()
+ if err != nil {
+ log.Error().Err(err).Msg(ErrMetrics)
+ }
+ log.Info().
+ Hex("LastReqID", []byte(stats.LastRequestID)).
+ Str("LastResponse", stats.LastResponse).
+ Str("LastError", stats.LastError).
+ Uint32("Total", stats.Total).
+ Uint32("Succeeded", stats.Succeeded).
+ Uint32("Errored", stats.Errored).
+ Uint32("Empty", stats.Empty).Msg("On-chain stats for load test client")
+ if err := lc.HandleStruct(wasp.LabelsMapToModel(updatedLabels), time.Now(), stats); err != nil {
+ log.Error().Err(err).Msg(ErrLokiPush)
+ }
+ }
+ }()
+}
diff --git a/integration-tests/load/functions/request_gun.go b/integration-tests/load/functions/request_gun.go
new file mode 100644
index 00000000000..d9987eaa756
--- /dev/null
+++ b/integration-tests/load/functions/request_gun.go
@@ -0,0 +1,111 @@
+package loadfunctions
+
+import (
+ "github.com/smartcontractkit/wasp"
+)
+
+type TestMode int
+
+const (
+ ModeHTTPPayload TestMode = iota
+ ModeSecretsOnlyPayload
+ ModeReal
+)
+
+type SingleFunctionCallGun struct {
+ ft *FunctionsTest
+ mode TestMode
+ times uint32
+ source string
+ slotID uint8
+ slotVersion uint64
+ encryptedSecrets []byte
+ args []string
+ subscriptionId uint64
+ jobId [32]byte
+}
+
+func NewSingleFunctionCallGun(
+ ft *FunctionsTest,
+ mode TestMode,
+ times uint32,
+ source string,
+ slotID uint8,
+ slotVersion uint64,
+ args []string,
+ subscriptionId uint64,
+ jobId [32]byte,
+) *SingleFunctionCallGun {
+ return &SingleFunctionCallGun{
+ ft: ft,
+ mode: mode,
+ times: times,
+ source: source,
+ slotID: slotID,
+ slotVersion: slotVersion,
+ args: args,
+ subscriptionId: subscriptionId,
+ jobId: jobId,
+ }
+}
+
+func (m *SingleFunctionCallGun) callReal() *wasp.CallResult {
+ err := m.ft.LoadTestClient.SendRequestWithDONHostedSecrets(
+ m.times,
+ m.source,
+ m.slotID,
+ m.slotVersion,
+ m.args,
+ m.subscriptionId,
+ m.jobId,
+ )
+ if err != nil {
+ return &wasp.CallResult{Error: err.Error(), Failed: true}
+ }
+ return &wasp.CallResult{}
+}
+
+func (m *SingleFunctionCallGun) callWithSecrets() *wasp.CallResult {
+ err := m.ft.LoadTestClient.SendRequestWithDONHostedSecrets(
+ m.times,
+ m.source,
+ m.slotID,
+ m.slotVersion,
+ m.args,
+ m.subscriptionId,
+ m.jobId,
+ )
+ if err != nil {
+ return &wasp.CallResult{Error: err.Error(), Failed: true}
+ }
+ return &wasp.CallResult{}
+}
+
+func (m *SingleFunctionCallGun) callWithHttp() *wasp.CallResult {
+ err := m.ft.LoadTestClient.SendRequest(
+ m.times,
+ m.source,
+ []byte{},
+ m.args,
+ m.subscriptionId,
+ m.jobId,
+ )
+ if err != nil {
+ return &wasp.CallResult{Error: err.Error(), Failed: true}
+ }
+ return &wasp.CallResult{}
+}
+
+// Call implements example gun call, assertions on response bodies should be done here
+func (m *SingleFunctionCallGun) Call(_ *wasp.Generator) *wasp.CallResult {
+ switch m.mode {
+ case ModeSecretsOnlyPayload:
+ return m.callWithSecrets()
+ case ModeHTTPPayload:
+ return m.callWithHttp()
+ case ModeReal:
+ return m.callReal()
+ default:
+ panic("test mode must be ModeSecretsOnlyPayload, ModeHTTPPayload or ModeReal")
+ }
+}
diff --git a/integration-tests/load/functions/setup.go b/integration-tests/load/functions/setup.go
index cd8038c41ba..5d44cbc698e 100644
--- a/integration-tests/load/functions/setup.go
+++ b/integration-tests/load/functions/setup.go
@@ -1,64 +1,181 @@
package loadfunctions
import (
+ "crypto/ecdsa"
+ "math/big"
+ mrand "math/rand"
+ "os"
+ "strconv"
+ "time"
+
+ "github.com/ethereum/go-ethereum/crypto"
+ "github.com/go-resty/resty/v2"
"github.com/pkg/errors"
"github.com/rs/zerolog/log"
+ "github.com/smartcontractkit/chainlink-testing-framework/blockchain"
+ "github.com/smartcontractkit/chainlink-testing-framework/networks"
+ "github.com/smartcontractkit/tdh2/go/tdh2/tdh2easy"
+
"github.com/smartcontractkit/chainlink/integration-tests/contracts"
- "github.com/smartcontractkit/chainlink/integration-tests/docker/test_env"
chainlinkutils "github.com/smartcontractkit/chainlink/v2/core/utils"
- "math/big"
)
-type Contracts struct {
- LinkToken contracts.LinkToken
- Coordinator contracts.FunctionsCoordinator
- Router contracts.FunctionsRouter
- LoadTestClient contracts.FunctionsLoadTestClient
+type FunctionsTest struct {
+ EVMClient blockchain.EVMClient
+ ContractDeployer contracts.ContractDeployer
+ ContractLoader contracts.ContractLoader
+ LinkToken contracts.LinkToken
+ Coordinator contracts.FunctionsCoordinator
+ Router contracts.FunctionsRouter
+ LoadTestClient contracts.FunctionsLoadTestClient
+ EthereumPrivateKey *ecdsa.PrivateKey
+ EthereumPublicKey *ecdsa.PublicKey
+ ThresholdPublicKey *tdh2easy.PublicKey
+ DONPublicKey []byte
+ ThresholdPublicKeyBytes []byte
+ ThresholdEncryptedSecrets string
}
-func SetupLocalLoadTestEnv(cfg *PerformanceConfig) (*test_env.CLClusterTestEnv, *Contracts, error) {
- env, err := test_env.NewCLTestEnvBuilder().
- Build()
+type S4SecretsCfg struct {
+ GatewayURL string
+ PrivateKey string
+ RecieverAddr string
+ MessageID string
+ Method string
+ DonID string
+ S4SetSlotID uint
+ S4SetVersion uint64
+ S4SetExpirationPeriod int64
+ S4SetPayload string
+}
+
+func SetupLocalLoadTestEnv(cfg *PerformanceConfig) (*FunctionsTest, error) {
+ bc, err := blockchain.NewEVMClientFromNetwork(networks.SelectedNetwork, log.Logger)
+ if err != nil {
+ return nil, err
+ }
+ cd, err := contracts.NewContractDeployer(bc, log.Logger)
if err != nil {
- return env, nil, err
+ return nil, err
}
- env.EVMClient.GetNonceSetting()
- lt, err := env.ContractLoader.LoadLINKToken(cfg.Common.LINKTokenAddr)
+
+ cl, err := contracts.NewContractLoader(bc, log.Logger)
if err != nil {
- return env, nil, err
+ return nil, err
}
- coord, err := env.ContractLoader.LoadFunctionsCoordinator(cfg.Common.Coordinator)
if err != nil {
- return env, nil, err
+ return nil, err
}
- router, err := env.ContractLoader.LoadFunctionsRouter(cfg.Common.Router)
+ lt, err := cl.LoadLINKToken(cfg.Common.LINKTokenAddr)
if err != nil {
- return env, nil, err
+ return nil, err
}
- loadTestClient, err := env.ContractLoader.LoadFunctionsLoadTestClient(cfg.Common.LoadTestClient)
+ coord, err := cl.LoadFunctionsCoordinator(cfg.Common.Coordinator)
if err != nil {
- return env, nil, err
+ return nil, err
+ }
+ router, err := cl.LoadFunctionsRouter(cfg.Common.Router)
+ if err != nil {
+ return nil, err
+ }
+ var loadTestClient contracts.FunctionsLoadTestClient
+ if cfg.Common.LoadTestClient != "" {
+ loadTestClient, err = cl.LoadFunctionsLoadTestClient(cfg.Common.LoadTestClient)
+ } else {
+ loadTestClient, err = cd.DeployFunctionsLoadTestClient(cfg.Common.Router)
+ }
+ if err != nil {
+ return nil, err
}
if cfg.Common.SubscriptionID == 0 {
log.Info().Msg("Creating new subscription")
subID, err := router.CreateSubscriptionWithConsumer(loadTestClient.Address())
if err != nil {
- return env, nil, errors.Wrap(err, "failed to create a new subscription")
+ return nil, errors.Wrap(err, "failed to create a new subscription")
}
encodedSubId, err := chainlinkutils.ABIEncode(`[{"type":"uint64"}]`, subID)
if err != nil {
- return env, nil, errors.Wrap(err, "failed to encode subscription ID for funding")
+ return nil, errors.Wrap(err, "failed to encode subscription ID for funding")
}
_, err = lt.TransferAndCall(router.Address(), big.NewInt(0).Mul(cfg.Common.Funding.SubFunds, big.NewInt(1e18)), encodedSubId)
if err != nil {
- return env, nil, errors.Wrap(err, "failed to transferAndCall router, LINK funding")
+ return nil, errors.Wrap(err, "failed to transferAndCall router, LINK funding")
}
cfg.Common.SubscriptionID = subID
}
- return env, &Contracts{
- LinkToken: lt,
- Coordinator: coord,
- Router: router,
- LoadTestClient: loadTestClient,
+ pKey, pubKey, err := parseEthereumPrivateKey(os.Getenv("MUMBAI_KEYS"))
+ if err != nil {
+ return nil, errors.Wrap(err, "failed to load Ethereum private key")
+ }
+ tpk, err := coord.GetThresholdPublicKey()
+ if err != nil {
+ return nil, errors.Wrap(err, "failed to get Threshold public key")
+ }
+ log.Info().Hex("ThresholdPublicKeyBytesHex", tpk).Msg("Loaded coordinator keys")
+ donPubKey, err := coord.GetDONPublicKey()
+ if err != nil {
+ return nil, errors.Wrap(err, "failed to get DON public key")
+ }
+ log.Info().Hex("DONPublicKeyHex", donPubKey).Msg("Loaded DON key")
+ tdh2pk, err := ParseTDH2Key(tpk)
+ if err != nil {
+ return nil, errors.Wrap(err, "failed to unmarshal tdh2 public key")
+ }
+ var encryptedSecrets string
+ if cfg.Common.Secrets != "" {
+ encryptedSecrets, err = EncryptS4Secrets(pKey, tdh2pk, donPubKey, cfg.Common.Secrets)
+ if err != nil {
+ return nil, errors.Wrap(err, "failed to generate tdh2 secrets")
+ }
+ slotID, slotVersion, err := UploadS4Secrets(resty.New(), &S4SecretsCfg{
+ GatewayURL: cfg.Common.GatewayURL,
+ PrivateKey: cfg.MumbaiPrivateKey,
+ MessageID: strconv.Itoa(mrand.Intn(100000-1) + 1),
+ Method: "secrets_set",
+ DonID: cfg.Common.DONID,
+ S4SetSlotID: uint(mrand.Intn(5)),
+ S4SetVersion: uint64(time.Now().UnixNano()),
+ S4SetExpirationPeriod: 60 * 60 * 1000,
+ S4SetPayload: encryptedSecrets,
+ })
+ if err != nil {
+ return nil, errors.Wrap(err, "failed to upload secrets to S4")
+ }
+ cfg.Common.SecretsSlotID = slotID
+ cfg.Common.SecretsVersionID = slotVersion
+ log.Info().
+ Uint8("SlotID", slotID).
+ Uint64("SlotVersion", slotVersion).
+ Msg("Set new secret")
+ }
+ return &FunctionsTest{
+ EVMClient: bc,
+ ContractDeployer: cd,
+ ContractLoader: cl,
+ LinkToken: lt,
+ Coordinator: coord,
+ Router: router,
+ LoadTestClient: loadTestClient,
+ EthereumPrivateKey: pKey,
+ EthereumPublicKey: pubKey,
+ ThresholdPublicKey: tdh2pk,
+ ThresholdPublicKeyBytes: tpk,
+ ThresholdEncryptedSecrets: encryptedSecrets,
+ DONPublicKey: donPubKey,
}, nil
}
+
+func parseEthereumPrivateKey(pk string) (*ecdsa.PrivateKey, *ecdsa.PublicKey, error) {
+ pKey, err := crypto.HexToECDSA(pk)
+ if err != nil {
+ return nil, nil, errors.Wrap(err, "failed to convert Ethereum key from hex")
+ }
+
+ publicKey := pKey.Public()
+ pubKey, ok := publicKey.(*ecdsa.PublicKey)
+ if !ok {
+ return nil, nil, errors.Wrap(err, "failed to get public key from Ethereum private key")
+ }
+ log.Info().Str("Address", crypto.PubkeyToAddress(*pubKey).Hex()).Msg("Parsed private key for address")
+ return pKey, pubKey, nil
+}
diff --git a/integration-tests/migration/upgrade_version_test.go b/integration-tests/migration/upgrade_version_test.go
index 1f90bd123eb..d1d79de5eed 100644
--- a/integration-tests/migration/upgrade_version_test.go
+++ b/integration-tests/migration/upgrade_version_test.go
@@ -6,13 +6,15 @@ import (
"github.com/smartcontractkit/chainlink-testing-framework/utils"
"github.com/stretchr/testify/require"
- "github.com/smartcontractkit/chainlink/integration-tests/docker/test_env"
"os"
+
+ "github.com/smartcontractkit/chainlink/integration-tests/docker/test_env"
)
func TestVersionUpgrade(t *testing.T) {
t.Parallel()
env, err := test_env.NewCLTestEnvBuilder().
+ WithTestLogger(t).
WithGeth().
WithCLNodes(1).
Build()
diff --git a/integration-tests/networks/known_networks.go b/integration-tests/networks/known_networks.go
deleted file mode 100644
index 2886f6c359d..00000000000
--- a/integration-tests/networks/known_networks.go
+++ /dev/null
@@ -1,577 +0,0 @@
-// Package networks holds all known network information for the tests
-package networks
-
-import (
- "fmt"
- "os"
- "strings"
- "time"
-
- "github.com/rs/zerolog/log"
-
- "github.com/smartcontractkit/chainlink-testing-framework/utils"
-
- "github.com/smartcontractkit/chainlink-testing-framework/blockchain"
- "github.com/smartcontractkit/chainlink-testing-framework/logging"
-)
-
-// Pre-configured test networks and their connections
-// Some networks with public RPC endpoints are already filled out, but make use of environment variables to use info like
-// private RPC endpoints and private keys.
-var (
- // To create replica of simulated EVM network, with different chain ids
- AdditionalSimulatedChainIds = []int64{3337, 4337, 5337, 6337, 7337, 8337, 9337, 9338}
- AdditionalSimulatedPvtKeys = []string{
- "5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a",
- "7c852118294e51e653712a81e05800f419141751be58f605c371e15141b007a6",
- "47e179ec197488593b187f80a00eb0da91f1b9d0b13f8733639f19c30a34926a",
- "8b3a350cf5c34c9194ca85829a2df0ec3153be0318b5e2d3348e872092edffba",
- "92db14e403b83dfe3df233f83dfa3a0d7096f21ca9b0d6d6b8d88b2b4ec1564e",
- "4bbbf85ce3377467afe5d46f804f221813b2bb87f24d81f60f1fcdbf7cbf4356",
- "dbda1821b80551c9d65939329250298aa3472ba22feea921c0cf5d620ea67b97",
- "2a871d0798f97d79848a013d4936a73bf4cc922c825d33c1cf7073dff6d409c6",
- }
- // SelectedNetworks uses the SELECTED_NETWORKS env var to determine which network to run the test on.
- // For use in tests that utilize multiple chains. For tests on one chain, see SelectedNetwork
- // For CCIP use index 1 and 2 of SELECTED_NETWORKS to denote source and destination network respectively
- SelectedNetworks []blockchain.EVMNetwork = determineSelectedNetworks()
- // SelectedNetwork uses the first listed network in SELECTED_NETWORKS, for use in tests on only one chain
- SelectedNetwork blockchain.EVMNetwork = SelectedNetworks[0]
-
- // SimulatedEVM represents a simulated network
- SimulatedEVM blockchain.EVMNetwork = blockchain.SimulatedEVMNetwork
- // generalEVM is a customizable network through environment variables
- // This is getting little use, and causes some confusion. Can re-enable if people want it.
- // generalEVM blockchain.EVMNetwork = blockchain.LoadNetworkFromEnvironment()
-
- // SimulatedevmNonDev1 represents a simulated network which can be used to deploy a non-dev geth node
- SimulatedEVMNonDev1 = blockchain.EVMNetwork{
- Name: "source-chain",
- Simulated: true,
- ClientImplementation: blockchain.EthereumClientImplementation,
- SupportsEIP1559: true,
- ChainID: 1337,
- PrivateKeys: []string{
- "ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80",
- },
- URLs: []string{"ws://source-chain-ethereum-geth:8546"},
- HTTPURLs: []string{"http://source-chain-ethereum-geth:8544"},
- ChainlinkTransactionLimit: 500000,
- Timeout: blockchain.JSONStrDuration{Duration: 2 * time.Minute},
- MinimumConfirmations: 1,
- GasEstimationBuffer: 10000,
- DefaultGasLimit: 6000000,
- }
-
- // SimulatedEVM_NON_DEV_2 represents a simulated network with chain id 2337 which can be used to deploy a non-dev geth node
- SimulatedEVMNonDev2 = blockchain.EVMNetwork{
- Name: "dest-chain",
- Simulated: true,
- SupportsEIP1559: true,
- ClientImplementation: blockchain.EthereumClientImplementation,
- ChainID: 2337,
- PrivateKeys: []string{
- "59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d",
- },
- URLs: []string{"ws://dest-chain-ethereum-geth:8546"},
- HTTPURLs: []string{"http://dest-chain-ethereum-geth:8544"},
- ChainlinkTransactionLimit: 500000,
- Timeout: blockchain.JSONStrDuration{Duration: 2 * time.Minute},
- MinimumConfirmations: 1,
- GasEstimationBuffer: 10000,
- DefaultGasLimit: 6000000,
- }
-
- SimulatedEVMNonDev = blockchain.EVMNetwork{
- Name: "geth",
- Simulated: true,
- SupportsEIP1559: true,
- ClientImplementation: blockchain.EthereumClientImplementation,
- ChainID: 1337,
- PrivateKeys: []string{
- "ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80",
- },
- URLs: []string{"ws://geth-ethereum-geth:8546"},
- HTTPURLs: []string{"http://geth-ethereum-geth:8544"},
- ChainlinkTransactionLimit: 500000,
- Timeout: blockchain.JSONStrDuration{Duration: 2 * time.Minute},
- MinimumConfirmations: 1,
- GasEstimationBuffer: 10000,
- }
-
- EthereumMainnet blockchain.EVMNetwork = blockchain.EVMNetwork{
- Name: "Ethereum Mainnet",
- SupportsEIP1559: true,
- ClientImplementation: blockchain.EthereumClientImplementation,
- ChainID: 1,
- Simulated: false,
- ChainlinkTransactionLimit: 5000,
- Timeout: blockchain.JSONStrDuration{Duration: 5 * time.Minute},
- MinimumConfirmations: 1,
- GasEstimationBuffer: 0,
- FinalityTag: true,
- DefaultGasLimit: 6000000,
- }
-
- // sepoliaTestnet https://sepolia.dev/
- SepoliaTestnet blockchain.EVMNetwork = blockchain.EVMNetwork{
- Name: "Sepolia Testnet",
- SupportsEIP1559: true,
- ClientImplementation: blockchain.EthereumClientImplementation,
- ChainID: 11155111,
- Simulated: false,
- ChainlinkTransactionLimit: 5000,
- Timeout: blockchain.JSONStrDuration{Duration: time.Minute},
- MinimumConfirmations: 1,
- GasEstimationBuffer: 1000,
- FinalityTag: true,
- DefaultGasLimit: 6000000,
- }
-
- // goerliTestnet https://goerli.net/
- GoerliTestnet blockchain.EVMNetwork = blockchain.EVMNetwork{
- Name: "Goerli Testnet",
- SupportsEIP1559: true,
- ClientImplementation: blockchain.EthereumClientImplementation,
- ChainID: 5,
- Simulated: false,
- ChainlinkTransactionLimit: 5000,
- Timeout: blockchain.JSONStrDuration{Duration: 5 * time.Minute},
- MinimumConfirmations: 1,
- GasEstimationBuffer: 1000,
- FinalityTag: true,
- DefaultGasLimit: 6000000,
- }
-
- KlaytnMainnet blockchain.EVMNetwork = blockchain.EVMNetwork{
- Name: "Klaytn Mainnet",
- SupportsEIP1559: false,
- ClientImplementation: blockchain.KlaytnClientImplementation,
- ChainID: 8217,
- Simulated: false,
- ChainlinkTransactionLimit: 5000,
- Timeout: blockchain.JSONStrDuration{Duration: time.Minute},
- MinimumConfirmations: 1,
- GasEstimationBuffer: 0,
- }
-
- // klaytnBaobab https://klaytn.foundation/
- KlaytnBaobab blockchain.EVMNetwork = blockchain.EVMNetwork{
- Name: "Klaytn Baobab",
- SupportsEIP1559: false,
- ClientImplementation: blockchain.KlaytnClientImplementation,
- ChainID: 1001,
- Simulated: false,
- ChainlinkTransactionLimit: 5000,
- Timeout: blockchain.JSONStrDuration{Duration: time.Minute},
- MinimumConfirmations: 1,
- GasEstimationBuffer: 0,
- }
-
- MetisAndromeda blockchain.EVMNetwork = blockchain.EVMNetwork{
- Name: "Metis Andromeda",
- SupportsEIP1559: false,
- ClientImplementation: blockchain.MetisClientImplementation,
- ChainID: 1088,
- Simulated: false,
- ChainlinkTransactionLimit: 5000,
- Timeout: blockchain.JSONStrDuration{Duration: time.Minute},
- MinimumConfirmations: 1,
- GasEstimationBuffer: 0,
- }
-
- // metisStardust https://www.metis.io/
- MetisStardust blockchain.EVMNetwork = blockchain.EVMNetwork{
- Name: "Metis Stardust",
- SupportsEIP1559: false,
- ClientImplementation: blockchain.MetisClientImplementation,
- ChainID: 588,
- Simulated: false,
- ChainlinkTransactionLimit: 5000,
- Timeout: blockchain.JSONStrDuration{Duration: time.Minute},
- MinimumConfirmations: 1,
- GasEstimationBuffer: 1000,
- }
-
- ArbitrumMainnet blockchain.EVMNetwork = blockchain.EVMNetwork{
- Name: "Arbitrum Mainnet",
- SupportsEIP1559: true,
- ClientImplementation: blockchain.ArbitrumClientImplementation,
- ChainID: 42161,
- Simulated: false,
- ChainlinkTransactionLimit: 5000,
- Timeout: blockchain.JSONStrDuration{Duration: 2 * time.Minute},
- MinimumConfirmations: 0,
- GasEstimationBuffer: 0,
- FinalityTag: true,
- DefaultGasLimit: 100000000,
- }
-
- // arbitrumGoerli https://developer.offchainlabs.com/docs/public_chains
- ArbitrumGoerli blockchain.EVMNetwork = blockchain.EVMNetwork{
- Name: "Arbitrum Goerli",
- SupportsEIP1559: true,
- ClientImplementation: blockchain.ArbitrumClientImplementation,
- ChainID: 421613,
- Simulated: false,
- ChainlinkTransactionLimit: 5000,
- Timeout: blockchain.JSONStrDuration{Duration: time.Minute},
- MinimumConfirmations: 0,
- GasEstimationBuffer: 0,
- FinalityTag: true,
- DefaultGasLimit: 100000000,
- }
-
- OptimismMainnet blockchain.EVMNetwork = blockchain.EVMNetwork{
- Name: "Optimism Mainnet",
- SupportsEIP1559: true,
- ClientImplementation: blockchain.OptimismClientImplementation,
- ChainID: 10,
- Simulated: false,
- ChainlinkTransactionLimit: 5000,
- Timeout: blockchain.JSONStrDuration{Duration: time.Minute},
- MinimumConfirmations: 1,
- GasEstimationBuffer: 0,
- FinalityTag: true,
- DefaultGasLimit: 6000000,
- }
-
- // optimismGoerli https://dev.optimism.io/kovan-to-goerli/
- OptimismGoerli blockchain.EVMNetwork = blockchain.EVMNetwork{
- Name: "Optimism Goerli",
- SupportsEIP1559: true,
- ClientImplementation: blockchain.OptimismClientImplementation,
- ChainID: 420,
- Simulated: false,
- ChainlinkTransactionLimit: 5000,
- Timeout: blockchain.JSONStrDuration{Duration: time.Minute},
- MinimumConfirmations: 1,
- GasEstimationBuffer: 0,
- FinalityTag: true,
- DefaultGasLimit: 6000000,
- }
-
- RSKMainnet blockchain.EVMNetwork = blockchain.EVMNetwork{
- Name: "RSK Mainnet",
- SupportsEIP1559: false,
- ClientImplementation: blockchain.RSKClientImplementation,
- ChainID: 30,
- Simulated: false,
- ChainlinkTransactionLimit: 5000,
- Timeout: blockchain.JSONStrDuration{Duration: time.Minute},
- MinimumConfirmations: 1,
- GasEstimationBuffer: 1000,
- }
-
- // rskTestnet https://www.rsk.co/
- RSKTestnet blockchain.EVMNetwork = blockchain.EVMNetwork{
- Name: "RSK Testnet",
- SupportsEIP1559: false,
- ClientImplementation: blockchain.RSKClientImplementation,
- ChainID: 31,
- Simulated: false,
- ChainlinkTransactionLimit: 5000,
- Timeout: blockchain.JSONStrDuration{Duration: time.Minute},
- MinimumConfirmations: 1,
- GasEstimationBuffer: 1000,
- }
-
- PolygonMainnet blockchain.EVMNetwork = blockchain.EVMNetwork{
- Name: "Polygon Mainnet",
- SupportsEIP1559: true,
- ClientImplementation: blockchain.PolygonClientImplementation,
- ChainID: 137,
- Simulated: false,
- ChainlinkTransactionLimit: 5000,
- Timeout: blockchain.JSONStrDuration{Duration: 2 * time.Minute},
- MinimumConfirmations: 1,
- GasEstimationBuffer: 0,
- FinalityDepth: 550,
- DefaultGasLimit: 6000000,
- }
-
- // PolygonMumbai https://mumbai.polygonscan.com/
- PolygonMumbai blockchain.EVMNetwork = blockchain.EVMNetwork{
- Name: "Polygon Mumbai",
- SupportsEIP1559: true,
- ClientImplementation: blockchain.PolygonClientImplementation,
- ChainID: 80001,
- Simulated: false,
- ChainlinkTransactionLimit: 5000,
- Timeout: blockchain.JSONStrDuration{Duration: time.Minute},
- MinimumConfirmations: 1,
- GasEstimationBuffer: 1000,
- FinalityDepth: 550,
- DefaultGasLimit: 6000000,
- }
-
- AvalancheMainnet blockchain.EVMNetwork = blockchain.EVMNetwork{
- Name: "Avalanche Mainnet",
- SupportsEIP1559: true,
- ClientImplementation: blockchain.EthereumClientImplementation,
- ChainID: 43114,
- Simulated: false,
- ChainlinkTransactionLimit: 5000,
- Timeout: blockchain.JSONStrDuration{Duration: time.Minute},
- MinimumConfirmations: 1,
- GasEstimationBuffer: 0,
- FinalityDepth: 35,
- DefaultGasLimit: 6000000,
- }
-
- AvalancheFuji = blockchain.EVMNetwork{
- Name: "Avalanche Fuji",
- SupportsEIP1559: true,
- ClientImplementation: blockchain.EthereumClientImplementation,
- ChainID: 43113,
- Simulated: false,
- ChainlinkTransactionLimit: 5000,
- Timeout: blockchain.JSONStrDuration{Duration: time.Minute},
- MinimumConfirmations: 1,
- GasEstimationBuffer: 1000,
- FinalityDepth: 35,
- DefaultGasLimit: 6000000,
- }
-
- Quorum = blockchain.EVMNetwork{
- Name: "Quorum",
- SupportsEIP1559: false,
- ClientImplementation: blockchain.QuorumClientImplementation,
- ChainID: 1337,
- Simulated: false,
- ChainlinkTransactionLimit: 5000,
- Timeout: blockchain.JSONStrDuration{Duration: time.Minute},
- MinimumConfirmations: 1,
- GasEstimationBuffer: 0,
- }
-
- BaseGoerli blockchain.EVMNetwork = blockchain.EVMNetwork{
- Name: "Base Goerli",
- SupportsEIP1559: true,
- ClientImplementation: blockchain.OptimismClientImplementation,
- ChainID: 84531,
- Simulated: false,
- ChainlinkTransactionLimit: 5000,
- Timeout: blockchain.JSONStrDuration{Duration: time.Minute},
- MinimumConfirmations: 0,
- GasEstimationBuffer: 0,
- }
-
- CeloAlfajores = blockchain.EVMNetwork{
- Name: "Celo Alfajores",
- SupportsEIP1559: false,
- ClientImplementation: blockchain.CeloClientImplementation,
- ChainID: 44787,
- Simulated: false,
- ChainlinkTransactionLimit: 5000,
- Timeout: blockchain.JSONStrDuration{Duration: time.Minute},
- MinimumConfirmations: 1,
- GasEstimationBuffer: 1000,
- }
-
- ScrollSepolia = blockchain.EVMNetwork{
- Name: "Scroll Sepolia",
- ClientImplementation: blockchain.ScrollClientImplementation,
- ChainID: 534351,
- Simulated: false,
- ChainlinkTransactionLimit: 5000,
- Timeout: blockchain.JSONStrDuration{Duration: time.Minute},
- MinimumConfirmations: 1,
- GasEstimationBuffer: 0,
- }
-
- ScrollMainnet = blockchain.EVMNetwork{
- Name: "Scroll Mainnet",
- ClientImplementation: blockchain.ScrollClientImplementation,
- ChainID: 534352,
- Simulated: false,
- ChainlinkTransactionLimit: 5000,
- Timeout: blockchain.JSONStrDuration{Duration: time.Minute},
- MinimumConfirmations: 1,
- GasEstimationBuffer: 0,
- }
-
- CeloMainnet = blockchain.EVMNetwork{
- Name: "Celo",
- ClientImplementation: blockchain.CeloClientImplementation,
- ChainID: 42220,
- Simulated: false,
- ChainlinkTransactionLimit: 5000,
- Timeout: blockchain.JSONStrDuration{Duration: time.Minute},
- MinimumConfirmations: 1,
- GasEstimationBuffer: 1000,
- }
-
- BaseMainnet blockchain.EVMNetwork = blockchain.EVMNetwork{
- Name: "Base Mainnet",
- SupportsEIP1559: true,
- ClientImplementation: blockchain.OptimismClientImplementation,
- ChainID: 8453,
- Simulated: false,
- ChainlinkTransactionLimit: 5000,
- Timeout: blockchain.JSONStrDuration{Duration: time.Minute},
- MinimumConfirmations: 0,
- GasEstimationBuffer: 0,
- }
-
- BSCTestnet blockchain.EVMNetwork = blockchain.EVMNetwork{
- Name: "BSC Testnet",
- SupportsEIP1559: true,
- ClientImplementation: blockchain.BSCClientImplementation,
- ChainID: 97,
- Simulated: false,
- ChainlinkTransactionLimit: 5000,
- Timeout: blockchain.JSONStrDuration{Duration: time.Minute},
- MinimumConfirmations: 3,
- GasEstimationBuffer: 0,
- }
-
- BSCMainnet blockchain.EVMNetwork = blockchain.EVMNetwork{
- Name: "BSC Mainnet",
- SupportsEIP1559: true,
- ClientImplementation: blockchain.BSCClientImplementation,
- ChainID: 56,
- Simulated: false,
- ChainlinkTransactionLimit: 5000,
- Timeout: blockchain.JSONStrDuration{Duration: time.Minute},
- MinimumConfirmations: 3,
- GasEstimationBuffer: 0,
- }
-
- MappedNetworks = map[string]blockchain.EVMNetwork{
- "SIMULATED": SimulatedEVM,
- "SIMULATED_1": SimulatedEVMNonDev1,
- "SIMULATED_2": SimulatedEVMNonDev2,
- "SIMULATED_NONDEV": SimulatedEVMNonDev,
- // "GENERAL": generalEVM, // See above
- "ETHEREUM_MAINNET": EthereumMainnet,
- "GOERLI": GoerliTestnet,
- "SEPOLIA": SepoliaTestnet,
- "KLAYTN_MAINNET": KlaytnMainnet,
- "KLAYTN_BAOBAB": KlaytnBaobab,
- "METIS_ANDROMEDA": MetisAndromeda,
- "METIS_STARDUST": MetisStardust,
- "ARBITRUM_MAINNET": ArbitrumMainnet,
- "ARBITRUM_GOERLI": ArbitrumGoerli,
- "OPTIMISM_MAINNET": OptimismMainnet,
- "OPTIMISM_GOERLI": OptimismGoerli,
- "BASE_GOERLI": BaseGoerli,
- "CELO_ALFAJORES": CeloAlfajores,
- "CELO_MAINNET": CeloMainnet,
- "RSK": RSKTestnet,
- "MUMBAI": PolygonMumbai,
- "POLYGON_MAINNET": PolygonMainnet,
- "AVALANCHE_FUJI": AvalancheFuji,
- "AVALANCHE_MAINNET": AvalancheMainnet,
- "QUORUM": Quorum,
- "SCROLL_SEPOLIA": ScrollSepolia,
- "SCROLL_MAINNET": ScrollMainnet,
- "BASE_MAINNET": BaseMainnet,
- "BSC_TESTNET": BSCTestnet,
- "BSC_MAINNET": BSCMainnet,
- }
-)
-
-// determineSelectedNetworks uses `SELECTED_NETWORKS` to determine which networks to run the tests on.
-// Use DetermineSelectedNetwork for tests that only use one network
-func determineSelectedNetworks() []blockchain.EVMNetwork {
- logging.Init()
- selectedNetworks := make([]blockchain.EVMNetwork, 0)
- rawSelectedNetworks := strings.ToUpper(os.Getenv("SELECTED_NETWORKS"))
- setNetworkNames := strings.Split(rawSelectedNetworks, ",")
-
- for _, setNetworkName := range setNetworkNames {
- if chosenNetwork, valid := MappedNetworks[setNetworkName]; valid {
- log.Info().
- Interface("SELECTED_NETWORKS", setNetworkNames).
- Str("Network Name", chosenNetwork.Name).
- Msg("Read network choice from 'SELECTED_NETWORKS'")
- setURLs(setNetworkName, &chosenNetwork)
- setKeys(setNetworkName, &chosenNetwork)
- selectedNetworks = append(selectedNetworks, chosenNetwork)
- } else {
- validNetworks := make([]string, 0)
- for validNetwork := range MappedNetworks {
- validNetworks = append(validNetworks, validNetwork)
- }
- log.Fatal().
- Interface("SELECTED_NETWORKS", setNetworkNames).
- Str("Valid Networks", strings.Join(validNetworks, ", ")).
- Msg("SELECTED_NETWORKS value is invalid. Use a valid network(s).")
- }
- }
- return selectedNetworks
-}
-
-// setURLs sets a network URL(s) based on env vars
-func setURLs(prefix string, network *blockchain.EVMNetwork) {
- prefix = strings.Trim(prefix, "_")
- prefix = strings.ToUpper(prefix)
-
- if strings.Contains(prefix, "SIMULATED") { // Use defaults for SIMULATED
- return
- }
-
- wsEnvVar := fmt.Sprintf("%s_URLS", prefix)
- httpEnvVar := fmt.Sprintf("%s_HTTP_URLS", prefix)
- wsEnvURLs, err := utils.GetEnv(wsEnvVar)
- if err != nil {
- log.Fatal().Err(err).Str("env var", wsEnvVar).Msg("Error getting env var")
- }
- httpEnvURLs, err := utils.GetEnv(httpEnvVar)
- if err != nil {
- log.Fatal().Err(err).Str("env var", httpEnvVar).Msg("Error getting env var")
- }
- if wsEnvURLs == "" {
- evmUrls, err := utils.GetEnv("EVM_URLS")
- if err != nil {
- log.Fatal().Err(err).Str("env var", "EVM_URLS").Msg("Error getting env var")
- }
- evmhttpUrls, err := utils.GetEnv("EVM_HTTP_URLS")
- if err != nil {
- log.Fatal().Err(err).Str("env var", "EVM_HTTP_URLS").Msg("Error getting env var")
- }
- wsURLs := strings.Split(evmUrls, ",")
- httpURLs := strings.Split(evmhttpUrls, ",")
- log.Warn().
- Interface("EVM_URLS", wsURLs).
- Interface("EVM_HTTP_URLS", httpURLs).
- Msgf("No '%s' env var defined, defaulting to 'EVM_URLS'", wsEnvVar)
- network.URLs = wsURLs
- network.HTTPURLs = httpURLs
- return
- }
-
- wsURLs := strings.Split(wsEnvURLs, ",")
- httpURLs := strings.Split(httpEnvURLs, ",")
- network.URLs = wsURLs
- network.HTTPURLs = httpURLs
- log.Info().Msg("Read network URLs")
-}
-
-// setKeys sets a network's private key(s) based on env vars
-func setKeys(prefix string, network *blockchain.EVMNetwork) {
- prefix = strings.Trim(prefix, "_")
- prefix = strings.ToUpper(prefix)
-
- if strings.Contains(prefix, "SIMULATED") { // Use defaults for SIMULATED
- return
- }
-
- envVar := fmt.Sprintf("%s_KEYS", prefix)
- keysEnv, err := utils.GetEnv(envVar)
- if err != nil {
- log.Fatal().Err(err).Str("env var", envVar).Msg("Error getting env var")
- }
- if keysEnv == "" {
- keys := strings.Split(os.Getenv("EVM_KEYS"), ",")
- log.Warn().
- Interface("EVM_KEYS", keys).
- Msg(fmt.Sprintf("No '%s' env var defined, defaulting to 'EVM_KEYS'", envVar))
- network.PrivateKeys = keys
- return
- }
- keys := strings.Split(keysEnv, ",")
- network.PrivateKeys = keys
- log.Info().Msg("Read network Keys")
-}
diff --git a/integration-tests/performance/cron_test.go b/integration-tests/performance/cron_test.go
index 933014a1698..c66a1803564 100644
--- a/integration-tests/performance/cron_test.go
+++ b/integration-tests/performance/cron_test.go
@@ -22,9 +22,10 @@ import (
ctfClient "github.com/smartcontractkit/chainlink-testing-framework/client"
"github.com/smartcontractkit/chainlink-testing-framework/utils"
+ "github.com/smartcontractkit/chainlink-testing-framework/networks"
+
"github.com/smartcontractkit/chainlink/integration-tests/actions"
"github.com/smartcontractkit/chainlink/integration-tests/client"
- "github.com/smartcontractkit/chainlink/integration-tests/networks"
"github.com/smartcontractkit/chainlink/integration-tests/testreporters"
"github.com/smartcontractkit/chainlink/integration-tests/testsetups"
)
diff --git a/integration-tests/performance/directrequest_test.go b/integration-tests/performance/directrequest_test.go
index 47a16de1091..98c03c2bb96 100644
--- a/integration-tests/performance/directrequest_test.go
+++ b/integration-tests/performance/directrequest_test.go
@@ -18,27 +18,27 @@ import (
mockservercfg "github.com/smartcontractkit/chainlink-env/pkg/helm/mockserver-cfg"
"github.com/smartcontractkit/chainlink-testing-framework/blockchain"
ctfClient "github.com/smartcontractkit/chainlink-testing-framework/client"
- "github.com/smartcontractkit/chainlink-testing-framework/utils"
+ "github.com/smartcontractkit/chainlink-testing-framework/logging"
+ "github.com/smartcontractkit/chainlink-testing-framework/networks"
"github.com/smartcontractkit/chainlink/integration-tests/actions"
"github.com/smartcontractkit/chainlink/integration-tests/client"
"github.com/smartcontractkit/chainlink/integration-tests/contracts"
- "github.com/smartcontractkit/chainlink/integration-tests/networks"
"github.com/smartcontractkit/chainlink/integration-tests/testsetups"
"github.com/google/uuid"
)
func TestDirectRequestPerformance(t *testing.T) {
- l := utils.GetTestLogger(t)
+ l := logging.GetTestLogger(t)
testEnvironment := setupDirectRequestTest(t)
if testEnvironment.WillUseRemoteRunner() {
return
}
- chainClient, err := blockchain.NewEVMClient(blockchain.SimulatedEVMNetwork, testEnvironment)
+ chainClient, err := blockchain.NewEVMClient(blockchain.SimulatedEVMNetwork, testEnvironment, l)
require.NoError(t, err, "Connecting to blockchain nodes shouldn't fail")
- contractDeployer, err := contracts.NewContractDeployer(chainClient)
+ contractDeployer, err := contracts.NewContractDeployer(chainClient, l)
require.NoError(t, err, "Deploying contracts shouldn't fail")
chainlinkNodes, err := client.ConnectChainlinkNodes(testEnvironment)
require.NoError(t, err, "Connecting to chainlink nodes shouldn't fail")
@@ -82,6 +82,7 @@ func TestDirectRequestPerformance(t *testing.T) {
Name: "direct_request",
MinIncomingConfirmations: "1",
ContractAddress: oracle.Address(),
+ EVMChainID: chainClient.GetChainID().String(),
ExternalJobID: jobUUID.String(),
ObservationSource: ost,
})
diff --git a/integration-tests/performance/flux_test.go b/integration-tests/performance/flux_test.go
index ecacce90ca7..2c33096a356 100644
--- a/integration-tests/performance/flux_test.go
+++ b/integration-tests/performance/flux_test.go
@@ -19,25 +19,25 @@ import (
mockservercfg "github.com/smartcontractkit/chainlink-env/pkg/helm/mockserver-cfg"
"github.com/smartcontractkit/chainlink-testing-framework/blockchain"
ctfClient "github.com/smartcontractkit/chainlink-testing-framework/client"
- "github.com/smartcontractkit/chainlink-testing-framework/utils"
+ "github.com/smartcontractkit/chainlink-testing-framework/logging"
+ "github.com/smartcontractkit/chainlink-testing-framework/networks"
"github.com/smartcontractkit/chainlink/integration-tests/actions"
"github.com/smartcontractkit/chainlink/integration-tests/client"
"github.com/smartcontractkit/chainlink/integration-tests/contracts"
- "github.com/smartcontractkit/chainlink/integration-tests/networks"
"github.com/smartcontractkit/chainlink/integration-tests/testsetups"
)
func TestFluxPerformance(t *testing.T) {
- l := utils.GetTestLogger(t)
+ l := logging.GetTestLogger(t)
testEnvironment, testNetwork := setupFluxTest(t)
if testEnvironment.WillUseRemoteRunner() {
return
}
- chainClient, err := blockchain.NewEVMClient(testNetwork, testEnvironment)
+ chainClient, err := blockchain.NewEVMClient(testNetwork, testEnvironment, l)
require.NoError(t, err, "Connecting to blockchain nodes shouldn't fail")
- contractDeployer, err := contracts.NewContractDeployer(chainClient)
+ contractDeployer, err := contracts.NewContractDeployer(chainClient, l)
require.NoError(t, err, "Deploying contracts shouldn't fail")
chainlinkNodes, err := client.ConnectChainlinkNodes(testEnvironment)
require.NoError(t, err, "Connecting to chainlink nodes shouldn't fail")
@@ -99,6 +99,7 @@ func TestFluxPerformance(t *testing.T) {
fluxSpec := &client.FluxMonitorJobSpec{
Name: fmt.Sprintf("flux-monitor-%s", adapterUUID),
ContractAddress: fluxInstance.Address(),
+ EVMChainID: chainClient.GetChainID().String(),
Threshold: 0,
AbsoluteThreshold: 0,
PollTimerPeriod: 15 * time.Second, // min 15s
@@ -115,7 +116,7 @@ func TestFluxPerformance(t *testing.T) {
return
}
fluxRoundTimeout := 2 * time.Minute
- fluxRound := contracts.NewFluxAggregatorRoundConfirmer(fluxInstance, big.NewInt(1), fluxRoundTimeout)
+ fluxRound := contracts.NewFluxAggregatorRoundConfirmer(fluxInstance, big.NewInt(1), fluxRoundTimeout, l)
chainClient.AddHeaderEventSubscription(fluxInstance.Address(), fluxRound)
err = chainClient.WaitForEvents()
require.NoError(t, err, "Waiting for event subscriptions in nodes shouldn't fail")
@@ -133,7 +134,7 @@ func TestFluxPerformance(t *testing.T) {
require.Equal(t, int64(3), data.AllocatedFunds.Int64(),
"Expected allocated funds to be %d, but found %d", int64(3), data.AllocatedFunds.Int64())
- fluxRound = contracts.NewFluxAggregatorRoundConfirmer(fluxInstance, big.NewInt(2), fluxRoundTimeout)
+ fluxRound = contracts.NewFluxAggregatorRoundConfirmer(fluxInstance, big.NewInt(2), fluxRoundTimeout, l)
chainClient.AddHeaderEventSubscription(fluxInstance.Address(), fluxRound)
err = mockServer.SetValuePath(adapterPath, 1e10)
require.NoError(t, err, "Setting value path in mock server shouldn't fail")
diff --git a/integration-tests/performance/keeper_test.go b/integration-tests/performance/keeper_test.go
index 346f0897d47..7ab0f53d0d0 100644
--- a/integration-tests/performance/keeper_test.go
+++ b/integration-tests/performance/keeper_test.go
@@ -18,13 +18,13 @@ import (
"github.com/smartcontractkit/chainlink-env/pkg/helm/mockserver"
mockservercfg "github.com/smartcontractkit/chainlink-env/pkg/helm/mockserver-cfg"
"github.com/smartcontractkit/chainlink-testing-framework/blockchain"
- "github.com/smartcontractkit/chainlink-testing-framework/utils"
+ "github.com/smartcontractkit/chainlink-testing-framework/logging"
+ "github.com/smartcontractkit/chainlink-testing-framework/networks"
"github.com/smartcontractkit/chainlink/integration-tests/actions"
"github.com/smartcontractkit/chainlink/integration-tests/client"
"github.com/smartcontractkit/chainlink/integration-tests/contracts"
"github.com/smartcontractkit/chainlink/integration-tests/contracts/ethereum"
- "github.com/smartcontractkit/chainlink/integration-tests/networks"
"github.com/smartcontractkit/chainlink/integration-tests/testsetups"
)
@@ -44,7 +44,7 @@ var keeperDefaultRegistryConfig = contracts.KeeperRegistrySettings{
}
func TestKeeperPerformance(t *testing.T) {
- l := utils.GetTestLogger(t)
+ l := logging.GetTestLogger(t)
testEnvironment, chainClient, chainlinkNodes, contractDeployer, linkToken := setupKeeperTest(t, "basic-smoke")
if testEnvironment.WillUseRemoteRunner() {
return
@@ -67,7 +67,7 @@ func TestKeeperPerformance(t *testing.T) {
// Not the last node, hence not all nodes started profiling yet.
return
}
- actions.CreateKeeperJobs(t, chainlinkNodes, registry, contracts.OCRv2Config{})
+ actions.CreateKeeperJobs(t, chainlinkNodes, registry, contracts.OCRv2Config{}, chainClient.GetChainID().String())
err := chainClient.WaitForEvents()
require.NoError(t, err, "Error creating keeper jobs")
@@ -173,9 +173,10 @@ PerformGasOverhead = 150_000`
return testEnvironment, nil, nil, nil, nil
}
- chainClient, err := blockchain.NewEVMClient(network, testEnvironment)
+ l := logging.GetTestLogger(t)
+ chainClient, err := blockchain.NewEVMClient(network, testEnvironment, l)
require.NoError(t, err, "Connecting to blockchain nodes shouldn't fail")
- contractDeployer, err := contracts.NewContractDeployer(chainClient)
+ contractDeployer, err := contracts.NewContractDeployer(chainClient, l)
require.NoError(t, err, "Deploying contracts shouldn't fail")
chainlinkNodes, err := client.ConnectChainlinkNodes(testEnvironment)
require.NoError(t, err, "Connecting to chainlink nodes shouldn't fail")
diff --git a/integration-tests/performance/ocr_test.go b/integration-tests/performance/ocr_test.go
index 25791161bc2..d3d29049653 100644
--- a/integration-tests/performance/ocr_test.go
+++ b/integration-tests/performance/ocr_test.go
@@ -17,11 +17,13 @@ import (
mockservercfg "github.com/smartcontractkit/chainlink-env/pkg/helm/mockserver-cfg"
"github.com/smartcontractkit/chainlink-testing-framework/blockchain"
ctfClient "github.com/smartcontractkit/chainlink-testing-framework/client"
+ "github.com/smartcontractkit/chainlink-testing-framework/logging"
+
+ "github.com/smartcontractkit/chainlink-testing-framework/networks"
"github.com/smartcontractkit/chainlink/integration-tests/actions"
"github.com/smartcontractkit/chainlink/integration-tests/client"
"github.com/smartcontractkit/chainlink/integration-tests/contracts"
- "github.com/smartcontractkit/chainlink/integration-tests/networks"
"github.com/smartcontractkit/chainlink/integration-tests/testsetups"
)
@@ -31,10 +33,10 @@ func TestOCRBasic(t *testing.T) {
if testEnvironment.WillUseRemoteRunner() {
return
}
-
- chainClient, err := blockchain.NewEVMClient(testNetwork, testEnvironment)
+ l := logging.GetTestLogger(t)
+ chainClient, err := blockchain.NewEVMClient(testNetwork, testEnvironment, l)
require.NoError(t, err, "Connecting to blockchain nodes shouldn't fail")
- contractDeployer, err := contracts.NewContractDeployer(chainClient)
+ contractDeployer, err := contracts.NewContractDeployer(chainClient, l)
require.NoError(t, err, "Deploying contracts shouldn't fail")
chainlinkNodes, err := client.ConnectChainlinkNodes(testEnvironment)
@@ -57,9 +59,9 @@ func TestOCRBasic(t *testing.T) {
require.NoError(t, err, "Error waiting for events")
profileFunction := func(chainlinkNode *client.ChainlinkClient) {
- err = actions.CreateOCRJobs(ocrInstances, bootstrapNode, workerNodes, 5, mockServer)
+ err = actions.CreateOCRJobs(ocrInstances, bootstrapNode, workerNodes, 5, mockServer, chainClient.GetChainID().String())
require.NoError(t, err)
- err = actions.StartNewRound(1, ocrInstances, chainClient)
+ err = actions.StartNewRound(1, ocrInstances, chainClient, l)
require.NoError(t, err)
answer, err := ocrInstances[0].GetLatestAnswer(context.Background())
@@ -68,7 +70,7 @@ func TestOCRBasic(t *testing.T) {
err = mockServer.SetValuePath("ocr", 10)
require.NoError(t, err)
- err = actions.StartNewRound(2, ocrInstances, chainClient)
+ err = actions.StartNewRound(2, ocrInstances, chainClient, l)
require.NoError(t, err)
answer, err = ocrInstances[0].GetLatestAnswer(context.Background())
diff --git a/integration-tests/performance/vrf_test.go b/integration-tests/performance/vrf_test.go
index 2074eecaf78..af3a3ecba81 100644
--- a/integration-tests/performance/vrf_test.go
+++ b/integration-tests/performance/vrf_test.go
@@ -16,26 +16,26 @@ import (
"github.com/smartcontractkit/chainlink-env/pkg/helm/chainlink"
"github.com/smartcontractkit/chainlink-env/pkg/helm/ethereum"
"github.com/smartcontractkit/chainlink-testing-framework/blockchain"
- "github.com/smartcontractkit/chainlink-testing-framework/utils"
+ "github.com/smartcontractkit/chainlink-testing-framework/logging"
+ "github.com/smartcontractkit/chainlink-testing-framework/networks"
"github.com/smartcontractkit/chainlink/integration-tests/actions"
"github.com/smartcontractkit/chainlink/integration-tests/client"
"github.com/smartcontractkit/chainlink/integration-tests/contracts"
- "github.com/smartcontractkit/chainlink/integration-tests/networks"
"github.com/smartcontractkit/chainlink/integration-tests/testsetups"
)
func TestVRFBasic(t *testing.T) {
t.Parallel()
- l := utils.GetTestLogger(t)
+ l := logging.GetTestLogger(t)
testEnvironment, testNetwork := setupVRFTest(t)
if testEnvironment.WillUseRemoteRunner() {
return
}
- chainClient, err := blockchain.NewEVMClient(testNetwork, testEnvironment)
+ chainClient, err := blockchain.NewEVMClient(testNetwork, testEnvironment, l)
require.NoError(t, err, "Connecting client shouldn't fail")
- cd, err := contracts.NewContractDeployer(chainClient)
+ cd, err := contracts.NewContractDeployer(chainClient, l)
require.NoError(t, err, "Deploying contracts shouldn't fail")
chainlinkNodes, err := client.ConnectChainlinkNodes(testEnvironment)
require.NoError(t, err, "Connecting to chainlink nodes shouldn't fail")
diff --git a/integration-tests/reorg/automation_reorg_test.go b/integration-tests/reorg/automation_reorg_test.go
index cfc6a2b2968..ab439e59f29 100644
--- a/integration-tests/reorg/automation_reorg_test.go
+++ b/integration-tests/reorg/automation_reorg_test.go
@@ -17,13 +17,14 @@ import (
"github.com/smartcontractkit/chainlink-env/pkg/helm/chainlink"
"github.com/smartcontractkit/chainlink-env/pkg/helm/reorg"
"github.com/smartcontractkit/chainlink-testing-framework/blockchain"
+ "github.com/smartcontractkit/chainlink-testing-framework/logging"
+ "github.com/smartcontractkit/chainlink-testing-framework/networks"
"github.com/smartcontractkit/chainlink-testing-framework/utils"
"github.com/smartcontractkit/chainlink/integration-tests/actions"
"github.com/smartcontractkit/chainlink/integration-tests/client"
"github.com/smartcontractkit/chainlink/integration-tests/contracts"
"github.com/smartcontractkit/chainlink/integration-tests/contracts/ethereum"
- "github.com/smartcontractkit/chainlink/integration-tests/networks"
)
var (
@@ -123,7 +124,7 @@ const (
* normal pace after the event.
*/
func TestAutomationReorg(t *testing.T) {
- l := utils.GetTestLogger(t)
+ l := logging.GetTestLogger(t)
network := networks.SelectedNetwork
cd, err := chainlink.NewDeployment(numberOfNodes, defaultAutomationSettings)
@@ -146,9 +147,9 @@ func TestAutomationReorg(t *testing.T) {
return
}
- chainClient, err := blockchain.NewEVMClient(network, testEnvironment)
+ chainClient, err := blockchain.NewEVMClient(network, testEnvironment, l)
require.NoError(t, err, "Error connecting to blockchain")
- contractDeployer, err := contracts.NewContractDeployer(chainClient)
+ contractDeployer, err := contracts.NewContractDeployer(chainClient, l)
require.NoError(t, err, "Error building contract deployer")
chainlinkNodes, err := client.ConnectChainlinkNodes(testEnvironment)
require.NoError(t, err, "Error connecting to Chainlink nodes")
@@ -172,15 +173,18 @@ func TestAutomationReorg(t *testing.T) {
t,
ethereum.RegistryVersion_2_0,
defaultOCRRegistryConfig,
- numberOfUpkeeps,
linkToken,
contractDeployer,
chainClient,
)
+ // Fund the registry with LINK
+ err = linkToken.Transfer(registry.Address(), big.NewInt(0).Mul(big.NewInt(1e18), big.NewInt(int64(numberOfUpkeeps))))
+ require.NoError(t, err, "Funding keeper registry contract shouldn't fail")
+
actions.CreateOCRKeeperJobs(t, chainlinkNodes, registry.Address(), network.ChainID, 0, ethereum.RegistryVersion_2_0)
nodesWithoutBootstrap := chainlinkNodes[1:]
- ocrConfig, err := actions.BuildAutoOCR2ConfigVars(t, nodesWithoutBootstrap, defaultOCRRegistryConfig, registrar.Address(), 5*time.Second)
+ ocrConfig, err := actions.BuildAutoOCR2ConfigVars(t, nodesWithoutBootstrap, defaultOCRRegistryConfig, registrar.Address(), 30*time.Second)
require.NoError(t, err, "OCR2 config should be built successfully")
err = registry.SetConfig(defaultOCRRegistryConfig, ocrConfig)
require.NoError(t, err, "Registry config should be be set successfully")
diff --git a/integration-tests/reorg/reorg_test.go b/integration-tests/reorg/reorg_test.go
index d6ac5ce1cf1..5666d8c7540 100644
--- a/integration-tests/reorg/reorg_test.go
+++ b/integration-tests/reorg/reorg_test.go
@@ -1,6 +1,7 @@
package reorg
import (
+ "context"
"fmt"
"math/big"
"os"
@@ -23,13 +24,13 @@ import (
ctfClient "github.com/smartcontractkit/chainlink-testing-framework/client"
"github.com/smartcontractkit/chainlink-testing-framework/utils"
- "context"
"github.com/onsi/gomega"
"github.com/rs/zerolog/log"
+ "github.com/smartcontractkit/chainlink-testing-framework/networks"
+
"github.com/smartcontractkit/chainlink/integration-tests/actions"
"github.com/smartcontractkit/chainlink/integration-tests/client"
"github.com/smartcontractkit/chainlink/integration-tests/contracts"
- "github.com/smartcontractkit/chainlink/integration-tests/networks"
)
const (
@@ -90,6 +91,7 @@ func CleanupReorgTest(
func TestDirectRequestReorg(t *testing.T) {
logging.Init()
+ l := logging.GetTestLogger(t)
testEnvironment := environment.New(&environment.Config{
TTL: 1 * time.Hour,
Test: t,
@@ -130,9 +132,9 @@ func TestDirectRequestReorg(t *testing.T) {
err = testEnvironment.AddHelmCharts(chainlinkDeployment).Run()
require.NoError(t, err, "Error adding to test environment")
- chainClient, err := blockchain.NewEVMClient(networkSettings, testEnvironment)
+ chainClient, err := blockchain.NewEVMClient(networkSettings, testEnvironment, l)
require.NoError(t, err, "Error connecting to blockchain")
- cd, err := contracts.NewContractDeployer(chainClient)
+ cd, err := contracts.NewContractDeployer(chainClient, l)
require.NoError(t, err, "Error building contract deployer")
chainlinkNodes, err := client.ConnectChainlinkNodes(testEnvironment)
require.NoError(t, err, "Error connecting to Chainlink nodes")
@@ -180,6 +182,7 @@ func TestDirectRequestReorg(t *testing.T) {
Name: "direct_request",
MinIncomingConfirmations: minIncomingConfirmations,
ContractAddress: oracle.Address(),
+ EVMChainID: chainClient.GetChainID().String(),
ExternalJobID: jobUUID.String(),
ObservationSource: ost,
})
diff --git a/integration-tests/runner_helpers.go b/integration-tests/runner_helpers.go
index 17950064575..43268a703ac 100644
--- a/integration-tests/runner_helpers.go
+++ b/integration-tests/runner_helpers.go
@@ -12,12 +12,12 @@ import (
"strings"
"time"
- gh "github.com/cli/go-gh/v2"
+ "github.com/cli/go-gh/v2"
"github.com/ethereum/go-ethereum/crypto"
"github.com/manifoldco/promptui"
"github.com/rs/zerolog/log"
- "github.com/smartcontractkit/chainlink/integration-tests/networks"
+ "github.com/smartcontractkit/chainlink-testing-framework/networks"
)
func waitForWorkflowRun(branch, ghUser string) (string, error) {
diff --git a/integration-tests/scripts/buildTestMatrixList.sh b/integration-tests/scripts/buildTestMatrixList.sh
new file mode 100755
index 00000000000..7f058b5b659
--- /dev/null
+++ b/integration-tests/scripts/buildTestMatrixList.sh
@@ -0,0 +1,64 @@
+#!/usr/bin/env bash
+
+# requires a path to a test file to compare the test list against
+# requires a matrix job name to be passed in, for example "automation"
+# requires a node label to be passed in, for example "ubuntu-latest"
+
+set -e
+
+# get this scripts directory
+SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd)
+
+cd "$SCRIPT_DIR"/../ || exit 1
+
+FILENAME=$1
+MATRIX_JOB_NAME=$2
+NODE_LABEL=$3
+NODE_COUNT=$4
+
+# Get list of test names from JSON file
+JSONFILE="${FILENAME}_test_list.json"
+COUNTER=1
+
+# Build a JSON object in the format expected by our integration-tests workflow matrix
+matrix_output() {
+ local counter=$1
+ local job_name=$2
+ local test_name=$3
+ local node_label=$4
+ local node_count=$5
+ local counter_out=$(printf "%02d\n" $counter)
+ echo -n "{\"name\": \"${job_name}-${counter_out}\", \"file\": \"${job_name}\",\"nodes\": ${node_count}, \"os\": \"${node_label}\", \"pyroscope_env\": \"ci-smoke-${job_name}-evm-simulated\", \"run\": \"-run '^${test_name}$'\"}"
+}
+
+# Read the JSON file and loop through 'tests' and 'run'
+jq -c '.tests[]' ${JSONFILE} | while read -r test; do
+ testName=$(echo ${test} | jq -r '.name')
+ label=$(echo ${test} | jq -r '.label // empty')
+ effective_node_label=${label:-$NODE_LABEL}
+ node_count=$(echo ${test} | jq -r '.nodes // empty')
+ effective_node_count=${node_count:-$NODE_COUNT}
+ subTests=$(echo ${test} | jq -r '.run[]?.name // empty')
+ output=""
+
+ # Loop through subtests, if any, and print in the desired format
+ if [ -n "$subTests" ]; then
+ for subTest in $subTests; do
+ if [ $COUNTER -ne 1 ]; then
+ echo -n ","
+ fi
+ matrix_output $COUNTER $MATRIX_JOB_NAME "${testName}/${subTest}" ${effective_node_label} ${effective_node_count}
+ ((COUNTER++))
+ done
+ else
+ if [ $COUNTER -ne 1 ]; then
+ echo -n ","
+ fi
+ matrix_output $COUNTER $MATRIX_JOB_NAME "${testName}" ${effective_node_label} ${effective_node_count}
+ ((COUNTER++))
+ fi
+
+done > "./tmpout.json"
+OUTPUT=$(cat ./tmpout.json)
+echo "[${OUTPUT}]"
+rm ./tmpout.json
diff --git a/integration-tests/scripts/compareTestList.sh b/integration-tests/scripts/compareTestList.sh
new file mode 100755
index 00000000000..8cc916c7d63
--- /dev/null
+++ b/integration-tests/scripts/compareTestList.sh
@@ -0,0 +1,48 @@
+#!/usr/bin/env bash
+
+# accepts a path to a test file to compare the test list against
+
+set -e
+
+# get this scripts directory
+SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd)
+
+cd "$SCRIPT_DIR"/../ || exit 1
+
+FILENAME=$1
+
+TESTLIST=$(cat ${FILENAME} | grep "func Test.*\(t \*testing.T\)" | grep -o 'Test[A-Za-z0-9_]*')
+
+# convert the test list from above into json in the form {"tests":[{"name":"TestName"}]}
+TESTLISTJSON=$(echo $TESTLIST | jq -R -s -c '{tests: split(" ") | map({"name":.})}')
+
+# Get list of test names from JSON file
+JSONFILE="${FILENAME}_test_list.json"
+JSONTESTLIST=$(jq -r '.tests[].name' ${JSONFILE})
+
+# Convert lists to arrays
+TESTLIST_ARRAY=($(echo "$TESTLIST"))
+JSONTESTLIST_ARRAY=($(echo "$JSONTESTLIST"))
+
+ERRORS_FOUND=false
+
+# Compare TESTLIST_ARRAY against JSONTESTLIST_ARRAY
+for test in "${TESTLIST_ARRAY[@]}"; do
+ if [[ ! " ${JSONTESTLIST_ARRAY[@]} " =~ " ${test} " ]]; then
+ echo "$test exists only in ${FILENAME}."
+ ERRORS_FOUND=true
+ fi
+done
+
+# Compare JSONTESTLIST_ARRAY against TESTLIST_ARRAY
+for test in "${JSONTESTLIST_ARRAY[@]}"; do
+ if [[ ! " ${TESTLIST_ARRAY[@]} " =~ " ${test} " ]]; then
+ echo "$test exists only in ${JSONFILE}."
+ ERRORS_FOUND=true
+ fi
+done
+
+if [ "$ERRORS_FOUND" = true ] ; then
+ echo "Test lists do not match. Please update ${JSONFILE} with the updated tests to run in CI."
+ exit 1
+fi
diff --git a/integration-tests/smoke/automation_test.go b/integration-tests/smoke/automation_test.go
index ab757afe87a..76ee75b21ba 100644
--- a/integration-tests/smoke/automation_test.go
+++ b/integration-tests/smoke/automation_test.go
@@ -6,28 +6,32 @@ import (
"math/big"
"os"
"strconv"
- "strings"
"testing"
"time"
+ "github.com/ethereum/go-ethereum/common"
"github.com/onsi/gomega"
"github.com/stretchr/testify/require"
- "go.uber.org/zap/zapcore"
- "github.com/smartcontractkit/chainlink-env/environment"
- "github.com/smartcontractkit/chainlink-env/logging"
- "github.com/smartcontractkit/chainlink-env/pkg/helm/chainlink"
- eth "github.com/smartcontractkit/chainlink-env/pkg/helm/ethereum"
"github.com/smartcontractkit/chainlink-testing-framework/blockchain"
+ "github.com/smartcontractkit/chainlink-testing-framework/logging"
+ "github.com/smartcontractkit/chainlink-testing-framework/networks"
"github.com/smartcontractkit/chainlink-testing-framework/utils"
"github.com/smartcontractkit/chainlink/integration-tests/actions"
"github.com/smartcontractkit/chainlink/integration-tests/client"
"github.com/smartcontractkit/chainlink/integration-tests/contracts"
"github.com/smartcontractkit/chainlink/integration-tests/contracts/ethereum"
- "github.com/smartcontractkit/chainlink/integration-tests/networks"
+ "github.com/smartcontractkit/chainlink/integration-tests/docker/test_env"
+ "github.com/smartcontractkit/chainlink/integration-tests/types/config/node"
+ it_utils "github.com/smartcontractkit/chainlink/integration-tests/utils"
+ cltypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types"
+ "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/automation_utils_2_1"
+ "github.com/smartcontractkit/chainlink/v2/core/store/models"
)
+var utilsABI = cltypes.MustGetABI(automation_utils_2_1.AutomationUtilsABI)
+
const (
automationDefaultUpkeepGasLimit = uint32(2500000)
automationDefaultLinkFunds = int64(9e18)
@@ -37,25 +41,6 @@ const (
)
var (
- automationBaseTOML = `[Feature]
-LogPoller = true
-
-[OCR2]
-Enabled = true
-
-[Keeper]
-TurnLookBack = 0
-
-[Keeper.Registry]
-SyncInterval = '5m'
-PerformGasOverhead = 150_000
-
-[P2P]
-[P2P.V2]
-Enabled = true
-AnnounceAddresses = ["0.0.0.0:6690"]
-ListenAddresses = ["0.0.0.0:6690"]`
-
defaultOCRRegistryConfig = contracts.KeeperRegistrySettings{
PaymentPremiumPPB: uint32(200000000),
FlatFeeMicroLINK: uint32(0),
@@ -100,17 +85,18 @@ func TestAutomationBasic(t *testing.T) {
func SetupAutomationBasic(t *testing.T, nodeUpgrade bool) {
t.Parallel()
- l := utils.GetTestLogger(t)
-
registryVersions := map[string]ethereum.KeeperRegistryVersion{
- "registry_2_0": ethereum.RegistryVersion_2_0,
+ "registry_2_0": ethereum.RegistryVersion_2_0,
"registry_2_1_conditional": ethereum.RegistryVersion_2_1,
- "registry_2_1_logtrigger": ethereum.RegistryVersion_2_1,
+ "registry_2_1_logtrigger": ethereum.RegistryVersion_2_1,
}
- for name, registryVersion := range registryVersions {
+ for n, rv := range registryVersions {
+ name := n
+ registryVersion := rv
t.Run(name, func(t *testing.T) {
t.Parallel()
+ l := logging.GetTestLogger(t)
var (
upgradeImage string
@@ -125,12 +111,9 @@ func SetupAutomationBasic(t *testing.T, nodeUpgrade bool) {
require.NoError(t, err, "Error getting upgrade version")
testName = "node-upgrade"
}
- chainClient, chainlinkNodes, contractDeployer, linkToken, registry, registrar, onlyStartRunner, testEnv := setupAutomationTest(
+ chainClient, _, contractDeployer, linkToken, registry, registrar, testEnv := setupAutomationTestDocker(
t, testName, registryVersion, defaultOCRRegistryConfig, nodeUpgrade,
)
- if onlyStartRunner {
- return
- }
// Use the name to determine if this is a log trigger or not
isLogTrigger := name == "registry_2_1_logtrigger"
@@ -151,8 +134,6 @@ func SetupAutomationBasic(t *testing.T, nodeUpgrade bool) {
l.Info().Msg("Waiting for all upkeeps to be performed")
gom := gomega.NewGomegaWithT(t)
- // Wait for 30 seconds to allow everything to be ready before emitting logs
- time.Sleep(30 * time.Second)
for i := 0; i < len(upkeepIDs); i++ {
err := consumers[i].Start()
if err != nil {
@@ -180,7 +161,7 @@ func SetupAutomationBasic(t *testing.T, nodeUpgrade bool) {
expect := 5
// Upgrade the nodes one at a time and check that the upkeeps are still being performed
for i := 0; i < 5; i++ {
- actions.UpgradeChainlinkNodeVersions(testEnv, upgradeImage, upgradeVersion, chainlinkNodes[i])
+ actions.UpgradeChainlinkNodeVersionsLocal(upgradeImage, upgradeVersion, testEnv.CLNodes[i])
time.Sleep(time.Second * 10)
expect = expect + 5
gom.Eventually(func(g gomega.Gomega) {
@@ -229,622 +210,843 @@ func SetupAutomationBasic(t *testing.T, nodeUpgrade bool) {
}
}
-func TestAutomationAddFunds(t *testing.T) {
+func TestSetUpkeepTriggerConfig(t *testing.T) {
t.Parallel()
+ l := logging.GetTestLogger(t)
- chainClient, _, contractDeployer, linkToken, registry, registrar, onlyStartRunner, _ := setupAutomationTest(
- t, "add-funds", ethereum.RegistryVersion_2_0, defaultOCRRegistryConfig, false,
+ chainClient, _, contractDeployer, linkToken, registry, registrar, _ := setupAutomationTestDocker(
+ t, "set-trigger-config", ethereum.RegistryVersion_2_1, defaultOCRRegistryConfig, false,
)
- if onlyStartRunner {
- return
- }
-
- consumers, upkeepIDs := actions.DeployConsumers(t, registry, registrar, linkToken, contractDeployer, chainClient, defaultAmountOfUpkeeps, big.NewInt(1), automationDefaultUpkeepGasLimit, false)
- gom := gomega.NewGomegaWithT(t)
- // Since the upkeep is currently underfunded, check that it doesn't get executed
- gom.Consistently(func(g gomega.Gomega) {
- counter, err := consumers[0].Counter(context.Background())
- g.Expect(err).ShouldNot(gomega.HaveOccurred(), "Calling consumer's counter shouldn't fail")
- g.Expect(counter.Int64()).Should(gomega.Equal(int64(0)),
- "Expected consumer counter to remain zero, but got %d", counter.Int64())
- }, "2m", "1s").Should(gomega.Succeed()) // ~1m for setup, 1m assertion
-
- // Grant permission to the registry to fund the upkeep
- err := linkToken.Approve(registry.Address(), big.NewInt(9e18))
- require.NoError(t, err, "Could not approve permissions for the registry on the link token contract")
- err = chainClient.WaitForEvents()
- require.NoError(t, err, "Error waiting for events")
-
- // Add funds to the upkeep whose ID we know from above
- err = registry.AddUpkeepFunds(upkeepIDs[0], big.NewInt(9e18))
- require.NoError(t, err, "Unable to add upkeep")
- err = chainClient.WaitForEvents()
- require.NoError(t, err, "Error waiting for events")
-
- // Now the new upkeep should be performing because we added enough funds
- gom.Eventually(func(g gomega.Gomega) {
- counter, err := consumers[0].Counter(context.Background())
- g.Expect(err).ShouldNot(gomega.HaveOccurred(), "Calling consumer's counter shouldn't fail")
- g.Expect(counter.Int64()).Should(gomega.BeNumerically(">", int64(0)),
- "Expected newly registered upkeep's counter to be greater than 0, but got %d", counter.Int64())
- }, "2m", "1s").Should(gomega.Succeed()) // ~1m for perform, 1m buffer
-}
-
-func TestAutomationPauseUnPause(t *testing.T) {
- t.Parallel()
- l := utils.GetTestLogger(t)
-
- chainClient, _, contractDeployer, linkToken, registry, registrar, onlyStartRunner, _ := setupAutomationTest(
- t, "pause-unpause", ethereum.RegistryVersion_2_0, defaultOCRRegistryConfig, false,
+ consumers, upkeepIDs := actions.DeployConsumers(
+ t,
+ registry,
+ registrar,
+ linkToken,
+ contractDeployer,
+ chainClient,
+ defaultAmountOfUpkeeps,
+ big.NewInt(automationDefaultLinkFunds),
+ automationDefaultUpkeepGasLimit,
+ true,
)
- if onlyStartRunner {
- return
- }
- consumers, upkeepIDs := actions.DeployConsumers(t, registry, registrar, linkToken, contractDeployer, chainClient, defaultAmountOfUpkeeps, big.NewInt(automationDefaultLinkFunds), automationDefaultUpkeepGasLimit, false)
+ // Start log trigger based upkeeps for all consumers
+ for i := 0; i < len(consumers); i++ {
+ err := consumers[i].Start()
+ if err != nil {
+ return
+ }
+ }
+ l.Info().Msg("Waiting for all upkeeps to perform")
gom := gomega.NewGomegaWithT(t)
gom.Eventually(func(g gomega.Gomega) {
- // Check if the upkeeps are performing multiple times by analysing their counters and checking they are greater than 5
+ // Check if the upkeeps are performing multiple times by analyzing their counters
for i := 0; i < len(upkeepIDs); i++ {
counter, err := consumers[i].Counter(context.Background())
- g.Expect(err).ShouldNot(gomega.HaveOccurred(), "Failed to retrieve consumer counter for upkeep at index %d", i)
- g.Expect(counter.Int64()).Should(gomega.BeNumerically(">", int64(5)),
- "Expected consumer counter to be greater than 5, but got %d", counter.Int64())
- l.Info().Int("Upkeep Index", i).Int64("Upkeep counter", counter.Int64()).Msg("Number of upkeeps performed")
+ require.NoError(t, err, "Failed to retrieve consumer counter for upkeep at index %d", i)
+ expect := 5
+ l.Info().Int64("Upkeeps Performed", counter.Int64()).Int("Upkeep Index", i).Msg("Number of upkeeps performed")
+ g.Expect(counter.Int64()).Should(gomega.BeNumerically(">=", int64(expect)),
+ "Expected consumer counter to be greater than %d, but got %d", expect, counter.Int64())
}
}, "5m", "1s").Should(gomega.Succeed()) // ~1m for cluster setup, ~2m for performing each upkeep 5 times, ~2m buffer
- // pause all the registered upkeeps via the registry
- for i := 0; i < len(upkeepIDs); i++ {
- err := registry.PauseUpkeep(upkeepIDs[i])
- require.NoError(t, err, "Could not pause upkeep at index %d", i)
+ topic0InBytesMatch := [32]byte{
+ 61, 83, 163, 149, 80, 224, 70, 136,
+ 6, 88, 39, 243, 187, 134, 88, 76,
+ 176, 7, 171, 158, 188, 167, 235,
+ 213, 40, 231, 48, 28, 156, 49, 235, 93,
+ } // bytes representation of 0x3d53a39550e04688065827f3bb86584cb007ab9ebca7ebd528e7301c9c31eb5d
+
+ topic0InBytesNoMatch := [32]byte{
+ 62, 83, 163, 149, 80, 224, 70, 136,
+ 6, 88, 39, 243, 187, 134, 88, 76,
+ 176, 7, 171, 158, 188, 167, 235,
+ 213, 40, 231, 48, 28, 156, 49, 235, 93,
+ } // changed the first byte from 61 to 62 to make it not match
+
+ bytes0 := [32]byte{
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ } // bytes representation of 0x0000000000000000000000000000000000000000000000000000000000000000
+
+ // Update the trigger config so no upkeeps are triggered
+ for i := 0; i < len(consumers); i++ {
+ upkeepAddr := consumers[i].Address()
+
+ logTriggerConfigStruct := automation_utils_2_1.LogTriggerConfig{
+ ContractAddress: common.HexToAddress(upkeepAddr),
+ FilterSelector: 0,
+ Topic0: topic0InBytesNoMatch,
+ Topic1: bytes0,
+ Topic2: bytes0,
+ Topic3: bytes0,
+ }
+ encodedLogTriggerConfig, err := utilsABI.Methods["_logTriggerConfig"].Inputs.Pack(&logTriggerConfigStruct)
+ if err != nil {
+ return
+ }
+
+ err = registry.SetUpkeepTriggerConfig(upkeepIDs[i], encodedLogTriggerConfig)
+ require.NoError(t, err, "Could not set upkeep trigger config at index %d", i)
}
err := chainClient.WaitForEvents()
- require.NoError(t, err, "Error waiting for upkeeps to be paused")
+ require.NoError(t, err, "Error encountered when waiting for setting trigger config for upkeeps")
- var countersAfterPause = make([]*big.Int, len(upkeepIDs))
+ var countersAfterSetNoMatch = make([]*big.Int, len(upkeepIDs))
+
+ // Wait for 10 seconds to let in-flight upkeeps finish
+ time.Sleep(10 * time.Second)
for i := 0; i < len(upkeepIDs); i++ {
// Obtain the amount of times the upkeep has been executed so far
- countersAfterPause[i], err = consumers[i].Counter(context.Background())
+ countersAfterSetNoMatch[i], err = consumers[i].Counter(context.Background())
require.NoError(t, err, "Failed to retrieve consumer counter for upkeep at index %d", i)
- l.Info().Int("Upkeep Index", i).Int64("Upkeeps Performed", countersAfterPause[i].Int64()).Msg("Paused Upkeep")
+ l.Info().Int64("Upkeep Count", countersAfterSetNoMatch[i].Int64()).Int("Upkeep Index", i).Msg("Upkeep")
}
+ l.Info().Msg("Making sure the counter stays consistent")
gom.Consistently(func(g gomega.Gomega) {
for i := 0; i < len(upkeepIDs); i++ {
- // In most cases counters should remain constant, but there might be a straggling perform tx which
- // gets committed later and increases counter by 1
+ // Expect the counter to remain constant (At most increase by 2 to account for stale performs) because the upkeep trigger config is not met
+ bufferCount := int64(2)
latestCounter, err := consumers[i].Counter(context.Background())
g.Expect(err).ShouldNot(gomega.HaveOccurred(), "Failed to retrieve consumer counter for upkeep at index %d", i)
- g.Expect(latestCounter.Int64()).Should(gomega.BeNumerically("<=", countersAfterPause[i].Int64()+1),
- "Expected consumer counter not have increased more than %d, but got %d",
- countersAfterPause[i].Int64()+1, latestCounter.Int64())
+ g.Expect(latestCounter.Int64()).Should(gomega.BeNumerically("<=", countersAfterSetNoMatch[i].Int64()+bufferCount),
+ "Expected consumer counter to remain less than or equal to %d, but got %d",
+ countersAfterSetNoMatch[i].Int64()+bufferCount, latestCounter.Int64())
}
}, "1m", "1s").Should(gomega.Succeed())
- // unpause all the registered upkeeps via the registry
- for i := 0; i < len(upkeepIDs); i++ {
- err := registry.UnpauseUpkeep(upkeepIDs[i])
- require.NoError(t, err, "Could not unpause upkeep at index %d", i)
+ // Update the trigger config, so upkeeps start performing again
+ for i := 0; i < len(consumers); i++ {
+ upkeepAddr := consumers[i].Address()
+
+ logTriggerConfigStruct := automation_utils_2_1.LogTriggerConfig{
+ ContractAddress: common.HexToAddress(upkeepAddr),
+ FilterSelector: 0,
+ Topic0: topic0InBytesMatch,
+ Topic1: bytes0,
+ Topic2: bytes0,
+ Topic3: bytes0,
+ }
+ encodedLogTriggerConfig, err := utilsABI.Methods["_logTriggerConfig"].Inputs.Pack(&logTriggerConfigStruct)
+ if err != nil {
+ return
+ }
+
+ err = registry.SetUpkeepTriggerConfig(upkeepIDs[i], encodedLogTriggerConfig)
+ require.NoError(t, err, "Could not set upkeep trigger config at index %d", i)
}
err = chainClient.WaitForEvents()
- require.NoError(t, err, "Error waiting for upkeeps to be unpaused")
+ require.NoError(t, err, "Error encountered when waiting for setting trigger config for upkeeps")
+
+ var countersAfterSetMatch = make([]*big.Int, len(upkeepIDs))
+
+ for i := 0; i < len(upkeepIDs); i++ {
+ // Obtain the amount of times the upkeep has been executed so far
+ countersAfterSetMatch[i], err = consumers[i].Counter(context.Background())
+ require.NoError(t, err, "Failed to retrieve consumer counter for upkeep at index %d", i)
+ l.Info().Int64("Upkeep Count", countersAfterSetMatch[i].Int64()).Int("Upkeep Index", i).Msg("Upkeep")
+ }
+ // Wait for 30 seconds to make sure backend is ready
+ time.Sleep(30 * time.Second)
+ // Start the consumers again
+ for i := 0; i < len(consumers); i++ {
+ err := consumers[i].Start()
+ if err != nil {
+ return
+ }
+ }
+
+ l.Info().Msg("Making sure the counter starts increasing again")
gom.Eventually(func(g gomega.Gomega) {
- // Check if the upkeeps are performing multiple times by analysing their counters and checking they are greater than 5 + numbers of performing before pause
+ // Check if the upkeeps are performing multiple times by analyzing their counters
for i := 0; i < len(upkeepIDs); i++ {
counter, err := consumers[i].Counter(context.Background())
- g.Expect(err).ShouldNot(gomega.HaveOccurred(), "Failed to retrieve consumer counter for upkeep at index %d", i)
- g.Expect(counter.Int64()).Should(gomega.BeNumerically(">", countersAfterPause[i].Int64()+1),
- "Expected consumer counter to be greater than %d, but got %d", countersAfterPause[i].Int64()+1, counter.Int64())
- l.Info().Int64("Upkeep counter", counter.Int64()).Msg("Number of upkeeps performed")
+ require.NoError(t, err, "Failed to retrieve consumer counter for upkeep at index %d", i)
+ expect := int64(5)
+ l.Info().Int64("Upkeeps Performed", counter.Int64()).Int("Upkeep Index", i).Msg("Number of upkeeps performed")
+ g.Expect(counter.Int64()).Should(gomega.BeNumerically(">=", countersAfterSetMatch[i].Int64()+expect),
+ "Expected consumer counter to be greater than %d, but got %d", countersAfterSetMatch[i].Int64()+expect, counter.Int64())
}
- }, "2m", "1s").Should(gomega.Succeed()) // ~1m to perform, 1m buffer
+ }, "5m", "1s").Should(gomega.Succeed()) // ~1m for cluster setup, ~2m for performing each upkeep 5 times, ~2m buffer
+}
+
+func TestAutomationAddFunds(t *testing.T) {
+ t.Parallel()
+ registryVersions := map[string]ethereum.KeeperRegistryVersion{
+ "registry_2_0": ethereum.RegistryVersion_2_0,
+ "registry_2_1": ethereum.RegistryVersion_2_1,
+ }
+
+ for n, rv := range registryVersions {
+ name := n
+ registryVersion := rv
+ t.Run(name, func(t *testing.T) {
+ t.Parallel()
+ chainClient, _, contractDeployer, linkToken, registry, registrar, _ := setupAutomationTestDocker(
+ t, "add-funds", registryVersion, defaultOCRRegistryConfig, false,
+ )
+
+ consumers, upkeepIDs := actions.DeployConsumers(t, registry, registrar, linkToken, contractDeployer, chainClient, defaultAmountOfUpkeeps, big.NewInt(1), automationDefaultUpkeepGasLimit, false)
+
+ gom := gomega.NewGomegaWithT(t)
+ // Since the upkeep is currently underfunded, check that it doesn't get executed
+ gom.Consistently(func(g gomega.Gomega) {
+ counter, err := consumers[0].Counter(context.Background())
+ g.Expect(err).ShouldNot(gomega.HaveOccurred(), "Calling consumer's counter shouldn't fail")
+ g.Expect(counter.Int64()).Should(gomega.Equal(int64(0)),
+ "Expected consumer counter to remain zero, but got %d", counter.Int64())
+ }, "2m", "1s").Should(gomega.Succeed()) // ~1m for setup, 1m assertion
+
+ // Grant permission to the registry to fund the upkeep
+ err := linkToken.Approve(registry.Address(), big.NewInt(9e18))
+ require.NoError(t, err, "Could not approve permissions for the registry on the link token contract")
+ err = chainClient.WaitForEvents()
+ require.NoError(t, err, "Error waiting for events")
+
+ // Add funds to the upkeep whose ID we know from above
+ err = registry.AddUpkeepFunds(upkeepIDs[0], big.NewInt(9e18))
+ require.NoError(t, err, "Unable to add upkeep")
+ err = chainClient.WaitForEvents()
+ require.NoError(t, err, "Error waiting for events")
+
+ // Now the new upkeep should be performing because we added enough funds
+ gom.Eventually(func(g gomega.Gomega) {
+ counter, err := consumers[0].Counter(context.Background())
+ g.Expect(err).ShouldNot(gomega.HaveOccurred(), "Calling consumer's counter shouldn't fail")
+ g.Expect(counter.Int64()).Should(gomega.BeNumerically(">", int64(0)),
+ "Expected newly registered upkeep's counter to be greater than 0, but got %d", counter.Int64())
+ }, "2m", "1s").Should(gomega.Succeed()) // ~1m for perform, 1m buffer
+ })
+ }
+}
+
+func TestAutomationPauseUnPause(t *testing.T) {
+ t.Parallel()
+ registryVersions := map[string]ethereum.KeeperRegistryVersion{
+ "registry_2_0": ethereum.RegistryVersion_2_0,
+ "registry_2_1": ethereum.RegistryVersion_2_1,
+ }
+
+ for n, rv := range registryVersions {
+ name := n
+ registryVersion := rv
+ t.Run(name, func(t *testing.T) {
+ t.Parallel()
+ l := logging.GetTestLogger(t)
+ chainClient, _, contractDeployer, linkToken, registry, registrar, _ := setupAutomationTestDocker(
+ t, "pause-unpause", registryVersion, defaultOCRRegistryConfig, false,
+ )
+
+ consumers, upkeepIDs := actions.DeployConsumers(t, registry, registrar, linkToken, contractDeployer, chainClient, defaultAmountOfUpkeeps, big.NewInt(automationDefaultLinkFunds), automationDefaultUpkeepGasLimit, false)
+
+ gom := gomega.NewGomegaWithT(t)
+ gom.Eventually(func(g gomega.Gomega) {
+ // Check if the upkeeps are performing multiple times by analyzing their counters and checking they are greater than 5
+ for i := 0; i < len(upkeepIDs); i++ {
+ counter, err := consumers[i].Counter(context.Background())
+ g.Expect(err).ShouldNot(gomega.HaveOccurred(), "Failed to retrieve consumer counter for upkeep at index %d", i)
+ g.Expect(counter.Int64()).Should(gomega.BeNumerically(">", int64(5)),
+ "Expected consumer counter to be greater than 5, but got %d", counter.Int64())
+ l.Info().Int("Upkeep Index", i).Int64("Upkeep counter", counter.Int64()).Msg("Number of upkeeps performed")
+ }
+ }, "5m", "1s").Should(gomega.Succeed()) // ~1m for cluster setup, ~2m for performing each upkeep 5 times, ~2m buffer
+
+ // pause all the registered upkeeps via the registry
+ for i := 0; i < len(upkeepIDs); i++ {
+ err := registry.PauseUpkeep(upkeepIDs[i])
+ require.NoError(t, err, "Could not pause upkeep at index %d", i)
+ }
+
+ err := chainClient.WaitForEvents()
+ require.NoError(t, err, "Error waiting for upkeeps to be paused")
+
+ var countersAfterPause = make([]*big.Int, len(upkeepIDs))
+ for i := 0; i < len(upkeepIDs); i++ {
+ // Obtain the amount of times the upkeep has been executed so far
+ countersAfterPause[i], err = consumers[i].Counter(context.Background())
+ require.NoError(t, err, "Failed to retrieve consumer counter for upkeep at index %d", i)
+ l.Info().Int("Upkeep Index", i).Int64("Upkeeps Performed", countersAfterPause[i].Int64()).Msg("Paused Upkeep")
+ }
+
+ gom.Consistently(func(g gomega.Gomega) {
+ for i := 0; i < len(upkeepIDs); i++ {
+ // In most cases counters should remain constant, but there might be a straggling perform tx which
+ // gets committed later and increases counter by 1
+ latestCounter, err := consumers[i].Counter(context.Background())
+ g.Expect(err).ShouldNot(gomega.HaveOccurred(), "Failed to retrieve consumer counter for upkeep at index %d", i)
+ g.Expect(latestCounter.Int64()).Should(gomega.BeNumerically("<=", countersAfterPause[i].Int64()+1),
+ "Expected consumer counter not have increased more than %d, but got %d",
+ countersAfterPause[i].Int64()+1, latestCounter.Int64())
+ }
+ }, "1m", "1s").Should(gomega.Succeed())
+
+ // unpause all the registered upkeeps via the registry
+ for i := 0; i < len(upkeepIDs); i++ {
+ err := registry.UnpauseUpkeep(upkeepIDs[i])
+ require.NoError(t, err, "Could not unpause upkeep at index %d", i)
+ }
+
+ err = chainClient.WaitForEvents()
+ require.NoError(t, err, "Error waiting for upkeeps to be unpaused")
+
+ gom.Eventually(func(g gomega.Gomega) {
+ // Check if the upkeeps are performing multiple times by analysing their counters and checking they are greater than 5 + numbers of performing before pause
+ for i := 0; i < len(upkeepIDs); i++ {
+ counter, err := consumers[i].Counter(context.Background())
+ g.Expect(err).ShouldNot(gomega.HaveOccurred(), "Failed to retrieve consumer counter for upkeep at index %d", i)
+ g.Expect(counter.Int64()).Should(gomega.BeNumerically(">", countersAfterPause[i].Int64()+1),
+ "Expected consumer counter to be greater than %d, but got %d", countersAfterPause[i].Int64()+1, counter.Int64())
+ l.Info().Int64("Upkeep counter", counter.Int64()).Msg("Number of upkeeps performed")
+ }
+ }, "2m", "1s").Should(gomega.Succeed()) // ~1m to perform, 1m buffer
+ })
+ }
}
func TestAutomationRegisterUpkeep(t *testing.T) {
t.Parallel()
- l := utils.GetTestLogger(t)
- chainClient, _, contractDeployer, linkToken, registry, registrar, onlyStartRunner, _ := setupAutomationTest(
- t, "register-upkeep", ethereum.RegistryVersion_2_0, defaultOCRRegistryConfig, false,
- )
- if onlyStartRunner {
- return
+ registryVersions := map[string]ethereum.KeeperRegistryVersion{
+ "registry_2_0": ethereum.RegistryVersion_2_0,
+ "registry_2_1": ethereum.RegistryVersion_2_1,
}
- consumers, upkeepIDs := actions.DeployConsumers(t, registry, registrar, linkToken, contractDeployer, chainClient, defaultAmountOfUpkeeps, big.NewInt(automationDefaultLinkFunds), automationDefaultUpkeepGasLimit, false)
+ for n, rv := range registryVersions {
+ name := n
+ registryVersion := rv
+ t.Run(name, func(t *testing.T) {
+ t.Parallel()
+ l := logging.GetTestLogger(t)
+ chainClient, _, contractDeployer, linkToken, registry, registrar, _ := setupAutomationTestDocker(
+ t, "register-upkeep", registryVersion, defaultOCRRegistryConfig, false,
+ )
- var initialCounters = make([]*big.Int, len(upkeepIDs))
- gom := gomega.NewGomegaWithT(t)
- // Observe that the upkeeps which are initially registered are performing and
- // store the value of their initial counters in order to compare later on that the value increased.
- gom.Eventually(func(g gomega.Gomega) {
- for i := 0; i < len(upkeepIDs); i++ {
- counter, err := consumers[i].Counter(context.Background())
- initialCounters[i] = counter
- g.Expect(err).ShouldNot(gomega.HaveOccurred(), "Failed to retrieve consumer counter for upkeep at index %d", i)
- g.Expect(counter.Int64()).Should(gomega.BeNumerically(">", int64(0)),
- "Expected consumer counter to be greater than 0, but got %d", counter.Int64())
- l.Info().
- Int64("Upkeep counter", counter.Int64()).
- Int64("Upkeep ID", int64(i)).
- Msg("Number of upkeeps performed")
- }
- }, "4m", "1s").Should(gomega.Succeed()) // ~1m for cluster setup, ~1m for performing each upkeep once, ~2m buffer
+ consumers, upkeepIDs := actions.DeployConsumers(t, registry, registrar, linkToken, contractDeployer, chainClient, defaultAmountOfUpkeeps, big.NewInt(automationDefaultLinkFunds), automationDefaultUpkeepGasLimit, false)
- newConsumers, _ := actions.RegisterNewUpkeeps(t, contractDeployer, chainClient, linkToken,
- registry, registrar, automationDefaultUpkeepGasLimit, 1)
+ var initialCounters = make([]*big.Int, len(upkeepIDs))
+ gom := gomega.NewGomegaWithT(t)
+ // Observe that the upkeeps which are initially registered are performing and
+ // store the value of their initial counters in order to compare later on that the value increased.
+ gom.Eventually(func(g gomega.Gomega) {
+ for i := 0; i < len(upkeepIDs); i++ {
+ counter, err := consumers[i].Counter(context.Background())
+ initialCounters[i] = counter
+ g.Expect(err).ShouldNot(gomega.HaveOccurred(), "Failed to retrieve consumer counter for upkeep at index %d", i)
+ g.Expect(counter.Int64()).Should(gomega.BeNumerically(">", int64(0)),
+ "Expected consumer counter to be greater than 0, but got %d", counter.Int64())
+ l.Info().
+ Int64("Upkeep counter", counter.Int64()).
+ Int64("Upkeep ID", int64(i)).
+ Msg("Number of upkeeps performed")
+ }
+ }, "4m", "1s").Should(gomega.Succeed()) // ~1m for cluster setup, ~1m for performing each upkeep once, ~2m buffer
- // We know that newConsumers has size 1, so we can just use the newly registered upkeep.
- newUpkeep := newConsumers[0]
+ newConsumers, _ := actions.RegisterNewUpkeeps(t, contractDeployer, chainClient, linkToken,
+ registry, registrar, automationDefaultUpkeepGasLimit, 1)
- // Test that the newly registered upkeep is also performing.
- gom.Eventually(func(g gomega.Gomega) {
- counter, err := newUpkeep.Counter(context.Background())
- g.Expect(err).ShouldNot(gomega.HaveOccurred(), "Calling newly deployed upkeep's counter shouldn't fail")
- g.Expect(counter.Int64()).Should(gomega.BeNumerically(">", int64(0)),
- "Expected newly registered upkeep's counter to be greater than 0, but got %d", counter.Int64())
- l.Info().Int64("Upkeeps Performed", counter.Int64()).Msg("Newly Registered Upkeep")
- }, "2m", "1s").Should(gomega.Succeed()) // ~1m for upkeep to perform, 1m buffer
+ // We know that newConsumers has size 1, so we can just use the newly registered upkeep.
+ newUpkeep := newConsumers[0]
- gom.Eventually(func(g gomega.Gomega) {
- for i := 0; i < len(upkeepIDs); i++ {
- currentCounter, err := consumers[i].Counter(context.Background())
- g.Expect(err).ShouldNot(gomega.HaveOccurred(), "Calling consumer's counter shouldn't fail")
-
- l.Info().
- Int64("Upkeep ID", int64(i)).
- Int64("Upkeep counter", currentCounter.Int64()).
- Int64("initial counter", initialCounters[i].Int64()).
- Msg("Number of upkeeps performed")
-
- g.Expect(currentCounter.Int64()).Should(gomega.BeNumerically(">", initialCounters[i].Int64()),
- "Expected counter to have increased from initial value of %s, but got %s",
- initialCounters[i], currentCounter)
- }
- }, "2m", "1s").Should(gomega.Succeed()) // ~1m for upkeeps to perform, 1m buffer
+ // Test that the newly registered upkeep is also performing.
+ gom.Eventually(func(g gomega.Gomega) {
+ counter, err := newUpkeep.Counter(context.Background())
+ g.Expect(err).ShouldNot(gomega.HaveOccurred(), "Calling newly deployed upkeep's counter shouldn't fail")
+ g.Expect(counter.Int64()).Should(gomega.BeNumerically(">", int64(0)),
+ "Expected newly registered upkeep's counter to be greater than 0, but got %d", counter.Int64())
+ l.Info().Int64("Upkeeps Performed", counter.Int64()).Msg("Newly Registered Upkeep")
+ }, "2m", "1s").Should(gomega.Succeed()) // ~1m for upkeep to perform, 1m buffer
+
+ gom.Eventually(func(g gomega.Gomega) {
+ for i := 0; i < len(upkeepIDs); i++ {
+ currentCounter, err := consumers[i].Counter(context.Background())
+ g.Expect(err).ShouldNot(gomega.HaveOccurred(), "Calling consumer's counter shouldn't fail")
+
+ l.Info().
+ Int64("Upkeep ID", int64(i)).
+ Int64("Upkeep counter", currentCounter.Int64()).
+ Int64("initial counter", initialCounters[i].Int64()).
+ Msg("Number of upkeeps performed")
+
+ g.Expect(currentCounter.Int64()).Should(gomega.BeNumerically(">", initialCounters[i].Int64()),
+ "Expected counter to have increased from initial value of %s, but got %s",
+ initialCounters[i], currentCounter)
+ }
+ }, "2m", "1s").Should(gomega.Succeed()) // ~1m for upkeeps to perform, 1m buffer
+ })
+ }
}
func TestAutomationPauseRegistry(t *testing.T) {
t.Parallel()
-
- chainClient, _, contractDeployer, linkToken, registry, registrar, onlyStartRunner, _ := setupAutomationTest(
- t, "pause-registry", ethereum.RegistryVersion_2_0, defaultOCRRegistryConfig, false,
- )
- if onlyStartRunner {
- return
+ registryVersions := map[string]ethereum.KeeperRegistryVersion{
+ "registry_2_0": ethereum.RegistryVersion_2_0,
+ "registry_2_1": ethereum.RegistryVersion_2_1,
}
- consumers, upkeepIDs := actions.DeployConsumers(t, registry, registrar, linkToken, contractDeployer, chainClient, defaultAmountOfUpkeeps, big.NewInt(automationDefaultLinkFunds), automationDefaultUpkeepGasLimit, false)
- gom := gomega.NewGomegaWithT(t)
+ for n, rv := range registryVersions {
+ name := n
+ registryVersion := rv
+ t.Run(name, func(t *testing.T) {
+ t.Parallel()
+ chainClient, _, contractDeployer, linkToken, registry, registrar, _ := setupAutomationTestDocker(
+ t, "pause-registry", registryVersion, defaultOCRRegistryConfig, false,
+ )
- // Observe that the upkeeps which are initially registered are performing
- gom.Eventually(func(g gomega.Gomega) {
- for i := 0; i < len(upkeepIDs); i++ {
- counter, err := consumers[i].Counter(context.Background())
- g.Expect(err).ShouldNot(gomega.HaveOccurred(), "Failed to retrieve consumer counter for upkeep at index %d", i)
- g.Expect(counter.Int64()).Should(gomega.BeNumerically(">", int64(0)),
- "Expected consumer counter to be greater than 0, but got %d")
- }
- }, "4m", "1s").Should(gomega.Succeed()) // ~1m for cluster setup, ~1m for performing each upkeep once, ~2m buffer
+ consumers, upkeepIDs := actions.DeployConsumers(t, registry, registrar, linkToken, contractDeployer, chainClient, defaultAmountOfUpkeeps, big.NewInt(automationDefaultLinkFunds), automationDefaultUpkeepGasLimit, false)
+ gom := gomega.NewGomegaWithT(t)
- // Pause the registry
- err := registry.Pause()
- require.NoError(t, err, "Error pausing registry")
- err = chainClient.WaitForEvents()
- require.NoError(t, err, "Error waiting for registry to pause")
+ // Observe that the upkeeps which are initially registered are performing
+ gom.Eventually(func(g gomega.Gomega) {
+ for i := 0; i < len(upkeepIDs); i++ {
+ counter, err := consumers[i].Counter(context.Background())
+ g.Expect(err).ShouldNot(gomega.HaveOccurred(), "Failed to retrieve consumer counter for upkeep at index %d", i)
+ g.Expect(counter.Int64()).Should(gomega.BeNumerically(">", int64(0)),
+ "Expected consumer counter to be greater than 0, but got %d")
+ }
+ }, "4m", "1s").Should(gomega.Succeed()) // ~1m for cluster setup, ~1m for performing each upkeep once, ~2m buffer
- // Store how many times each upkeep performed once the registry was successfully paused
- var countersAfterPause = make([]*big.Int, len(upkeepIDs))
- for i := 0; i < len(upkeepIDs); i++ {
- countersAfterPause[i], err = consumers[i].Counter(context.Background())
- require.NoError(t, err, "Failed to retrieve consumer counter for upkeep at index %d", i)
- }
+ // Pause the registry
+ err := registry.Pause()
+ require.NoError(t, err, "Error pausing registry")
+ err = chainClient.WaitForEvents()
+ require.NoError(t, err, "Error waiting for registry to pause")
- // After we paused the registry, the counters of all the upkeeps should stay constant
- // because they are no longer getting serviced
- gom.Consistently(func(g gomega.Gomega) {
- for i := 0; i < len(upkeepIDs); i++ {
- latestCounter, err := consumers[i].Counter(context.Background())
- g.Expect(err).ShouldNot(gomega.HaveOccurred(), "Failed to retrieve consumer counter for upkeep at index %d", i)
- g.Expect(latestCounter.Int64()).Should(gomega.Equal(countersAfterPause[i].Int64()),
- "Expected consumer counter to remain constant at %d, but got %d",
- countersAfterPause[i].Int64(), latestCounter.Int64())
- }
- }, "1m", "1s").Should(gomega.Succeed())
+ // Store how many times each upkeep performed once the registry was successfully paused
+ var countersAfterPause = make([]*big.Int, len(upkeepIDs))
+ for i := 0; i < len(upkeepIDs); i++ {
+ countersAfterPause[i], err = consumers[i].Counter(context.Background())
+ require.NoError(t, err, "Failed to retrieve consumer counter for upkeep at index %d", i)
+ }
+
+ // After we paused the registry, the counters of all the upkeeps should stay constant
+ // because they are no longer getting serviced
+ gom.Consistently(func(g gomega.Gomega) {
+ for i := 0; i < len(upkeepIDs); i++ {
+ latestCounter, err := consumers[i].Counter(context.Background())
+ g.Expect(err).ShouldNot(gomega.HaveOccurred(), "Failed to retrieve consumer counter for upkeep at index %d", i)
+ g.Expect(latestCounter.Int64()).Should(gomega.Equal(countersAfterPause[i].Int64()),
+ "Expected consumer counter to remain constant at %d, but got %d",
+ countersAfterPause[i].Int64(), latestCounter.Int64())
+ }
+ }, "1m", "1s").Should(gomega.Succeed())
+ })
+ }
}
func TestAutomationKeeperNodesDown(t *testing.T) {
t.Parallel()
- l := utils.GetTestLogger(t)
- chainClient, chainlinkNodes, contractDeployer, linkToken, registry, registrar, onlyStartRunner, _ := setupAutomationTest(
- t, "keeper-nodes-down", ethereum.RegistryVersion_2_0, defaultOCRRegistryConfig, false,
- )
- if onlyStartRunner {
- return
+ registryVersions := map[string]ethereum.KeeperRegistryVersion{
+ "registry_2_0": ethereum.RegistryVersion_2_0,
+ "registry_2_1": ethereum.RegistryVersion_2_1,
}
- consumers, upkeepIDs := actions.DeployConsumers(t, registry, registrar, linkToken, contractDeployer, chainClient, defaultAmountOfUpkeeps, big.NewInt(automationDefaultLinkFunds), automationDefaultUpkeepGasLimit, false)
- gom := gomega.NewGomegaWithT(t)
- nodesWithoutBootstrap := chainlinkNodes[1:]
+ for n, rv := range registryVersions {
+ name := n
+ registryVersion := rv
+ t.Run(name, func(t *testing.T) {
+ t.Parallel()
+ l := logging.GetTestLogger(t)
+ chainClient, chainlinkNodes, contractDeployer, linkToken, registry, registrar, _ := setupAutomationTestDocker(
+ t, "keeper-nodes-down", registryVersion, defaultOCRRegistryConfig, false,
+ )
- var initialCounters = make([]*big.Int, len(upkeepIDs))
+ consumers, upkeepIDs := actions.DeployConsumers(t, registry, registrar, linkToken, contractDeployer, chainClient, defaultAmountOfUpkeeps, big.NewInt(automationDefaultLinkFunds), automationDefaultUpkeepGasLimit, false)
+ gom := gomega.NewGomegaWithT(t)
+ nodesWithoutBootstrap := chainlinkNodes[1:]
- // Watch upkeeps being performed and store their counters in order to compare them later in the test
- gom.Eventually(func(g gomega.Gomega) {
- for i := 0; i < len(upkeepIDs); i++ {
- counter, err := consumers[i].Counter(context.Background())
- initialCounters[i] = counter
- g.Expect(err).ShouldNot(gomega.HaveOccurred(), "Failed to retrieve consumer counter for upkeep at index %d", i)
- g.Expect(counter.Int64()).Should(gomega.BeNumerically(">", int64(0)),
- "Expected consumer counter to be greater than 0, but got %d", counter.Int64())
- }
- }, "4m", "1s").Should(gomega.Succeed()) // ~1m for cluster setup, ~1m for performing each upkeep once, ~2m buffer
+ var initialCounters = make([]*big.Int, len(upkeepIDs))
- // Take down 1 node. Currently, using 4 nodes so f=1 and is the max nodes that can go down.
- err := nodesWithoutBootstrap[0].MustDeleteJob("1")
- require.NoError(t, err, "Error deleting job from Chainlink node")
- err = chainClient.WaitForEvents()
- require.NoError(t, err, "Error waiting for blockchain events")
+ // Watch upkeeps being performed and store their counters in order to compare them later in the test
+ gom.Eventually(func(g gomega.Gomega) {
+ for i := 0; i < len(upkeepIDs); i++ {
+ counter, err := consumers[i].Counter(context.Background())
+ initialCounters[i] = counter
+ g.Expect(err).ShouldNot(gomega.HaveOccurred(), "Failed to retrieve consumer counter for upkeep at index %d", i)
+ g.Expect(counter.Int64()).Should(gomega.BeNumerically(">", int64(0)),
+ "Expected consumer counter to be greater than 0, but got %d", counter.Int64())
+ }
+ }, "4m", "1s").Should(gomega.Succeed()) // ~1m for cluster setup, ~1m for performing each upkeep once, ~2m buffer
- l.Info().Msg("Successfully managed to take down the first half of the nodes")
+ // Take down 1 node. Currently, using 4 nodes so f=1 and is the max nodes that can go down.
+ err := nodesWithoutBootstrap[0].MustDeleteJob("1")
+ require.NoError(t, err, "Error deleting job from Chainlink node")
+ err = chainClient.WaitForEvents()
+ require.NoError(t, err, "Error waiting for blockchain events")
- // Assert that upkeeps are still performed and their counters have increased
- gom.Eventually(func(g gomega.Gomega) {
- for i := 0; i < len(upkeepIDs); i++ {
- currentCounter, err := consumers[i].Counter(context.Background())
- g.Expect(err).ShouldNot(gomega.HaveOccurred(), "Failed to retrieve consumer counter for upkeep at index %d", i)
- g.Expect(currentCounter.Int64()).Should(gomega.BeNumerically(">", initialCounters[i].Int64()),
- "Expected counter to have increased from initial value of %s, but got %s",
- initialCounters[i], currentCounter)
- }
- }, "2m", "1s").Should(gomega.Succeed()) // ~1m for each upkeep to perform once, 1m buffer
-
- // Take down the rest
- restOfNodesDown := nodesWithoutBootstrap[1:]
- for _, nodeToTakeDown := range restOfNodesDown {
- err = nodeToTakeDown.MustDeleteJob("1")
- require.NoError(t, err, "Error deleting job from Chainlink node")
- err = chainClient.WaitForEvents()
- require.NoError(t, err, "Error waiting for blockchain events")
- }
- l.Info().Msg("Successfully managed to take down the second half of the nodes")
+ l.Info().Msg("Successfully managed to take down the first half of the nodes")
- // See how many times each upkeep was executed
- var countersAfterNoMoreNodes = make([]*big.Int, len(upkeepIDs))
- for i := 0; i < len(upkeepIDs); i++ {
- countersAfterNoMoreNodes[i], err = consumers[i].Counter(context.Background())
- require.NoError(t, err, "Failed to retrieve consumer counter for upkeep at index %d", i)
- l.Info().Int("Upkeep Index", i).Int64("Performed", countersAfterNoMoreNodes[i].Int64()).Msg("Upkeeps Performed")
- }
+ // Assert that upkeeps are still performed and their counters have increased
+ gom.Eventually(func(g gomega.Gomega) {
+ for i := 0; i < len(upkeepIDs); i++ {
+ currentCounter, err := consumers[i].Counter(context.Background())
+ g.Expect(err).ShouldNot(gomega.HaveOccurred(), "Failed to retrieve consumer counter for upkeep at index %d", i)
+ g.Expect(currentCounter.Int64()).Should(gomega.BeNumerically(">", initialCounters[i].Int64()),
+ "Expected counter to have increased from initial value of %s, but got %s",
+ initialCounters[i], currentCounter)
+ }
+ }, "2m", "1s").Should(gomega.Succeed()) // ~1m for each upkeep to perform once, 1m buffer
+
+ // Take down the rest
+ restOfNodesDown := nodesWithoutBootstrap[1:]
+ for _, nodeToTakeDown := range restOfNodesDown {
+ err = nodeToTakeDown.MustDeleteJob("1")
+ require.NoError(t, err, "Error deleting job from Chainlink node")
+ err = chainClient.WaitForEvents()
+ require.NoError(t, err, "Error waiting for blockchain events")
+ }
+ l.Info().Msg("Successfully managed to take down the second half of the nodes")
- // Once all the nodes are taken down, there might be some straggling transactions which went through before
- // all the nodes were taken down
- gom.Consistently(func(g gomega.Gomega) {
- for i := 0; i < len(upkeepIDs); i++ {
- latestCounter, err := consumers[i].Counter(context.Background())
- g.Expect(err).ShouldNot(gomega.HaveOccurred(), "Failed to retrieve consumer counter for upkeep at index %d", i)
- g.Expect(latestCounter.Int64()).Should(gomega.BeNumerically("<=", countersAfterNoMoreNodes[i].Int64()+1),
- "Expected consumer counter to not have increased more than %d, but got %d",
- countersAfterNoMoreNodes[i].Int64()+1, latestCounter.Int64())
- }
- }, "2m", "1s").Should(gomega.Succeed())
+ // See how many times each upkeep was executed
+ var countersAfterNoMoreNodes = make([]*big.Int, len(upkeepIDs))
+ for i := 0; i < len(upkeepIDs); i++ {
+ countersAfterNoMoreNodes[i], err = consumers[i].Counter(context.Background())
+ require.NoError(t, err, "Failed to retrieve consumer counter for upkeep at index %d", i)
+ l.Info().Int("Upkeep Index", i).Int64("Performed", countersAfterNoMoreNodes[i].Int64()).Msg("Upkeeps Performed")
+ }
+
+ // Once all the nodes are taken down, there might be some straggling transactions which went through before
+ // all the nodes were taken down
+ gom.Consistently(func(g gomega.Gomega) {
+ for i := 0; i < len(upkeepIDs); i++ {
+ latestCounter, err := consumers[i].Counter(context.Background())
+ g.Expect(err).ShouldNot(gomega.HaveOccurred(), "Failed to retrieve consumer counter for upkeep at index %d", i)
+ g.Expect(latestCounter.Int64()).Should(gomega.BeNumerically("<=", countersAfterNoMoreNodes[i].Int64()+1),
+ "Expected consumer counter to not have increased more than %d, but got %d",
+ countersAfterNoMoreNodes[i].Int64()+1, latestCounter.Int64())
+ }
+ }, "2m", "1s").Should(gomega.Succeed())
+ })
+ }
}
func TestAutomationPerformSimulation(t *testing.T) {
t.Parallel()
-
- chainClient, _, contractDeployer, linkToken, registry, registrar, onlyStartRunner, _ := setupAutomationTest(
- t, "perform-simulation", ethereum.RegistryVersion_2_0, defaultOCRRegistryConfig, false,
- )
- if onlyStartRunner {
- return
+ registryVersions := map[string]ethereum.KeeperRegistryVersion{
+ "registry_2_0": ethereum.RegistryVersion_2_0,
+ "registry_2_1": ethereum.RegistryVersion_2_1,
}
- consumersPerformance, _ := actions.DeployPerformanceConsumers(
- t,
- registry,
- registrar,
- linkToken,
- contractDeployer,
- chainClient,
- defaultAmountOfUpkeeps,
- big.NewInt(automationDefaultLinkFunds),
- automationDefaultUpkeepGasLimit,
- 10000, // How many blocks this upkeep will be eligible from first upkeep block
- 5, // Interval of blocks that upkeeps are expected to be performed
- 100000, // How much gas should be burned on checkUpkeep() calls
- 4000000, // How much gas should be burned on performUpkeep() calls. Initially set higher than defaultUpkeepGasLimit
- )
- gom := gomega.NewGomegaWithT(t)
+ for n, rv := range registryVersions {
+ name := n
+ registryVersion := rv
+ t.Run(name, func(t *testing.T) {
+ t.Parallel()
+ chainClient, _, contractDeployer, linkToken, registry, registrar, _ := setupAutomationTestDocker(
+ t, "perform-simulation", registryVersion, defaultOCRRegistryConfig, false,
+ )
+
+ consumersPerformance, _ := actions.DeployPerformanceConsumers(
+ t,
+ registry,
+ registrar,
+ linkToken,
+ contractDeployer,
+ chainClient,
+ defaultAmountOfUpkeeps,
+ big.NewInt(automationDefaultLinkFunds),
+ automationDefaultUpkeepGasLimit,
+ 10000, // How many blocks this upkeep will be eligible from first upkeep block
+ 5, // Interval of blocks that upkeeps are expected to be performed
+ 100000, // How much gas should be burned on checkUpkeep() calls
+ 4000000, // How much gas should be burned on performUpkeep() calls. Initially set higher than defaultUpkeepGasLimit
+ )
+ gom := gomega.NewGomegaWithT(t)
- consumerPerformance := consumersPerformance[0]
+ consumerPerformance := consumersPerformance[0]
- // Initially performGas is set high, so performUpkeep reverts and no upkeep should be performed
- gom.Consistently(func(g gomega.Gomega) {
- // Consumer count should remain at 0
- cnt, err := consumerPerformance.GetUpkeepCount(context.Background())
- g.Expect(err).ShouldNot(gomega.HaveOccurred(), "Calling consumer's Counter shouldn't fail")
- g.Expect(cnt.Int64()).Should(gomega.Equal(int64(0)),
- "Expected consumer counter to remain constant at %d, but got %d", 0, cnt.Int64(),
- )
- }, "2m", "1s").Should(gomega.Succeed()) // ~1m for setup, 1m assertion
-
- // Set performGas on consumer to be low, so that performUpkeep starts becoming successful
- err := consumerPerformance.SetPerformGasToBurn(context.Background(), big.NewInt(100000))
- require.NoError(t, err, "Perform gas should be set successfully on consumer")
- err = chainClient.WaitForEvents()
- require.NoError(t, err, "Error waiting for set perform gas tx")
+ // Initially performGas is set high, so performUpkeep reverts and no upkeep should be performed
+ gom.Consistently(func(g gomega.Gomega) {
+ // Consumer count should remain at 0
+ cnt, err := consumerPerformance.GetUpkeepCount(context.Background())
+ g.Expect(err).ShouldNot(gomega.HaveOccurred(), "Calling consumer's Counter shouldn't fail")
+ g.Expect(cnt.Int64()).Should(gomega.Equal(int64(0)),
+ "Expected consumer counter to remain constant at %d, but got %d", 0, cnt.Int64(),
+ )
+ }, "2m", "1s").Should(gomega.Succeed()) // ~1m for setup, 1m assertion
+
+ // Set performGas on consumer to be low, so that performUpkeep starts becoming successful
+ err := consumerPerformance.SetPerformGasToBurn(context.Background(), big.NewInt(100000))
+ require.NoError(t, err, "Perform gas should be set successfully on consumer")
+ err = chainClient.WaitForEvents()
+ require.NoError(t, err, "Error waiting for set perform gas tx")
- // Upkeep should now start performing
- gom.Eventually(func(g gomega.Gomega) {
- cnt, err := consumerPerformance.GetUpkeepCount(context.Background())
- g.Expect(err).ShouldNot(gomega.HaveOccurred(), "Calling consumer's Counter shouldn't fail")
- g.Expect(cnt.Int64()).Should(gomega.BeNumerically(">", int64(0)),
- "Expected consumer counter to be greater than 0, but got %d", cnt.Int64(),
- )
- }, "2m", "1s").Should(gomega.Succeed()) // ~1m to perform once, 1m buffer
+ // Upkeep should now start performing
+ gom.Eventually(func(g gomega.Gomega) {
+ cnt, err := consumerPerformance.GetUpkeepCount(context.Background())
+ g.Expect(err).ShouldNot(gomega.HaveOccurred(), "Calling consumer's Counter shouldn't fail")
+ g.Expect(cnt.Int64()).Should(gomega.BeNumerically(">", int64(0)),
+ "Expected consumer counter to be greater than 0, but got %d", cnt.Int64(),
+ )
+ }, "2m", "1s").Should(gomega.Succeed()) // ~1m to perform once, 1m buffer
+ })
+ }
}
func TestAutomationCheckPerformGasLimit(t *testing.T) {
t.Parallel()
- l := utils.GetTestLogger(t)
- chainClient, chainlinkNodes, contractDeployer, linkToken, registry, registrar, onlyStartRunner, _ := setupAutomationTest(
- t, "gas-limit", ethereum.RegistryVersion_2_0, defaultOCRRegistryConfig, false,
- )
- if onlyStartRunner {
- return
+ registryVersions := map[string]ethereum.KeeperRegistryVersion{
+ "registry_2_0": ethereum.RegistryVersion_2_0,
+ "registry_2_1": ethereum.RegistryVersion_2_1,
}
- consumersPerformance, upkeepIDs := actions.DeployPerformanceConsumers(
- t,
- registry,
- registrar,
- linkToken,
- contractDeployer,
- chainClient,
- defaultAmountOfUpkeeps,
- big.NewInt(automationDefaultLinkFunds),
- automationDefaultUpkeepGasLimit,
- 10000, // How many blocks this upkeep will be eligible from first upkeep block
- 5, // Interval of blocks that upkeeps are expected to be performed
- 100000, // How much gas should be burned on checkUpkeep() calls
- 4000000, // How much gas should be burned on performUpkeep() calls. Initially set higher than defaultUpkeepGasLimit
- )
- gom := gomega.NewGomegaWithT(t)
+ for n, rv := range registryVersions {
+ name := n
+ registryVersion := rv
+ t.Run(name, func(t *testing.T) {
+ t.Parallel()
+ l := logging.GetTestLogger(t)
+ chainClient, chainlinkNodes, contractDeployer, linkToken, registry, registrar, _ := setupAutomationTestDocker(
+ t, "gas-limit", registryVersion, defaultOCRRegistryConfig, false,
+ )
- nodesWithoutBootstrap := chainlinkNodes[1:]
- consumerPerformance := consumersPerformance[0]
- upkeepID := upkeepIDs[0]
+ consumersPerformance, upkeepIDs := actions.DeployPerformanceConsumers(
+ t,
+ registry,
+ registrar,
+ linkToken,
+ contractDeployer,
+ chainClient,
+ defaultAmountOfUpkeeps,
+ big.NewInt(automationDefaultLinkFunds),
+ automationDefaultUpkeepGasLimit,
+ 10000, // How many blocks this upkeep will be eligible from first upkeep block
+ 5, // Interval of blocks that upkeeps are expected to be performed
+ 100000, // How much gas should be burned on checkUpkeep() calls
+ 4000000, // How much gas should be burned on performUpkeep() calls. Initially set higher than defaultUpkeepGasLimit
+ )
+ gom := gomega.NewGomegaWithT(t)
- // Initially performGas is set higher than defaultUpkeepGasLimit, so no upkeep should be performed
- gom.Consistently(func(g gomega.Gomega) {
- cnt, err := consumerPerformance.GetUpkeepCount(context.Background())
- g.Expect(err).ShouldNot(gomega.HaveOccurred(), "Calling consumer's counter shouldn't fail")
- g.Expect(cnt.Int64()).Should(
- gomega.Equal(int64(0)),
- "Expected consumer counter to remain constant at %d, but got %d", 0, cnt.Int64(),
- )
- }, "2m", "1s").Should(gomega.Succeed()) // ~1m for setup, 1m assertion
-
- // Increase gas limit for the upkeep, higher than the performGasBurn
- err := registry.SetUpkeepGasLimit(upkeepID, uint32(4500000))
- require.NoError(t, err, "Error setting upkeep gas limit")
- err = chainClient.WaitForEvents()
- require.NoError(t, err, "Error waiting for SetUpkeepGasLimit tx")
+ nodesWithoutBootstrap := chainlinkNodes[1:]
+ consumerPerformance := consumersPerformance[0]
+ upkeepID := upkeepIDs[0]
- // Upkeep should now start performing
- gom.Eventually(func(g gomega.Gomega) {
- cnt, err := consumerPerformance.GetUpkeepCount(context.Background())
- g.Expect(err).ShouldNot(gomega.HaveOccurred(), "Calling consumer's counter shouldn't fail")
- g.Expect(cnt.Int64()).Should(gomega.BeNumerically(">", int64(0)),
- "Expected consumer counter to be greater than 0, but got %d", cnt.Int64(),
- )
- }, "2m", "1s").Should(gomega.Succeed()) // ~1m to perform once, 1m buffer
-
- // Now increase the checkGasBurn on consumer, upkeep should stop performing
- err = consumerPerformance.SetCheckGasToBurn(context.Background(), big.NewInt(3000000))
- require.NoError(t, err, "Check gas burn should be set successfully on consumer")
- err = chainClient.WaitForEvents()
- require.NoError(t, err, "Error waiting for SetCheckGasToBurn tx")
+ // Initially performGas is set higher than defaultUpkeepGasLimit, so no upkeep should be performed
+ gom.Consistently(func(g gomega.Gomega) {
+ cnt, err := consumerPerformance.GetUpkeepCount(context.Background())
+ g.Expect(err).ShouldNot(gomega.HaveOccurred(), "Calling consumer's counter shouldn't fail")
+ g.Expect(cnt.Int64()).Should(
+ gomega.Equal(int64(0)),
+ "Expected consumer counter to remain constant at %d, but got %d", 0, cnt.Int64(),
+ )
+ }, "2m", "1s").Should(gomega.Succeed()) // ~1m for setup, 1m assertion
+
+ // Increase gas limit for the upkeep, higher than the performGasBurn
+ err := registry.SetUpkeepGasLimit(upkeepID, uint32(4500000))
+ require.NoError(t, err, "Error setting upkeep gas limit")
+ err = chainClient.WaitForEvents()
+ require.NoError(t, err, "Error waiting for SetUpkeepGasLimit tx")
- // Get existing performed count
- existingCnt, err := consumerPerformance.GetUpkeepCount(context.Background())
- require.NoError(t, err, "Calling consumer's counter shouldn't fail")
- l.Info().Int64("Upkeep counter", existingCnt.Int64()).Msg("Upkeep counter when check gas increased")
+ // Upkeep should now start performing
+ gom.Eventually(func(g gomega.Gomega) {
+ cnt, err := consumerPerformance.GetUpkeepCount(context.Background())
+ g.Expect(err).ShouldNot(gomega.HaveOccurred(), "Calling consumer's counter shouldn't fail")
+ g.Expect(cnt.Int64()).Should(gomega.BeNumerically(">", int64(0)),
+ "Expected consumer counter to be greater than 0, but got %d", cnt.Int64(),
+ )
+ }, "2m", "1s").Should(gomega.Succeed()) // ~1m to perform once, 1m buffer
+
+ // Now increase the checkGasBurn on consumer, upkeep should stop performing
+ err = consumerPerformance.SetCheckGasToBurn(context.Background(), big.NewInt(3000000))
+ require.NoError(t, err, "Check gas burn should be set successfully on consumer")
+ err = chainClient.WaitForEvents()
+ require.NoError(t, err, "Error waiting for SetCheckGasToBurn tx")
- // In most cases count should remain constant, but it might increase by upto 1 due to pending perform
- gom.Consistently(func(g gomega.Gomega) {
- cnt, err := consumerPerformance.GetUpkeepCount(context.Background())
- g.Expect(err).ShouldNot(gomega.HaveOccurred(), "Calling consumer's counter shouldn't fail")
- g.Expect(cnt.Int64()).Should(
- gomega.BeNumerically("<=", existingCnt.Int64()+1),
- "Expected consumer counter to remain less than equal %d, but got %d", existingCnt.Int64()+1, cnt.Int64(),
- )
- }, "1m", "1s").Should(gomega.Succeed())
+ // Get existing performed count
+ existingCnt, err := consumerPerformance.GetUpkeepCount(context.Background())
+ require.NoError(t, err, "Calling consumer's counter shouldn't fail")
+ l.Info().Int64("Upkeep counter", existingCnt.Int64()).Msg("Upkeep counter when check gas increased")
- existingCnt, err = consumerPerformance.GetUpkeepCount(context.Background())
- require.NoError(t, err, "Calling consumer's counter shouldn't fail")
- existingCntInt := existingCnt.Int64()
- l.Info().Int64("Upkeep counter", existingCntInt).Msg("Upkeep counter when consistently block finished")
-
- // Now increase checkGasLimit on registry
- highCheckGasLimit := automationDefaultRegistryConfig
- highCheckGasLimit.CheckGasLimit = uint32(5000000)
- ocrConfig, err := actions.BuildAutoOCR2ConfigVars(t, nodesWithoutBootstrap, highCheckGasLimit, registrar.Address(), 5*time.Second)
- require.NoError(t, err, "Error building OCR config")
- err = registry.SetConfig(highCheckGasLimit, ocrConfig)
- require.NoError(t, err, "Registry config should be be set successfully")
- err = chainClient.WaitForEvents()
- require.NoError(t, err, "Error waiting for set config tx")
+ // In most cases count should remain constant, but it might increase by upto 1 due to pending perform
+ gom.Consistently(func(g gomega.Gomega) {
+ cnt, err := consumerPerformance.GetUpkeepCount(context.Background())
+ g.Expect(err).ShouldNot(gomega.HaveOccurred(), "Calling consumer's counter shouldn't fail")
+ g.Expect(cnt.Int64()).Should(
+ gomega.BeNumerically("<=", existingCnt.Int64()+1),
+ "Expected consumer counter to remain less than equal %d, but got %d", existingCnt.Int64()+1, cnt.Int64(),
+ )
+ }, "1m", "1s").Should(gomega.Succeed())
- // Upkeep should start performing again, and it should get regularly performed
- gom.Eventually(func(g gomega.Gomega) {
- cnt, err := consumerPerformance.GetUpkeepCount(context.Background())
- g.Expect(err).ShouldNot(gomega.HaveOccurred(), "Calling consumer's Counter shouldn't fail")
- g.Expect(cnt.Int64()).Should(gomega.BeNumerically(">", existingCntInt),
- "Expected consumer counter to be greater than %d, but got %d", existingCntInt, cnt.Int64(),
- )
- }, "3m", "1s").Should(gomega.Succeed()) // ~1m to setup cluster, 1m to perform once, 1m buffer
+ existingCnt, err = consumerPerformance.GetUpkeepCount(context.Background())
+ require.NoError(t, err, "Calling consumer's counter shouldn't fail")
+ existingCntInt := existingCnt.Int64()
+ l.Info().Int64("Upkeep counter", existingCntInt).Msg("Upkeep counter when consistently block finished")
+
+ // Now increase checkGasLimit on registry
+ highCheckGasLimit := automationDefaultRegistryConfig
+ highCheckGasLimit.CheckGasLimit = uint32(5000000)
+ highCheckGasLimit.RegistryVersion = registryVersion
+ ocrConfig, err := actions.BuildAutoOCR2ConfigVarsLocal(l, nodesWithoutBootstrap, highCheckGasLimit, registrar.Address(), 30*time.Second)
+ require.NoError(t, err, "Error building OCR config")
+
+ err = registry.SetConfig(highCheckGasLimit, ocrConfig)
+ require.NoError(t, err, "Registry config should be set successfully!")
+ err = chainClient.WaitForEvents()
+ require.NoError(t, err, "Error waiting for set config tx")
+
+ // Upkeep should start performing again, and it should get regularly performed
+ gom.Eventually(func(g gomega.Gomega) {
+ cnt, err := consumerPerformance.GetUpkeepCount(context.Background())
+ g.Expect(err).ShouldNot(gomega.HaveOccurred(), "Calling consumer's Counter shouldn't fail")
+ g.Expect(cnt.Int64()).Should(gomega.BeNumerically(">", existingCntInt),
+ "Expected consumer counter to be greater than %d, but got %d", existingCntInt, cnt.Int64(),
+ )
+ }, "3m", "1s").Should(gomega.Succeed()) // ~1m to setup cluster, 1m to perform once, 1m buffer
+ })
+ }
}
func TestUpdateCheckData(t *testing.T) {
t.Parallel()
- l := utils.GetTestLogger(t)
- chainClient, _, contractDeployer, linkToken, registry, registrar, onlyStartRunner, _ := setupAutomationTest(
- t, "update-check-data", ethereum.RegistryVersion_2_0, defaultOCRRegistryConfig, false,
- )
- if onlyStartRunner {
- return
+ registryVersions := map[string]ethereum.KeeperRegistryVersion{
+ "registry_2_0": ethereum.RegistryVersion_2_0,
+ "registry_2_1": ethereum.RegistryVersion_2_1,
}
- performDataChecker, upkeepIDs := actions.DeployPerformDataCheckerConsumers(
- t,
- registry,
- registrar,
- linkToken,
- contractDeployer,
- chainClient,
- defaultAmountOfUpkeeps,
- big.NewInt(automationDefaultLinkFunds),
- automationDefaultUpkeepGasLimit,
- []byte(automationExpectedData),
- )
- gom := gomega.NewGomegaWithT(t)
+ for n, rv := range registryVersions {
+ name := n
+ registryVersion := rv
+ t.Run(name, func(t *testing.T) {
+ t.Parallel()
+ l := logging.GetTestLogger(t)
+ chainClient, _, contractDeployer, linkToken, registry, registrar, _ := setupAutomationTestDocker(
+ t, "update-check-data", registryVersion, defaultOCRRegistryConfig, false,
+ )
- gom.Consistently(func(g gomega.Gomega) {
- // expect the counter to remain 0 because perform data does not match
- for i := 0; i < len(upkeepIDs); i++ {
- counter, err := performDataChecker[i].Counter(context.Background())
- g.Expect(err).ShouldNot(gomega.HaveOccurred(), "Failed to retrieve perform data checker"+
- " for upkeep at index "+strconv.Itoa(i))
- g.Expect(counter.Int64()).Should(gomega.Equal(int64(0)),
- "Expected perform data checker counter to be 0, but got %d", counter.Int64())
- l.Info().Int64("Upkeep perform data checker", counter.Int64()).Msg("Number of upkeeps performed")
- }
- }, "2m", "1s").Should(gomega.Succeed()) // ~1m for setup, 1m assertion
+ performDataChecker, upkeepIDs := actions.DeployPerformDataCheckerConsumers(
+ t,
+ registry,
+ registrar,
+ linkToken,
+ contractDeployer,
+ chainClient,
+ defaultAmountOfUpkeeps,
+ big.NewInt(automationDefaultLinkFunds),
+ automationDefaultUpkeepGasLimit,
+ []byte(automationExpectedData),
+ )
+ gom := gomega.NewGomegaWithT(t)
- for i := 0; i < len(upkeepIDs); i++ {
- err := registry.UpdateCheckData(upkeepIDs[i], []byte(automationExpectedData))
- require.NoError(t, err, "Could not update check data for upkeep at index %d", i)
- }
+ gom.Consistently(func(g gomega.Gomega) {
+ // expect the counter to remain 0 because perform data does not match
+ for i := 0; i < len(upkeepIDs); i++ {
+ counter, err := performDataChecker[i].Counter(context.Background())
+ g.Expect(err).ShouldNot(gomega.HaveOccurred(), "Failed to retrieve perform data checker"+
+ " for upkeep at index "+strconv.Itoa(i))
+ g.Expect(counter.Int64()).Should(gomega.Equal(int64(0)),
+ "Expected perform data checker counter to be 0, but got %d", counter.Int64())
+ l.Info().Int64("Upkeep perform data checker", counter.Int64()).Msg("Number of upkeeps performed")
+ }
+ }, "2m", "1s").Should(gomega.Succeed()) // ~1m for setup, 1m assertion
- err := chainClient.WaitForEvents()
- require.NoError(t, err, "Error while waiting for check data update")
+ for i := 0; i < len(upkeepIDs); i++ {
+ err := registry.UpdateCheckData(upkeepIDs[i], []byte(automationExpectedData))
+ require.NoError(t, err, "Could not update check data for upkeep at index %d", i)
+ }
- // retrieve new check data for all upkeeps
- for i := 0; i < len(upkeepIDs); i++ {
- upkeep, err := registry.GetUpkeepInfo(context.Background(), upkeepIDs[i])
- require.NoError(t, err, "Failed to get upkeep info at index %d", i)
- require.Equal(t, []byte(automationExpectedData), upkeep.CheckData, "Upkeep data not as expected")
- }
+ err := chainClient.WaitForEvents()
+ require.NoError(t, err, "Error while waiting for check data update")
- gom.Eventually(func(g gomega.Gomega) {
- // Check if the upkeeps are performing multiple times by analysing their counters and checking they are greater than 5
- for i := 0; i < len(upkeepIDs); i++ {
- counter, err := performDataChecker[i].Counter(context.Background())
- g.Expect(err).ShouldNot(gomega.HaveOccurred(), "Failed to retrieve perform data checker counter"+
- " for upkeep at index "+strconv.Itoa(i))
- g.Expect(counter.Int64()).Should(gomega.BeNumerically(">", int64(0)),
- "Expected perform data checker counter to be greater than 0, but got %d", counter.Int64())
- l.Info().Int64("Upkeep perform data checker", counter.Int64()).Msg("Number of upkeeps performed")
- }
- }, "2m", "1s").Should(gomega.Succeed()) // ~1m to perform once, 1m buffer
+ // retrieve new check data for all upkeeps
+ for i := 0; i < len(upkeepIDs); i++ {
+ upkeep, err := registry.GetUpkeepInfo(context.Background(), upkeepIDs[i])
+ require.NoError(t, err, "Failed to get upkeep info at index %d", i)
+ require.Equal(t, []byte(automationExpectedData), upkeep.CheckData, "Upkeep data not as expected")
+ }
+
+ gom.Eventually(func(g gomega.Gomega) {
+ // Check if the upkeeps are performing multiple times by analysing their counters and checking they are greater than 5
+ for i := 0; i < len(upkeepIDs); i++ {
+ counter, err := performDataChecker[i].Counter(context.Background())
+ g.Expect(err).ShouldNot(gomega.HaveOccurred(), "Failed to retrieve perform data checker counter"+
+ " for upkeep at index "+strconv.Itoa(i))
+ g.Expect(counter.Int64()).Should(gomega.BeNumerically(">", int64(0)),
+ "Expected perform data checker counter to be greater than 0, but got %d", counter.Int64())
+ l.Info().Int64("Upkeep perform data checker", counter.Int64()).Msg("Number of upkeeps performed")
+ }
+ }, "2m", "1s").Should(gomega.Succeed()) // ~1m to perform once, 1m buffer
+ })
+ }
}
-func setupAutomationTest(
+func setupAutomationTestDocker(
t *testing.T,
testName string,
registryVersion ethereum.KeeperRegistryVersion,
registryConfig contracts.KeeperRegistrySettings,
statefulDb bool,
) (
- chainClient blockchain.EVMClient,
- chainlinkNodes []*client.ChainlinkK8sClient,
- contractDeployer contracts.ContractDeployer,
- linkToken contracts.LinkToken,
- registry contracts.KeeperRegistry,
- registrar contracts.KeeperRegistrar,
- onlyStartRunner bool,
- testEnvironment *environment.Environment,
+ blockchain.EVMClient,
+ []*client.ChainlinkClient,
+ contracts.ContractDeployer,
+ contracts.LinkToken,
+ contracts.KeeperRegistry,
+ contracts.KeeperRegistrar,
+ *test_env.CLClusterTestEnv,
) {
+ l := logging.GetTestLogger(t)
// Add registry version to config
registryConfig.RegistryVersion = registryVersion
-
network := networks.SelectedNetwork
- evmConfig := eth.New(nil)
- if !network.Simulated {
- evmConfig = eth.New(ð.Props{
- NetworkName: network.Name,
- Simulated: network.Simulated,
- WsURLs: network.URLs,
- })
- }
- chainlinkProps := map[string]any{
- "toml": client.AddNetworksConfig(automationBaseTOML, network),
- "secretsToml": client.AddSecretTomlConfig("https://google.com", "username1", "password1"),
- "db": map[string]any{
- "stateful": statefulDb,
- },
- }
- cd, err := chainlink.NewDeployment(5, chainlinkProps)
- require.NoError(t, err, "Failed to create chainlink deployment")
- testEnvironment = environment.New(&environment.Config{
- NamespacePrefix: fmt.Sprintf("smoke-automation-%s-%s", testName, strings.ReplaceAll(strings.ToLower(network.Name), " ", "-")),
- Test: t,
- }).
- AddHelm(evmConfig).
- AddHelmCharts(cd)
- err = testEnvironment.Run()
-
- require.NoError(t, err, "Error setting up test environment")
-
- onlyStartRunner = testEnvironment.WillUseRemoteRunner()
- if !onlyStartRunner {
- chainClient, err = blockchain.NewEVMClient(network, testEnvironment)
- require.NoError(t, err, "Error connecting to blockchain")
- contractDeployer, err = contracts.NewContractDeployer(chainClient)
- require.NoError(t, err, "Error building contract deployer")
- chainlinkNodes, err = client.ConnectChainlinkNodes(testEnvironment)
- require.NoError(t, err, "Error connecting to Chainlink nodes")
- chainClient.ParallelTransactions(true)
-
- txCost, err := chainClient.EstimateCostForChainlinkOperations(1000)
- require.NoError(t, err, "Error estimating cost for Chainlink Operations")
- err = actions.FundChainlinkNodes(chainlinkNodes, chainClient, txCost)
- require.NoError(t, err, "Error funding Chainlink nodes")
-
- linkToken, err = contractDeployer.DeployLinkTokenContract()
- require.NoError(t, err, "Error deploying LINK token")
-
- registry, registrar = actions.DeployAutoOCRRegistryAndRegistrar(
- t,
- registryVersion,
- registryConfig,
- defaultAmountOfUpkeeps,
- linkToken,
- contractDeployer,
- chainClient,
- )
-
- actions.CreateOCRKeeperJobs(t, chainlinkNodes, registry.Address(), network.ChainID, 0, registryVersion)
- nodesWithoutBootstrap := chainlinkNodes[1:]
- ocrConfig, err := actions.BuildAutoOCR2ConfigVars(t, nodesWithoutBootstrap, registryConfig, registrar.Address(), 5*time.Second)
- require.NoError(t, err, "Error building OCR config vars")
- err = registry.SetConfig(automationDefaultRegistryConfig, ocrConfig)
- require.NoError(t, err, "Registry config should be be set successfully")
- require.NoError(t, chainClient.WaitForEvents(), "Waiting for config to be set")
- // Register cleanup for any test
- t.Cleanup(func() {
- err := actions.TeardownSuite(t, testEnvironment, utils.ProjectRoot, chainlinkNodes, nil, zapcore.ErrorLevel, chainClient)
- require.NoError(t, err, "Error tearing down environment")
- })
- }
+ // build the node config
+ clNodeConfig := node.NewConfig(node.NewBaseConfig())
+ syncInterval := models.MustMakeDuration(5 * time.Minute)
+ clNodeConfig.Feature.LogPoller = it_utils.Ptr[bool](true)
+ clNodeConfig.OCR2.Enabled = it_utils.Ptr[bool](true)
+ clNodeConfig.Keeper.TurnLookBack = it_utils.Ptr[int64](int64(0))
+ clNodeConfig.Keeper.Registry.SyncInterval = &syncInterval
+ clNodeConfig.Keeper.Registry.PerformGasOverhead = it_utils.Ptr[uint32](uint32(150000))
+ clNodeConfig.P2P.V2.Enabled = it_utils.Ptr[bool](true)
+ clNodeConfig.P2P.V2.AnnounceAddresses = &[]string{"0.0.0.0:6690"}
+ clNodeConfig.P2P.V2.ListenAddresses = &[]string{"0.0.0.0:6690"}
+
+ // launch the environment
+ env, err := test_env.NewCLTestEnvBuilder().
+ WithTestLogger(t).
+ WithGeth().
+ WithMockServer(1).
+ WithCLNodes(5).
+ WithCLNodeConfig(clNodeConfig).
+ WithFunding(big.NewFloat(.5)).
+ Build()
+ require.NoError(t, err, "Error deploying test environment")
+ env.ParallelTransactions(true)
+
+ txCost, err := env.EVMClient.EstimateCostForChainlinkOperations(1000)
+ require.NoError(t, err, "Error estimating cost for Chainlink Operations")
+ nodeClients := env.GetAPIs()
+ workerNodes := nodeClients[1:]
+ err = actions.FundChainlinkNodesLocal(workerNodes, env.EVMClient, txCost)
+ require.NoError(t, err, "Error funding Chainlink nodes")
+
+ linkToken, err := env.ContractDeployer.DeployLinkTokenContract()
+ require.NoError(t, err, "Error deploying LINK token")
+
+ registry, registrar := actions.DeployAutoOCRRegistryAndRegistrar(
+ t,
+ registryVersion,
+ registryConfig,
+ linkToken,
+ env.ContractDeployer,
+ env.EVMClient,
+ )
+
+ // Fund the registry with LINK
+ err = linkToken.Transfer(registry.Address(), big.NewInt(0).Mul(big.NewInt(1e18), big.NewInt(int64(defaultAmountOfUpkeeps))))
+ require.NoError(t, err, "Funding keeper registry contract shouldn't fail")
+
+ err = actions.CreateOCRKeeperJobsLocal(l, nodeClients, registry.Address(), network.ChainID, 0, registryVersion)
+ require.NoError(t, err, "Error creating OCR Keeper Jobs")
+ ocrConfig, err := actions.BuildAutoOCR2ConfigVarsLocal(l, workerNodes, registryConfig, registrar.Address(), 30*time.Second)
+ require.NoError(t, err, "Error building OCR config vars")
+ err = registry.SetConfig(automationDefaultRegistryConfig, ocrConfig)
+ require.NoError(t, err, "Registry config should be set successfully")
+ require.NoError(t, env.EVMClient.WaitForEvents(), "Waiting for config to be set")
- return chainClient, chainlinkNodes, contractDeployer, linkToken, registry, registrar, onlyStartRunner, testEnvironment
+ return env.EVMClient, nodeClients, env.ContractDeployer, linkToken, registry, registrar, env
}
diff --git a/integration-tests/smoke/automation_test.go_test_list.json b/integration-tests/smoke/automation_test.go_test_list.json
new file mode 100644
index 00000000000..d5311641ce7
--- /dev/null
+++ b/integration-tests/smoke/automation_test.go_test_list.json
@@ -0,0 +1,52 @@
+{
+ "tests": [
+ {
+ "name": "TestAutomationBasic",
+ "label": "ubuntu20.04-32cores-128GB",
+ "nodes": 3
+ },
+ {
+ "name": "TestSetUpkeepTriggerConfig"
+ },
+ {
+ "name": "TestAutomationAddFunds",
+ "label": "ubuntu20.04-32cores-128GB",
+ "nodes": 2
+ },
+ {
+ "name": "TestAutomationPauseUnPause",
+ "label": "ubuntu20.04-16cores-64GB",
+ "nodes": 2
+ },
+ {
+ "name": "TestAutomationRegisterUpkeep",
+ "label": "ubuntu20.04-16cores-64GB",
+ "nodes": 2
+ },
+ {
+ "name": "TestAutomationPauseRegistry",
+ "label": "ubuntu20.04-16cores-64GB",
+ "nodes": 2
+ },
+ {
+ "name": "TestAutomationKeeperNodesDown",
+ "label": "ubuntu20.04-16cores-64GB",
+ "nodes": 2
+ },
+ {
+ "name": "TestAutomationPerformSimulation",
+ "label": "ubuntu20.04-16cores-64GB",
+ "nodes": 2
+ },
+ {
+ "name": "TestAutomationCheckPerformGasLimit",
+ "label": "ubuntu20.04-32cores-128GB",
+ "nodes": 2
+ },
+ {
+ "name": "TestUpdateCheckData",
+ "label": "ubuntu20.04-32cores-128GB",
+ "nodes": 2
+ }
+ ]
+}
diff --git a/integration-tests/smoke/cron_test.go b/integration-tests/smoke/cron_test.go
index 30eadb8f16b..717ff8db1e9 100644
--- a/integration-tests/smoke/cron_test.go
+++ b/integration-tests/smoke/cron_test.go
@@ -2,23 +2,35 @@ package smoke
import (
"fmt"
+ "testing"
+
"github.com/google/uuid"
"github.com/onsi/gomega"
+ "github.com/stretchr/testify/require"
+
+ "github.com/smartcontractkit/chainlink-testing-framework/logging"
+
"github.com/smartcontractkit/chainlink/integration-tests/client"
"github.com/smartcontractkit/chainlink/integration-tests/docker/test_env"
- "github.com/stretchr/testify/require"
- "testing"
)
func TestCronBasic(t *testing.T) {
t.Parallel()
+ l := logging.GetTestLogger(t)
env, err := test_env.NewCLTestEnvBuilder().
+ WithTestLogger(t).
WithGeth().
WithMockServer(1).
WithCLNodes(1).
Build()
require.NoError(t, err)
+ t.Cleanup(func() {
+ if err := env.Cleanup(t); err != nil {
+ l.Error().Err(err).Msg("Error cleaning up test environment")
+ }
+ })
+
err = env.MockServer.Client.SetValuePath("/variable", 5)
require.NoError(t, err, "Setting value path in mockserver shouldn't fail")
diff --git a/integration-tests/smoke/flux_test.go b/integration-tests/smoke/flux_test.go
index da06fc4b57a..ed907e9e460 100644
--- a/integration-tests/smoke/flux_test.go
+++ b/integration-tests/smoke/flux_test.go
@@ -3,30 +3,40 @@ package smoke
import (
"context"
"fmt"
+ "math/big"
+ "strings"
+ "testing"
+ "time"
+
"github.com/ethereum/go-ethereum/common"
"github.com/google/uuid"
- "github.com/smartcontractkit/chainlink-testing-framework/utils"
+ "github.com/stretchr/testify/require"
+
+ "github.com/smartcontractkit/chainlink-testing-framework/logging"
+
"github.com/smartcontractkit/chainlink/integration-tests/actions"
"github.com/smartcontractkit/chainlink/integration-tests/client"
"github.com/smartcontractkit/chainlink/integration-tests/contracts"
"github.com/smartcontractkit/chainlink/integration-tests/docker/test_env"
- "github.com/stretchr/testify/require"
- "math/big"
- "strings"
- "testing"
- "time"
)
func TestFluxBasic(t *testing.T) {
t.Parallel()
- l := utils.GetTestLogger(t)
+ l := logging.GetTestLogger(t)
env, err := test_env.NewCLTestEnvBuilder().
+ WithTestLogger(t).
WithGeth().
WithMockServer(1).
WithCLNodes(3).
Build()
require.NoError(t, err)
+ t.Cleanup(func() {
+ if err := env.Cleanup(t); err != nil {
+ l.Error().Err(err).Msg("Error cleaning up test environment")
+ }
+ })
+
nodeAddresses, err := env.ChainlinkNodeAddresses()
require.NoError(t, err, "Retrieving on-chain wallet addresses for chainlink nodes shouldn't fail")
env.EVMClient.ParallelTransactions(true)
@@ -84,6 +94,7 @@ func TestFluxBasic(t *testing.T) {
fluxSpec := &client.FluxMonitorJobSpec{
Name: fmt.Sprintf("flux-monitor-%s", adapterUUID),
ContractAddress: fluxInstance.Address(),
+ EVMChainID: env.EVMClient.GetChainID().String(),
Threshold: 0,
AbsoluteThreshold: 0,
PollTimerPeriod: 15 * time.Second, // min 15s
@@ -96,7 +107,7 @@ func TestFluxBasic(t *testing.T) {
// initial value set is performed before jobs creation
fluxRoundTimeout := 1 * time.Minute
- fluxRound := contracts.NewFluxAggregatorRoundConfirmer(fluxInstance, big.NewInt(1), fluxRoundTimeout)
+ fluxRound := contracts.NewFluxAggregatorRoundConfirmer(fluxInstance, big.NewInt(1), fluxRoundTimeout, l)
env.EVMClient.AddHeaderEventSubscription(fluxInstance.Address(), fluxRound)
err = env.EVMClient.WaitForEvents()
require.NoError(t, err, "Waiting for event subscriptions in nodes shouldn't fail")
@@ -113,7 +124,7 @@ func TestFluxBasic(t *testing.T) {
require.Equal(t, int64(3), data.AllocatedFunds.Int64(),
"Expected allocated funds to be %d, but found %d", int64(3), data.AllocatedFunds.Int64())
- fluxRound = contracts.NewFluxAggregatorRoundConfirmer(fluxInstance, big.NewInt(2), fluxRoundTimeout)
+ fluxRound = contracts.NewFluxAggregatorRoundConfirmer(fluxInstance, big.NewInt(2), fluxRoundTimeout, l)
env.EVMClient.AddHeaderEventSubscription(fluxInstance.Address(), fluxRound)
err = env.MockServer.Client.SetValuePath(adapterPath, 1e10)
require.NoError(t, err, "Setting value path in mock server shouldn't fail")
diff --git a/integration-tests/smoke/forwarder_ocr_test.go b/integration-tests/smoke/forwarder_ocr_test.go
index 0b58be41d74..f0d20e5245c 100644
--- a/integration-tests/smoke/forwarder_ocr_test.go
+++ b/integration-tests/smoke/forwarder_ocr_test.go
@@ -1,26 +1,38 @@
package smoke
import (
+ "context"
"math/big"
"testing"
- "context"
"github.com/ethereum/go-ethereum/common"
+ "github.com/stretchr/testify/require"
+
+ "github.com/smartcontractkit/chainlink-testing-framework/logging"
+
"github.com/smartcontractkit/chainlink/integration-tests/actions"
"github.com/smartcontractkit/chainlink/integration-tests/docker/test_env"
- "github.com/stretchr/testify/require"
)
func TestForwarderOCRBasic(t *testing.T) {
t.Parallel()
+ l := logging.GetTestLogger(t)
+
env, err := test_env.NewCLTestEnvBuilder().
+ WithTestLogger(t).
WithGeth().
WithMockServer(1).
WithForwarders().
WithCLNodes(6).
- WithFunding(big.NewFloat(10)).
+ WithFunding(big.NewFloat(.1)).
Build()
require.NoError(t, err)
+ t.Cleanup(func() {
+ if err := env.Cleanup(t); err != nil {
+ l.Error().Err(err).Msg("Error cleaning up test environment")
+ }
+ })
+
env.ParallelTransactions(true)
nodeClients := env.GetAPIs()
@@ -43,7 +55,7 @@ func TestForwarderOCRBasic(t *testing.T) {
t, operators[i], authorizedForwarders[i], []common.Address{workerNodeAddresses[i]}, env.EVMClient, env.ContractLoader,
)
require.NoError(t, err, "Accepting Authorize Receivers on Operator shouldn't fail")
- err = actions.TrackForwarderLocal(env.EVMClient, authorizedForwarders[i], workerNodes[i])
+ err = actions.TrackForwarderLocal(env.EVMClient, authorizedForwarders[i], workerNodes[i], l)
require.NoError(t, err)
err = env.EVMClient.WaitForEvents()
}
@@ -55,10 +67,11 @@ func TestForwarderOCRBasic(t *testing.T) {
authorizedForwarders,
env.EVMClient,
)
+ require.NoError(t, err, "Error deploying OCR contracts")
- err = actions.CreateOCRJobsWithForwarderLocal(ocrInstances, bootstrapNode, workerNodes, 5, env.MockServer.Client)
+ err = actions.CreateOCRJobsWithForwarderLocal(ocrInstances, bootstrapNode, workerNodes, 5, env.MockServer.Client, env.EVMClient.GetChainID().String())
require.NoError(t, err, "failed to setup forwarder jobs")
- err = actions.StartNewRound(1, ocrInstances, env.EVMClient)
+ err = actions.StartNewRound(1, ocrInstances, env.EVMClient, l)
require.NoError(t, err)
err = env.EVMClient.WaitForEvents()
require.NoError(t, err, "Error waiting for events")
@@ -70,7 +83,7 @@ func TestForwarderOCRBasic(t *testing.T) {
err = actions.SetAllAdapterResponsesToTheSameValueLocal(10, ocrInstances, workerNodes, env.MockServer.Client)
require.NoError(t, err)
- err = actions.StartNewRound(2, ocrInstances, env.EVMClient)
+ err = actions.StartNewRound(2, ocrInstances, env.EVMClient, l)
require.NoError(t, err)
err = env.EVMClient.WaitForEvents()
require.NoError(t, err, "Error waiting for events")
diff --git a/integration-tests/smoke/forwarders_ocr2_test.go b/integration-tests/smoke/forwarders_ocr2_test.go
index cb6a3f0556d..48d1d20b4dc 100644
--- a/integration-tests/smoke/forwarders_ocr2_test.go
+++ b/integration-tests/smoke/forwarders_ocr2_test.go
@@ -10,25 +10,37 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/stretchr/testify/require"
+ "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"
)
func TestForwarderOCR2Basic(t *testing.T) {
t.Parallel()
+ l := logging.GetTestLogger(t)
+
env, err := test_env.NewCLTestEnvBuilder().
+ WithTestLogger(t).
WithGeth().
WithMockServer(1).
- WithCLNodeConfig(node.NewConfig(node.BaseConf,
+ WithCLNodeConfig(node.NewConfig(node.NewBaseConfig(),
node.WithOCR2(),
node.WithP2Pv2(),
)).
WithForwarders().
WithCLNodes(6).
- WithFunding(big.NewFloat(10)).
+ WithFunding(big.NewFloat(.1)).
Build()
require.NoError(t, err)
+ t.Cleanup(func() {
+ if err := env.Cleanup(t); err != nil {
+ l.Error().Err(err).Msg("Error cleaning up test environment")
+ }
+ })
+
env.ParallelTransactions(true)
nodeClients := env.GetAPIs()
@@ -50,7 +62,7 @@ func TestForwarderOCR2Basic(t *testing.T) {
for i := range workerNodes {
actions.AcceptAuthorizedReceiversOperator(t, operators[i], authorizedForwarders[i], []common.Address{workerNodeAddresses[i]}, env.EVMClient, env.ContractLoader)
require.NoError(t, err, "Accepting Authorized Receivers on Operator shouldn't fail")
- err = actions.TrackForwarderLocal(env.EVMClient, authorizedForwarders[i], workerNodes[i])
+ err = actions.TrackForwarderLocal(env.EVMClient, authorizedForwarders[i], workerNodes[i], l)
require.NoError(t, err, "failed to track forwarders")
err = env.EVMClient.WaitForEvents()
require.NoError(t, err, "Error waiting for events")
@@ -62,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")
@@ -72,14 +85,14 @@ 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
err = actions.ConfigureOCRv2AggregatorContracts(env.EVMClient, ocrv2Config, ocrInstances)
require.NoError(t, err, "Error configuring OCRv2 aggregator contracts")
- err = actions.StartNewOCR2Round(1, ocrInstances, env.EVMClient, time.Minute*10)
+ err = actions.StartNewOCR2Round(1, ocrInstances, env.EVMClient, time.Minute*10, l)
require.NoError(t, err)
answer, err := ocrInstances[0].GetLatestAnswer(context.Background())
@@ -90,7 +103,7 @@ func TestForwarderOCR2Basic(t *testing.T) {
ocrRoundVal := (5 + i) % 10
err = env.MockServer.Client.SetValuePath("ocr2", ocrRoundVal)
require.NoError(t, err)
- err = actions.StartNewOCR2Round(int64(i), ocrInstances, env.EVMClient, time.Minute*10)
+ err = actions.StartNewOCR2Round(int64(i), ocrInstances, env.EVMClient, time.Minute*10, l)
require.NoError(t, err)
answer, err = ocrInstances[0].GetLatestAnswer(context.Background())
diff --git a/integration-tests/smoke/keeper_test.go b/integration-tests/smoke/keeper_test.go
index 00cbe07eb0f..0e4cb7ce041 100644
--- a/integration-tests/smoke/keeper_test.go
+++ b/integration-tests/smoke/keeper_test.go
@@ -13,7 +13,9 @@ import (
"github.com/stretchr/testify/require"
"github.com/smartcontractkit/chainlink-testing-framework/blockchain"
- "github.com/smartcontractkit/chainlink-testing-framework/utils"
+ "github.com/smartcontractkit/chainlink-testing-framework/logging"
+
+ "github.com/smartcontractkit/chainlink/v2/core/store/models"
"github.com/smartcontractkit/chainlink/integration-tests/actions"
"github.com/smartcontractkit/chainlink/integration-tests/client"
@@ -21,7 +23,6 @@ import (
"github.com/smartcontractkit/chainlink/integration-tests/contracts/ethereum"
"github.com/smartcontractkit/chainlink/integration-tests/docker/test_env"
"github.com/smartcontractkit/chainlink/integration-tests/types/config/node"
- "github.com/smartcontractkit/chainlink/v2/core/store/models"
)
const (
@@ -75,17 +76,18 @@ var (
func TestKeeperBasicSmoke(t *testing.T) {
t.Parallel()
- l := utils.GetTestLogger(t)
registryVersions := []ethereum.KeeperRegistryVersion{
ethereum.RegistryVersion_1_1,
ethereum.RegistryVersion_1_2,
ethereum.RegistryVersion_1_3,
}
- chainClient, chainlinkNodes, contractDeployer, linkToken, _ := setupKeeperTest(t)
-
- for _, registryVersion := range registryVersions {
+ for _, rv := range registryVersions {
+ registryVersion := rv
t.Run(fmt.Sprintf("registry_1_%d", registryVersion), func(t *testing.T) {
+ t.Parallel()
+ l := logging.GetTestLogger(t)
+ chainClient, chainlinkNodes, contractDeployer, linkToken, _ := setupKeeperTest(t)
registry, _, consumers, upkeepIDs := actions.DeployKeeperContracts(
t,
registryVersion,
@@ -99,13 +101,13 @@ func TestKeeperBasicSmoke(t *testing.T) {
)
gom := gomega.NewGomegaWithT(t)
- _, err := actions.CreateKeeperJobsLocal(chainlinkNodes, registry, contracts.OCRv2Config{})
+ _, err := actions.CreateKeeperJobsLocal(l, chainlinkNodes, registry, contracts.OCRv2Config{}, chainClient.GetChainID().String())
require.NoError(t, err, "Error creating keeper jobs")
err = chainClient.WaitForEvents()
require.NoError(t, err, "Error creating keeper jobs")
gom.Eventually(func(g gomega.Gomega) error {
- // Check if the upkeeps are performing multiple times by analysing their counters and checking they are greater than 10
+ // Check if the upkeeps are performing multiple times by analyzing their counters and checking they are greater than 10
for i := 0; i < len(upkeepIDs); i++ {
counter, err := consumers[i].Counter(context.Background())
g.Expect(err).ShouldNot(gomega.HaveOccurred(), "Failed to retrieve consumer counter for upkeep at index %d", i)
@@ -150,17 +152,18 @@ func TestKeeperBasicSmoke(t *testing.T) {
func TestKeeperBlockCountPerTurn(t *testing.T) {
t.Parallel()
- l := utils.GetTestLogger(t)
registryVersions := []ethereum.KeeperRegistryVersion{
ethereum.RegistryVersion_1_1,
ethereum.RegistryVersion_1_2,
ethereum.RegistryVersion_1_3,
}
- chainClient, chainlinkNodes, contractDeployer, linkToken, _ := setupKeeperTest(t)
-
- for _, registryVersion := range registryVersions {
+ for _, rv := range registryVersions {
+ registryVersion := rv
t.Run(fmt.Sprintf("registry_1_%d", registryVersion), func(t *testing.T) {
+ t.Parallel()
+ l := logging.GetTestLogger(t)
+ chainClient, chainlinkNodes, contractDeployer, linkToken, _ := setupKeeperTest(t)
registry, _, consumers, upkeepIDs := actions.DeployKeeperContracts(
t,
registryVersion,
@@ -174,7 +177,7 @@ func TestKeeperBlockCountPerTurn(t *testing.T) {
)
gom := gomega.NewGomegaWithT(t)
- _, err := actions.CreateKeeperJobsLocal(chainlinkNodes, registry, contracts.OCRv2Config{})
+ _, err := actions.CreateKeeperJobsLocal(l, chainlinkNodes, registry, contracts.OCRv2Config{}, chainClient.GetChainID().String())
require.NoError(t, err, "Error creating keeper jobs")
err = chainClient.WaitForEvents()
require.NoError(t, err, "Error creating keeper jobs")
@@ -259,10 +262,12 @@ func TestKeeperSimulation(t *testing.T) {
ethereum.RegistryVersion_1_3,
}
- chainClient, chainlinkNodes, contractDeployer, linkToken, _ := setupKeeperTest(t)
-
- for _, registryVersion := range registryVersions {
+ for _, rv := range registryVersions {
+ registryVersion := rv
t.Run(fmt.Sprintf("registry_1_%d", registryVersion), func(t *testing.T) {
+ t.Parallel()
+ l := logging.GetTestLogger(t)
+ chainClient, chainlinkNodes, contractDeployer, linkToken, _ := setupKeeperTest(t)
registry, _, consumersPerformance, upkeepIDs := actions.DeployPerformanceKeeperContracts(
t,
registryVersion,
@@ -280,7 +285,7 @@ func TestKeeperSimulation(t *testing.T) {
)
gom := gomega.NewGomegaWithT(t)
- _, err := actions.CreateKeeperJobsLocal(chainlinkNodes, registry, contracts.OCRv2Config{})
+ _, err := actions.CreateKeeperJobsLocal(l, chainlinkNodes, registry, contracts.OCRv2Config{}, chainClient.GetChainID().String())
require.NoError(t, err, "Error creating keeper jobs")
err = chainClient.WaitForEvents()
require.NoError(t, err, "Error creating keeper jobs")
@@ -325,14 +330,16 @@ func TestKeeperSimulation(t *testing.T) {
func TestKeeperCheckPerformGasLimit(t *testing.T) {
t.Parallel()
- l := utils.GetTestLogger(t)
registryVersions := []ethereum.KeeperRegistryVersion{
ethereum.RegistryVersion_1_2,
ethereum.RegistryVersion_1_3,
}
- for _, registryVersion := range registryVersions {
+ for _, rv := range registryVersions {
+ registryVersion := rv
t.Run(fmt.Sprintf("registry_1_%d", registryVersion), func(t *testing.T) {
+ t.Parallel()
+ l := logging.GetTestLogger(t)
chainClient, chainlinkNodes, contractDeployer, linkToken, _ := setupKeeperTest(t)
registry, _, consumersPerformance, upkeepIDs := actions.DeployPerformanceKeeperContracts(
t,
@@ -351,7 +358,7 @@ func TestKeeperCheckPerformGasLimit(t *testing.T) {
)
gom := gomega.NewGomegaWithT(t)
- _, err := actions.CreateKeeperJobsLocal(chainlinkNodes, registry, contracts.OCRv2Config{})
+ _, err := actions.CreateKeeperJobsLocal(l, chainlinkNodes, registry, contracts.OCRv2Config{}, chainClient.GetChainID().String())
require.NoError(t, err, "Error creating keeper jobs")
err = chainClient.WaitForEvents()
require.NoError(t, err, "Error creating keeper jobs")
@@ -435,17 +442,18 @@ func TestKeeperCheckPerformGasLimit(t *testing.T) {
func TestKeeperRegisterUpkeep(t *testing.T) {
t.Parallel()
- l := utils.GetTestLogger(t)
registryVersions := []ethereum.KeeperRegistryVersion{
ethereum.RegistryVersion_1_1,
ethereum.RegistryVersion_1_2,
ethereum.RegistryVersion_1_3,
}
- chainClient, chainlinkNodes, contractDeployer, linkToken, _ := setupKeeperTest(t)
-
- for _, registryVersion := range registryVersions {
+ for _, rv := range registryVersions {
+ registryVersion := rv
t.Run(fmt.Sprintf("registry_1_%d", registryVersion), func(t *testing.T) {
+ t.Parallel()
+ l := logging.GetTestLogger(t)
+ chainClient, chainlinkNodes, contractDeployer, linkToken, _ := setupKeeperTest(t)
registry, registrar, consumers, upkeepIDs := actions.DeployKeeperContracts(
t,
registryVersion,
@@ -459,7 +467,7 @@ func TestKeeperRegisterUpkeep(t *testing.T) {
)
gom := gomega.NewGomegaWithT(t)
- _, err := actions.CreateKeeperJobsLocal(chainlinkNodes, registry, contracts.OCRv2Config{})
+ _, err := actions.CreateKeeperJobsLocal(l, chainlinkNodes, registry, contracts.OCRv2Config{}, chainClient.GetChainID().String())
require.NoError(t, err, "Error creating keeper jobs")
err = chainClient.WaitForEvents()
require.NoError(t, err, "Error creating keeper jobs")
@@ -529,10 +537,12 @@ func TestKeeperAddFunds(t *testing.T) {
ethereum.RegistryVersion_1_3,
}
- chainClient, chainlinkNodes, contractDeployer, linkToken, _ := setupKeeperTest(t)
-
- for _, registryVersion := range registryVersions {
+ for _, rv := range registryVersions {
+ registryVersion := rv
t.Run(fmt.Sprintf("registry_1_%d", registryVersion), func(t *testing.T) {
+ t.Parallel()
+ l := logging.GetTestLogger(t)
+ chainClient, chainlinkNodes, contractDeployer, linkToken, _ := setupKeeperTest(t)
registry, _, consumers, upkeepIDs := actions.DeployKeeperContracts(
t,
registryVersion,
@@ -546,7 +556,7 @@ func TestKeeperAddFunds(t *testing.T) {
)
gom := gomega.NewGomegaWithT(t)
- _, err := actions.CreateKeeperJobsLocal(chainlinkNodes, registry, contracts.OCRv2Config{})
+ _, err := actions.CreateKeeperJobsLocal(l, chainlinkNodes, registry, contracts.OCRv2Config{}, chainClient.GetChainID().String())
require.NoError(t, err, "Error creating keeper jobs")
err = chainClient.WaitForEvents()
require.NoError(t, err, "Error creating keeper jobs")
@@ -584,17 +594,18 @@ func TestKeeperAddFunds(t *testing.T) {
func TestKeeperRemove(t *testing.T) {
t.Parallel()
- l := utils.GetTestLogger(t)
registryVersions := []ethereum.KeeperRegistryVersion{
ethereum.RegistryVersion_1_1,
ethereum.RegistryVersion_1_2,
ethereum.RegistryVersion_1_3,
}
- chainClient, chainlinkNodes, contractDeployer, linkToken, _ := setupKeeperTest(t)
-
- for _, registryVersion := range registryVersions {
+ for _, rv := range registryVersions {
+ registryVersion := rv
t.Run(fmt.Sprintf("registry_1_%d", registryVersion), func(t *testing.T) {
+ t.Parallel()
+ l := logging.GetTestLogger(t)
+ chainClient, chainlinkNodes, contractDeployer, linkToken, _ := setupKeeperTest(t)
registry, _, consumers, upkeepIDs := actions.DeployKeeperContracts(
t,
registryVersion,
@@ -608,7 +619,7 @@ func TestKeeperRemove(t *testing.T) {
)
gom := gomega.NewGomegaWithT(t)
- _, err := actions.CreateKeeperJobsLocal(chainlinkNodes, registry, contracts.OCRv2Config{})
+ _, err := actions.CreateKeeperJobsLocal(l, chainlinkNodes, registry, contracts.OCRv2Config{}, chainClient.GetChainID().String())
require.NoError(t, err, "Error creating keeper jobs")
err = chainClient.WaitForEvents()
require.NoError(t, err, "Error creating keeper jobs")
@@ -667,10 +678,12 @@ func TestKeeperPauseRegistry(t *testing.T) {
ethereum.RegistryVersion_1_3,
}
- chainClient, chainlinkNodes, contractDeployer, linkToken, _ := setupKeeperTest(t)
-
- for _, registryVersion := range registryVersions {
+ for _, rv := range registryVersions {
+ registryVersion := rv
t.Run(fmt.Sprintf("registry_1_%d", registryVersion), func(t *testing.T) {
+ t.Parallel()
+ l := logging.GetTestLogger(t)
+ chainClient, chainlinkNodes, contractDeployer, linkToken, _ := setupKeeperTest(t)
registry, _, consumers, upkeepIDs := actions.DeployKeeperContracts(
t,
registryVersion,
@@ -684,7 +697,7 @@ func TestKeeperPauseRegistry(t *testing.T) {
)
gom := gomega.NewGomegaWithT(t)
- _, err := actions.CreateKeeperJobsLocal(chainlinkNodes, registry, contracts.OCRv2Config{})
+ _, err := actions.CreateKeeperJobsLocal(l, chainlinkNodes, registry, contracts.OCRv2Config{}, chainClient.GetChainID().String())
require.NoError(t, err, "Error creating keeper jobs")
err = chainClient.WaitForEvents()
require.NoError(t, err, "Error creating keeper jobs")
@@ -730,6 +743,7 @@ func TestKeeperPauseRegistry(t *testing.T) {
func TestKeeperMigrateRegistry(t *testing.T) {
t.Parallel()
+ l := logging.GetTestLogger(t)
chainClient, chainlinkNodes, contractDeployer, linkToken, _ := setupKeeperTest(t)
registry, _, consumers, upkeepIDs := actions.DeployKeeperContracts(
t,
@@ -744,7 +758,7 @@ func TestKeeperMigrateRegistry(t *testing.T) {
)
gom := gomega.NewGomegaWithT(t)
- _, err := actions.CreateKeeperJobsLocal(chainlinkNodes, registry, contracts.OCRv2Config{})
+ _, err := actions.CreateKeeperJobsLocal(l, chainlinkNodes, registry, contracts.OCRv2Config{}, chainClient.GetChainID().String())
require.NoError(t, err, "Error creating keeper jobs")
err = chainClient.WaitForEvents()
require.NoError(t, err, "Error creating keeper jobs")
@@ -763,7 +777,7 @@ func TestKeeperMigrateRegistry(t *testing.T) {
)
// Set the jobs for the second registry
- _, err = actions.CreateKeeperJobsLocal(chainlinkNodes, secondRegistry, contracts.OCRv2Config{})
+ _, err = actions.CreateKeeperJobsLocal(l, chainlinkNodes, secondRegistry, contracts.OCRv2Config{}, chainClient.GetChainID().String())
require.NoError(t, err, "Error creating keeper jobs")
err = chainClient.WaitForEvents()
require.NoError(t, err, "Error creating keeper jobs")
@@ -811,15 +825,17 @@ func TestKeeperMigrateRegistry(t *testing.T) {
func TestKeeperNodeDown(t *testing.T) {
t.Parallel()
- l := utils.GetTestLogger(t)
registryVersions := []ethereum.KeeperRegistryVersion{
ethereum.RegistryVersion_1_1,
ethereum.RegistryVersion_1_2,
ethereum.RegistryVersion_1_3,
}
- for _, registryVersion := range registryVersions {
+ for _, rv := range registryVersions {
+ registryVersion := rv
t.Run(fmt.Sprintf("registry_1_%d", registryVersion), func(t *testing.T) {
+ t.Parallel()
+ l := logging.GetTestLogger(t)
chainClient, chainlinkNodes, contractDeployer, linkToken, _ := setupKeeperTest(t)
registry, _, consumers, upkeepIDs := actions.DeployKeeperContracts(
t,
@@ -834,7 +850,7 @@ func TestKeeperNodeDown(t *testing.T) {
)
gom := gomega.NewGomegaWithT(t)
- jobs, err := actions.CreateKeeperJobsLocal(chainlinkNodes, registry, contracts.OCRv2Config{})
+ jobs, err := actions.CreateKeeperJobsLocal(l, chainlinkNodes, registry, contracts.OCRv2Config{}, chainClient.GetChainID().String())
require.NoError(t, err, "Error creating keeper jobs")
err = chainClient.WaitForEvents()
require.NoError(t, err, "Error creating keeper jobs")
@@ -925,7 +941,7 @@ type nodeAndJob struct {
func TestKeeperPauseUnPauseUpkeep(t *testing.T) {
t.Parallel()
- l := utils.GetTestLogger(t)
+ l := logging.GetTestLogger(t)
chainClient, chainlinkNodes, contractDeployer, linkToken, _ := setupKeeperTest(t)
registry, _, consumers, upkeepIDs := actions.DeployKeeperContracts(
t,
@@ -940,7 +956,7 @@ func TestKeeperPauseUnPauseUpkeep(t *testing.T) {
)
gom := gomega.NewGomegaWithT(t)
- _, err := actions.CreateKeeperJobsLocal(chainlinkNodes, registry, contracts.OCRv2Config{})
+ _, err := actions.CreateKeeperJobsLocal(l, chainlinkNodes, registry, contracts.OCRv2Config{}, chainClient.GetChainID().String())
require.NoError(t, err, "Error creating keeper jobs")
err = chainClient.WaitForEvents()
require.NoError(t, err, "Error creating keeper jobs")
@@ -1015,7 +1031,7 @@ func TestKeeperPauseUnPauseUpkeep(t *testing.T) {
func TestKeeperUpdateCheckData(t *testing.T) {
t.Parallel()
- l := utils.GetTestLogger(t)
+ l := logging.GetTestLogger(t)
chainClient, chainlinkNodes, contractDeployer, linkToken, _ := setupKeeperTest(t)
registry, _, performDataChecker, upkeepIDs := actions.DeployPerformDataCheckerContracts(
t,
@@ -1031,7 +1047,7 @@ func TestKeeperUpdateCheckData(t *testing.T) {
)
gom := gomega.NewGomegaWithT(t)
- _, err := actions.CreateKeeperJobsLocal(chainlinkNodes, registry, contracts.OCRv2Config{})
+ _, err := actions.CreateKeeperJobsLocal(l, chainlinkNodes, registry, contracts.OCRv2Config{}, chainClient.GetChainID().String())
require.NoError(t, err, "Error creating keeper jobs")
err = chainClient.WaitForEvents()
require.NoError(t, err, "Error creating keeper jobs")
@@ -1082,15 +1098,17 @@ func setupKeeperTest(t *testing.T) (
contracts.LinkToken,
*test_env.CLClusterTestEnv,
) {
- clNodeConfig := node.NewConfig(node.BaseConf)
+ clNodeConfig := node.NewConfig(node.NewBaseConfig())
turnLookBack := int64(0)
syncInterval := models.MustMakeDuration(5 * time.Second)
performGasOverhead := uint32(150000)
clNodeConfig.Keeper.TurnLookBack = &turnLookBack
clNodeConfig.Keeper.Registry.SyncInterval = &syncInterval
clNodeConfig.Keeper.Registry.PerformGasOverhead = &performGasOverhead
+ l := logging.GetTestLogger(t)
env, err := test_env.NewCLTestEnvBuilder().
+ WithTestLogger(t).
WithGeth().
WithMockServer(1).
WithCLNodes(5).
@@ -1098,6 +1116,11 @@ func setupKeeperTest(t *testing.T) (
WithFunding(big.NewFloat(.5)).
Build()
require.NoError(t, err, "Error deploying test environment")
+ t.Cleanup(func() {
+ if err := env.Cleanup(t); err != nil {
+ l.Error().Err(err).Msg("Error cleaning up test environment")
+ }
+ })
env.ParallelTransactions(true)
diff --git a/integration-tests/smoke/keeper_test.go_test_list.json b/integration-tests/smoke/keeper_test.go_test_list.json
new file mode 100644
index 00000000000..dfa2c49358c
--- /dev/null
+++ b/integration-tests/smoke/keeper_test.go_test_list.json
@@ -0,0 +1,58 @@
+{
+ "tests": [
+ {
+ "name": "TestKeeperBasicSmoke",
+ "label": "ubuntu20.04-32cores-128GB",
+ "nodes": 3
+ },
+ {
+ "name": "TestKeeperBlockCountPerTurn",
+ "label": "ubuntu20.04-32cores-128GB",
+ "nodes": 3
+ },
+ {
+ "name": "TestKeeperSimulation",
+ "label": "ubuntu20.04-16cores-64GB",
+ "nodes": 2
+ },
+ {
+ "name": "TestKeeperCheckPerformGasLimit",
+ "label": "ubuntu20.04-16cores-64GB",
+ "nodes": 3
+ },
+ {
+ "name": "TestKeeperRegisterUpkeep",
+ "label": "ubuntu20.04-16cores-64GB",
+ "nodes": 3
+ },
+ {
+ "name": "TestKeeperAddFunds",
+ "label": "ubuntu20.04-16cores-64GB",
+ "nodes": 3
+ },
+ {
+ "name": "TestKeeperRemove",
+ "label": "ubuntu20.04-32cores-128GB",
+ "nodes": 3
+ },
+ {
+ "name": "TestKeeperPauseRegistry",
+ "label": "ubuntu20.04-16cores-64GB",
+ "nodes": 2
+ },
+ {
+ "name": "TestKeeperMigrateRegistry"
+ },
+ {
+ "name": "TestKeeperNodeDown",
+ "label": "ubuntu20.04-32cores-128GB",
+ "nodes": 3
+ },
+ {
+ "name": "TestKeeperPauseUnPauseUpkeep"
+ },
+ {
+ "name": "TestKeeperUpdateCheckData"
+ }
+ ]
+}
diff --git a/integration-tests/smoke/ocr2_test.go b/integration-tests/smoke/ocr2_test.go
index 7dd0b23223c..a1ad9fa5296 100644
--- a/integration-tests/smoke/ocr2_test.go
+++ b/integration-tests/smoke/ocr2_test.go
@@ -4,38 +4,51 @@ import (
"context"
"fmt"
"math/big"
+ "strings"
"testing"
"time"
+ "github.com/stretchr/testify/require"
+
"github.com/smartcontractkit/chainlink-env/environment"
"github.com/smartcontractkit/chainlink-env/pkg/helm/chainlink"
"github.com/smartcontractkit/chainlink-env/pkg/helm/ethereum"
"github.com/smartcontractkit/chainlink-env/pkg/helm/mockserver"
mockservercfg "github.com/smartcontractkit/chainlink-env/pkg/helm/mockserver-cfg"
"github.com/smartcontractkit/chainlink-testing-framework/blockchain"
+ "github.com/smartcontractkit/chainlink-testing-framework/logging"
+ "github.com/smartcontractkit/chainlink-testing-framework/networks"
+
"github.com/smartcontractkit/chainlink/integration-tests/actions"
"github.com/smartcontractkit/chainlink/integration-tests/client"
"github.com/smartcontractkit/chainlink/integration-tests/config"
+ "github.com/smartcontractkit/chainlink/integration-tests/contracts"
"github.com/smartcontractkit/chainlink/integration-tests/docker/test_env"
- "github.com/smartcontractkit/chainlink/integration-tests/networks"
"github.com/smartcontractkit/chainlink/integration-tests/types/config/node"
- "github.com/stretchr/testify/require"
- "strings"
)
// Tests a basic OCRv2 median feed
func TestOCRv2Basic(t *testing.T) {
+ l := logging.GetTestLogger(t)
+
env, err := test_env.NewCLTestEnvBuilder().
+ WithTestLogger(t).
WithGeth().
WithMockServer(1).
- WithCLNodeConfig(node.NewConfig(node.BaseConf,
+ WithCLNodeConfig(node.NewConfig(node.NewBaseConfig(),
node.WithOCR2(),
node.WithP2Pv2(),
)).
WithCLNodes(6).
- WithFunding(big.NewFloat(10)).
+ WithFunding(big.NewFloat(.1)).
Build()
require.NoError(t, err)
+ t.Cleanup(func() {
+ if err := env.Cleanup(t); err != nil {
+ l.Error().Err(err).Msg("Error cleaning up test environment")
+ }
+ })
+
env.ParallelTransactions(true)
nodeClients := env.GetAPIs()
@@ -57,19 +70,20 @@ 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)
require.NoError(t, err, "Error configuring OCRv2 aggregator contracts")
- err = actions.StartNewOCR2Round(1, aggregatorContracts, env.EVMClient, time.Minute*5)
+ err = actions.StartNewOCR2Round(1, aggregatorContracts, env.EVMClient, time.Minute*5, l)
require.NoError(t, err, "Error starting new OCR2 round")
roundData, err := aggregatorContracts[0].GetRound(context.Background(), big.NewInt(1))
require.NoError(t, err, "Getting latest answer from OCR contract shouldn't fail")
@@ -80,7 +94,7 @@ func TestOCRv2Basic(t *testing.T) {
err = env.MockServer.Client.SetValuePath("ocr2", 10)
require.NoError(t, err)
- err = actions.StartNewOCR2Round(2, aggregatorContracts, env.EVMClient, time.Minute*5)
+ err = actions.StartNewOCR2Round(2, aggregatorContracts, env.EVMClient, time.Minute*5, l)
require.NoError(t, err)
roundData, err = aggregatorContracts[0].GetRound(context.Background(), big.NewInt(2))
diff --git a/integration-tests/smoke/ocr2vrf_test.go b/integration-tests/smoke/ocr2vrf_test.go
index 504750fdafb..c9f689ca7ae 100644
--- a/integration-tests/smoke/ocr2vrf_test.go
+++ b/integration-tests/smoke/ocr2vrf_test.go
@@ -13,6 +13,8 @@ import (
"github.com/smartcontractkit/chainlink-env/pkg/helm/chainlink"
eth "github.com/smartcontractkit/chainlink-env/pkg/helm/ethereum"
"github.com/smartcontractkit/chainlink-testing-framework/blockchain"
+ "github.com/smartcontractkit/chainlink-testing-framework/logging"
+ "github.com/smartcontractkit/chainlink-testing-framework/networks"
"github.com/smartcontractkit/chainlink-testing-framework/utils"
"github.com/smartcontractkit/chainlink/integration-tests/actions"
@@ -21,21 +23,20 @@ import (
"github.com/smartcontractkit/chainlink/integration-tests/client"
"github.com/smartcontractkit/chainlink/integration-tests/config"
"github.com/smartcontractkit/chainlink/integration-tests/contracts"
- "github.com/smartcontractkit/chainlink/integration-tests/networks"
)
func TestOCR2VRFRedeemModel(t *testing.T) {
t.Parallel()
t.Skip("VRFv3 is on pause, skipping")
- l := utils.GetTestLogger(t)
+ l := logging.GetTestLogger(t)
testEnvironment, testNetwork := setupOCR2VRFEnvironment(t)
if testEnvironment.WillUseRemoteRunner() {
return
}
- chainClient, err := blockchain.NewEVMClient(testNetwork, testEnvironment)
+ chainClient, err := blockchain.NewEVMClient(testNetwork, testEnvironment, l)
require.NoError(t, err, "Error connecting to blockchain")
- contractDeployer, err := contracts.NewContractDeployer(chainClient)
+ contractDeployer, err := contracts.NewContractDeployer(chainClient, l)
require.NoError(t, err, "Error building contract deployer")
chainlinkNodes, err := client.ConnectChainlinkNodes(testEnvironment)
require.NoError(t, err, "Error connecting to Chainlink nodes")
@@ -89,15 +90,15 @@ func TestOCR2VRFRedeemModel(t *testing.T) {
func TestOCR2VRFFulfillmentModel(t *testing.T) {
t.Parallel()
t.Skip("VRFv3 is on pause, skipping")
- l := utils.GetTestLogger(t)
+ l := logging.GetTestLogger(t)
testEnvironment, testNetwork := setupOCR2VRFEnvironment(t)
if testEnvironment.WillUseRemoteRunner() {
return
}
- chainClient, err := blockchain.NewEVMClient(testNetwork, testEnvironment)
+ chainClient, err := blockchain.NewEVMClient(testNetwork, testEnvironment, l)
require.NoError(t, err, "Error connecting to blockchain")
- contractDeployer, err := contracts.NewContractDeployer(chainClient)
+ contractDeployer, err := contracts.NewContractDeployer(chainClient, l)
require.NoError(t, err, "Error building contract deployer")
chainlinkNodes, err := client.ConnectChainlinkNodes(testEnvironment)
require.NoError(t, err, "Error connecting to Chainlink nodes")
diff --git a/integration-tests/smoke/ocr_test.go b/integration-tests/smoke/ocr_test.go
index 1ae52ade305..56d045fa097 100644
--- a/integration-tests/smoke/ocr_test.go
+++ b/integration-tests/smoke/ocr_test.go
@@ -1,24 +1,36 @@
package smoke
import (
+ "context"
+ "math/big"
"testing"
- "context"
+ "github.com/stretchr/testify/require"
+
+ "github.com/smartcontractkit/chainlink-testing-framework/logging"
+
"github.com/smartcontractkit/chainlink/integration-tests/actions"
"github.com/smartcontractkit/chainlink/integration-tests/docker/test_env"
- "github.com/stretchr/testify/require"
- "math/big"
)
func TestOCRBasic(t *testing.T) {
t.Parallel()
+ l := logging.GetTestLogger(t)
+
env, err := test_env.NewCLTestEnvBuilder().
+ WithTestLogger(t).
WithGeth().
WithMockServer(1).
WithCLNodes(6).
- WithFunding(big.NewFloat(10)).
+ WithFunding(big.NewFloat(.1)).
Build()
require.NoError(t, err)
+ t.Cleanup(func() {
+ if err := env.Cleanup(t); err != nil {
+ l.Error().Err(err).Msg("Error cleaning up test environment")
+ }
+ })
+
env.ParallelTransactions(true)
nodeClients := env.GetAPIs()
@@ -27,18 +39,15 @@ func TestOCRBasic(t *testing.T) {
linkTokenContract, err := env.ContractDeployer.DeployLinkTokenContract()
require.NoError(t, err, "Deploying Link Token Contract shouldn't fail")
- err = actions.FundChainlinkNodesLocal(workerNodes, env.EVMClient, big.NewFloat(.05))
- require.NoError(t, err, "Error funding Chainlink nodes")
-
ocrInstances, err := actions.DeployOCRContractsLocal(1, linkTokenContract, env.ContractDeployer, workerNodes, env.EVMClient)
require.NoError(t, err)
err = env.EVMClient.WaitForEvents()
require.NoError(t, err, "Error waiting for events")
- err = actions.CreateOCRJobsLocal(ocrInstances, bootstrapNode, workerNodes, 5, env.MockServer.Client)
+ err = actions.CreateOCRJobsLocal(ocrInstances, bootstrapNode, workerNodes, 5, env.MockServer.Client, env.EVMClient.GetChainID().String())
require.NoError(t, err)
- _ = actions.StartNewRound(1, ocrInstances, env.EVMClient)
+ err = actions.StartNewRound(1, ocrInstances, env.EVMClient, l)
require.NoError(t, err)
answer, err := ocrInstances[0].GetLatestAnswer(context.Background())
@@ -47,7 +56,7 @@ func TestOCRBasic(t *testing.T) {
err = actions.SetAllAdapterResponsesToTheSameValueLocal(10, ocrInstances, workerNodes, env.MockServer.Client)
require.NoError(t, err)
- err = actions.StartNewRound(2, ocrInstances, env.EVMClient)
+ err = actions.StartNewRound(2, ocrInstances, env.EVMClient, l)
require.NoError(t, err)
answer, err = ocrInstances[0].GetLatestAnswer(context.Background())
diff --git a/integration-tests/smoke/runlog_test.go b/integration-tests/smoke/runlog_test.go
index d40d5677fde..0bfc41eca71 100644
--- a/integration-tests/smoke/runlog_test.go
+++ b/integration-tests/smoke/runlog_test.go
@@ -3,27 +3,37 @@ package smoke
import (
"context"
"fmt"
+ "math/big"
+ "strings"
+ "testing"
+
"github.com/google/uuid"
"github.com/onsi/gomega"
- "github.com/smartcontractkit/chainlink-testing-framework/utils"
+ "github.com/stretchr/testify/require"
+
+ "github.com/smartcontractkit/chainlink-testing-framework/logging"
+
"github.com/smartcontractkit/chainlink/integration-tests/client"
"github.com/smartcontractkit/chainlink/integration-tests/docker/test_env"
- "github.com/stretchr/testify/require"
- "math/big"
- "strings"
- "testing"
)
func TestRunLogBasic(t *testing.T) {
t.Parallel()
- l := utils.GetTestLogger(t)
+ l := logging.GetTestLogger(t)
+
env, err := test_env.NewCLTestEnvBuilder().
+ WithTestLogger(t).
WithGeth().
WithMockServer(1).
WithCLNodes(1).
- WithFunding(big.NewFloat(1)).
+ WithFunding(big.NewFloat(.1)).
Build()
require.NoError(t, err)
+ t.Cleanup(func() {
+ if err := env.Cleanup(t); err != nil {
+ l.Error().Err(err).Msg("Error cleaning up test environment")
+ }
+ })
lt, err := env.ContractDeployer.DeployLinkTokenContract()
require.NoError(t, err, "Deploying Link Token Contract shouldn't fail")
@@ -59,6 +69,7 @@ func TestRunLogBasic(t *testing.T) {
Name: fmt.Sprintf("direct-request-%s", uuid.NewString()),
MinIncomingConfirmations: "1",
ContractAddress: oracle.Address(),
+ EVMChainID: env.EVMClient.GetChainID().String(),
ExternalJobID: jobUUID.String(),
ObservationSource: ost,
})
diff --git a/integration-tests/smoke/vrf_test.go b/integration-tests/smoke/vrf_test.go
index 2f3a8bb40f5..47f8cd8e30f 100644
--- a/integration-tests/smoke/vrf_test.go
+++ b/integration-tests/smoke/vrf_test.go
@@ -3,29 +3,39 @@ package smoke
import (
"context"
"fmt"
+ "math/big"
+ "testing"
+ "time"
+
"github.com/google/uuid"
"github.com/onsi/gomega"
- "github.com/smartcontractkit/chainlink-testing-framework/utils"
+ "github.com/stretchr/testify/require"
+
+ "github.com/smartcontractkit/chainlink-testing-framework/logging"
+
"github.com/smartcontractkit/chainlink/integration-tests/actions"
"github.com/smartcontractkit/chainlink/integration-tests/actions/vrfv1"
"github.com/smartcontractkit/chainlink/integration-tests/client"
"github.com/smartcontractkit/chainlink/integration-tests/docker/test_env"
- "github.com/stretchr/testify/require"
- "math/big"
- "testing"
- "time"
)
func TestVRFBasic(t *testing.T) {
t.Parallel()
- l := utils.GetTestLogger(t)
+ l := logging.GetTestLogger(t)
+
env, err := test_env.NewCLTestEnvBuilder().
+ WithTestLogger(t).
WithGeth().
WithMockServer(1).
WithCLNodes(1).
- WithFunding(big.NewFloat(1)).
+ WithFunding(big.NewFloat(.1)).
Build()
require.NoError(t, err)
+ t.Cleanup(func() {
+ if err := env.Cleanup(t); err != nil {
+ l.Error().Err(err).Msg("Error cleaning up test environment")
+ }
+ })
env.ParallelTransactions(true)
lt, err := actions.DeployLINKToken(env.ContractDeployer)
@@ -57,6 +67,7 @@ func TestVRFBasic(t *testing.T) {
MinIncomingConfirmations: 1,
PublicKey: pubKeyCompressed,
ExternalJobID: jobUUID.String(),
+ EVMChainID: env.EVMClient.GetChainID().String(),
ObservationSource: ost,
})
require.NoError(t, err, "Creating VRF Job shouldn't fail")
diff --git a/integration-tests/smoke/vrfv2_test.go b/integration-tests/smoke/vrfv2_test.go
index ed9b9f16318..18e9efeae44 100644
--- a/integration-tests/smoke/vrfv2_test.go
+++ b/integration-tests/smoke/vrfv2_test.go
@@ -7,9 +7,10 @@ import (
"time"
"github.com/onsi/gomega"
- "github.com/smartcontractkit/chainlink-testing-framework/utils"
"github.com/stretchr/testify/require"
+ "github.com/smartcontractkit/chainlink-testing-framework/logging"
+
"github.com/smartcontractkit/chainlink/integration-tests/actions"
"github.com/smartcontractkit/chainlink/integration-tests/actions/vrfv2_actions"
vrfConst "github.com/smartcontractkit/chainlink/integration-tests/actions/vrfv2_actions/vrfv2_constants"
@@ -19,14 +20,20 @@ import (
func TestVRFv2Basic(t *testing.T) {
t.Parallel()
- l := utils.GetTestLogger(t)
+ l := logging.GetTestLogger(t)
env, err := test_env.NewCLTestEnvBuilder().
+ WithTestLogger(t).
WithGeth().
WithCLNodes(1).
WithFunding(vrfConst.ChainlinkNodeFundingAmountEth).
Build()
require.NoError(t, err)
+ t.Cleanup(func() {
+ if err := env.Cleanup(t); err != nil {
+ l.Error().Err(err).Msg("Error cleaning up test environment")
+ }
+ })
env.ParallelTransactions(true)
mockFeed, err := actions.DeployMockETHLinkFeed(env.ContractDeployer, vrfConst.LinkEthFeedResponse)
diff --git a/integration-tests/smoke/vrfv2plus_test.go b/integration-tests/smoke/vrfv2plus_test.go
new file mode 100644
index 00000000000..e26a4ed6b1f
--- /dev/null
+++ b/integration-tests/smoke/vrfv2plus_test.go
@@ -0,0 +1,456 @@
+package smoke
+
+import (
+ "context"
+ "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"
+
+ "github.com/smartcontractkit/chainlink/integration-tests/actions"
+ "github.com/smartcontractkit/chainlink/integration-tests/actions/vrfv2plus"
+ "github.com/smartcontractkit/chainlink/integration-tests/actions/vrfv2plus/vrfv2plus_constants"
+ "github.com/smartcontractkit/chainlink/integration-tests/docker/test_env"
+)
+
+func TestVRFv2PlusBilling(t *testing.T) {
+ t.Parallel()
+ l := logging.GetTestLogger(t)
+
+ env, err := test_env.NewCLTestEnvBuilder().
+ WithTestLogger(t).
+ WithGeth().
+ WithCLNodes(1).
+ WithFunding(vrfv2plus_constants.ChainlinkNodeFundingAmountNative).
+ Build()
+ require.NoError(t, err, "error creating test env")
+ t.Cleanup(func() {
+ if err := env.Cleanup(t); err != nil {
+ l.Error().Err(err).Msg("Error cleaning up test environment")
+ }
+ })
+
+ env.ParallelTransactions(true)
+
+ mockETHLinkFeed, err := actions.DeployMockETHLinkFeed(env.ContractDeployer, vrfv2plus_constants.LinkNativeFeedResponse)
+ require.NoError(t, err, "error deploying mock ETH/LINK feed")
+
+ linkToken, err := actions.DeployLINKToken(env.ContractDeployer)
+ require.NoError(t, err, "error deploying LINK contract")
+
+ 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().
+ 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")
+
+ t.Run("VRFV2 Plus With Link Billing", func(t *testing.T) {
+ var isNativeBilling = false
+ subBalanceBeforeRequest := subscription.Balance
+
+ jobRunsBeforeTest, err := env.CLNodes[0].API.MustReadRunsByJob(vrfv2PlusData.VRFJob.Data.ID)
+ require.NoError(t, err, "error reading job runs")
+
+ // test and assert
+ randomWordsFulfilledEvent, err := vrfv2plus.RequestRandomnessAndWaitForFulfillment(
+ vrfv2PlusContracts.LoadTestConsumers[0],
+ vrfv2PlusContracts.Coordinator,
+ vrfv2PlusData,
+ subID,
+ isNativeBilling,
+ l,
+ )
+ require.NoError(t, err, "error requesting randomness and waiting for fulfilment")
+
+ expectedSubBalanceJuels := new(big.Int).Sub(subBalanceBeforeRequest, randomWordsFulfilledEvent.Payment)
+ subscription, err = vrfv2PlusContracts.Coordinator.GetSubscription(context.Background(), subID)
+ require.NoError(t, err, "error getting subscription information")
+ subBalanceAfterRequest := subscription.Balance
+ require.Equal(t, expectedSubBalanceJuels, subBalanceAfterRequest)
+
+ jobRuns, err := env.CLNodes[0].API.MustReadRunsByJob(vrfv2PlusData.VRFJob.Data.ID)
+ require.NoError(t, err, "error reading job runs")
+ require.Equal(t, len(jobRunsBeforeTest.Data)+1, len(jobRuns.Data))
+
+ 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().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, 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.NativeBalance
+
+ jobRunsBeforeTest, err := env.CLNodes[0].API.MustReadRunsByJob(vrfv2PlusData.VRFJob.Data.ID)
+ require.NoError(t, err, "error reading job runs")
+
+ // test and assert
+ randomWordsFulfilledEvent, err := vrfv2plus.RequestRandomnessAndWaitForFulfillment(
+ vrfv2PlusContracts.LoadTestConsumers[0],
+ vrfv2PlusContracts.Coordinator,
+ vrfv2PlusData,
+ subID,
+ isNativeBilling,
+ l,
+ )
+ require.NoError(t, err, "error requesting randomness and waiting for fulfilment")
+ expectedSubBalanceWei := new(big.Int).Sub(subNativeTokenBalanceBeforeRequest, randomWordsFulfilledEvent.Payment)
+ subscription, err = vrfv2PlusContracts.Coordinator.GetSubscription(context.Background(), subID)
+ require.NoError(t, err)
+ subBalanceAfterRequest := subscription.NativeBalance
+ require.Equal(t, expectedSubBalanceWei, subBalanceAfterRequest)
+
+ jobRuns, err := env.CLNodes[0].API.MustReadRunsByJob(vrfv2PlusData.VRFJob.Data.ID)
+ require.NoError(t, err, "error reading job runs")
+ require.Equal(t, len(jobRunsBeforeTest.Data)+1, len(jobRuns.Data))
+
+ 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().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, 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")
+ }
+ })
+
+}
+func TestVRFv2PlusMigration(t *testing.T) {
+ t.Parallel()
+ l := logging.GetTestLogger(t)
+
+ env, err := test_env.NewCLTestEnvBuilder().
+ WithTestLogger(t).
+ WithGeth().
+ WithCLNodes(1).
+ WithFunding(vrfv2plus_constants.ChainlinkNodeFundingAmountNative).
+ Build()
+ require.NoError(t, err, "error creating test env")
+ t.Cleanup(func() {
+ if err := env.Cleanup(t); err != nil {
+ l.Error().Err(err).Msg("Error cleaning up test environment")
+ }
+ })
+
+ env.ParallelTransactions(true)
+
+ 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.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().
+ 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")
+
+ activeSubIdsOldCoordinatorBeforeMigration, err := vrfv2PlusContracts.Coordinator.GetActiveSubscriptionIds(context.Background(), big.NewInt(0), big.NewInt(0))
+ require.NoError(t, err, "error occurred getting active sub ids")
+ require.Len(t, activeSubIdsOldCoordinatorBeforeMigration, 1, "Active Sub Ids length is not equal to 1")
+ require.Equal(t, subID, activeSubIdsOldCoordinatorBeforeMigration[0])
+
+ oldSubscriptionBeforeMigration, err := vrfv2PlusContracts.Coordinator.GetSubscription(context.Background(), subID)
+ require.NoError(t, err, "error getting subscription information")
+
+ //Migration Process
+ newCoordinator, err := env.ContractDeployer.DeployVRFCoordinatorV2PlusUpgradedVersion(vrfv2PlusContracts.BHS.Address())
+ require.NoError(t, err, "error deploying VRF CoordinatorV2PlusUpgradedVersion")
+
+ err = env.EVMClient.WaitForEvents()
+ require.NoError(t, err, vrfv2plus.ErrWaitTXsComplete)
+
+ _, err = vrfv2plus.VRFV2PlusUpgradedVersionRegisterProvingKey(vrfv2PlusData.VRFKey, vrfv2PlusData.PrimaryEthAddress, newCoordinator)
+ require.NoError(t, err, errors.Wrap(err, vrfv2plus.ErrRegisteringProvingKey))
+
+ err = newCoordinator.SetConfig(
+ vrfv2plus_constants.MinimumConfirmations,
+ vrfv2plus_constants.MaxGasLimitVRFCoordinatorConfig,
+ vrfv2plus_constants.StalenessSeconds,
+ vrfv2plus_constants.GasAfterPaymentCalculation,
+ vrfv2plus_constants.LinkNativeFeedResponse,
+ vrfv2plus_constants.VRFCoordinatorV2PlusUpgradedVersionFeeConfig,
+ )
+
+ err = newCoordinator.SetLINKAndLINKNativeFeed(linkAddress.Address(), mockETHLinkFeedAddress.Address())
+ require.NoError(t, err, vrfv2plus.ErrSetLinkNativeLinkFeed)
+ err = env.EVMClient.WaitForEvents()
+ require.NoError(t, err, vrfv2plus.ErrWaitTXsComplete)
+
+ _, err = vrfv2plus.CreateVRFV2PlusJob(
+ env.GetAPIs()[0],
+ newCoordinator.Address(),
+ vrfv2PlusData.PrimaryEthAddress,
+ vrfv2PlusData.VRFKey.Data.ID,
+ vrfv2PlusData.ChainID.String(),
+ vrfv2plus_constants.MinimumConfirmations,
+ )
+ require.NoError(t, err, vrfv2plus.ErrCreateVRFV2PlusJobs)
+
+ err = vrfv2PlusContracts.Coordinator.RegisterMigratableCoordinator(newCoordinator.Address())
+ require.NoError(t, err, "error registering migratable coordinator")
+
+ err = env.EVMClient.WaitForEvents()
+ require.NoError(t, err, vrfv2plus.ErrWaitTXsComplete)
+
+ oldCoordinatorLinkTotalBalanceBeforeMigration, oldCoordinatorEthTotalBalanceBeforeMigration, err := vrfv2plus.GetCoordinatorTotalBalance(vrfv2PlusContracts.Coordinator)
+ require.NoError(t, err)
+
+ migratedCoordinatorLinkTotalBalanceBeforeMigration, migratedCoordinatorEthTotalBalanceBeforeMigration, err := vrfv2plus.GetUpgradedCoordinatorTotalBalance(newCoordinator)
+ require.NoError(t, err)
+
+ err = env.EVMClient.WaitForEvents()
+ require.NoError(t, err, vrfv2plus.ErrWaitTXsComplete)
+
+ err = vrfv2PlusContracts.Coordinator.Migrate(subID, newCoordinator.Address())
+ require.NoError(t, err, "error migrating sub id ", subID.String(), " from ", vrfv2PlusContracts.Coordinator.Address(), " to new Coordinator address ", newCoordinator.Address())
+ migrationCompletedEvent, err := vrfv2PlusContracts.Coordinator.WaitForMigrationCompletedEvent(time.Minute * 1)
+ require.NoError(t, err, "error waiting for MigrationCompleted event")
+ err = env.EVMClient.WaitForEvents()
+ require.NoError(t, err, vrfv2plus.ErrWaitTXsComplete)
+
+ l.Debug().
+ Str("Subscription ID", migrationCompletedEvent.SubId.String()).
+ Str("Migrated From Coordinator", vrfv2PlusContracts.Coordinator.Address()).
+ Str("Migrated To Coordinator", migrationCompletedEvent.NewCoordinator.String()).
+ Msg("MigrationCompleted Event")
+
+ oldCoordinatorLinkTotalBalanceAfterMigration, oldCoordinatorEthTotalBalanceAfterMigration, err := vrfv2plus.GetCoordinatorTotalBalance(vrfv2PlusContracts.Coordinator)
+ require.NoError(t, err)
+
+ migratedCoordinatorLinkTotalBalanceAfterMigration, migratedCoordinatorEthTotalBalanceAfterMigration, err := vrfv2plus.GetUpgradedCoordinatorTotalBalance(newCoordinator)
+ require.NoError(t, err)
+
+ migratedSubscription, err := newCoordinator.GetSubscription(context.Background(), subID)
+ require.NoError(t, err, "error getting subscription information")
+
+ l.Debug().
+ 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")
+
+ //Verify that Coordinators were updated in Consumers
+ for _, consumer := range vrfv2PlusContracts.LoadTestConsumers {
+ coordinatorAddressInConsumerAfterMigration, err := consumer.GetCoordinator(context.Background())
+ require.NoError(t, err, "error getting Coordinator from Consumer contract")
+ require.Equal(t, newCoordinator.Address(), coordinatorAddressInConsumerAfterMigration.String())
+ l.Debug().
+ Str("Consumer", consumer.Address()).
+ Str("Coordinator", coordinatorAddressInConsumerAfterMigration.String()).
+ Msg("Coordinator Address in Consumer After Migration")
+ }
+
+ //Verify old and migrated subs
+ 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)
+
+ //Verify that old sub was deleted from old Coordinator
+ _, err = vrfv2PlusContracts.Coordinator.GetSubscription(context.Background(), subID)
+ require.Error(t, err, "error not occurred when trying to get deleted subscription from old Coordinator after sub migration")
+
+ _, err = vrfv2PlusContracts.Coordinator.GetActiveSubscriptionIds(context.Background(), big.NewInt(0), big.NewInt(0))
+ require.Error(t, err, "error not occurred getting active sub ids. Should occur since it should revert when sub id array is empty")
+
+ activeSubIdsMigratedCoordinator, err := newCoordinator.GetActiveSubscriptionIds(context.Background(), big.NewInt(0), big.NewInt(0))
+ require.NoError(t, err, "error occurred getting active sub ids")
+ require.Len(t, activeSubIdsMigratedCoordinator, 1, "Active Sub Ids length is not equal to 1 for Migrated Coordinator after migration")
+ require.Equal(t, subID, activeSubIdsMigratedCoordinator[0])
+
+ //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.NativeBalance, migratedCoordinatorEthTotalBalanceBeforeMigration)
+
+ expectedLinkTotalBalanceForOldCoordinator := new(big.Int).Sub(oldCoordinatorLinkTotalBalanceBeforeMigration, oldSubscriptionBeforeMigration.Balance)
+ expectedEthTotalBalanceForOldCoordinator := new(big.Int).Sub(oldCoordinatorEthTotalBalanceBeforeMigration, oldSubscriptionBeforeMigration.NativeBalance)
+ require.Equal(t, expectedLinkTotalBalanceForMigratedCoordinator, migratedCoordinatorLinkTotalBalanceAfterMigration)
+ require.Equal(t, expectedEthTotalBalanceForMigratedCoordinator, migratedCoordinatorEthTotalBalanceAfterMigration)
+ require.Equal(t, expectedLinkTotalBalanceForOldCoordinator, oldCoordinatorLinkTotalBalanceAfterMigration)
+ require.Equal(t, expectedEthTotalBalanceForOldCoordinator, oldCoordinatorEthTotalBalanceAfterMigration)
+
+ //Verify rand requests fulfills with Link Token billing
+ _, err = vrfv2plus.RequestRandomnessAndWaitForFulfillmentUpgraded(
+ vrfv2PlusContracts.LoadTestConsumers[0],
+ newCoordinator,
+ vrfv2PlusData,
+ subID,
+ false,
+ l,
+ )
+ require.NoError(t, err, "error requesting randomness and waiting for fulfilment")
+
+ //Verify rand requests fulfills with Native Token billing
+ _, err = vrfv2plus.RequestRandomnessAndWaitForFulfillmentUpgraded(
+ vrfv2PlusContracts.LoadTestConsumers[1],
+ newCoordinator,
+ vrfv2PlusData,
+ subID,
+ true,
+ l,
+ )
+ require.NoError(t, err, "error requesting randomness and waiting for fulfilment")
+
+}
diff --git a/integration-tests/soak/forwarder_ocr_test.go b/integration-tests/soak/forwarder_ocr_test.go
index e8bcea0f5b8..bc02f367892 100644
--- a/integration-tests/soak/forwarder_ocr_test.go
+++ b/integration-tests/soak/forwarder_ocr_test.go
@@ -5,14 +5,14 @@ import (
"github.com/stretchr/testify/require"
- "github.com/smartcontractkit/chainlink-testing-framework/utils"
+ "github.com/smartcontractkit/chainlink-testing-framework/logging"
"github.com/smartcontractkit/chainlink/integration-tests/actions"
"github.com/smartcontractkit/chainlink/integration-tests/testsetups"
)
func TestForwarderOCRSoak(t *testing.T) {
- l := utils.GetTestLogger(t)
+ l := logging.GetTestLogger(t)
// Use this variable to pass in any custom EVM specific TOML values to your Chainlink nodes
customNetworkTOML := `[EVM.Transactions]
ForwardersEnabled = true`
diff --git a/integration-tests/soak/ocr_test.go b/integration-tests/soak/ocr_test.go
index c0fd0a4525f..b2375f13ac2 100644
--- a/integration-tests/soak/ocr_test.go
+++ b/integration-tests/soak/ocr_test.go
@@ -5,14 +5,14 @@ import (
"github.com/stretchr/testify/require"
- "github.com/smartcontractkit/chainlink-testing-framework/utils"
+ "github.com/smartcontractkit/chainlink-testing-framework/logging"
"github.com/smartcontractkit/chainlink/integration-tests/actions"
"github.com/smartcontractkit/chainlink/integration-tests/testsetups"
)
func TestOCRSoak(t *testing.T) {
- l := utils.GetTestLogger(t)
+ l := logging.GetTestLogger(t)
// Use this variable to pass in any custom EVM specific TOML values to your Chainlink nodes
customNetworkTOML := ``
// Uncomment below for debugging TOML issues on the node
diff --git a/integration-tests/testreporters/keeper_benchmark.go b/integration-tests/testreporters/keeper_benchmark.go
index 72d3e7c640d..c800eb37be2 100644
--- a/integration-tests/testreporters/keeper_benchmark.go
+++ b/integration-tests/testreporters/keeper_benchmark.go
@@ -28,6 +28,7 @@ type KeeperBenchmarkTestReporter struct {
ReportMutex sync.Mutex
AttemptedChainlinkTransactions []*client.TransactionsData `json:"attemptedChainlinkTransactions"`
NumRevertedUpkeeps int64
+ NumStaleUpkeepReports int64
Summary KeeperBenchmarkTestSummary `json:"summary"`
namespace string
@@ -60,8 +61,10 @@ type KeeperBenchmarkTestMetrics struct {
Delay map[string]interface{} `json:"delay"`
PercentWithinSLA float64 `json:"percentWithinSLA"`
PercentRevert float64 `json:"percentRevert"`
+ PercentStale float64 `json:"percentStale"`
TotalTimesEligible int64 `json:"totalTimesEligible"`
TotalTimesPerformed int64 `json:"totalTimesPerformed"`
+ TotalStaleReports int64 `json:"totalStaleReports"`
AverageActualPerformsPerBlock float64 `json:"averageActualPerformsPerBlock"`
}
@@ -91,7 +94,7 @@ func (k *KeeperBenchmarkTestReporter) WriteReport(folderLocation string) error {
defer keeperReportFile.Close()
keeperReportWriter := csv.NewWriter(keeperReportFile)
- var totalEligibleCount, totalPerformed, totalMissedSLA, totalReverted int64
+ var totalEligibleCount, totalPerformed, totalMissedSLA, totalReverted, totalStaleReports int64
var allDelays []int64
for _, report := range k.Reports {
totalEligibleCount += report.TotalEligibleCount
@@ -101,10 +104,12 @@ func (k *KeeperBenchmarkTestReporter) WriteReport(folderLocation string) error {
allDelays = append(allDelays, report.AllCheckDelays...)
}
totalReverted = k.NumRevertedUpkeeps
+ totalStaleReports = k.NumStaleUpkeepReports
pctWithinSLA := (1.0 - float64(totalMissedSLA)/float64(totalEligibleCount)) * 100
- var pctReverted float64
+ var pctReverted, pctStale float64
if totalPerformed > 0 {
pctReverted = (float64(totalReverted) / float64(totalPerformed)) * 100
+ pctStale = (float64(totalStaleReports) / float64(totalPerformed)) * 100
}
err = keeperReportWriter.Write([]string{"Full Test Summary"})
@@ -115,6 +120,7 @@ func (k *KeeperBenchmarkTestReporter) WriteReport(folderLocation string) error {
"Total Times Eligible",
"Total Performed",
"Total Reverted",
+ "Total Stale Reports",
"Average Perform Delay",
"Median Perform Delay",
"90th pct Perform Delay",
@@ -122,6 +128,7 @@ func (k *KeeperBenchmarkTestReporter) WriteReport(folderLocation string) error {
"Max Perform Delay",
"Percent Within SLA",
"Percent Revert",
+ "Percent Stale",
})
if err != nil {
return err
@@ -131,6 +138,7 @@ func (k *KeeperBenchmarkTestReporter) WriteReport(folderLocation string) error {
fmt.Sprint(totalEligibleCount),
fmt.Sprint(totalPerformed),
fmt.Sprint(totalReverted),
+ fmt.Sprint(totalStaleReports),
fmt.Sprintf("%.2f", avg),
fmt.Sprint(median),
fmt.Sprint(ninetyPct),
@@ -138,6 +146,7 @@ func (k *KeeperBenchmarkTestReporter) WriteReport(folderLocation string) error {
fmt.Sprint(max),
fmt.Sprintf("%.2f%%", pctWithinSLA),
fmt.Sprintf("%.2f%%", pctReverted),
+ fmt.Sprintf("%.2f%%", pctStale),
})
if err != nil {
return err
@@ -216,6 +225,8 @@ func (k *KeeperBenchmarkTestReporter) WriteReport(folderLocation string) error {
k.Summary.Metrics.PercentRevert = pctReverted
k.Summary.Metrics.TotalTimesEligible = totalEligibleCount
k.Summary.Metrics.TotalTimesPerformed = totalPerformed
+ k.Summary.Metrics.TotalStaleReports = totalStaleReports
+ k.Summary.Metrics.PercentStale = pctStale
k.Summary.Metrics.AverageActualPerformsPerBlock = float64(totalPerformed) / float64(k.Summary.TestInputs["BlockRange"].(int64))
// TODO: Set test expectations
diff --git a/integration-tests/testsetups/don_evm_chain.go b/integration-tests/testsetups/don_evm_chain.go
index a9e69b32f49..545d9515801 100644
--- a/integration-tests/testsetups/don_evm_chain.go
+++ b/integration-tests/testsetups/don_evm_chain.go
@@ -3,6 +3,7 @@ package testsetups
import (
"testing"
+ "github.com/rs/zerolog"
"github.com/stretchr/testify/require"
e "github.com/smartcontractkit/chainlink-env/environment"
@@ -25,6 +26,7 @@ type DonChain struct {
LinkTokenContract contracts.LinkToken
ChainlinkNodes []*client.ChainlinkK8sClient
Mockserver *ctfClient.MockserverClient
+ l zerolog.Logger
}
type DonChainConfig struct {
@@ -35,10 +37,11 @@ type DonChainConfig struct {
ChainlinkValues map[string]interface{}
}
-func NewDonChain(conf *DonChainConfig) *DonChain {
+func NewDonChain(conf *DonChainConfig, logger zerolog.Logger) *DonChain {
return &DonChain{
conf: conf,
EVMNetwork: conf.EVMNetwork,
+ l: logger,
}
}
@@ -59,10 +62,10 @@ func (s *DonChain) Deploy() {
func (s *DonChain) initializeClients() {
var err error
network := *s.conf.EVMNetwork
- s.EVMClient, err = blockchain.NewEVMClient(network, s.conf.Env)
+ s.EVMClient, err = blockchain.NewEVMClient(network, s.conf.Env, s.l)
require.NoError(s.conf.T, err, "Connecting to blockchain nodes shouldn't fail")
- s.ContractDeployer, err = contracts.NewContractDeployer(s.EVMClient)
+ s.ContractDeployer, err = contracts.NewContractDeployer(s.EVMClient, s.l)
require.NoError(s.conf.T, err)
s.ChainlinkNodes, err = client.ConnectChainlinkNodes(s.conf.Env)
diff --git a/integration-tests/testsetups/keeper_benchmark.go b/integration-tests/testsetups/keeper_benchmark.go
index 8bc11c43599..ba0cc23b23b 100644
--- a/integration-tests/testsetups/keeper_benchmark.go
+++ b/integration-tests/testsetups/keeper_benchmark.go
@@ -19,9 +19,10 @@ import (
"github.com/smartcontractkit/chainlink-env/environment"
"github.com/smartcontractkit/chainlink-testing-framework/blockchain"
+ "github.com/smartcontractkit/chainlink-testing-framework/logging"
reportModel "github.com/smartcontractkit/chainlink-testing-framework/testreporters"
- "github.com/smartcontractkit/chainlink-testing-framework/utils"
+ iregistry21 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/i_keeper_registry_master_wrapper_2_1"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_registry_wrapper1_1"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_registry_wrapper1_2"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/keeper_registry_wrapper1_3"
@@ -99,7 +100,7 @@ func NewKeeperBenchmarkTest(inputs KeeperBenchmarkTestInputs) *KeeperBenchmarkTe
// Setup prepares contracts for the test
func (k *KeeperBenchmarkTest) Setup(t *testing.T, env *environment.Environment) {
- l := utils.GetTestLogger(t)
+ l := logging.GetTestLogger(t)
startTime := time.Now()
k.TestReporter.Summary.StartTime = startTime.UnixMilli()
k.ensureInputValues(t)
@@ -111,10 +112,11 @@ func (k *KeeperBenchmarkTest) Setup(t *testing.T, env *environment.Environment)
k.keeperRegistrars = make([]contracts.KeeperRegistrar, len(inputs.RegistryVersions))
k.keeperConsumerContracts = make([]contracts.AutomationConsumerBenchmark, len(inputs.RegistryVersions))
k.upkeepIDs = make([][]*big.Int, len(inputs.RegistryVersions))
+ l.Debug().Interface("TestInputs", inputs).Msg("Setting up benchmark test")
var err error
// Connect to networks and prepare for contract deployment
- k.contractDeployer, err = contracts.NewContractDeployer(k.chainClient)
+ k.contractDeployer, err = contracts.NewContractDeployer(k.chainClient, l)
require.NoError(t, err, "Building a new contract deployer shouldn't fail")
k.chainlinkNodes, err = client.ConnectChainlinkNodes(k.env)
require.NoError(t, err, "Connecting to chainlink nodes shouldn't fail")
@@ -184,7 +186,7 @@ func (k *KeeperBenchmarkTest) Setup(t *testing.T, env *environment.Environment)
for index := range keysToFund {
// Fund chainlink nodes
nodesToFund := k.chainlinkNodes
- if inputs.RegistryVersions[index] == ethereum.RegistryVersion_2_0 {
+ if inputs.RegistryVersions[index] == ethereum.RegistryVersion_2_0 || inputs.RegistryVersions[index] == ethereum.RegistryVersion_2_1 {
nodesToFund = k.chainlinkNodes[1:]
}
err = actions.FundChainlinkNodesAddress(nodesToFund, k.chainClient, k.Inputs.ChainlinkNodeFunding, index)
@@ -200,7 +202,7 @@ func (k *KeeperBenchmarkTest) Setup(t *testing.T, env *environment.Environment)
// Run runs the keeper benchmark test
func (k *KeeperBenchmarkTest) Run(t *testing.T) {
- l := utils.GetTestLogger(t)
+ l := logging.GetTestLogger(t)
u := k.Inputs.Upkeeps
k.TestReporter.Summary.Load.TotalCheckGasPerBlock = int64(u.NumberOfUpkeeps) * u.CheckGasToBurn
k.TestReporter.Summary.Load.TotalPerformGasPerBlock = int64((float64(u.NumberOfUpkeeps) /
@@ -226,9 +228,6 @@ func (k *KeeperBenchmarkTest) Run(t *testing.T) {
nodesWithoutBootstrap := k.chainlinkNodes[1:]
for rIndex := range k.keeperRegistries {
- if k.Inputs.DeltaStage == 0 {
- k.Inputs.DeltaStage = k.Inputs.BlockTime * 5
- }
var txKeyId = rIndex
if inputs.ForceSingleTxnKey {
@@ -240,14 +239,14 @@ func (k *KeeperBenchmarkTest) Run(t *testing.T) {
require.NoError(t, err, "Building OCR config shouldn't fail")
// Send keeper jobs to registry and chainlink nodes
- if inputs.RegistryVersions[rIndex] == ethereum.RegistryVersion_2_0 {
- actions.CreateOCRKeeperJobs(t, k.chainlinkNodes, k.keeperRegistries[rIndex].Address(), k.chainClient.GetChainID().Int64(), txKeyId, ethereum.RegistryVersion_2_0)
+ if inputs.RegistryVersions[rIndex] == ethereum.RegistryVersion_2_0 || inputs.RegistryVersions[rIndex] == ethereum.RegistryVersion_2_1 {
+ actions.CreateOCRKeeperJobs(t, k.chainlinkNodes, k.keeperRegistries[rIndex].Address(), k.chainClient.GetChainID().Int64(), txKeyId, inputs.RegistryVersions[rIndex])
err = k.keeperRegistries[rIndex].SetConfig(*inputs.KeeperRegistrySettings, ocrConfig)
require.NoError(t, err, "Registry config should be be set successfully")
// Give time for OCR nodes to bootstrap
time.Sleep(1 * time.Minute)
} else {
- actions.CreateKeeperJobsWithKeyIndex(t, k.chainlinkNodes, k.keeperRegistries[rIndex], txKeyId, ocrConfig)
+ actions.CreateKeeperJobsWithKeyIndex(t, k.chainlinkNodes, k.keeperRegistries[rIndex], txKeyId, ocrConfig, k.chainClient.GetChainID().String())
}
err = k.chainClient.WaitForEvents()
require.NoError(t, err, "Error waiting for registry setConfig")
@@ -265,6 +264,7 @@ func (k *KeeperBenchmarkTest) Run(t *testing.T) {
&k.TestReporter,
int64(index),
inputs.Upkeeps.FirstEligibleBuffer,
+ l,
),
)
}
@@ -324,7 +324,7 @@ func (k *KeeperBenchmarkTest) subscribeToUpkeepPerformedEvent(
metricsReporter *testreporters.KeeperBenchmarkTestReporter,
rIndex int,
) {
- l := utils.GetTestLogger(t)
+ l := logging.GetTestLogger(t)
contractABI, err := keeper_registry_wrapper1_1.KeeperRegistryMetaData.GetAbi()
require.NoError(t, err, "Error getting ABI")
switch k.Inputs.RegistryVersions[rIndex] {
@@ -336,6 +336,8 @@ func (k *KeeperBenchmarkTest) subscribeToUpkeepPerformedEvent(
contractABI, err = keeper_registry_wrapper1_3.KeeperRegistryMetaData.GetAbi()
case ethereum.RegistryVersion_2_0:
contractABI, err = keeper_registry_wrapper2_0.KeeperRegistryMetaData.GetAbi()
+ case ethereum.RegistryVersion_2_1:
+ contractABI, err = iregistry21.IKeeperRegistryMasterMetaData.GetAbi()
default:
contractABI, err = keeper_registry_wrapper2_0.KeeperRegistryMetaData.GetAbi()
}
@@ -349,6 +351,7 @@ func (k *KeeperBenchmarkTest) subscribeToUpkeepPerformedEvent(
require.NoError(t, err, "Subscribing to upkeep performed events log shouldn't fail")
go func() {
var numRevertedUpkeeps int64
+ var numStaleReports int64
for {
select {
case err := <-sub.Err():
@@ -360,32 +363,44 @@ func (k *KeeperBenchmarkTest) subscribeToUpkeepPerformedEvent(
case vLog := <-eventLogs:
eventDetails, err := contractABI.EventByID(vLog.Topics[0])
require.NoError(t, err, "Getting event details for subscribed log shouldn't fail")
- if eventDetails.Name != "UpkeepPerformed" {
+ if eventDetails.Name != "UpkeepPerformed" && eventDetails.Name != "StaleUpkeepReport" {
// Skip non upkeepPerformed Logs
continue
}
- parsedLog, err := k.keeperRegistries[rIndex].ParseUpkeepPerformedLog(&vLog)
- require.NoError(t, err, "Parsing upkeep performed log shouldn't fail")
-
- if parsedLog.Success {
- l.Info().
- Str("Upkeep ID", parsedLog.Id.String()).
- Bool("Success", parsedLog.Success).
- Str("From", parsedLog.From.String()).
- Str("Registry", k.keeperRegistries[rIndex].Address()).
- Msg("Got successful Upkeep Performed log on Registry")
-
- } else {
+ if eventDetails.Name == "UpkeepPerformed" {
+ parsedLog, err := k.keeperRegistries[rIndex].ParseUpkeepPerformedLog(&vLog)
+ require.NoError(t, err, "Parsing upkeep performed log shouldn't fail")
+
+ if parsedLog.Success {
+ l.Info().
+ Str("Upkeep ID", parsedLog.Id.String()).
+ Bool("Success", parsedLog.Success).
+ Str("From", parsedLog.From.String()).
+ Str("Registry", k.keeperRegistries[rIndex].Address()).
+ Msg("Got successful Upkeep Performed log on Registry")
+
+ } else {
+ l.Warn().
+ Str("Upkeep ID", parsedLog.Id.String()).
+ Bool("Success", parsedLog.Success).
+ Str("From", parsedLog.From.String()).
+ Str("Registry", k.keeperRegistries[rIndex].Address()).
+ Msg("Got reverted Upkeep Performed log on Registry")
+ numRevertedUpkeeps++
+ }
+ } else if eventDetails.Name == "StaleUpkeepReport" {
+ parsedLog, err := k.keeperRegistries[rIndex].ParseStaleUpkeepReportLog(&vLog)
+ require.NoError(t, err, "Parsing stale upkeep report log shouldn't fail")
l.Warn().
Str("Upkeep ID", parsedLog.Id.String()).
- Bool("Success", parsedLog.Success).
- Str("From", parsedLog.From.String()).
Str("Registry", k.keeperRegistries[rIndex].Address()).
- Msg("Got reverted Upkeep Performed log on Registry")
- numRevertedUpkeeps++
+ Msg("Got stale Upkeep report log on Registry")
+ numStaleReports++
}
+
case <-doneChan:
metricsReporter.NumRevertedUpkeeps = numRevertedUpkeeps
+ metricsReporter.NumStaleUpkeepReports = numStaleReports
return
}
}
@@ -427,6 +442,10 @@ func (k *KeeperBenchmarkTest) ensureInputValues(t *testing.T) {
require.NotNil(t, inputs.Upkeeps.FirstEligibleBuffer, "You need to set FirstEligibleBuffer")
require.NotNil(t, inputs.RegistryVersions[0], "You need to set RegistryVersion")
require.NotNil(t, inputs.BlockTime, "You need to set BlockTime")
+
+ if k.Inputs.DeltaStage == 0 {
+ k.Inputs.DeltaStage = k.Inputs.BlockTime * 5
+ }
}
func (k *KeeperBenchmarkTest) SendSlackNotification(slackClient *slack.Client) error {
@@ -458,39 +477,53 @@ func (k *KeeperBenchmarkTest) DeployBenchmarkKeeperContracts(
t *testing.T,
index int,
) {
- l := utils.GetTestLogger(t)
+ l := logging.GetTestLogger(t)
registryVersion := k.Inputs.RegistryVersions[index]
+ k.Inputs.KeeperRegistrySettings.RegistryVersion = registryVersion
upkeep := k.Inputs.Upkeeps
- registry := actions.DeployKeeperRegistry(t, k.contractDeployer, k.chainClient,
- &contracts.KeeperRegistryOpts{
- RegistryVersion: registryVersion,
- LinkAddr: k.linkToken.Address(),
- ETHFeedAddr: k.ethFeed.Address(),
- GasFeedAddr: k.gasFeed.Address(),
- TranscoderAddr: actions.ZeroAddress.Hex(),
- RegistrarAddr: actions.ZeroAddress.Hex(),
- Settings: *k.Inputs.KeeperRegistrySettings,
- },
+ var (
+ registry contracts.KeeperRegistry
+ registrar contracts.KeeperRegistrar
)
- // Fund the registry with 1 LINK * amount of AutomationConsumerBenchmark contracts
- err := k.linkToken.Transfer(registry.Address(), big.NewInt(0).Mul(big.NewInt(1e18), big.NewInt(int64(k.Inputs.Upkeeps.NumberOfUpkeeps))))
- require.NoError(t, err, "Funding keeper registry contract shouldn't fail")
+ // Contract deployment is different for legacy keepers and OCR automation
+ if registryVersion <= ethereum.RegistryVersion_1_3 { // Legacy keeper - v1.X
+ registry = actions.DeployKeeperRegistry(t, k.contractDeployer, k.chainClient,
+ &contracts.KeeperRegistryOpts{
+ RegistryVersion: registryVersion,
+ LinkAddr: k.linkToken.Address(),
+ ETHFeedAddr: k.ethFeed.Address(),
+ GasFeedAddr: k.gasFeed.Address(),
+ TranscoderAddr: actions.ZeroAddress.Hex(),
+ RegistrarAddr: actions.ZeroAddress.Hex(),
+ Settings: *k.Inputs.KeeperRegistrySettings,
+ },
+ )
- registrarSettings := contracts.KeeperRegistrarSettings{
- AutoApproveConfigType: 2,
- AutoApproveMaxAllowed: math.MaxUint16,
- RegistryAddr: registry.Address(),
- MinLinkJuels: big.NewInt(0),
- }
- registrar := actions.DeployKeeperRegistrar(t, registryVersion, k.linkToken, registrarSettings, k.contractDeployer, k.chainClient, registry)
- if registryVersion == ethereum.RegistryVersion_2_0 {
- nodesWithoutBootstrap := k.chainlinkNodes[1:]
- ocrConfig, err := actions.BuildAutoOCR2ConfigVarsWithKeyIndex(
- t, nodesWithoutBootstrap, *k.Inputs.KeeperRegistrySettings, registrar.Address(), k.Inputs.DeltaStage, 0)
- require.NoError(t, err, "OCR config should be built successfully")
+ // Fund the registry with 1 LINK * amount of AutomationConsumerBenchmark contracts
+ err := k.linkToken.Transfer(registry.Address(), big.NewInt(0).Mul(big.NewInt(1e18), big.NewInt(int64(k.Inputs.Upkeeps.NumberOfUpkeeps))))
+ require.NoError(t, err, "Funding keeper registry contract shouldn't fail")
+
+ registrarSettings := contracts.KeeperRegistrarSettings{
+ AutoApproveConfigType: 2,
+ AutoApproveMaxAllowed: math.MaxUint16,
+ RegistryAddr: registry.Address(),
+ MinLinkJuels: big.NewInt(0),
+ }
+ registrar = actions.DeployKeeperRegistrar(t, registryVersion, k.linkToken, registrarSettings, k.contractDeployer, k.chainClient, registry)
+ } else { // OCR automation - v2.X
+ registry, registrar = actions.DeployAutoOCRRegistryAndRegistrar(
+ t, registryVersion, *k.Inputs.KeeperRegistrySettings, k.linkToken, k.contractDeployer, k.chainClient)
+
+ // Fund the registry with LINK
+ err := k.linkToken.Transfer(registry.Address(), big.NewInt(0).Mul(big.NewInt(1e18), big.NewInt(int64(k.Inputs.Upkeeps.NumberOfUpkeeps))))
+ require.NoError(t, err, "Funding keeper registry contract shouldn't fail")
+ ocrConfig, err := actions.BuildAutoOCR2ConfigVars(t, k.chainlinkNodes[1:], *k.Inputs.KeeperRegistrySettings, registrar.Address(), k.Inputs.DeltaStage)
+ l.Debug().Interface("KeeperRegistrySettings", *k.Inputs.KeeperRegistrySettings).Interface("OCRConfig", ocrConfig).Msg("Config")
+ require.NoError(t, err, "Error building OCR config vars")
err = registry.SetConfig(*k.Inputs.KeeperRegistrySettings, ocrConfig)
require.NoError(t, err, "Registry config should be be set successfully")
+
}
consumer := DeployKeeperConsumersBenchmark(t, k.contractDeployer, k.chainClient)
@@ -555,7 +588,7 @@ func DeployKeeperConsumersBenchmark(
contractDeployer contracts.ContractDeployer,
client blockchain.EVMClient,
) contracts.AutomationConsumerBenchmark {
- l := utils.GetTestLogger(t)
+ l := logging.GetTestLogger(t)
// Deploy consumer
keeperConsumerInstance, err := contractDeployer.DeployKeeperConsumerBenchmark()
diff --git a/integration-tests/testsetups/ocr.go b/integration-tests/testsetups/ocr.go
index 88f52fa16f3..5f12995cc06 100644
--- a/integration-tests/testsetups/ocr.go
+++ b/integration-tests/testsetups/ocr.go
@@ -22,7 +22,6 @@ import (
"github.com/kelseyhightower/envconfig"
"github.com/pelletier/go-toml/v2"
"github.com/rs/zerolog"
- "github.com/rs/zerolog/log"
"github.com/stretchr/testify/require"
"github.com/smartcontractkit/chainlink-env/environment"
@@ -32,15 +31,16 @@ import (
mockservercfg "github.com/smartcontractkit/chainlink-env/pkg/helm/mockserver-cfg"
"github.com/smartcontractkit/chainlink-testing-framework/blockchain"
ctfClient "github.com/smartcontractkit/chainlink-testing-framework/client"
+ "github.com/smartcontractkit/chainlink-testing-framework/logging"
reportModel "github.com/smartcontractkit/chainlink-testing-framework/testreporters"
- "github.com/smartcontractkit/chainlink-testing-framework/utils"
"github.com/smartcontractkit/libocr/gethwrappers/offchainaggregator"
+ "github.com/smartcontractkit/chainlink-testing-framework/networks"
+
"github.com/smartcontractkit/chainlink/integration-tests/actions"
"github.com/smartcontractkit/chainlink/integration-tests/client"
"github.com/smartcontractkit/chainlink/integration-tests/config"
"github.com/smartcontractkit/chainlink/integration-tests/contracts"
- "github.com/smartcontractkit/chainlink/integration-tests/networks"
"github.com/smartcontractkit/chainlink/integration-tests/testreporters"
)
@@ -114,7 +114,7 @@ func NewOCRSoakTest(t *testing.T, forwarderFlow bool) (*OCRSoakTest, error) {
t: t,
startTime: time.Now(),
timeLeft: testInputs.TestDuration,
- log: utils.GetTestLogger(t),
+ log: logging.GetTestLogger(t),
ocrRoundStates: make([]*testreporters.OCRRoundState, 0),
ocrInstanceMap: make(map[string]contracts.OffchainAggregator),
}
@@ -164,7 +164,7 @@ func (o *OCRSoakTest) LoadEnvironment(chainlinkURLs []string, chainURL, mockServ
network = networks.SelectedNetwork
err error
)
- o.chainClient, err = blockchain.ConnectEVMClient(network)
+ o.chainClient, err = blockchain.ConnectEVMClient(network, o.log)
require.NoError(o.t, err, "Error connecting to EVM client")
chainlinkNodes, err := client.ConnectChainlinkNodeURLs(chainlinkURLs)
require.NoError(o.t, err, "Error connecting to chainlink nodes")
@@ -186,9 +186,9 @@ func (o *OCRSoakTest) Setup() {
// Environment currently being used to soak test on
// Make connections to soak test resources
- o.chainClient, err = blockchain.NewEVMClient(network, o.testEnvironment)
+ o.chainClient, err = blockchain.NewEVMClient(network, o.testEnvironment, o.log)
require.NoError(o.t, err, "Error creating EVM client")
- contractDeployer, err := contracts.NewContractDeployer(o.chainClient)
+ contractDeployer, err := contracts.NewContractDeployer(o.chainClient, o.log)
require.NoError(o.t, err, "Unable to create contract deployer")
require.NotNil(o.t, contractDeployer, "Contract deployer shouldn't be nil")
nodes, err := client.ConnectChainlinkNodes(o.testEnvironment)
@@ -206,7 +206,7 @@ func (o *OCRSoakTest) Setup() {
require.NoError(o.t, err, "Error funding Chainlink nodes")
if o.OperatorForwarderFlow {
- contractLoader, err := contracts.NewContractLoader(o.chainClient)
+ contractLoader, err := contracts.NewContractLoader(o.chainClient, o.log)
require.NoError(o.t, err, "Loading contracts shouldn't fail")
operators, authorizedForwarders, _ := actions.DeployForwarderContracts(
@@ -262,9 +262,9 @@ func (o *OCRSoakTest) Run() {
startingValue := 5
if o.OperatorForwarderFlow {
- actions.CreateOCRJobsWithForwarder(o.t, o.ocrInstances, o.bootstrapNode, o.workerNodes, startingValue, o.mockServer)
+ actions.CreateOCRJobsWithForwarder(o.t, o.ocrInstances, o.bootstrapNode, o.workerNodes, startingValue, o.mockServer, o.chainClient.GetChainID().String())
} else {
- err := actions.CreateOCRJobs(o.ocrInstances, o.bootstrapNode, o.workerNodes, startingValue, o.mockServer)
+ err := actions.CreateOCRJobs(o.ocrInstances, o.bootstrapNode, o.workerNodes, startingValue, o.mockServer, o.chainClient.GetChainID().String())
require.NoError(o.t, err, "Error creating OCR jobs")
}
@@ -274,6 +274,7 @@ func (o *OCRSoakTest) Run() {
Msg("Starting OCR Soak Test")
o.testLoop(o.Inputs.TestDuration, startingValue)
+ o.complete()
}
// Networks returns the networks that the test is running on
@@ -383,11 +384,11 @@ func (o *OCRSoakTest) LoadState() error {
o.startingBlockNum = testState.StartingBlockNum
network := networks.SelectedNetwork
- o.chainClient, err = blockchain.ConnectEVMClient(network)
+ o.chainClient, err = blockchain.ConnectEVMClient(network, o.log)
if err != nil {
return err
}
- contractDeployer, err := contracts.NewContractDeployer(o.chainClient)
+ contractDeployer, err := contracts.NewContractDeployer(o.chainClient, o.log)
if err != nil {
return err
}
@@ -422,7 +423,10 @@ func (o *OCRSoakTest) Resume() {
StartTime: time.Now(),
Message: "Test Resumed",
})
- log.Info().Str("Time Left", o.Inputs.TestDuration.String()).Msg("Resuming OCR Soak Test")
+ o.log.Info().
+ Str("Total Duration", o.Inputs.TestDuration.String()).
+ Str("Time Left", o.timeLeft.String()).
+ Msg("Resuming OCR Soak Test")
ocrAddresses := make([]common.Address, len(o.ocrInstances))
for i, ocrInstance := range o.ocrInstances {
@@ -442,7 +446,7 @@ func (o *OCRSoakTest) Resume() {
o.log.Info().Msg("Test Complete, collecting on-chain events")
err = o.collectEvents()
- log.Error().Err(err).Interface("Query", o.filterQuery).Msg("Error collecting on-chain events, expect malformed report")
+ o.log.Error().Err(err).Interface("Query", o.filterQuery).Msg("Error collecting on-chain events, expect malformed report")
o.TestReporter.RecordEvents(o.ocrRoundStates, o.testIssues)
}
@@ -464,6 +468,7 @@ func (o *OCRSoakTest) testLoop(testDuration time.Duration, newValue int) {
lastValue := 0
newRoundTrigger := time.NewTimer(0) // Want to trigger a new round ASAP
defer newRoundTrigger.Stop()
+ o.setFilterQuery()
err := o.observeOCREvents()
require.NoError(o.t, err, "Error subscribing to OCR events")
@@ -479,7 +484,7 @@ func (o *OCRSoakTest) testLoop(testDuration time.Duration, newValue int) {
if err := o.SaveState(); err != nil {
o.log.Error().Err(err).Msg("Error saving state")
}
- log.Warn().Str("Time Taken", time.Since(saveStart).String()).Msg("Saved state")
+ o.log.Warn().Str("Time Taken", time.Since(saveStart).String()).Msg("Saved state")
os.Exit(2) // Exit with code 2 to indicate test was interrupted, not just a normal failure
case <-endTest:
return
@@ -514,10 +519,19 @@ func (o *OCRSoakTest) testLoop(testDuration time.Duration, newValue int) {
}
}
-// observeOCREvents subscribes to OCR events and logs them to the test logger
-// WARNING: Should only be used for observation and logging. This is not a reliable way to collect events.
-func (o *OCRSoakTest) observeOCREvents() error {
- // set the filter query to listen for AnswerUpdated events on all OCR contracts
+// completes the test
+func (o *OCRSoakTest) complete() {
+ o.log.Info().Msg("Test Complete, collecting on-chain events")
+
+ err := o.collectEvents()
+ if err != nil {
+ o.log.Error().Err(err).Interface("Query", o.filterQuery).Msg("Error collecting on-chain events, expect malformed report")
+ }
+ o.TestReporter.RecordEvents(o.ocrRoundStates, o.testIssues)
+}
+
+// setFilterQuery to look for all events that happened
+func (o *OCRSoakTest) setFilterQuery() {
ocrAddresses := make([]common.Address, len(o.ocrInstances))
for i, ocrInstance := range o.ocrInstances {
ocrAddresses[i] = common.HexToAddress(ocrInstance.Address())
@@ -529,7 +543,16 @@ func (o *OCRSoakTest) observeOCREvents() error {
Topics: [][]common.Hash{{contractABI.Events["AnswerUpdated"].ID}},
FromBlock: big.NewInt(0).SetUint64(o.startingBlockNum),
}
+ o.log.Debug().
+ Interface("Addresses", ocrAddresses).
+ Str("Topic", contractABI.Events["AnswerUpdated"].ID.Hex()).
+ Uint64("Starting Block", o.startingBlockNum).
+ Msg("Filter Query Set")
+}
+// observeOCREvents subscribes to OCR events and logs them to the test logger
+// WARNING: Should only be used for observation and logging. This is not a reliable way to collect events.
+func (o *OCRSoakTest) observeOCREvents() error {
eventLogs := make(chan types.Log)
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
@@ -545,7 +568,7 @@ func (o *OCRSoakTest) observeOCREvents() error {
case event := <-eventLogs:
answerUpdated, err := o.ocrInstances[0].ParseEventAnswerUpdated(event)
if err != nil {
- log.Warn().
+ o.log.Warn().
Err(err).
Str("Address", event.Address.Hex()).
Uint64("Block Number", event.BlockNumber).
@@ -560,7 +583,7 @@ func (o *OCRSoakTest) observeOCREvents() error {
Msg("Answer Updated Event")
case err = <-eventSub.Err():
for err != nil {
- o.log.Trace().
+ o.log.Info().
Err(err).
Interface("Query", o.filterQuery).
Msg("Error while subscribed to OCR Logs. Resubscribing")
@@ -609,18 +632,19 @@ func (o *OCRSoakTest) collectEvents() error {
o.log.Info().Msg("Collecting on-chain events")
// We must retrieve the events, use exponential backoff for timeout to retry
- var (
- contractEvents []types.Log
- err error
- timeout = time.Second * 15
- )
+ timeout := time.Second * 15
+ o.log.Info().Interface("Filter Query", o.filterQuery).Str("Timeout", timeout.String()).Msg("Retrieving on-chain events")
+
+ ctx, cancel := context.WithTimeout(context.Background(), timeout)
+ contractEvents, err := o.chainClient.FilterLogs(ctx, o.filterQuery)
+ cancel()
for err != nil {
- log.Info().Interface("Filter Query", o.filterQuery).Str("Timeout", timeout.String()).Msg("Retrieving on-chain events")
+ o.log.Info().Interface("Filter Query", o.filterQuery).Str("Timeout", timeout.String()).Msg("Retrieving on-chain events")
ctx, cancel := context.WithTimeout(context.Background(), timeout)
contractEvents, err = o.chainClient.FilterLogs(ctx, o.filterQuery)
cancel()
if err != nil {
- log.Warn().Interface("Filter Query", o.filterQuery).Str("Timeout", timeout.String()).Msg("Error collecting on-chain events, trying again")
+ o.log.Warn().Interface("Filter Query", o.filterQuery).Str("Timeout", timeout.String()).Msg("Error collecting on-chain events, trying again")
timeout *= 2
}
}
diff --git a/integration-tests/testsetups/vrfv2.go b/integration-tests/testsetups/vrfv2.go
index 7afe9cf2cca..cfa26e8f279 100644
--- a/integration-tests/testsetups/vrfv2.go
+++ b/integration-tests/testsetups/vrfv2.go
@@ -16,8 +16,8 @@ import (
"github.com/smartcontractkit/chainlink-env/environment"
"github.com/smartcontractkit/chainlink-testing-framework/blockchain"
+ "github.com/smartcontractkit/chainlink-testing-framework/logging"
reportModel "github.com/smartcontractkit/chainlink-testing-framework/testreporters"
- "github.com/smartcontractkit/chainlink-testing-framework/utils"
"github.com/smartcontractkit/chainlink/integration-tests/client"
"github.com/smartcontractkit/chainlink/integration-tests/contracts"
@@ -80,7 +80,7 @@ func (v *VRFV2SoakTest) Setup(t *testing.T, env *environment.Environment) {
// Run starts the VRFV2 soak test
func (v *VRFV2SoakTest) Run(t *testing.T) {
- l := utils.GetTestLogger(t)
+ l := logging.GetTestLogger(t)
l.Info().
Str("Test Duration", v.Inputs.TestDuration.Truncate(time.Second).String()).
Int("Max number of requests per minute wanted", v.Inputs.RequestsPerMinute).
diff --git a/integration-tests/types/config/node/core.go b/integration-tests/types/config/node/core.go
index 6968f3fadc4..3702d11745f 100644
--- a/integration-tests/types/config/node/core.go
+++ b/integration-tests/types/config/node/core.go
@@ -2,11 +2,9 @@ package node
import (
"bytes"
- "embed"
"fmt"
"math/big"
- "net"
- "path/filepath"
+ "os"
"time"
"go.uber.org/zap/zapcore"
@@ -22,48 +20,47 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/utils/config"
"github.com/smartcontractkit/chainlink/integration-tests/actions/vrfv2_actions/vrfv2_constants"
+ utils2 "github.com/smartcontractkit/chainlink/integration-tests/utils"
)
-var (
- BaseConf = &chainlink.Config{
+func NewBaseConfig() *chainlink.Config {
+ return &chainlink.Config{
Core: toml.Core{
- RootDir: ptr("/home/chainlink"),
+ RootDir: utils2.Ptr("/home/chainlink"),
Database: toml.Database{
- MaxIdleConns: ptr(int64(20)),
- MaxOpenConns: ptr(int64(40)),
- MigrateOnStartup: ptr(true),
+ MaxIdleConns: utils2.Ptr(int64(20)),
+ MaxOpenConns: utils2.Ptr(int64(40)),
+ MigrateOnStartup: utils2.Ptr(true),
},
Log: toml.Log{
- Level: ptr(toml.LogLevel(zapcore.DebugLevel)),
- JSONConsole: ptr(true),
+ Level: utils2.Ptr(toml.LogLevel(zapcore.DebugLevel)),
+ JSONConsole: utils2.Ptr(true),
File: toml.LogFile{
- MaxSize: ptr(utils.FileSize(0)),
+ MaxSize: utils2.Ptr(utils.FileSize(0)),
},
},
WebServer: toml.WebServer{
- AllowOrigins: ptr("*"),
- HTTPPort: ptr[uint16](6688),
- SecureCookies: ptr(false),
+ AllowOrigins: utils2.Ptr("*"),
+ HTTPPort: utils2.Ptr[uint16](6688),
+ SecureCookies: utils2.Ptr(false),
SessionTimeout: models.MustNewDuration(time.Hour * 999),
TLS: toml.WebServerTLS{
- HTTPSPort: ptr[uint16](0),
+ HTTPSPort: utils2.Ptr[uint16](0),
},
RateLimit: toml.WebServerRateLimit{
- Authenticated: ptr(int64(2000)),
- Unauthenticated: ptr(int64(100)),
+ Authenticated: utils2.Ptr(int64(2000)),
+ Unauthenticated: utils2.Ptr(int64(100)),
},
},
Feature: toml.Feature{
- LogPoller: ptr(true),
- FeedsManager: ptr(true),
- UICSAKeys: ptr(true),
+ LogPoller: utils2.Ptr(true),
+ FeedsManager: utils2.Ptr(true),
+ UICSAKeys: utils2.Ptr(true),
},
P2P: toml.P2P{},
},
}
- //go:embed defaults/*.toml
- defaultsFS embed.FS
-)
+}
type NodeConfigOpt = func(c *chainlink.Config)
@@ -75,26 +72,28 @@ func NewConfig(baseConf *chainlink.Config, opts ...NodeConfigOpt) *chainlink.Con
}
func NewConfigFromToml(tomlFile string, opts ...NodeConfigOpt) (*chainlink.Config, error) {
- path := filepath.Join("defaults", tomlFile+".toml")
- b, err := defaultsFS.ReadFile(path)
+ readFile, err := os.ReadFile(tomlFile)
if err != nil {
return nil, err
}
var cfg chainlink.Config
- err = config.DecodeTOML(bytes.NewReader(b), &cfg)
+ if err != nil {
+ return nil, err
+ }
+ err = config.DecodeTOML(bytes.NewReader(readFile), &cfg)
if err != nil {
return nil, err
}
for _, opt := range opts {
opt(&cfg)
}
- return &cfg, err
+ return &cfg, nil
}
func WithOCR1() NodeConfigOpt {
return func(c *chainlink.Config) {
c.OCR = toml.OCR{
- Enabled: ptr(true),
+ Enabled: utils2.Ptr(true),
}
}
}
@@ -102,7 +101,7 @@ func WithOCR1() NodeConfigOpt {
func WithOCR2() NodeConfigOpt {
return func(c *chainlink.Config) {
c.OCR2 = toml.OCR2{
- Enabled: ptr(true),
+ Enabled: utils2.Ptr(true),
}
}
}
@@ -110,9 +109,9 @@ func WithOCR2() NodeConfigOpt {
func WithP2Pv1() NodeConfigOpt {
return func(c *chainlink.Config) {
c.P2P.V1 = toml.P2PV1{
- Enabled: ptr(true),
- ListenIP: mustIP("0.0.0.0"),
- ListenPort: ptr[uint16](6690),
+ Enabled: utils2.Ptr(true),
+ ListenIP: utils2.MustIP("0.0.0.0"),
+ ListenPort: utils2.Ptr[uint16](6690),
}
}
}
@@ -120,7 +119,7 @@ func WithP2Pv1() NodeConfigOpt {
func WithP2Pv2() NodeConfigOpt {
return func(c *chainlink.Config) {
c.P2P.V2 = toml.P2PV2{
- Enabled: ptr(true),
+ Enabled: utils2.Ptr(true),
ListenAddresses: &[]string{"0.0.0.0:6690"},
}
}
@@ -137,10 +136,10 @@ func SetChainConfig(
var nodes []*evmcfg.Node
for i := range wsUrls {
node := evmcfg.Node{
- Name: ptr(fmt.Sprintf("node_%d_%s", i, chain.Name)),
- WSURL: mustURL(wsUrls[i]),
- HTTPURL: mustURL(httpUrls[i]),
- SendOnly: ptr(false),
+ Name: utils2.Ptr(fmt.Sprintf("node_%d_%s", i, chain.Name)),
+ WSURL: utils2.MustURL(wsUrls[i]),
+ HTTPURL: utils2.MustURL(httpUrls[i]),
+ SendOnly: utils2.Ptr(false),
}
nodes = append(nodes, &node)
@@ -148,8 +147,8 @@ func SetChainConfig(
var chainConfig evmcfg.Chain
if chain.Simulated {
chainConfig = evmcfg.Chain{
- AutoCreateKey: ptr(true),
- FinalityDepth: ptr[uint32](1),
+ AutoCreateKey: utils2.Ptr(true),
+ FinalityDepth: utils2.Ptr[uint32](1),
MinContractPayment: assets.NewLinkFromJuels(0),
}
}
@@ -162,7 +161,7 @@ func SetChainConfig(
}
if forwarders {
cfg.EVM[0].Transactions = evmcfg.Transactions{
- ForwardersEnabled: ptr(true),
+ ForwardersEnabled: utils2.Ptr(true),
}
}
}
@@ -174,25 +173,25 @@ func WithPrivateEVMs(networks []blockchain.EVMNetwork) NodeConfigOpt {
evmConfigs = append(evmConfigs, &evmcfg.EVMConfig{
ChainID: utils.NewBig(big.NewInt(network.ChainID)),
Chain: evmcfg.Chain{
- AutoCreateKey: ptr(true),
- FinalityDepth: ptr[uint32](50),
+ AutoCreateKey: utils2.Ptr(true),
+ FinalityDepth: utils2.Ptr[uint32](50),
MinContractPayment: assets.NewLinkFromJuels(0),
LogPollInterval: models.MustNewDuration(1 * time.Second),
HeadTracker: evmcfg.HeadTracker{
- HistoryDepth: ptr(uint32(100)),
+ HistoryDepth: utils2.Ptr(uint32(100)),
},
GasEstimator: evmcfg.GasEstimator{
- LimitDefault: ptr(uint32(6000000)),
+ LimitDefault: utils2.Ptr(uint32(6000000)),
PriceMax: assets.GWei(200),
FeeCapDefault: assets.GWei(200),
},
},
Nodes: []*evmcfg.Node{
{
- Name: ptr(network.Name),
- WSURL: mustURL(network.URLs[0]),
- HTTPURL: mustURL(network.HTTPURLs[0]),
- SendOnly: ptr(false),
+ Name: utils2.Ptr(network.Name),
+ WSURL: utils2.MustURL(network.URLs[0]),
+ HTTPURL: utils2.MustURL(network.HTTPURLs[0]),
+ SendOnly: utils2.Ptr(false),
},
},
})
@@ -207,35 +206,17 @@ func WithVRFv2EVMEstimator(addr string) NodeConfigOpt {
return func(c *chainlink.Config) {
c.EVM[0].KeySpecific = evmcfg.KeySpecificConfig{
{
- Key: ptr(ethkey.EIP55Address(addr)),
+ Key: utils2.Ptr(ethkey.EIP55Address(addr)),
GasEstimator: evmcfg.KeySpecificGasEstimator{
PriceMax: est,
},
},
}
c.EVM[0].Chain.GasEstimator = evmcfg.GasEstimator{
- LimitDefault: ptr[uint32](3500000),
+ LimitDefault: utils2.Ptr[uint32](3500000),
}
c.EVM[0].Chain.Transactions = evmcfg.Transactions{
- MaxQueued: ptr[uint32](10000),
+ MaxQueued: utils2.Ptr[uint32](10000),
}
}
}
-
-func ptr[T any](t T) *T { return &t }
-
-func mustURL(s string) *models.URL {
- var u models.URL
- if err := u.UnmarshalText([]byte(s)); err != nil {
- panic(err)
- }
- return &u
-}
-
-func mustIP(s string) *net.IP {
- var ip net.IP
- if err := ip.UnmarshalText([]byte(s)); err != nil {
- panic(err)
- }
- return &ip
-}
diff --git a/integration-tests/utils/common.go b/integration-tests/utils/common.go
new file mode 100644
index 00000000000..c8243097a7d
--- /dev/null
+++ b/integration-tests/utils/common.go
@@ -0,0 +1,25 @@
+package utils
+
+import (
+ "net"
+
+ "github.com/smartcontractkit/chainlink/v2/core/store/models"
+)
+
+func Ptr[T any](t T) *T { return &t }
+
+func MustURL(s string) *models.URL {
+ var u models.URL
+ if err := u.UnmarshalText([]byte(s)); err != nil {
+ panic(err)
+ }
+ return &u
+}
+
+func MustIP(s string) *net.IP {
+ var ip net.IP
+ if err := ip.UnmarshalText([]byte(s)); err != nil {
+ panic(err)
+ }
+ return &ip
+}
diff --git a/integration-tests/utils/templates/geth.go b/integration-tests/utils/templates/geth.go
deleted file mode 100644
index 11ccc8dd4ba..00000000000
--- a/integration-tests/utils/templates/geth.go
+++ /dev/null
@@ -1,56 +0,0 @@
-package templates
-
-import (
- "github.com/google/uuid"
-)
-
-type GenesisJsonTemplate struct {
- AccountAddr string
- ChainId string
-}
-
-// String representation of the job
-func (c GenesisJsonTemplate) String() (string, error) {
- tpl := `
-{
- "config": {
- "chainId": {{ .ChainId }},
- "homesteadBlock": 0,
- "eip150Block": 0,
- "eip155Block": 0,
- "eip158Block": 0,
- "eip160Block": 0,
- "byzantiumBlock": 0,
- "constantinopleBlock": 0,
- "petersburgBlock": 0,
- "istanbulBlock": 0,
- "muirGlacierBlock": 0,
- "berlinBlock": 0,
- "londonBlock": 0
- },
- "nonce": "0x0000000000000042",
- "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "difficulty": "1",
- "coinbase": "0x3333333333333333333333333333333333333333",
- "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "extraData": "0x",
- "gasLimit": "8000000000",
- "alloc": {
- "{{ .AccountAddr }}": {
- "balance": "20000000000000000000000"
- }
- }
- }`
- return MarshalTemplate(c, uuid.NewString(), tpl)
-}
-
-var InitGethScript = `
-#!/bin/bash
-if [ ! -d /root/.ethereum/keystore ]; then
- echo "/root/.ethereum/keystore not found, running 'geth init'..."
- geth init /root/genesis.json
- echo "...done!"
-fi
-
-geth "$@"
-`
diff --git a/integration-tests/utils/templates/secrets.go b/integration-tests/utils/templates/secrets.go
index 09d45f15cca..3d3f9e44a90 100644
--- a/integration-tests/utils/templates/secrets.go
+++ b/integration-tests/utils/templates/secrets.go
@@ -1,6 +1,9 @@
package templates
-import "github.com/google/uuid"
+import (
+ "github.com/google/uuid"
+ "github.com/smartcontractkit/chainlink-testing-framework/utils/templates"
+)
// NodeSecretsTemplate are used as text templates because of secret redacted fields of chainlink.Secrets
// secret fields can't be marshalled as a plain text
@@ -25,5 +28,5 @@ URL = 'localhost:1338'
Username = 'node'
Password = 'nodepass'
`
- return MarshalTemplate(c, uuid.NewString(), tpl)
+ return templates.MarshalTemplate(c, uuid.NewString(), tpl)
}
diff --git a/integration-tests/utils/templates/template.go b/integration-tests/utils/templates/template.go
deleted file mode 100644
index 515c9968e1f..00000000000
--- a/integration-tests/utils/templates/template.go
+++ /dev/null
@@ -1,25 +0,0 @@
-package templates
-
-import (
- "bytes"
- "errors"
- "text/template"
-)
-
-var (
- ErrParsingTemplate = errors.New("failed to parse Go text template")
-)
-
-// MarshalTemplate Helper to marshal templates
-func MarshalTemplate(jobSpec interface{}, name, templateString string) (string, error) {
- var buf bytes.Buffer
- tmpl, err := template.New(name).Parse(templateString)
- if err != nil {
- return "", errors.Join(err, ErrParsingTemplate)
- }
- err = tmpl.Execute(&buf, jobSpec)
- if err != nil {
- return "", err
- }
- return buf.String(), err
-}
diff --git a/operator_ui/TAG b/operator_ui/TAG
index b6ab818cb54..6762dd4e0f7 100644
--- a/operator_ui/TAG
+++ b/operator_ui/TAG
@@ -1 +1 @@
-v0.8.0-95ae9da
+v0.8.0-a8fbbb3
diff --git a/plugins/README.md b/plugins/README.md
index ab6aeed7a3c..73c39c6c94d 100644
--- a/plugins/README.md
+++ b/plugins/README.md
@@ -13,18 +13,42 @@ plugin. The [cmd](cmd) directory contains their `package main`s for now. These c
## How to use
[chainlink.Dockerfile](chainlink.Dockerfile) extends the regular [core/chainlink.Dockerfile](../core/chainlink.Dockerfile)
-to include the plugin binaries, and enables support by setting `CL_SOLANA_CMD` and `CL_MEDIAN_CMD`. Either plugin can be
-disabled by un-setting the environment variable, which will revert to the original in-process runtime. Images built from
-this Dockerfile can otherwise be used normally, provided that the [pre-requisites](#pre-requisites) have been met.
+to include the plugin binaries, and enables support by setting `CL_SOLANA_CMD`, `CL_STARKNET_CMD`, and `CL_MEDIAN_CMD`.
+Either plugin can be disabled by un-setting the environment variable, which will revert to the original in-process runtime.
+Images built from this Dockerfile can otherwise be used normally, provided that the [pre-requisites](#pre-requisites) have been met.
### Pre-requisites
#### Timeouts
LOOPPs communicate over GRPC, which always includes a `context.Context` and requires realistic timeouts. Placeholder/dummy
-values (e.g. `MaxDurationQuery = 0`) will not work and must be updated to realistic values.
-
+values (e.g. `MaxDurationQuery = 0`) will not work and must be updated to realistic values. In lieu of reconfiguring already
+deployed contracts on Solana, the environment variable `CL_MIN_OCR2_MAX_DURATION_QUERY` can be set establish a new minimum
+via libocr's [LocalConfig.MinOCR2MaxDurationQuery](https://pkg.go.dev/github.com/smartcontractkit/libocr/offchainreporting2plus/types#LocalConfig).
+If left unset, the default value is `100ms`.
#### Prometheus
-TODO how to preserve metrics https://smartcontract-it.atlassian.net/browse/BCF-2202
+
+LOOPPs are dynamic, and so must be monitoring.
+We use Plugin discovery to dynamically determine what to monitor based on what plugins are running
+and we route external prom scraping to the plugins without exposing them directly
+
+The endpoints are
+
+`/discovery` : HTTP Service Discovery [https://prometheus.io/docs/prometheus/latest/configuration/configuration/#http_sd_config]
+Prometheus server is configured to poll this url to discover new endpoints to monitor. The node serves the response based on what plugins are running,
+
+`/plugins//metrics`: The node acts as very thin middleware to route from Prometheus server scrape requests to individual plugin /metrics endpoint
+Once a plugin is discovered via the discovery mechanism above, the Prometheus service calls the target endpoint at the scrape interval
+The node acts as middleware to route the request to the /metrics endpoint of the requested plugin
+
+The simplest change to monitor LOOPPs is to add a service discovery to the scrape configuration
+- job_name: 'chainlink_node'
+ ...
++ http_sd_configs:
++ - url: "http://127.0.0.1:6688/discovery"
++ refresh_interval: 30s
+
+
+See the Prometheus documentation for full details [https://prometheus.io/docs/prometheus/latest/configuration/configuration/#http_sd_config]
\ No newline at end of file
diff --git a/plugins/chainlink.Dockerfile b/plugins/chainlink.Dockerfile
index f983c18d1a0..6f713e078af 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 aac68eb5005..00836fa7c24 100644
--- a/plugins/cmd/chainlink-median/main.go
+++ b/plugins/cmd/chainlink-median/main.go
@@ -14,13 +14,13 @@ const (
)
func main() {
- s := plugins.StartServer(loggerName)
+ s := plugins.MustNewStartedServer(loggerName)
defer s.Stop()
p := median.NewPlugin(s.Logger)
defer s.Logger.ErrorIfFn(p.Close, "Failed to close")
- s.MustRegister(p.Name(), p)
+ s.MustRegister(p)
stop := make(chan struct{})
defer close(stop)
diff --git a/plugins/cmd/chainlink-solana/main.go b/plugins/cmd/chainlink-solana/main.go
index 3e1d7c05cb5..ec30fa59f41 100644
--- a/plugins/cmd/chainlink-solana/main.go
+++ b/plugins/cmd/chainlink-solana/main.go
@@ -21,13 +21,13 @@ const (
)
func main() {
- s := plugins.StartServer(loggerName)
+ s := plugins.MustNewStartedServer(loggerName)
defer s.Stop()
p := &pluginRelayer{Base: plugins.Base{Logger: s.Logger}}
defer s.Logger.ErrorIfFn(p.Close, "Failed to close")
- s.MustRegister(p.Name(), p)
+ s.MustRegister(p)
stopCh := make(chan struct{})
defer close(stopCh)
@@ -56,21 +56,22 @@ func (c *pluginRelayer) NewRelayer(ctx context.Context, config string, keystore
d := toml.NewDecoder(strings.NewReader(config))
d.DisallowUnknownFields()
var cfg struct {
- Solana solana.SolanaConfigs
+ Solana solana.SolanaConfig
}
+
if err := d.Decode(&cfg); err != nil {
- return nil, fmt.Errorf("failed to decode config toml: %w", err)
+ return nil, fmt.Errorf("failed to decode config toml: %w:\n\t%s", err, config)
}
- chainSet, err := solana.NewChainSet(solana.ChainSetOpts{
+ opts := solana.ChainOpts{
Logger: c.Logger,
KeyStore: keystore,
- Configs: solana.NewConfigs(cfg.Solana),
- }, cfg.Solana)
+ }
+ chain, err := solana.NewChain(&cfg.Solana, opts)
if err != nil {
return nil, fmt.Errorf("failed to create chain: %w", err)
}
- ra := relay.NewRelayerAdapter(pkgsol.NewRelayer(c.Logger, chainSet), chainSet)
+ ra := relay.NewRelayerAdapter(pkgsol.NewRelayer(c.Logger, chain), chain)
c.SubService(ra)
diff --git a/plugins/cmd/chainlink-starknet/main.go b/plugins/cmd/chainlink-starknet/main.go
index 835ea9a18d4..1052f3c1fc6 100644
--- a/plugins/cmd/chainlink-starknet/main.go
+++ b/plugins/cmd/chainlink-starknet/main.go
@@ -21,13 +21,13 @@ const (
)
func main() {
- s := plugins.StartServer(loggerName)
+ s := plugins.MustNewStartedServer(loggerName)
defer s.Stop()
p := &pluginRelayer{Base: plugins.Base{Logger: s.Logger}}
defer s.Logger.ErrorIfFn(p.Close, "Failed to close")
- s.MustRegister(p.Name(), p)
+ s.MustRegister(p)
stopCh := make(chan struct{})
defer close(stopCh)
@@ -60,21 +60,22 @@ func (c *pluginRelayer) NewRelayer(ctx context.Context, config string, loopKs lo
d := toml.NewDecoder(strings.NewReader(config))
d.DisallowUnknownFields()
var cfg struct {
- Starknet starknet.StarknetConfigs
+ Starknet starknet.StarknetConfig
}
if err := d.Decode(&cfg); err != nil {
- return nil, fmt.Errorf("failed to decode config toml: %w", err)
+ return nil, fmt.Errorf("failed to decode config toml: %w:\n\t%s", err, config)
}
- chainSet, err := starknet.NewChainSet(starknet.ChainSetOpts{
+ opts := starknet.ChainOpts{
Logger: c.Logger,
KeyStore: loopKs,
- Configs: starknet.NewConfigs(cfg.Starknet),
- }, cfg.Starknet)
+ }
+
+ chain, err := starknet.NewChain(&cfg.Starknet, opts)
if err != nil {
return nil, fmt.Errorf("failed to create chain: %w", err)
}
- ra := relay.NewRelayerAdapter(pkgstarknet.NewRelayer(c.Logger, chainSet), chainSet)
+ ra := relay.NewRelayerAdapter(pkgstarknet.NewRelayer(c.Logger, chain), chain)
c.SubService(ra)
diff --git a/plugins/loop_registry.go b/plugins/loop_registry.go
index b24c6ee7d98..c8bab8a9949 100644
--- a/plugins/loop_registry.go
+++ b/plugins/loop_registry.go
@@ -31,7 +31,7 @@ type LoopRegistry struct {
func NewLoopRegistry(lggr logger.Logger) *LoopRegistry {
return &LoopRegistry{
registry: map[string]*RegisteredLoop{},
- lggr: lggr,
+ lggr: logger.Named(lggr, "LoopRegistry"),
}
}
@@ -48,7 +48,7 @@ func (m *LoopRegistry) Register(id string) (*RegisteredLoop, error) {
envCfg := NewEnvConfig(nextPort)
m.registry[id] = &RegisteredLoop{Name: id, EnvCfg: envCfg}
- m.lggr.Debug("Registered loopp %q with config %v, port %d", id, envCfg, envCfg.PrometheusPort())
+ m.lggr.Debugf("Registered loopp %q with config %v, port %d", id, envCfg, envCfg.PrometheusPort())
return m.registry[id], nil
}
diff --git a/plugins/plugin.go b/plugins/plugin.go
index dff3345efd3..0b93ef26f5c 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 2c1bffb85b8..3b0348a68b4 100644
--- a/plugins/server.go
+++ b/plugins/server.go
@@ -9,61 +9,91 @@ 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.
-func (s *Server) MustRegister(name string, c services.Checkable) {
- err := s.Register(name, c)
- if err != nil {
- s.Logger.Fatalf("Failed to register %s with health checker: %v", name, err)
+func (s *Server) MustRegister(c services.Checkable) {
+ if err := s.Register(c); err != nil {
+ s.Logger.Fatalf("Failed to register %s with health checker: %v", c.Name(), err)
}
}
// 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 28f9ca8a84c..ea142ce17fe 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/testdata/scripts/node/validate/default.txtar b/testdata/scripts/node/validate/default.txtar
index 8a678e96cb9..85b16edaa27 100644
--- a/testdata/scripts/node/validate/default.txtar
+++ b/testdata/scripts/node/validate/default.txtar
@@ -10,7 +10,6 @@ AllowSimplePasswords = false
# Input Configuration:
# Effective Configuration, with defaults applied:
-ExplorerURL = ''
InsecureFastScrypt = false
RootDir = '~/.chainlink'
ShutdownGracePeriod = '5s'
diff --git a/testdata/scripts/node/validate/disk-based-logging-disabled.txtar b/testdata/scripts/node/validate/disk-based-logging-disabled.txtar
index 1692480a698..5f02793ff57 100644
--- a/testdata/scripts/node/validate/disk-based-logging-disabled.txtar
+++ b/testdata/scripts/node/validate/disk-based-logging-disabled.txtar
@@ -54,7 +54,6 @@ WSURL = 'wss://foo.bar/ws'
HTTPURL = 'https://foo.bar'
# Effective Configuration, with defaults applied:
-ExplorerURL = ''
InsecureFastScrypt = false
RootDir = '~/.chainlink'
ShutdownGracePeriod = '5s'
diff --git a/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar b/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar
index 7f6104afeca..527a739f7ca 100644
--- a/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar
+++ b/testdata/scripts/node/validate/disk-based-logging-no-dir.txtar
@@ -54,7 +54,6 @@ WSURL = 'wss://foo.bar/ws'
HTTPURL = 'https://foo.bar'
# Effective Configuration, with defaults applied:
-ExplorerURL = ''
InsecureFastScrypt = false
RootDir = '~/.chainlink'
ShutdownGracePeriod = '5s'
diff --git a/testdata/scripts/node/validate/disk-based-logging.txtar b/testdata/scripts/node/validate/disk-based-logging.txtar
index e5d5151376e..791a8aad076 100644
--- a/testdata/scripts/node/validate/disk-based-logging.txtar
+++ b/testdata/scripts/node/validate/disk-based-logging.txtar
@@ -54,7 +54,6 @@ WSURL = 'wss://foo.bar/ws'
HTTPURL = 'https://foo.bar'
# Effective Configuration, with defaults applied:
-ExplorerURL = ''
InsecureFastScrypt = false
RootDir = '~/.chainlink'
ShutdownGracePeriod = '5s'
diff --git a/testdata/scripts/node/validate/invalid.txtar b/testdata/scripts/node/validate/invalid.txtar
index 974bb507f9a..e9db92fb8f7 100644
--- a/testdata/scripts/node/validate/invalid.txtar
+++ b/testdata/scripts/node/validate/invalid.txtar
@@ -44,7 +44,6 @@ WSURL = 'wss://foo.bar/ws'
HTTPURL = 'https://foo.bar'
# Effective Configuration, with defaults applied:
-ExplorerURL = ''
InsecureFastScrypt = false
RootDir = '~/.chainlink'
ShutdownGracePeriod = '5s'
diff --git a/testdata/scripts/node/validate/valid.txtar b/testdata/scripts/node/validate/valid.txtar
index 0fc036a899c..f48fa1926d8 100644
--- a/testdata/scripts/node/validate/valid.txtar
+++ b/testdata/scripts/node/validate/valid.txtar
@@ -51,7 +51,6 @@ WSURL = 'wss://foo.bar/ws'
HTTPURL = 'https://foo.bar'
# Effective Configuration, with defaults applied:
-ExplorerURL = ''
InsecureFastScrypt = false
RootDir = '~/.chainlink'
ShutdownGracePeriod = '5s'
diff --git a/tools/docker/README.md b/tools/docker/README.md
index cd2b39307f8..58c1e196699 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 0257a766b62..72f2f06d7ce 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 b8150e2c894..b16c1e19332 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/config.toml b/tools/docker/config.toml
index 2c21ce008c8..23108ae295c 100644
--- a/tools/docker/config.toml
+++ b/tools/docker/config.toml
@@ -1,5 +1,3 @@
-ExplorerURL = 'ws://explorer:3001'
-
[Log]
Level = 'info'
diff --git a/tools/docker/dev-secrets.toml b/tools/docker/dev-secrets.toml
index 41554f9c4f9..b27b8a8a8e3 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 9ebf82df071..46fad445d66 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 25793e7cfe8..00000000000
--- 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 85361e15220..00000000000
--- 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 19f8026b203..4d3ef7def20 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 04dad6fea06..beecd8b3e4f 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 325c39a0438..f63b89273c9 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 592b673a23b..d935000222f 100644
--- a/tools/flakeytests/runner.go
+++ b/tools/flakeytests/runner.go
@@ -3,6 +3,8 @@ package flakeytests
import (
"bufio"
"bytes"
+ "encoding/json"
+ "errors"
"fmt"
"io"
"log"
@@ -10,72 +12,118 @@ import (
"os/exec"
"regexp"
"strings"
+ "time"
)
var (
- failedTestRe = regexp.MustCompile(`^--- FAIL: (Test\w+)`)
- logPanicRe = regexp.MustCompile(`^panic: Log in goroutine after (Test\w+)`)
-
- failedPkgRe = regexp.MustCompile(`^FAIL\s+github\.com\/smartcontractkit\/chainlink\/v2\/(\S+)`)
+ panicRe = regexp.MustCompile(`^panic:`)
)
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 {
+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()
}
+type TestEvent struct {
+ Time time.Time
+ Action string
+ Package string
+ Test string
+ Elapsed float64 // seconds
+ Output string
+}
+
+func newEvent(b []byte) (*TestEvent, error) {
+ e := &TestEvent{}
+ err := json.Unmarshal(b, e)
+ return e, err
+}
+
func parseOutput(readers ...io.Reader) (map[string]map[string]int, error) {
- testsWithoutPackage := []string{}
tests := map[string]map[string]int{}
for _, r := range readers {
s := bufio.NewScanner(r)
for s.Scan() {
- t := s.Text()
- switch {
- case failedTestRe.MatchString(t):
- m := failedTestRe.FindStringSubmatch(t)
- testsWithoutPackage = append(testsWithoutPackage, m[1])
- case logPanicRe.MatchString(t):
- m := logPanicRe.FindStringSubmatch(t)
- testsWithoutPackage = append(testsWithoutPackage, m[1])
- case failedPkgRe.MatchString(t):
- p := failedPkgRe.FindStringSubmatch(t)
- for _, t := range testsWithoutPackage {
- if tests[p[1]] == nil {
- tests[p[1]] = map[string]int{}
+ t := s.Bytes()
+ if len(t) == 0 {
+ continue
+ }
+
+ // Skip the line if doesn't start with a "{" --
+ // this mean it isn't JSON output.
+ if !strings.HasPrefix(string(t), "{") {
+ continue
+ }
+
+ e, err := newEvent(t)
+ if err != nil {
+ return nil, err
+ }
+
+ // We're only interested in test failures, for which
+ // both Package and Test would be present.
+ if e.Package == "" || e.Test == "" {
+ continue
+ }
+
+ switch e.Action {
+ case "fail":
+ if tests[e.Package] == nil {
+ tests[e.Package] = map[string]int{}
+ }
+ tests[e.Package][e.Test]++
+ case "output":
+ if panicRe.MatchString(e.Output) {
+ if tests[e.Package] == nil {
+ tests[e.Package] = map[string]int{}
}
- tests[p[1]][t]++
+ tests[e.Package][e.Test]++
}
- testsWithoutPackage = []string{}
}
}
@@ -86,8 +134,13 @@ func parseOutput(readers ...io.Reader) (map[string]map[string]int, error) {
return tests, nil
}
-func (r *Runner) runTests(failedTests map[string]map[string]int) (io.Reader, error) {
- var out bytes.Buffer
+type exitCoder interface {
+ ExitCode() int
+}
+
+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 {
@@ -95,14 +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)
- return &out, err
+ 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, nil
+ return suspectedFlakes, nil
}
func (r *Runner) Run() error {
@@ -111,28 +190,11 @@ func (r *Runner) Run() error {
return err
}
- output, err := r.runTests(failedTests)
- if err != nil {
- return err
- }
-
- failedReruns, err := r.parse(output)
+ suspectedFlakes, err := r.runTests(failedTests)
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 6560d43e2f9..8fa81db5ba0 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,38 +12,20 @@ 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) {
- output := `
---- FAIL: TestLink (0.00s)
- --- FAIL: TestLink/1.1_link#01 (0.00s)
- currencies_test.go:325:
- Error Trace: /Users/ccordenier/Development/chainlink/core/assets/currencies_test.go:325
- Error: Not equal:
- expected: "1.2 link"
- actual : "1.1 link"
-
- Diff:
- --- Expected
- +++ Actual
- @@ -1 +1 @@
- -1.2 link
- +1.1 link
- Test: TestLink/1.1_link#01
-FAIL
-FAIL github.com/smartcontractkit/chainlink/v2/core/assets 0.338s
-FAIL
+ output := `{"Time":"2023-09-07T15:39:46.378315+01:00","Action":"fail","Package":"github.com/smartcontractkit/chainlink/v2/core/assets","Test":"TestLink","Elapsed":0}
`
r := strings.NewReader(output)
@@ -49,69 +33,28 @@ FAIL
require.NoError(t, err)
assert.Len(t, ts, 1)
- assert.Len(t, ts["core/assets"], 1)
- assert.Equal(t, ts["core/assets"]["TestLink"], 1)
+ assert.Len(t, ts["github.com/smartcontractkit/chainlink/v2/core/assets"], 1)
+ assert.Equal(t, ts["github.com/smartcontractkit/chainlink/v2/core/assets"]["TestLink"], 1)
}
-func TestParser_PanicInTest(t *testing.T) {
- output := `
-? github.com/smartcontractkit/chainlink/v2/tools/flakeytests/cmd/runner [no test files]
---- FAIL: TestParser (0.00s)
-panic: foo [recovered]
- panic: foo
-
-goroutine 21 [running]:
-testing.tRunner.func1.2({0x1009953c0, 0x1009d1e40})
- /opt/homebrew/Cellar/go/1.20.3/libexec/src/testing/testing.go:1526 +0x1c8
-testing.tRunner.func1()
- /opt/homebrew/Cellar/go/1.20.3/libexec/src/testing/testing.go:1529 +0x384
-panic({0x1009953c0, 0x1009d1e40})
- /opt/homebrew/Cellar/go/1.20.3/libexec/src/runtime/panic.go:884 +0x204
-github.com/smartcontractkit/chainlink/v2/tools/flakeytests.TestParser(0x0?)
- /Users/ccordenier/Development/chainlink/tools/flakeytests/runner_test.go:50 +0xa4
-testing.tRunner(0x14000083520, 0x1009d1588)
- /opt/homebrew/Cellar/go/1.20.3/libexec/src/testing/testing.go:1576 +0x10c
-created by testing.(*T).Run
- /opt/homebrew/Cellar/go/1.20.3/libexec/src/testing/testing.go:1629 +0x368
-FAIL github.com/smartcontractkit/chainlink/v2/tools/flakeytests 0.197s
-FAIL`
+func TestParser_SkipsNonJSON(t *testing.T) {
+ output := `Failed tests and panics:
+-------
+{"Time":"2023-09-07T15:39:46.378315+01:00","Action":"fail","Package":"github.com/smartcontractkit/chainlink/v2/core/assets","Test":"TestLink","Elapsed":0}
+`
r := strings.NewReader(output)
ts, err := parseOutput(r)
require.NoError(t, err)
assert.Len(t, ts, 1)
- assert.Len(t, ts["tools/flakeytests"], 1)
- assert.Equal(t, ts["tools/flakeytests"]["TestParser"], 1)
+ assert.Len(t, ts["github.com/smartcontractkit/chainlink/v2/core/assets"], 1)
+ assert.Equal(t, ts["github.com/smartcontractkit/chainlink/v2/core/assets"]["TestLink"], 1)
}
func TestParser_PanicDueToLogging(t *testing.T) {
output := `
-panic: Log in goroutine after TestIntegration_LogEventProvider_Backfill has completed: 2023-07-19T10:10:45.925Z WARN KeepersRegistry.LogEventProvider logprovider/provider.go:218 failed to read logs {"version": "2.3.0@d898528", "where": "reader", "err": "fetched logs with errors: context canceled"}
-
-goroutine 4999 [running]:
-testing.(*common).logDepth(0xc0051f6000, {0xc003011960, 0xd3}, 0x3)
- /opt/hostedtoolcache/go/1.20.5/x64/src/testing/testing.go:1003 +0x4e7
-testing.(*common).log(...)
- /opt/hostedtoolcache/go/1.20.5/x64/src/testing/testing.go:985
-testing.(*common).Logf(0xc0051f6000, {0x21ba777?, 0x41ac8a?}, {0xc00217c330?, 0x1e530c0?, 0x1?})
- /opt/hostedtoolcache/go/1.20.5/x64/src/testing/testing.go:1036 +0x5a
-go.uber.org/zap/zaptest.testingWriter.Write({{0x7f4c5c94f018?, 0xc0051f6000?}, 0xa8?}, {0xc003017000?, 0xd4, 0xc00217c320?})
- /home/runner/go/pkg/mod/go.uber.org/zap@v1.24.0/zaptest/logger.go:130 +0xe6
-go.uber.org/zap/zapcore.(*ioCore).Write(0xc0022f60f0, {0x1, {0xc1260b897723e1ca, 0x4bdc75e54, 0x3d56e40}, {0x22e96a1, 0x20}, {0x22c3204, 0x13}, {0x1, ...}, ...}, ...)
- /home/runner/go/pkg/mod/go.uber.org/zap@v1.24.0/zapcore/core.go:99 +0xb5
-go.uber.org/zap/zapcore.(*CheckedEntry).Write(0xc001265ba0, {0xc0023ca100, 0x1, 0x2})
- /home/runner/go/pkg/mod/go.uber.org/zap@v1.24.0/zapcore/entry.go:255 +0x1d9
-go.uber.org/zap.(*SugaredLogger).log(0xc00363a008, 0x1, {0x22c3204?, 0x13?}, {0x0?, 0x0?, 0x0?}, {0xc004ea3f80, 0x2, 0x2})
- /home/runner/go/pkg/mod/go.uber.org/zap@v1.24.0/sugar.go:295 +0xee
-go.uber.org/zap.(*SugaredLogger).Warnw(...)
- /home/runner/go/pkg/mod/go.uber.org/zap@v1.24.0/sugar.go:216
-github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider.(*logEventProvider).startReader(0xc00076d730, {0x2917018?, 0xc0043c4000?}, 0xc003b2a000)
- /home/runner/work/chainlink/chainlink/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider.go:218 +0x29f
-created by github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider.(*logEventProvider).Start
- /home/runner/work/chainlink/chainlink/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider/provider.go:108 +0x133
-FAIL github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evm21/logprovider 20.380s
-FAIL
+{"Time":"2023-09-07T16:01:40.649849+01:00","Action":"output","Package":"github.com/smartcontractkit/chainlink/v2/core/assets","Test":"TestAssets_LinkScanValue","Output":"panic: foo\n"}
`
r := strings.NewReader(output)
@@ -119,14 +62,24 @@ FAIL
require.NoError(t, err)
assert.Len(t, ts, 1)
- assert.Len(t, ts["core/services/ocr2/plugins/ocr2keeper/evm21/logprovider"], 1)
- assert.Equal(t, ts["core/services/ocr2/plugins/ocr2keeper/evm21/logprovider"]["TestIntegration_LogEventProvider_Backfill"], 1)
+ assert.Len(t, ts["github.com/smartcontractkit/chainlink/v2/core/assets"], 1)
+ assert.Equal(t, ts["github.com/smartcontractkit/chainlink/v2/core/assets"]["TestAssets_LinkScanValue"], 1)
}
func TestParser_SuccessfulOutput(t *testing.T) {
output := `
-? github.com/smartcontractkit/chainlink/v2/tools/flakeytests/cmd/runner [no test files]
-ok github.com/smartcontractkit/chainlink/v2/tools/flakeytests 0.320s
+{"Time":"2023-09-07T16:22:52.556853+01:00","Action":"start","Package":"github.com/smartcontractkit/chainlink/v2/core/assets"}
+{"Time":"2023-09-07T16:22:52.762353+01:00","Action":"run","Package":"github.com/smartcontractkit/chainlink/v2/core/assets","Test":"TestAssets_NewLinkAndString"}
+{"Time":"2023-09-07T16:22:52.762456+01:00","Action":"output","Package":"github.com/smartcontractkit/chainlink/v2/core/assets","Test":"TestAssets_NewLinkAndString","Output":"=== RUN TestAssets_NewLinkAndString\n"}
+{"Time":"2023-09-07T16:22:52.76249+01:00","Action":"output","Package":"github.com/smartcontractkit/chainlink/v2/core/assets","Test":"TestAssets_NewLinkAndString","Output":"=== PAUSE TestAssets_NewLinkAndString\n"}
+{"Time":"2023-09-07T16:22:52.7625+01:00","Action":"pause","Package":"github.com/smartcontractkit/chainlink/v2/core/assets","Test":"TestAssets_NewLinkAndString"}
+{"Time":"2023-09-07T16:22:52.762511+01:00","Action":"cont","Package":"github.com/smartcontractkit/chainlink/v2/core/assets","Test":"TestAssets_NewLinkAndString"}
+{"Time":"2023-09-07T16:22:52.762528+01:00","Action":"output","Package":"github.com/smartcontractkit/chainlink/v2/core/assets","Test":"TestAssets_NewLinkAndString","Output":"=== CONT TestAssets_NewLinkAndString\n"}
+{"Time":"2023-09-07T16:22:52.762546+01:00","Action":"output","Package":"github.com/smartcontractkit/chainlink/v2/core/assets","Test":"TestAssets_NewLinkAndString","Output":"--- PASS: TestAssets_NewLinkAndString (0.00s)\n"}
+{"Time":"2023-09-07T16:22:52.762557+01:00","Action":"pass","Package":"github.com/smartcontractkit/chainlink/v2/core/assets","Test":"TestAssets_NewLinkAndString","Elapsed":0}
+{"Time":"2023-09-07T16:22:52.762566+01:00","Action":"output","Package":"github.com/smartcontractkit/chainlink/v2/core/assets","Output":"PASS\n"}
+{"Time":"2023-09-07T16:22:52.762955+01:00","Action":"output","Package":"github.com/smartcontractkit/chainlink/v2/core/assets","Output":"ok \tgithub.com/smartcontractkit/chainlink/v2/core/assets\t0.206s\n"}
+{"Time":"2023-09-07T16:22:52.765598+01:00","Action":"pass","Package":"github.com/smartcontractkit/chainlink/v2/core/assets","Elapsed":0.209}
`
r := strings.NewReader(output)
@@ -135,35 +88,64 @@ ok github.com/smartcontractkit/chainlink/v2/tools/flakeytests 0.320s
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 := `
---- FAIL: TestLink (0.00s)
- --- FAIL: TestLink/1.1_link#01 (0.00s)
- currencies_test.go:325:
- Error Trace: /Users/ccordenier/Development/chainlink/core/assets/currencies_test.go:325
- Error: Not equal:
- expected: "1.2 link"
- actual : "1.1 link"
-
- Diff:
- --- Expected
- +++ Actual
- @@ -1 +1 @@
- -1.2 link
- +1.1 link
- Test: TestLink/1.1_link#01
-FAIL
-FAIL github.com/smartcontractkit/chainlink/v2/core/assets 0.338s
-FAIL
+ 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(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,
+ }
+
+ // This will report a flake since we've mocked the rerun
+ // to only report one failure (not two as expected).
+ err := r.Run()
+ require.NoError(t, err)
+ assert.Len(t, m.entries, 1)
+ _, ok := m.entries["github.com/smartcontractkit/chainlink/v2/core/assets"]["TestLink"]
+ assert.True(t, ok)
+}
+
+func TestRunner_WithFailedPackage(t *testing.T) {
+ 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,
}
@@ -173,74 +155,25 @@ FAIL
err := r.Run()
require.NoError(t, err)
assert.Len(t, m.entries, 1)
- assert.Equal(t, m.entries["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) {
- output := `
---- FAIL: TestLink (0.00s)
- --- FAIL: TestLink/1.1_link#01 (0.00s)
- currencies_test.go:325:
- Error Trace: /Users/ccordenier/Development/chainlink/core/assets/currencies_test.go:325
- Error: Not equal:
- expected: "1.2 link"
- actual : "1.1 link"
-
- Diff:
- --- Expected
- +++ Actual
- @@ -1 +1 @@
- -1.2 link
- +1.1 link
- Test: TestLink/1.1_link#01
-FAIL
-FAIL github.com/smartcontractkit/chainlink/v2/core/assets 0.338s
-FAIL
-`
+ 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 := `
---- FAIL: TestLink (0.00s)
- --- FAIL: TestLink/1.1_link#01 (0.00s)
- currencies_test.go:325:
- Error Trace: /Users/ccordenier/Development/chainlink/core/assets/currencies_test.go:325
- Error: Not equal:
- expected: "1.2 link"
- actual : "1.1 link"
-
- Diff:
- --- Expected
- +++ Actual
- @@ -1 +1 @@
- -1.2 link
- +1.1 link
- Test: TestLink/1.1_link#01
---- FAIL: TestLink (0.00s)
- --- FAIL: TestLink/1.1_link#01 (0.00s)
- currencies_test.go:325:
- Error Trace: /Users/ccordenier/Development/chainlink/core/assets/currencies_test.go:325
- Error: Not equal:
- expected: "1.2 link"
- actual : "1.1 link"
-
- Diff:
- --- Expected
- +++ Actual
- @@ -1 +1 @@
- -1.2 link
- +1.1 link
- Test: TestLink/1.1_link#01
-FAIL
-FAIL github.com/smartcontractkit/chainlink/v2/core/assets 0.315s
-FAIL
+{"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","Test":"TestLink","Elapsed":0}
`
m := newMockReporter()
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,
}
@@ -251,43 +184,197 @@ FAIL
}
func TestRunner_RerunSuccessful(t *testing.T) {
- output := `
---- FAIL: TestLink (0.00s)
- --- FAIL: TestLink/1.1_link#01 (0.00s)
- currencies_test.go:325:
- Error Trace: /Users/ccordenier/Development/chainlink/core/assets/currencies_test.go:325
- Error: Not equal:
- expected: "1.2 link"
- actual : "1.1 link"
-
- Diff:
- --- Expected
- +++ Actual
- @@ -1 +1 @@
- -1.2 link
- +1.1 link
- Test: TestLink/1.1_link#01
-FAIL
-FAIL github.com/smartcontractkit/chainlink/v2/core/assets 0.338s
-FAIL
-`
+ 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 := `
-ok github.com/smartcontractkit/chainlink/v2/core/assets 0.320s
-`
+ 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 {
+ 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)
+ _, ok := m.entries["github.com/smartcontractkit/chainlink/v2/core/assets"]["TestLink"]
+ assert.True(t, ok)
+}
+
+func TestRunner_RootLevelTest(t *testing.T) {
+ output := `{"Time":"2023-09-07T15:39:46.378315+01:00","Action":"fail","Package":"github.com/smartcontractkit/chainlink/v2/","Test":"TestConfigDocs","Elapsed":0}`
+
+ rerunOutput := ``
+ m := newMockReporter()
+ r := &Runner{
+ numReruns: 2,
+ readers: []io.Reader{strings.NewReader(output)},
+ 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)
+ _, ok := m.entries["github.com/smartcontractkit/chainlink/v2/"]["TestConfigDocs"]
+ assert.True(t, ok)
+}
+
+type exitError struct{}
+
+func (e *exitError) ExitCode() int { return 1 }
+
+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}`
+
+ 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)},
+ 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["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) {
+ outputs := []io.Reader{
+ strings.NewReader(`
+{"Time":"2023-09-07T15:39:46.378315+01:00","Action":"fail","Package":"github.com/smartcontractkit/chainlink/v2/core/assets","Test":"TestLink","Elapsed":0}
+`),
+ strings.NewReader(`
+{"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}
+`),
+ }
+
+ 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}`,
+ }
+
+ index := 0
+ m := newMockReporter()
+ r := &Runner{
+ numReruns: 2,
+ readers: outputs,
+ testCommand: testAdapter(func(pkg string, testNames []string, w io.Writer) error {
+ _, err := w.Write([]byte(rerunOutputs[index]))
+ index++
+ return err
+ }),
+ parse: parseOutput,
+ reporter: m,
+ }
+
+ err := r.Run()
+ require.NoError(t, err)
+ calls := index
+ 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)
}