diff --git a/.github/workflows/acceptance-public.yml b/.github/workflows/acceptance-public.yml index cd2f3a1cf7..5197543196 100644 --- a/.github/workflows/acceptance-public.yml +++ b/.github/workflows/acceptance-public.yml @@ -47,6 +47,15 @@ jobs: operator_id: ${{ inputs.operator_id }} operator_key: ${{ inputs.operator_key }} + rpc_api_schema_conformity: + name: API Conformity + uses: ./.github/workflows/acceptance-workflow.yml + with: + testfilter: api_conformity + envfile: ${{ inputs.network }}Acceptance.env + operator_id: ${{ inputs.operator_id }} + operator_key: ${{ inputs.operator_key }} + erc20: name: ERC20 uses: ./.github/workflows/acceptance-workflow.yml diff --git a/.github/workflows/acceptance.yml b/.github/workflows/acceptance.yml index e38f4ee1b9..c4abad95e8 100644 --- a/.github/workflows/acceptance.yml +++ b/.github/workflows/acceptance.yml @@ -26,6 +26,12 @@ jobs: with: testfilter: api_batch3 + rpc_api_schema_conformity: + name: API Conformity + uses: ./.github/workflows/acceptance-workflow.yml + with: + testfilter: rpc_api_schema_conformity + erc20: name: ERC20 uses: ./.github/workflows/acceptance-workflow.yml diff --git a/package-lock.json b/package-lock.json index ec6fc86df4..c9381ae925 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,6 +19,7 @@ "pino-pretty": "^7.6.1", "prom-client": "^14.0.1", "redis": "^4.6.7", + "ts-node": "^10.9.1", "typescript": "^4.6.3" }, "devDependencies": { @@ -446,7 +447,6 @@ "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dev": true, "dependencies": { "@jridgewell/trace-mapping": "0.3.9" }, @@ -458,7 +458,6 @@ "version": "0.3.9", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" @@ -3877,7 +3876,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", - "dev": true, "engines": { "node": ">=6.0.0" } @@ -3894,8 +3892,7 @@ "node_modules/@jridgewell/sourcemap-codec": { "version": "1.4.15", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.19", @@ -5324,26 +5321,22 @@ "node_modules/@tsconfig/node10": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", - "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", - "dev": true + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==" }, "node_modules/@tsconfig/node12": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==" }, "node_modules/@tsconfig/node14": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==" }, "node_modules/@tsconfig/node16": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", - "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "dev": true + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==" }, "node_modules/@tufjs/canonical-json": { "version": "1.0.0", @@ -6105,7 +6098,6 @@ "version": "8.2.0", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "dev": true, "engines": { "node": ">=0.4.0" } @@ -6284,8 +6276,7 @@ "node_modules/arg": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" }, "node_modules/argparse": { "version": "2.0.1", @@ -7964,9 +7955,9 @@ "integrity": "sha512-QcY2rm26FdrmQWOi0gp9TZDwty95nsfLVOUjLqujue1uyKb4VksYKaLb0FlcyLEMNx2e1KNdvRkDlqtCJRQIag==" }, "node_modules/cpu-features": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/cpu-features/-/cpu-features-0.0.8.tgz", - "integrity": "sha512-BbHBvtYhUhksqTjr6bhNOjGgMnhwhGTQmOoZGD+K7BCaQDCuZl/Ve1ZxUSMRwVC4D/rkCPQ2MAIeYzrWyK7eEg==", + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/cpu-features/-/cpu-features-0.0.9.tgz", + "integrity": "sha512-AKjgn2rP2yJyfbepsmLfiYcmtNn/2eUvocUyM/09yB0YDiz39HteK/5/T4Onf0pmdYDMgkBoGvRLvEguzyL7wQ==", "hasInstallScript": true, "optional": true, "dependencies": { @@ -8019,8 +8010,7 @@ "node_modules/create-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" }, "node_modules/cross-spawn": { "version": "7.0.3", @@ -9645,6 +9635,12 @@ "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, + "node_modules/execution-apis": { + "version": "0.0.0", + "resolved": "git+ssh://git@github.com/ethereum/execution-apis.git#c4089414bbbe975bbc4bf1ccf0a3d31f76feb3e1", + "dev": true, + "license": "CC0-1.0" + }, "node_modules/exponential-backoff": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.1.tgz", @@ -10244,6 +10240,7 @@ "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.5.tgz", "integrity": "sha512-HTm14iMQKK2FjFLRTM5lAVcyaUzOnqbPtesFIvREgXpJHdQm8bWS+GkQgIkfaBYRHuCnea7w8UVNfwiAQhlr9A==", "dev": true, + "hasInstallScript": true, "optional": true, "dependencies": { "node-gyp-build": "^4.3.0" @@ -10606,6 +10603,7 @@ "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.7.tgz", "integrity": "sha512-vLt1O5Pp+flcArHGIyKEQq883nBt8nN8tVBcoL0qUXj2XT1n7p70yGIq2VK98I5FdZ1YHc0wk/koOnHjnXWk1Q==", "dev": true, + "hasInstallScript": true, "optional": true, "dependencies": { "node-gyp-build": "^4.3.0" @@ -14151,8 +14149,7 @@ "node_modules/make-error": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" }, "node_modules/make-fetch-happen": { "version": "11.1.1", @@ -15262,6 +15259,11 @@ "node-gyp-build-test": "build-test.js" } }, + "node_modules/node-machine-id": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/node-machine-id/-/node-machine-id-1.1.12.tgz", + "integrity": "sha512-QNABxbrPa3qEIfrE6GOJ7BYIuignnJw7iQ2YPbc3Nla1HzRJjXzZOiikfF8m7eAMfichLt3M4VgLOetqgDmgGQ==" + }, "node_modules/node-preload": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", @@ -15674,7 +15676,7 @@ "cli-cursor": "3.1.0", "cli-spinners": "2.6.1", "cliui": "^7.0.2", - "dotenv": "~10.0.0", + "dotenv": "~16.3.1", "enquirer": "~2.3.6", "fast-glob": "3.2.7", "figures": "3.2.0", @@ -15686,6 +15688,7 @@ "jsonc-parser": "3.2.0", "lines-and-columns": "~2.0.3", "minimatch": "3.0.5", + "node-machine-id": "1.1.12", "npm-run-path": "^4.0.1", "open": "^8.4.0", "semver": "7.5.3", @@ -15772,14 +15775,6 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, - "node_modules/nx/node_modules/dotenv": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", - "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==", - "engines": { - "node": ">=10" - } - }, "node_modules/nx/node_modules/enquirer": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", @@ -19622,7 +19617,6 @@ "version": "10.9.1", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", - "dev": true, "dependencies": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", @@ -19661,11 +19655,21 @@ } } }, + "node_modules/ts-node/node_modules/acorn": { + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", + "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/ts-node/node_modules/diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true, "engines": { "node": ">=0.3.1" } @@ -20170,8 +20174,7 @@ "node_modules/v8-compile-cache-lib": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==" }, "node_modules/validate-npm-package-license": { "version": "3.0.4", @@ -20806,7 +20809,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true, "engines": { "node": ">=6" } @@ -20972,6 +20974,7 @@ "axios-retry": "^3.5.1", "chai": "^4.3.6", "ethers": "^6.7.0", + "execution-apis": "git://github.com/ethereum/execution-apis.git#v1.0.0-beta.3", "shelljs": "^0.8.5", "ts-mocha": "^9.0.2", "ts-node": "^10.8.1", @@ -21387,7 +21390,7 @@ "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.2", - "semver": "^7.5.3" + "semver": "^6.3.1" }, "dependencies": { "@babel/code-frame": { @@ -21424,7 +21427,7 @@ "@babel/helper-validator-option": "^7.22.5", "browserslist": "^4.21.9", "lru-cache": "^5.1.1", - "semver": "^7.5.3" + "semver": "^6.3.1" }, "dependencies": { "lru-cache": { @@ -21646,7 +21649,6 @@ "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dev": true, "requires": { "@jridgewell/trace-mapping": "0.3.9" }, @@ -21655,7 +21657,6 @@ "version": "0.3.9", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, "requires": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" @@ -21778,7 +21779,7 @@ "requires": { "hosted-git-info": "^2.1.4", "resolve": "^1.10.0", - "semver": "^7.5.3", + "semver": "2 || 3 || 4 || 5", "validate-npm-package-license": "^3.0.1" } }, @@ -21864,7 +21865,7 @@ "fs-extra": "^0.30.0", "memorystream": "^0.3.1", "require-from-string": "^1.1.0", - "semver": "^7.5.3", + "semver": "^5.3.0", "yargs": "^4.7.1" } }, @@ -23037,6 +23038,7 @@ "co-body": "6.1.0", "dotenv": "^16.0.0", "ethers": "^6.7.0", + "execution-apis": "git://github.com/ethereum/execution-apis.git#v1.0.0-beta.3", "koa": "^2.13.4", "koa-body-parser": "^0.2.1", "koa-cors": "^0.0.16", @@ -23302,7 +23304,7 @@ "integrity": "sha512-Wan4TyiGExymUQOD+WVE/Q/RDjr+eBv5JBVO5+RGa2FDyASFhUWA/E1G0ZyiynXf2clqlewXIHyuNxpR42S80A==", "requires": { "long": "^4.0.0", - "protobufjs": "^7.2.4" + "protobufjs": "^7.1.2" } }, "@hashgraph/sdk": { @@ -24351,8 +24353,7 @@ "@jridgewell/resolve-uri": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", - "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", - "dev": true + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==" }, "@jridgewell/set-array": { "version": "1.1.2", @@ -24363,8 +24364,7 @@ "@jridgewell/sourcemap-codec": { "version": "1.4.15", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" }, "@jridgewell/trace-mapping": { "version": "0.3.19", @@ -24525,7 +24525,7 @@ "npm-packlist": "5.1.1", "npm-registry-fetch": "^14.0.5", "npmlog": "^6.0.2", - "nx": "16.5.5", + "nx": ">=16.5.1 < 17", "p-map": "4.0.0", "p-map-series": "2.1.0", "p-queue": "6.6.2", @@ -24536,7 +24536,7 @@ "read-package-json": "6.0.4", "resolve-from": "5.0.0", "rimraf": "^4.4.1", - "semver": "^7.5.3", + "semver": "^7.3.4", "signal-exit": "3.0.7", "slash": "^3.0.0", "ssri": "^9.0.1", @@ -24747,7 +24747,7 @@ "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-3.1.0.tgz", "integrity": "sha512-7kZUAaLscfgbwBQRbvdMYaZOWyMEcPTH/tJjnyAWJ/dvvs9Ef+CERx/qJb9GExJpl1qipaDGn7KqHnFGGixd0w==", "requires": { - "semver": "^7.5.3" + "semver": "^7.3.5" } }, "@npmcli/git": { @@ -24761,7 +24761,7 @@ "proc-log": "^3.0.0", "promise-inflight": "^1.0.1", "promise-retry": "^2.0.1", - "semver": "^7.5.3", + "semver": "^7.3.5", "which": "^3.0.0" }, "dependencies": { @@ -24869,7 +24869,7 @@ "ejs": "^3.1.7", "enquirer": "~2.3.6", "ignore": "^5.0.4", - "semver": "^7.5.3", + "semver": "7.5.3", "tmp": "~0.2.1", "tslib": "^2.3.0" }, @@ -25449,26 +25449,22 @@ "@tsconfig/node10": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", - "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", - "dev": true + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==" }, "@tsconfig/node12": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==" }, "@tsconfig/node14": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==" }, "@tsconfig/node16": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", - "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "dev": true + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==" }, "@tufjs/canonical-json": { "version": "1.0.0", @@ -26076,8 +26072,7 @@ "acorn-walk": { "version": "8.2.0", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "dev": true + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==" }, "add-stream": { "version": "1.0.0", @@ -26212,8 +26207,7 @@ "arg": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" }, "argparse": { "version": "2.0.1", @@ -26723,7 +26717,7 @@ "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz", "integrity": "sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==", "requires": { - "semver": "^7.5.3" + "semver": "^7.0.0" } }, "byte-size": { @@ -27384,7 +27378,7 @@ "handlebars": "^4.7.7", "json-stringify-safe": "^5.0.1", "meow": "^8.1.2", - "semver": "^7.5.3", + "semver": "^7.0.0", "split": "^1.0.1" } }, @@ -27465,9 +27459,9 @@ "integrity": "sha512-QcY2rm26FdrmQWOi0gp9TZDwty95nsfLVOUjLqujue1uyKb4VksYKaLb0FlcyLEMNx2e1KNdvRkDlqtCJRQIag==" }, "cpu-features": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/cpu-features/-/cpu-features-0.0.8.tgz", - "integrity": "sha512-BbHBvtYhUhksqTjr6bhNOjGgMnhwhGTQmOoZGD+K7BCaQDCuZl/Ve1ZxUSMRwVC4D/rkCPQ2MAIeYzrWyK7eEg==", + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/cpu-features/-/cpu-features-0.0.9.tgz", + "integrity": "sha512-AKjgn2rP2yJyfbepsmLfiYcmtNn/2eUvocUyM/09yB0YDiz39HteK/5/T4Onf0pmdYDMgkBoGvRLvEguzyL7wQ==", "optional": true, "requires": { "buildcheck": "~0.0.6", @@ -27510,8 +27504,7 @@ "create-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" }, "cross-spawn": { "version": "7.0.3", @@ -28713,6 +28706,11 @@ "strip-final-newline": "^2.0.0" } }, + "execution-apis": { + "version": "git+ssh://git@github.com/ethereum/execution-apis.git#c4089414bbbe975bbc4bf1ccf0a3d31f76feb3e1", + "dev": true, + "from": "execution-apis@git://github.com/ethereum/execution-apis.git#v1.0.0-beta.3" + }, "exponential-backoff": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.1.tgz", @@ -29555,7 +29553,7 @@ "integrity": "sha512-hIvOeZwRbQ+7YEUmCkHqo8FOLQZCEn18yevLHADlFPZY02KJGsu5FZt9YW/lybfK2uhWFI7Qg/07LekJiTv7iA==", "requires": { "meow": "^8.1.2", - "semver": "^7.5.3" + "semver": "^7.0.0" } }, "git-up": { @@ -30048,7 +30046,7 @@ "promzard": "^1.0.0", "read": "^2.0.0", "read-package-json": "^6.0.0", - "semver": "^7.5.3", + "semver": "^7.3.5", "validate-npm-package-license": "^3.0.4", "validate-npm-package-name": "^5.0.0" }, @@ -30068,7 +30066,7 @@ "requires": { "hosted-git-info": "^6.0.0", "proc-log": "^3.0.0", - "semver": "^7.5.3", + "semver": "^7.3.5", "validate-npm-package-name": "^5.0.0" } } @@ -30516,7 +30514,7 @@ "@babel/core": "^7.7.5", "@istanbuljs/schema": "^0.1.2", "istanbul-lib-coverage": "^3.0.0", - "semver": "^7.5.3" + "semver": "^6.3.0" } }, "istanbul-lib-processinfo": { @@ -31953,8 +31951,7 @@ "make-error": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" }, "make-fetch-happen": { "version": "11.1.1", @@ -32219,7 +32216,7 @@ "requires": { "hosted-git-info": "^2.1.4", "resolve": "^1.10.0", - "semver": "^7.5.3", + "semver": "2 || 3 || 4 || 5", "validate-npm-package-license": "^3.0.1" } }, @@ -32801,7 +32798,7 @@ "nopt": "^6.0.0", "npmlog": "^6.0.0", "rimraf": "^3.0.2", - "semver": "^7.5.3", + "semver": "^7.3.5", "tar": "^6.1.2", "which": "^2.0.2" } @@ -32811,6 +32808,11 @@ "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.3.0.tgz", "integrity": "sha512-iWjXZvmboq0ja1pUGULQBexmxq8CV4xBhX7VDOTbL7ZR4FOowwY/VOtRxBN/yKxmdGoIp4j5ysNT4u3S2pDQ3Q==" }, + "node-machine-id": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/node-machine-id/-/node-machine-id-1.1.12.tgz", + "integrity": "sha512-QNABxbrPa3qEIfrE6GOJ7BYIuignnJw7iQ2YPbc3Nla1HzRJjXzZOiikfF8m7eAMfichLt3M4VgLOetqgDmgGQ==" + }, "node-preload": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", @@ -32870,7 +32872,7 @@ "requires": { "hosted-git-info": "^4.0.1", "is-core-module": "^2.5.0", - "semver": "^7.5.3", + "semver": "^7.3.4", "validate-npm-package-license": "^3.0.1" }, "dependencies": { @@ -32910,7 +32912,7 @@ "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-6.2.0.tgz", "integrity": "sha512-744wat5wAAHsxa4590mWO0tJ8PKxR8ORZsH9wGpQc3nWTzozMAgBN/XyqYw7mg3yqLM8dLwEnwSfKMmXAjF69g==", "requires": { - "semver": "^7.5.3" + "semver": "^7.1.1" } }, "npm-normalize-package-bin": { @@ -33016,7 +33018,7 @@ "npm-install-checks": "^6.0.0", "npm-normalize-package-bin": "^3.0.0", "npm-package-arg": "^10.0.0", - "semver": "^7.5.3" + "semver": "^7.3.5" }, "dependencies": { "hosted-git-info": { @@ -33039,7 +33041,7 @@ "requires": { "hosted-git-info": "^6.0.0", "proc-log": "^3.0.0", - "semver": "^7.5.3", + "semver": "^7.3.5", "validate-npm-package-name": "^5.0.0" } } @@ -33151,7 +33153,7 @@ "cli-cursor": "3.1.0", "cli-spinners": "2.6.1", "cliui": "^7.0.2", - "dotenv": "~10.0.0", + "dotenv": "~16.3.1", "enquirer": "~2.3.6", "fast-glob": "3.2.7", "figures": "3.2.0", @@ -33163,6 +33165,7 @@ "jsonc-parser": "3.2.0", "lines-and-columns": "~2.0.3", "minimatch": "3.0.5", + "node-machine-id": "1.1.12", "npm-run-path": "^4.0.1", "open": "^8.4.0", "semver": "^7.5.3", @@ -33207,11 +33210,6 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, - "dotenv": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", - "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==" - }, "enquirer": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", @@ -34533,7 +34531,7 @@ "requires": { "hosted-git-info": "^2.1.4", "resolve": "^1.10.0", - "semver": "^7.5.3", + "semver": "2 || 3 || 4 || 5", "validate-npm-package-license": "^3.0.1" } }, @@ -36115,7 +36113,6 @@ "version": "10.9.1", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", - "dev": true, "requires": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", @@ -36132,11 +36129,15 @@ "yn": "3.1.1" }, "dependencies": { + "acorn": { + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", + "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==" + }, "diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==" } } }, @@ -36503,8 +36504,7 @@ "v8-compile-cache-lib": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==" }, "validate-npm-package-license": { "version": "3.0.4", @@ -36793,7 +36793,7 @@ "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", "requires": { "pify": "^4.0.1", - "semver": "^7.5.3" + "semver": "^5.6.0" } }, "pify": { @@ -36979,8 +36979,7 @@ "yn": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==" }, "yocto-queue": { "version": "0.1.0", diff --git a/package.json b/package.json index 511f44387a..71c4061926 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,7 @@ "acceptancetest:ws": "ts-mocha packages/server/tests/acceptance/index.spec.ts -g '@web-socket' --exit", "acceptancetest:precompile-calls": "ts-mocha packages/server/tests/acceptance/index.spec.ts -g '@precompile-calls' --exit", "acceptancetest:cache-service": "ts-mocha packages/server/tests/acceptance/index.spec.ts -g '@cache-service' --exit", + "acceptancetest:rpc_api_schema_conformity": "ts-mocha packages/server/tests/acceptance/index.spec.ts -g '@api-conformity' --exit", "build": "npx lerna run build", "build-and-test": "npx lerna run build && npx lerna run test", "build:docker": "docker build . -t ${npm_package_name}", @@ -72,6 +73,7 @@ "pino-pretty": "^7.6.1", "prom-client": "^14.0.1", "redis": "^4.6.7", + "ts-node": "^10.9.1", "typescript": "^4.6.3" }, "overrides": { diff --git a/packages/server/package.json b/packages/server/package.json index cfb1dea628..f963ca1fd2 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -38,7 +38,8 @@ "shelljs": "^0.8.5", "ts-mocha": "^9.0.2", "ts-node": "^10.8.1", - "typescript": "^4.5.5" + "typescript": "^4.5.5", + "execution-apis": "git://github.com/ethereum/execution-apis.git#v1.0.0-beta.3" }, "scripts": { "build": "pnpm clean && pnpm compile", diff --git a/packages/server/tests/acceptance/conformityTests.spec.ts b/packages/server/tests/acceptance/conformityTests.spec.ts new file mode 100644 index 0000000000..bdc7640e67 --- /dev/null +++ b/packages/server/tests/acceptance/conformityTests.spec.ts @@ -0,0 +1,311 @@ +import fs from 'fs'; +const { bytecode } = require('../contracts/Basic.json'); +const path = require('path'); +const directoryPath = path.resolve(__dirname, '../../../../node_modules/execution-apis/tests'); +const axios = require('axios'); +const openRpcData = require('../../../../docs/openrpc.json'); +require('dotenv').config(); +import { signTransaction } from '../../../relay/tests/helpers'; +import { expect } from 'chai'; +let currentBlockHash; +let legacyTransactionAndBlockHash; +let transaction2930AndBlockHash; +let transaction1559AndBlockHash; +let createContractLegacyTransactionAndBlockHash; +const sendAccountAddress = '0xc37f417fA09933335240FCA72DD257BFBdE9C275'; +const receiveAccountAddress = '0x67D8d32E9Bf1a9968a5ff53B87d777Aa8EBBEe69'; +const relayUrl = 'http://127.0.0.1:7546'; +const gasPrice = '0x2C68AF0BB14000'; +const gasLimit = '0x3D090'; +const value = '0x2E90EDD000'; +const localNodeAccountPrivateKey = '0x6e9d61a325be3f6675cf8b7676c70e4a004d2308e3e182370a41f5653d52c6bd'; +const ACCESS_LIST_FILE_NAME = 'get-access-list.io'; +const DYNAMIC_FEE_FILE_NAME = 'get-dynamic-fee.io'; +const EMPTY_TX_FILE_NAME = 'get-empty-tx.io'; +const LEGACY_CREATE_FILE_NAME = 'get-legacy-create.io'; +const LEGACY_INPUT_FILE_NAME = 'get-legacy-input.io'; +const LEGACY_CONTRACT_FILE_NAME = 'get-legacy-contract.io'; +const LEGACY_TX_FILE_NAME = 'get-legacy-tx.io'; +const LEGACY_RECEIPT_FILE_NAME = 'get-legacy-receipt.io'; +const NOT_FOUND_TX_FILE_NAME = 'get-notfound-tx.io'; +const ETHEREUM_NETWORK_BLOCK_HASH = '0x7cb4dd3daba1f739d0c1ec7d998b4a2f6fd83019116455afa54ca4f49dfa0ad4'; +const ETHEREUM_NETWORK_SIGNED_TRANSACTION = + '0xf86709843b9aca018261a894aa000000000000000000000000000000000000000a825544820a95a0281582922adf6475f5b2241f0a4f886dafa947ecdc5913703b7840344a566b45a05f685fc099161126637a12308f278a8cd162788a6c6d5aee4d425cde261ba35d'; +const ETHEREUM_NETWORK_ACCOUNT_HASH = '0x5C41A21F14cFe9808cBEc1d91b55Ba75ed327Eb6'; +const EMPTY_TX_HASH = '0x0000000000000000000000000000000000000000000000000000000000000000'; +const NONEXISTENT_TX_HASH = '0x00000000000000000000000000000000000000000000000000000000deadbeef'; + +let legacyTransaction = { + chainId: 0x12a, + to: receiveAccountAddress, + from: sendAccountAddress, + value, + gasPrice, + gasLimit: gasLimit, + type: 0, +}; + +let transaction2930 = { + chainId: 0x12a, + to: receiveAccountAddress, + from: sendAccountAddress, + value, + gasPrice, + gasLimit: gasLimit, + type: 1, +}; + +let transaction1559 = { + chainId: 0x12a, + to: receiveAccountAddress, + from: sendAccountAddress, + value, + gasPrice, + maxPriorityFeePerGas: gasPrice, + maxFeePerGas: gasPrice, + gasLimit: gasLimit, + type: 2, +}; + +let createContractLegacyTransaction = { + chainId: 0x12a, + to: null, + from: sendAccountAddress, + gasLimit: gasLimit, + gasPrice: gasPrice, + type: 0, + data: bytecode, +}; + +async function getTransactionCount() { + const request = { + jsonrpc: '2.0', + id: 1, + method: 'eth_getTransactionCount', + params: [sendAccountAddress, 'latest'], + }; + + const response = await sendRequestToRelay(request); + + return response.result; +} + +async function getLatestBlockHash() { + const request = { + jsonrpc: '2.0', + method: 'eth_getBlockByNumber', + params: ['latest', false], + id: 0, + }; + + const response = await sendRequestToRelay(request); + + return response.result.hash; +} + +function splitReqAndRes(content) { + /** + * Splits a given input string into distinct segments representing the request and the response. + * + * @param {string} content - The input string to be segmented. + * @returns {{ request: string, response: string }} - An object containing the separated request and response strings. + */ + const lines = content.split('\n'); + const filteredLines = lines.filter((line) => line != '').map((line) => line.slice(3)); + + return { request: filteredLines[0], response: filteredLines[1] }; +} + +async function sendRequestToRelay(request) { + try { + const response = await axios.post(relayUrl, request); + return response.data; + } catch (error) { + console.error(error); + throw error; + } +} + +async function signAndSendRawTransaction(transaction) { + transaction.nonce = parseInt(await getTransactionCount(), 16); + const signed = await signTransaction(transaction, localNodeAccountPrivateKey); + const request = { + jsonrpc: '2.0', + id: 1, + method: 'eth_sendRawTransaction', + params: [signed], + }; + + const response = await sendRequestToRelay(request); + const requestTransactionReceipt = { + id: 'test_id', + jsonrpc: '2.0', + method: 'eth_getTransactionReceipt', + params: [response.result], + }; + const transactionReceipt = await sendRequestToRelay(requestTransactionReceipt); + return { + transactionHash: response.result, + blockHash: transactionReceipt.result.blockHash, + transactionIndex: transactionReceipt.result.transactionIndex, + blockNumber: transactionReceipt.result.blockNumber, + }; +} + +async function checkRequestBody(fileName, request) { + /** + * Modifies a request object for compatability with our network. + * + * @param {string} fileName - The name of the file associated with the request. + * @param {Object} request - The request object to be modified. + * @returns {Object} - The modified request object. + */ + if ( + (request.method === 'eth_getBlockByHash' && request.params[0] === ETHEREUM_NETWORK_BLOCK_HASH) || + (request.method === 'eth_sendRawTransaction' && request.params[0] === ETHEREUM_NETWORK_SIGNED_TRANSACTION) + ) { + request.params[0] = currentBlockHash; + } + if (request.method === 'eth_getTransactionByBlockHashAndIndex') { + request.params[0] = legacyTransactionAndBlockHash.blockHash; + request.params[1] = legacyTransactionAndBlockHash.transactionIndex; + } + if (request.method === 'eth_getTransactionByBlockNumberAndIndex') { + request.params[0] = legacyTransactionAndBlockHash.blockNumber; + request.params[1] = legacyTransactionAndBlockHash.transactionIndex; + } + if (request.method === 'eth_sendRawTransaction') { + if (request.params[0] === ETHEREUM_NETWORK_SIGNED_TRANSACTION) { + request.params[0] = currentBlockHash; + } else { + legacyTransaction.nonce = parseInt(await getTransactionCount(), 16); + const transactionHash = await signTransaction(legacyTransaction, localNodeAccountPrivateKey); + request.params[0] = transactionHash; + } + } + if (request.method === 'eth_getBalance') { + request.params[0] = ETHEREUM_NETWORK_ACCOUNT_HASH; + request.params[1] = currentBlockHash; + } + if (request.method === 'eth_getTransactionByHash' || request.method === 'eth_getTransactionReceipt') { + request = formatTransactionByHashAndReceiptRequests(fileName, request); + } + return request; +} + +function checkResponseFormat(fileName, actualReponse, expectedResponse) { + const actualResponseKeys = extractKeys(actualReponse); + const expectedResponseKeys = extractKeys(expectedResponse); + const missingKeys = expectedResponseKeys.filter((key) => !actualResponseKeys.includes(key)); + if ((fileName === DYNAMIC_FEE_FILE_NAME || fileName === ACCESS_LIST_FILE_NAME) && missingKeys[0] === 'result.v') { + return []; + } + + return missingKeys; +} + +function extractKeys(obj, prefix = '') { + let keys = []; + for (const key in obj) { + if (obj.hasOwnProperty(key)) { + const newKey = prefix ? `${prefix}.${key}` : key; + keys.push(newKey); + + if (typeof obj[key] === 'object' && !Array.isArray(obj[key])) { + keys = keys.concat(extractKeys(obj[key], newKey)); + } + } + } + + return keys; +} + +function formatTransactionByHashAndReceiptRequests(fileName, request) { + /** + * Formats a specific request by incorporating actual transaction and block hashes based on the provided file name. + * + * @param {string} fileName - The name of the file being processed. + * @param {Object} request - The specific request to be formatted. + * @returns {Object} - The formatted request containing updated transaction and block hashes. + */ + switch (fileName) { + case ACCESS_LIST_FILE_NAME: + request.params[0] = transaction2930AndBlockHash.transactionHash; + break; + case DYNAMIC_FEE_FILE_NAME: + request.params[0] = transaction1559AndBlockHash.transactionHash; + break; + case EMPTY_TX_FILE_NAME: + request.params[0] = EMPTY_TX_HASH; + break; + case LEGACY_CREATE_FILE_NAME: + request.params[0] = createContractLegacyTransactionAndBlockHash.transactionHash; + break; + case LEGACY_INPUT_FILE_NAME: + request.params[0] = createContractLegacyTransactionAndBlockHash.transactionHash; + break; + case LEGACY_CONTRACT_FILE_NAME: + request.params[0] = createContractLegacyTransactionAndBlockHash.transactionHash; + break; + case LEGACY_TX_FILE_NAME: + request.params[0] = legacyTransactionAndBlockHash.transactionHash; + break; + case LEGACY_RECEIPT_FILE_NAME: + request.params[0] = legacyTransactionAndBlockHash.transactionHash; + break; + case NOT_FOUND_TX_FILE_NAME: + request.params[0] = NONEXISTENT_TX_HASH; + break; + } + return request; +} + +async function processFileContent(file, content) { + /** + * Processes a file from the execution apis repo + * containing test request and response data. + * + * @param {string} file - The name of the file being processed. + * @param {Object} content - The content of the file, consisting of request and response data. + * @returns {Array} - An array of missing keys in the response data. + */ + console.log('Executing for ', file); + const modifiedRequest = await checkRequestBody(file, JSON.parse(content.request)); + const response = await sendRequestToRelay(modifiedRequest); + const missingKeys = checkResponseFormat(file, response, JSON.parse(content.response)); + + return missingKeys; +} + +describe('@api-conformity Ethereum execution apis tests', function () { + before(async () => { + legacyTransactionAndBlockHash = await signAndSendRawTransaction(legacyTransaction); + transaction2930AndBlockHash = await signAndSendRawTransaction(transaction2930); + transaction1559AndBlockHash = await signAndSendRawTransaction(transaction1559); + createContractLegacyTransactionAndBlockHash = await signAndSendRawTransaction(createContractLegacyTransaction); + currentBlockHash = await getLatestBlockHash(); + }); + //Reading the directories within the ethereum execution api repo + let directories = fs.readdirSync(directoryPath); + + const relaySupportedMethodNames = openRpcData.methods.map((method) => method.name); + + //Filtering in order to use only the tests for methods we support in our relay + directories = directories.filter((directory) => relaySupportedMethodNames.includes(directory)); + + for (const directory of directories) { + const filePath = path.join(directoryPath, directory); + + if (fs.statSync(filePath).isDirectory()) { + const files = fs.readdirSync(path.resolve(directoryPath, directory)); + for (const file of files) { + it(`Executing for ${directory}`, async () => { + const data = fs.readFileSync(path.resolve(directoryPath, directory, file)); + const content = splitReqAndRes(data.toString('utf-8')); + const missingKeys = await processFileContent(file, content); + expect(missingKeys).to.be.empty; + }); + } + } + } +});