diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index 98842a38b026..bd802e83bc69 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -34,6 +34,7 @@ jobs: with: node-version: 20 check-latest: true + cache: yarn - name: Node.js version id: node run: echo "v8CppApiVersion=$(node --print "process.versions.modules")" >> $GITHUB_OUTPUT diff --git a/.github/workflows/docs-check.yml b/.github/workflows/docs-check.yml index 1556cd191b55..a3c4363920a1 100644 --- a/.github/workflows/docs-check.yml +++ b/.github/workflows/docs-check.yml @@ -16,6 +16,7 @@ jobs: - uses: actions/setup-node@v3 with: node-version: 20 + cache: yarn - name: Node.js version id: node run: echo "v8CppApiVersion=$(node --print "process.versions.modules")" >> $GITHUB_OUTPUT diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index cdceb49d808a..a19def8e72de 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -15,6 +15,7 @@ jobs: with: node-version: 20 check-latest: true + cache: yarn - name: Node.js version id: node run: echo "v8CppApiVersion=$(node --print "process.versions.modules")" >> $GITHUB_OUTPUT diff --git a/.github/workflows/publish-dev.yml b/.github/workflows/publish-dev.yml index a656f8562bf3..2e71cc86c33c 100644 --- a/.github/workflows/publish-dev.yml +++ b/.github/workflows/publish-dev.yml @@ -23,6 +23,7 @@ jobs: node-version: 20 registry-url: "https://registry.npmjs.org" check-latest: true + cache: yarn - name: Node.js version id: node run: echo "v8CppApiVersion=$(node --print "process.versions.modules")" >> $GITHUB_OUTPUT diff --git a/.github/workflows/publish-rc.yml b/.github/workflows/publish-rc.yml index 005d2738b1c6..c0dfe3b513dd 100644 --- a/.github/workflows/publish-rc.yml +++ b/.github/workflows/publish-rc.yml @@ -56,6 +56,7 @@ jobs: with: node-version: 20 check-latest: true + cache: yarn - name: Node.js version id: node run: echo "v8CppApiVersion=$(node --print "process.versions.modules")" >> $GITHUB_OUTPUT diff --git a/.github/workflows/publish-stable.yml b/.github/workflows/publish-stable.yml index 01e222d48e72..c0d046891bdf 100644 --- a/.github/workflows/publish-stable.yml +++ b/.github/workflows/publish-stable.yml @@ -62,6 +62,7 @@ jobs: with: node-version: 20 check-latest: true + cache: yarn - name: Node.js version id: node run: echo "v8CppApiVersion=$(node --print "process.versions.modules")" >> $GITHUB_OUTPUT diff --git a/.github/workflows/test-browser.yml b/.github/workflows/test-browser.yml deleted file mode 100644 index c4c478b53a07..000000000000 --- a/.github/workflows/test-browser.yml +++ /dev/null @@ -1,64 +0,0 @@ -name: Browser tests - -concurrency: - # If PR, cancel prev commits. head_ref = source branch name on pull_request, null if push - group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -on: - push: - # We intentionally don't run push on feature branches. See PR for rational. - branches: [unstable, stable] - pull_request: - workflow_dispatch: - -jobs: - tests-main: - name: Tests - runs-on: buildjet-4vcpu-ubuntu-2204 - strategy: - fail-fast: false - matrix: - node: [20] - steps: - # - Uses YAML anchors in the future - - uses: actions/checkout@v3 - - uses: browser-actions/setup-firefox@latest - with: - firefox-version: "latest" - - uses: actions/setup-node@v3 - with: - node-version: ${{matrix.node}} - check-latest: true - - name: Node.js version - id: node - run: echo "v8CppApiVersion=$(node --print "process.versions.modules")" >> $GITHUB_OUTPUT - - name: Restore dependencies - uses: actions/cache@master - id: cache-deps - with: - path: | - node_modules - packages/*/node_modules - key: ${{ runner.os }}-${{ steps.node.outputs.v8CppApiVersion }}-${{ hashFiles('**/yarn.lock', '**/package.json') }} - - name: Install & build - if: steps.cache-deps.outputs.cache-hit != 'true' - run: yarn install --frozen-lockfile && yarn build - - name: Build - run: yarn build - if: steps.cache-deps.outputs.cache-hit == 'true' - # - - # Misc sanity checks - - name: Test root binary exists - run: ./lodestar --version - - name: Reject yarn.lock changes - run: .github/workflows/scripts/reject_yarn_lock_changes.sh - # Run only on forks - if: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository }} - - - name: Browser tests - run: | - export DISPLAY=':99.0' - Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 & - yarn test:browsers diff --git a/.github/workflows/test-e2e.yml b/.github/workflows/test-e2e.yml deleted file mode 100644 index 25d49c64ad01..000000000000 --- a/.github/workflows/test-e2e.yml +++ /dev/null @@ -1,78 +0,0 @@ -name: E2E tests - -concurrency: - # If PR, cancel prev commits. head_ref = source branch name on pull_request, null if push - group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -on: - push: - # We intentionally don't run push on feature branches. See PR for rational. - branches: [unstable, stable] - pull_request: - workflow_dispatch: - -env: - GOERLI_RPC_DEFAULT_URL: https://goerli.infura.io/v3/84842078b09946638c03157f83405213 - GETH_DOCKER_IMAGE: ethereum/client-go:v1.11.6 - NETHERMIND_DOCKER_IMAGE: nethermind/nethermind:1.18.0 - -jobs: - tests-main: - name: Tests - runs-on: buildjet-4vcpu-ubuntu-2204 - strategy: - fail-fast: false - matrix: - node: [20] - steps: - # - Uses YAML anchors in the future - - uses: actions/checkout@v3 - - uses: actions/setup-node@v3 - with: - node-version: ${{matrix.node}} - check-latest: true - - name: Node.js version - id: node - run: echo "v8CppApiVersion=$(node --print "process.versions.modules")" >> $GITHUB_OUTPUT - - name: Restore dependencies - uses: actions/cache@master - id: cache-deps - with: - path: | - node_modules - packages/*/node_modules - key: ${{ runner.os }}-${{ steps.node.outputs.v8CppApiVersion }}-${{ hashFiles('**/yarn.lock', '**/package.json') }} - - name: Install & build - if: steps.cache-deps.outputs.cache-hit != 'true' - run: yarn install --frozen-lockfile && yarn build - - name: Build - run: yarn build - if: steps.cache-deps.outputs.cache-hit == 'true' - # - - # Misc sanity checks - - name: Test root binary exists - run: ./lodestar --version - - name: Reject yarn.lock changes - run: .github/workflows/scripts/reject_yarn_lock_changes.sh - # Run only on forks - if: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository }} - - - name: Run the e2e test environment - run: scripts/run_e2e_env.sh start - - - name: E2E tests - run: yarn test:e2e - env: - GOERLI_RPC_URL: ${{ secrets.GOERLI_RPC_URL!=0 && secrets.GOERLI_RPC_URL || env.GOERLI_RPC_DEFAULT_URL }} - - - name: Stop the e2e test environment - run: scripts/run_e2e_env.sh stop - - - name: Upload debug log test for test env - if: ${{ always() }} - uses: actions/upload-artifact@v2 - with: - name: debug-e2e-test-logs - path: test-logs/e2e-test-env diff --git a/.github/workflows/test-sim-merge.yml b/.github/workflows/test-sim-merge.yml index 277a75862079..268df5620559 100644 --- a/.github/workflows/test-sim-merge.yml +++ b/.github/workflows/test-sim-merge.yml @@ -32,6 +32,7 @@ jobs: with: node-version: 20 check-latest: true + cache: yarn - name: Node.js version id: node run: echo "v8CppApiVersion=$(node --print "process.versions.modules")" >> $GITHUB_OUTPUT @@ -91,7 +92,7 @@ jobs: - name: Upload debug log test files if: ${{ always() }} - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: debug-test-logs path: packages/beacon-node/test-logs @@ -143,7 +144,7 @@ jobs: - name: Upload debug log test files if: ${{ always() }} - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: debug-test-logs path: packages/beacon-node/test-logs diff --git a/.github/workflows/test-sim.yml b/.github/workflows/test-sim.yml index 9fea85cd94af..a6e2581fdee6 100644 --- a/.github/workflows/test-sim.yml +++ b/.github/workflows/test-sim.yml @@ -33,6 +33,7 @@ jobs: with: node-version: 20 check-latest: true + cache: yarn - name: Node.js version id: node run: echo "v8CppApiVersion=$(node --print "process.versions.modules")" >> $GITHUB_OUTPUT diff --git a/.github/workflows/test-spec.yml b/.github/workflows/test-spec.yml deleted file mode 100644 index eb17c2e2babf..000000000000 --- a/.github/workflows/test-spec.yml +++ /dev/null @@ -1,69 +0,0 @@ -name: Spec tests - -concurrency: - # If PR, cancel prev commits. head_ref = source branch name on pull_request, null if push - group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -on: - push: - # We intentionally don't run push on feature branches. See PR for rational. - branches: [unstable, stable] - pull_request: - workflow_dispatch: - -jobs: - tests-spec: - name: Spec tests - runs-on: buildjet-4vcpu-ubuntu-2204 - steps: - # As of October 2020, runner has +8GB of free space w/out this script (takes 1m30s to run) - # - run: ./scripts/free-disk-space.sh - - # - Uses YAML anchors in the future - - uses: actions/checkout@v3 - - uses: actions/setup-node@v3 - with: - node-version: 20 - check-latest: true - - name: Node.js version - id: node - run: echo "v8CppApiVersion=$(node --print "process.versions.modules")" >> $GITHUB_OUTPUT - - name: Restore dependencies - uses: actions/cache@master - id: cache-deps - with: - path: | - node_modules - packages/*/node_modules - key: ${{ runner.os }}-${{ steps.node.outputs.v8CppApiVersion }}-${{ hashFiles('**/yarn.lock', '**/package.json') }} - - name: Install & build - if: steps.cache-deps.outputs.cache-hit != 'true' - run: yarn install --frozen-lockfile && yarn build - - name: Build - run: yarn build - if: steps.cache-deps.outputs.cache-hit == 'true' - # - - # Download spec tests with cache - - name: Restore spec tests cache - uses: actions/cache@master - with: - path: packages/beacon-node/spec-tests - key: spec-test-data-${{ hashFiles('packages/beacon-node/test/spec/specTestVersioning.ts') }} - - name: Download spec tests - run: yarn download-spec-tests - working-directory: packages/beacon-node - - # Run them in different steps to quickly identifying which command failed - # Otherwise just doing `yarn test:spec` you can't tell which specific suite failed - # many of the suites have identical names for minimal and mainnet - - name: Spec tests bls-general - run: yarn test:spec-bls-general - working-directory: packages/beacon-node - - name: Spec tests minimal - run: yarn test:spec-minimal - working-directory: packages/beacon-node - - name: Spec tests mainnet - run: NODE_OPTIONS='--max-old-space-size=4096' yarn test:spec-mainnet - working-directory: packages/beacon-node diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 22bef8d6c10a..37b4f6b8e554 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -11,10 +11,14 @@ on: branches: [unstable, stable] pull_request: workflow_dispatch: - + +env: + GETH_DOCKER_IMAGE: ethereum/client-go:v1.11.6 + NETHERMIND_DOCKER_IMAGE: nethermind/nethermind:1.18.0 + jobs: - tests-main: - name: Tests + build: + name: Build runs-on: buildjet-4vcpu-ubuntu-2204 strategy: fail-fast: false @@ -27,60 +31,271 @@ jobs: with: node-version: ${{matrix.node}} check-latest: true + cache: yarn - name: Node.js version id: node run: echo "v8CppApiVersion=$(node --print "process.versions.modules")" >> $GITHUB_OUTPUT - - name: Restore dependencies - uses: actions/cache@master - id: cache-deps + - name: Restore build + uses: actions/cache/restore@v3 + id: cache-build-restore with: path: | node_modules packages/*/node_modules - key: ${{ runner.os }}-${{ steps.node.outputs.v8CppApiVersion }}-${{ hashFiles('**/yarn.lock', '**/package.json') }} + lib/ + packages/*/lib + packages/*/.git-data.json + key: ${{ runner.os }}-${{ matrix.node }}-${{ github.event.pull_request.head.sha }} - name: Install & build - if: steps.cache-deps.outputs.cache-hit != 'true' + if: steps.cache-build-restore.outputs.cache-hit != 'true' run: yarn install --frozen-lockfile && yarn build - name: Build run: yarn build - if: steps.cache-deps.outputs.cache-hit == 'true' - # - - # Cache validator slashing protection data tests - - name: Restore spec tests cache - uses: actions/cache@master - with: - path: packages/validator/spec-tests - key: spec-test-data-${{ hashFiles('packages/validator/test/spec/params.ts') }} - - - name: Assert yarn prints no warnings - run: scripts/assert_no_yarn_warnings.sh - - # Misc sanity checks - - name: Lint Grafana dashboards - run: scripts/validate-grafana-dashboards.sh + if: steps.cache-build-restore.outputs.cache-hit == 'true' + - name: Check Build + run: yarn check-build - name: Test root binary exists - run: ./lodestar --version + run: ./lodestar --version - name: Reject yarn.lock changes run: .github/workflows/scripts/reject_yarn_lock_changes.sh # Run only on forks if: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository }} + - name: Cache build artifacts + uses: actions/cache@master + id: cache-build + with: + path: | + node_modules + packages/*/node_modules + lib/ + packages/*/lib + packages/*/.git-data.json + key: ${{ runner.os }}-${{ matrix.node }}-${{ github.event.pull_request.head.sha }} + + lint: + name: Lint + needs: build + runs-on: 'ubuntu-latest' + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: 20 + check-latest: true + cache: yarn + - name: Restore build cache + id: cache-primes-restore + uses: actions/cache/restore@v3 + with: + path: | + node_modules + packages/*/node_modules + lib/ + packages/*/lib + packages/*/.git-data.json + key: ${{ runner.os }}-20-${{ github.event.pull_request.head.sha }} + - name: Assert yarn prints no warnings + run: scripts/assert_no_yarn_warnings.sh + - name: Lint Code + run: yarn lint + - name: Lint Grafana dashboards + run: scripts/validate-grafana-dashboards.sh - name: Assert ESM module exports run: node scripts/assert_exports.mjs - name: Assert eslintrc rules sorted run: scripts/assert_eslintrc_sorted.mjs + type-checks: + name: Type Checks + needs: build + runs-on: 'ubuntu-latest' + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: 20 + check-latest: true + cache: yarn + - name: Restore build cache + id: cache-primes-restore + uses: actions/cache/restore@v3 + with: + path: | + node_modules + packages/*/node_modules + lib/ + packages/*/lib + packages/*/.git-data.json + key: ${{ runner.os }}-20-${{ github.event.pull_request.head.sha }} + - name: Check Types run: yarn check-types - + - name: README check run: yarn check-readme + + unit-tests: + name: Unit Tests + needs: type-checks + runs-on: buildjet-4vcpu-ubuntu-2204 + strategy: + fail-fast: false + matrix: + node: [20] + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: ${{matrix.node}} + check-latest: true + cache: yarn + - name: Restore build cache + id: cache-primes-restore + uses: actions/cache/restore@v3 + with: + path: | + node_modules + packages/*/node_modules + lib/ + packages/*/lib + packages/*/.git-data.json + key: ${{ runner.os }}-${{ matrix.node }}-${{ github.event.pull_request.head.sha }} + # Cache validator slashing protection data tests + - name: Restore spec tests cache + uses: actions/cache@master + with: + path: packages/validator/spec-tests + key: spec-test-data-${{ hashFiles('packages/validator/test/spec/params.ts') }} - - name: Lint - run: yarn lint - - name: Check Build - run: yarn check-build - name: Unit tests run: yarn test:unit - name: Upload coverage data run: yarn coverage + + e2e-tests: + name: E2E Tests + runs-on: buildjet-4vcpu-ubuntu-2204 + needs: build + strategy: + fail-fast: false + matrix: + node: [20] + steps: + # - Uses YAML anchors in the future + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: ${{matrix.node}} + check-latest: true + cache: yarn + - name: Restore build cache + id: cache-primes-restore + uses: actions/cache/restore@v3 + with: + path: | + node_modules + packages/*/node_modules + lib/ + packages/*/lib + packages/*/.git-data.json + key: ${{ runner.os }}-${{ matrix.node }}-${{ github.event.pull_request.head.sha }} + + - name: Run the e2e test environment + run: scripts/run_e2e_env.sh start + + - name: E2E tests + run: yarn test:e2e + env: + GOERLI_RPC_URL: ${{ secrets.GOERLI_RPC_URL!=0 && secrets.GOERLI_RPC_URL || env.GOERLI_RPC_DEFAULT_URL }} + + - name: Stop the e2e test environment + run: scripts/run_e2e_env.sh stop + + - name: Upload debug log test for test env + if: ${{ always() }} + uses: actions/upload-artifact@v3 + with: + name: debug-e2e-test-logs-node-${{matrix.node}} + path: test-logs/e2e-test-env + + browser-tests: + name: Browser Tests + runs-on: buildjet-4vcpu-ubuntu-2204 + needs: build + strategy: + fail-fast: false + matrix: + node: [20] + steps: + # - Uses YAML anchors in the future + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: ${{matrix.node}} + check-latest: true + cache: yarn + - name: Restore build cache + id: cache-primes-restore + uses: actions/cache/restore@v3 + with: + path: | + node_modules + packages/*/node_modules + lib/ + packages/*/lib + packages/*/.git-data.json + key: ${{ runner.os }}-${{ matrix.node }}-${{ github.event.pull_request.head.sha }} + + - name: Browser tests + run: | + export DISPLAY=':99.0' + Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 & + yarn test:browsers + + spec-tests: + name: Spec tests + needs: build + runs-on: buildjet-4vcpu-ubuntu-2204 + strategy: + fail-fast: false + matrix: + node: [20] + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: ${{matrix.node}} + check-latest: true + cache: yarn + - name: Restore build cache + id: cache-primes-restore + uses: actions/cache/restore@v3 + with: + path: | + node_modules + packages/*/node_modules + lib/ + packages/*/lib + packages/*/.git-data.json + key: ${{ runner.os }}-${{ matrix.node }}-${{ github.event.pull_request.head.sha }} + # Download spec tests with cache + - name: Restore spec tests cache + uses: actions/cache@master + with: + path: packages/beacon-node/spec-tests + key: spec-test-data-${{ hashFiles('packages/beacon-node/test/spec/specTestVersioning.ts') }} + - name: Download spec tests + run: yarn download-spec-tests + working-directory: packages/beacon-node + # Run them in different steps to quickly identifying which command failed + # Otherwise just doing `yarn test:spec` you can't tell which specific suite failed + # many of the suites have identical names for minimal and mainnet + - name: Spec tests bls-general + run: yarn test:spec-bls-general + working-directory: packages/beacon-node + - name: Spec tests minimal + run: yarn test:spec-minimal + working-directory: packages/beacon-node + - name: Spec tests mainnet + run: NODE_OPTIONS='--max-old-space-size=4096' yarn test:spec-mainnet + working-directory: packages/beacon-node diff --git a/package.json b/package.json index 6353104811c3..3c14dfbe7d72 100644 --- a/package.json +++ b/package.json @@ -93,7 +93,8 @@ "ts-node": "^10.9.1", "typescript": "^5.1.6", "typescript-docs-verifier": "^2.5.0", - "webpack": "^5.88.1" + "webpack": "^5.88.1", + "wait-port": "^1.0.4" }, "resolutions": { "dns-over-http-resolver": "^2.1.1" diff --git a/packages/api/src/beacon/index.ts b/packages/api/src/beacon/index.ts index e86895e3beae..7cbd86252471 100644 --- a/packages/api/src/beacon/index.ts +++ b/packages/api/src/beacon/index.ts @@ -1,4 +1,4 @@ -import {Api} from "./routes/index.js"; +import type {Api} from "./routes/index.js"; // NOTE: Don't export server here so it's not bundled to all consumers diff --git a/packages/api/src/beacon/routes/beacon/index.ts b/packages/api/src/beacon/routes/beacon/index.ts index d8879ca2d695..4d0c8186fd22 100644 --- a/packages/api/src/beacon/routes/beacon/index.ts +++ b/packages/api/src/beacon/routes/beacon/index.ts @@ -15,10 +15,11 @@ import * as state from "./state.js"; export * as block from "./block.js"; export * as pool from "./pool.js"; export * as state from "./state.js"; -export {BlockId, BlockHeaderResponse, BroadcastValidation} from "./block.js"; -export {AttestationFilters} from "./pool.js"; +export {BroadcastValidation} from "./block.js"; +export type {BlockId, BlockHeaderResponse} from "./block.js"; +export type {AttestationFilters} from "./pool.js"; // TODO: Review if re-exporting all these types is necessary -export { +export type { StateId, ValidatorId, ValidatorStatus, diff --git a/packages/api/src/beacon/server/index.ts b/packages/api/src/beacon/server/index.ts index 6c1cc9c16a4b..b1129394ee78 100644 --- a/packages/api/src/beacon/server/index.ts +++ b/packages/api/src/beacon/server/index.ts @@ -17,7 +17,7 @@ import * as validator from "./validator.js"; export {ApiError}; // Re-export for convenience -export {RouteConfig}; +export type {RouteConfig}; export function registerRoutes( server: ServerInstance, diff --git a/packages/api/src/builder/index.ts b/packages/api/src/builder/index.ts index 5d995484ffb6..76100fba2057 100644 --- a/packages/api/src/builder/index.ts +++ b/packages/api/src/builder/index.ts @@ -5,7 +5,7 @@ import * as builder from "./client.js"; // NOTE: Don't export server here so it's not bundled to all consumers -export {Api}; +export type {Api}; // Note: build API does not have namespaces as routes are declared at the "root" namespace diff --git a/packages/api/src/builder/server/index.ts b/packages/api/src/builder/server/index.ts index 2421abbc0dcc..3f979af4094a 100644 --- a/packages/api/src/builder/server/index.ts +++ b/packages/api/src/builder/server/index.ts @@ -5,7 +5,7 @@ import { ServerRoutes, getGenericJsonServer, registerRoute, - RouteConfig, + type RouteConfig, } from "../../utils/server/index.js"; import {Api, ReqTypes, routesData, getReturnTypes, getReqSerializers} from "../routes.js"; diff --git a/packages/api/src/index.ts b/packages/api/src/index.ts index a0436611798e..27ef2ada69d3 100644 --- a/packages/api/src/index.ts +++ b/packages/api/src/index.ts @@ -1,19 +1,10 @@ // Re-exporting beacon only for backwards compatibility export * from "./beacon/index.js"; export * from "./interfaces.js"; -export {HttpStatusCode, HttpErrorCodes, HttpSuccessCodes} from "./utils/client/httpStatusCode.js"; -export { - HttpClient, - IHttpClient, - HttpClientOptions, - HttpClientModules, - HttpError, - ApiError, - Metrics, - FetchError, - isFetchError, - fetch, -} from "./utils/client/index.js"; +export {HttpStatusCode} from "./utils/client/httpStatusCode.js"; +export type {HttpErrorCodes, HttpSuccessCodes} from "./utils/client/httpStatusCode.js"; +export {HttpClient, HttpError, ApiError, FetchError, isFetchError, fetch} from "./utils/client/index.js"; +export type {IHttpClient, HttpClientOptions, HttpClientModules, Metrics} from "./utils/client/index.js"; export * from "./utils/routes.js"; // NOTE: Don't export server here so it's not bundled to all consumers diff --git a/packages/api/src/keymanager/index.ts b/packages/api/src/keymanager/index.ts index 4f6b3c1b9985..3232876e2657 100644 --- a/packages/api/src/keymanager/index.ts +++ b/packages/api/src/keymanager/index.ts @@ -6,18 +6,8 @@ import * as keymanager from "./client.js"; // NOTE: Don't export server here so it's not bundled to all consumers -export { - ImportStatus, - DeletionStatus, - ImportRemoteKeyStatus, - DeleteRemoteKeyStatus, - ResponseStatus, - SignerDefinition, - KeystoreStr, - SlashingProtectionData, - PubkeyHex, - Api, -} from "./routes.js"; +export {ImportStatus, DeletionStatus, ImportRemoteKeyStatus, DeleteRemoteKeyStatus} from "./routes.js"; +export type {ResponseStatus, SignerDefinition, KeystoreStr, SlashingProtectionData, PubkeyHex, Api} from "./routes.js"; type ClientModules = HttpClientModules & { config: ChainForkConfig; diff --git a/packages/api/src/keymanager/server/index.ts b/packages/api/src/keymanager/server/index.ts index 2421abbc0dcc..3f979af4094a 100644 --- a/packages/api/src/keymanager/server/index.ts +++ b/packages/api/src/keymanager/server/index.ts @@ -5,7 +5,7 @@ import { ServerRoutes, getGenericJsonServer, registerRoute, - RouteConfig, + type RouteConfig, } from "../../utils/server/index.js"; import {Api, ReqTypes, routesData, getReturnTypes, getReqSerializers} from "../routes.js"; diff --git a/packages/api/src/utils/client/httpClient.ts b/packages/api/src/utils/client/httpClient.ts index 54a7ca8d4e42..2c0d682019c5 100644 --- a/packages/api/src/utils/client/httpClient.ts +++ b/packages/api/src/utils/client/httpClient.ts @@ -3,7 +3,7 @@ import {ReqGeneric, RouteDef} from "../index.js"; import {ApiClientResponse, ApiClientSuccessResponse} from "../../interfaces.js"; import {fetch, isFetchError} from "./fetch.js"; import {stringifyQuery, urlJoin} from "./format.js"; -import {Metrics} from "./metrics.js"; +import type {Metrics} from "./metrics.js"; import {HttpStatusCode} from "./httpStatusCode.js"; /** A higher default timeout, validator will sets its own shorter timeoutMs */ diff --git a/packages/beacon-node/.mocharc.spec.cjs b/packages/beacon-node/.mocharc.spec.cjs index 61fbf9430fe4..1a160c2d6131 100644 --- a/packages/beacon-node/.mocharc.spec.cjs +++ b/packages/beacon-node/.mocharc.spec.cjs @@ -3,6 +3,5 @@ module.exports = { require: ["./test/setupPreset.ts", "./test/setup.ts"], "node-option": ["loader=ts-node/esm"], timeout: 60_000, - // Do not run tests through workers, it's not proven to be faster than with `jobs: 2` - parallel: false, + parallel: true }; diff --git a/packages/beacon-node/package.json b/packages/beacon-node/package.json index 44759696641a..35638fa67109 100644 --- a/packages/beacon-node/package.json +++ b/packages/beacon-node/package.json @@ -80,7 +80,7 @@ "test:unit:minimal": "nyc --cache-dir .nyc_output/.cache -e .ts mocha 'test/unit/**/*.test.ts'", "test:unit:mainnet": "LODESTAR_PRESET=mainnet nyc --cache-dir .nyc_output/.cache -e .ts mocha 'test/unit-mainnet/**/*.test.ts'", "test:unit": "yarn test:unit:minimal && yarn test:unit:mainnet", - "test:e2e": "mocha 'test/e2e/**/*.test.ts'", + "test:e2e": "LODESTAR_PRESET=minimal mocha 'test/e2e/**/*.test.ts'", "test:sim": "mocha 'test/sim/**/*.test.ts'", "test:sim:merge-interop": "mocha 'test/sim/merge-interop.test.ts'", "test:sim:mergemock": "mocha 'test/sim/mergemock.test.ts'", diff --git a/packages/beacon-node/src/chain/blocks/index.ts b/packages/beacon-node/src/chain/blocks/index.ts index 46369a64d586..569fd0771022 100644 --- a/packages/beacon-node/src/chain/blocks/index.ts +++ b/packages/beacon-node/src/chain/blocks/index.ts @@ -11,7 +11,7 @@ import {assertLinearChainSegment} from "./utils/chainSegment.js"; import {BlockInput, FullyVerifiedBlock, ImportBlockOpts} from "./types.js"; import {verifyBlocksSanityChecks} from "./verifyBlocksSanityChecks.js"; import {removeEagerlyPersistedBlockInputs} from "./writeBlockInputToDb.js"; -export {ImportBlockOpts, AttestationImportOpt} from "./types.js"; +export {type ImportBlockOpts, AttestationImportOpt} from "./types.js"; const QUEUE_MAX_LENGTH = 256; diff --git a/packages/beacon-node/src/chain/bls/index.ts b/packages/beacon-node/src/chain/bls/index.ts index d13d367c153b..3ee72ac66cbd 100644 --- a/packages/beacon-node/src/chain/bls/index.ts +++ b/packages/beacon-node/src/chain/bls/index.ts @@ -1,3 +1,4 @@ -export {IBlsVerifier} from "./interface.js"; -export {BlsMultiThreadWorkerPool, BlsMultiThreadWorkerPoolModules} from "./multithread/index.js"; +export type {IBlsVerifier} from "./interface.js"; +export type {BlsMultiThreadWorkerPoolModules} from "./multithread/index.js"; +export {BlsMultiThreadWorkerPool} from "./multithread/index.js"; export {BlsSingleThreadVerifier} from "./singleThread.js"; diff --git a/packages/beacon-node/src/chain/emitter.ts b/packages/beacon-node/src/chain/emitter.ts index 81c38331c84e..8c02064b4a92 100644 --- a/packages/beacon-node/src/chain/emitter.ts +++ b/packages/beacon-node/src/chain/emitter.ts @@ -14,7 +14,7 @@ import {CachedBeaconStateAllForks} from "@lodestar/state-transition"; * - Fork Choice: the chain's fork choice is updated * - Checkpointing: the chain processes epoch boundaries */ -export const enum ChainEvent { +export enum ChainEvent { /** * This event signals that the chain has processed (or reprocessed) a checkpoint. * diff --git a/packages/beacon-node/src/chain/forkChoice/index.ts b/packages/beacon-node/src/chain/forkChoice/index.ts index 4de9d3e6ca23..7e195a84922d 100644 --- a/packages/beacon-node/src/chain/forkChoice/index.ts +++ b/packages/beacon-node/src/chain/forkChoice/index.ts @@ -21,7 +21,7 @@ import {ChainEventEmitter} from "../emitter.js"; import {ChainEvent} from "../emitter.js"; import {GENESIS_SLOT} from "../../constants/index.js"; -export {ForkChoiceOpts}; +export type {ForkChoiceOpts}; /** * Fork Choice extended with a ChainEventEmitter diff --git a/packages/beacon-node/src/chain/interface.ts b/packages/beacon-node/src/chain/interface.ts index 78fbf2c5a3fe..211ac7e3777a 100644 --- a/packages/beacon-node/src/chain/interface.ts +++ b/packages/beacon-node/src/chain/interface.ts @@ -37,8 +37,8 @@ import {IChainOptions} from "./options.js"; import {AssembledBlockType, BlockAttributes, BlockType} from "./produceBlock/produceBlockBody.js"; import {SeenAttestationDatas} from "./seenCache/seenAttestationData.js"; -export {BlockType, AssembledBlockType}; -export {ProposerPreparationData}; +export {BlockType, type AssembledBlockType}; +export {type ProposerPreparationData}; export type BlockHash = RootHex; export type StateGetOpts = { diff --git a/packages/beacon-node/src/db/index.ts b/packages/beacon-node/src/db/index.ts index 217764734af0..ed48845b6b97 100644 --- a/packages/beacon-node/src/db/index.ts +++ b/packages/beacon-node/src/db/index.ts @@ -1,2 +1,2 @@ -export {IBeaconDb} from "./interface.js"; +export type {IBeaconDb} from "./interface.js"; export {BeaconDb} from "./beacon.js"; diff --git a/packages/beacon-node/src/db/repositories/index.ts b/packages/beacon-node/src/db/repositories/index.ts index 774f58b81535..4a66a0ba9876 100644 --- a/packages/beacon-node/src/db/repositories/index.ts +++ b/packages/beacon-node/src/db/repositories/index.ts @@ -2,7 +2,8 @@ export {BlobSidecarsRepository} from "./blobSidecars.js"; export {BlobSidecarsArchiveRepository} from "./blobSidecarsArchive.js"; export {BlockRepository} from "./block.js"; -export {BlockArchiveBatchPutBinaryItem, BlockArchiveRepository, BlockFilterOptions} from "./blockArchive.js"; +export {BlockArchiveRepository} from "./blockArchive.js"; +export type {BlockArchiveBatchPutBinaryItem, BlockFilterOptions} from "./blockArchive.js"; export {StateArchiveRepository} from "./stateArchive.js"; export {AttesterSlashingRepository} from "./attesterSlashing.js"; diff --git a/packages/beacon-node/src/eth1/index.ts b/packages/beacon-node/src/eth1/index.ts index 3e44a0a6620d..f53af42ff6a3 100644 --- a/packages/beacon-node/src/eth1/index.ts +++ b/packages/beacon-node/src/eth1/index.ts @@ -6,7 +6,8 @@ import {Eth1DepositDataTracker, Eth1DepositDataTrackerModules} from "./eth1Depos import {Eth1MergeBlockTracker, Eth1MergeBlockTrackerModules} from "./eth1MergeBlockTracker.js"; import {Eth1Options} from "./options.js"; import {Eth1Provider} from "./provider/eth1Provider.js"; -export {IEth1ForBlockProduction, IEth1Provider, Eth1Provider}; +export {Eth1Provider}; +export type {IEth1ForBlockProduction, IEth1Provider}; // This module encapsulates all consumer functionality to the execution node (formerly eth1). The execution client // has to: diff --git a/packages/beacon-node/src/execution/engine/interface.ts b/packages/beacon-node/src/execution/engine/interface.ts index f2ce00e43a45..c4543c45a3e2 100644 --- a/packages/beacon-node/src/execution/engine/interface.ts +++ b/packages/beacon-node/src/execution/engine/interface.ts @@ -6,7 +6,7 @@ import {DATA, QUANTITY} from "../../eth1/provider/utils.js"; import {PayloadIdCache, PayloadId, WithdrawalV1} from "./payloadIdCache.js"; import {ExecutionPayloadBody} from "./types.js"; -export {PayloadIdCache, PayloadId, WithdrawalV1}; +export {PayloadIdCache, type PayloadId, type WithdrawalV1}; export enum ExecutionPayloadStatus { /** given payload is valid */ diff --git a/packages/beacon-node/src/index.ts b/packages/beacon-node/src/index.ts index 69adb74d5471..aa555a1ab0ca 100644 --- a/packages/beacon-node/src/index.ts +++ b/packages/beacon-node/src/index.ts @@ -1,17 +1,23 @@ export {initStateFromAnchorState, initStateFromDb, initStateFromEth1} from "./chain/index.js"; -export {BeaconDb, IBeaconDb} from "./db/index.js"; -export {Eth1Provider, IEth1Provider} from "./eth1/index.js"; -export {createNodeJsLibp2p, NodeJsLibp2pOpts} from "./network/index.js"; +export {BeaconDb, type IBeaconDb} from "./db/index.js"; +export {Eth1Provider, type IEth1Provider} from "./eth1/index.js"; +export {createNodeJsLibp2p, type NodeJsLibp2pOpts} from "./network/index.js"; export * from "./node/index.js"; // Export metrics utilities to de-duplicate validator metrics -export {RegistryMetricCreator, collectNodeJSMetrics, HttpMetricsServer, getHttpMetricsServer} from "./metrics/index.js"; +export { + RegistryMetricCreator, + collectNodeJSMetrics, + type HttpMetricsServer, + getHttpMetricsServer, +} from "./metrics/index.js"; // Export monitoring service to make it usable by validator export {MonitoringService} from "./monitoring/index.js"; // Export generic RestApi server for CLI -export {RestApiServer, RestApiServerOpts, RestApiServerModules, RestApiServerMetrics} from "./api/rest/base.js"; +export {RestApiServer} from "./api/rest/base.js"; +export type {RestApiServerOpts, RestApiServerModules, RestApiServerMetrics} from "./api/rest/base.js"; // Export type util for CLI - TEMP move to lodestar-types eventually export {getStateTypeFromBytes} from "./util/multifork.js"; diff --git a/packages/beacon-node/src/network/reqresp/ReqRespBeaconNode.ts b/packages/beacon-node/src/network/reqresp/ReqRespBeaconNode.ts index 994be87833d6..69b83ee327c6 100644 --- a/packages/beacon-node/src/network/reqresp/ReqRespBeaconNode.ts +++ b/packages/beacon-node/src/network/reqresp/ReqRespBeaconNode.ts @@ -35,7 +35,7 @@ import * as protocols from "./protocols.js"; import {collectExactOneTyped} from "./utils/collect.js"; export {getReqRespHandlers} from "./handlers/index.js"; -export {ReqRespMethod, RequestTypedContainer} from "./types.js"; +export {ReqRespMethod, type RequestTypedContainer} from "./types.js"; export interface ReqRespBeaconNodeModules { libp2p: Libp2p; diff --git a/packages/beacon-node/src/sync/interface.ts b/packages/beacon-node/src/sync/interface.ts index a9092e6503ab..4dd2fd96e21a 100644 --- a/packages/beacon-node/src/sync/interface.ts +++ b/packages/beacon-node/src/sync/interface.ts @@ -8,7 +8,7 @@ import {IBeaconChain} from "../chain/index.js"; import {Metrics} from "../metrics/index.js"; import {IBeaconDb} from "../db/index.js"; import {SyncChainDebugState} from "./range/chain.js"; -export {SyncChainDebugState}; +export type {SyncChainDebugState}; export type SyncingStatus = routes.node.SyncingStatus; diff --git a/packages/beacon-node/src/util/clock.ts b/packages/beacon-node/src/util/clock.ts index 2f19a5a8ca6b..82fc04aac727 100644 --- a/packages/beacon-node/src/util/clock.ts +++ b/packages/beacon-node/src/util/clock.ts @@ -6,7 +6,7 @@ import {ErrorAborted} from "@lodestar/utils"; import {computeEpochAtSlot, computeTimeAtSlot, getCurrentSlot} from "@lodestar/state-transition"; import {MAXIMUM_GOSSIP_CLOCK_DISPARITY} from "../constants/constants.js"; -export const enum ClockEvent { +export enum ClockEvent { /** * This event signals the start of a new slot, and that subsequent calls to `clock.currentSlot` will equal `slot`. * This event is guaranteed to be emitted every `SECONDS_PER_SLOT` seconds. diff --git a/packages/beacon-node/test/e2e/api/impl/config.test.ts b/packages/beacon-node/test/e2e/api/impl/config.test.ts index e4fa5b29211e..9ba196310e47 100644 --- a/packages/beacon-node/test/e2e/api/impl/config.test.ts +++ b/packages/beacon-node/test/e2e/api/impl/config.test.ts @@ -17,8 +17,6 @@ const CONSTANT_NAMES_SKIP_LIST = new Set([ ]); describe("api / impl / config", function () { - this.timeout(60 * 1000); - it("Ensure all constants are exposed", async () => { const constantNames = await downloadRemoteConstants(ethereumConsensusSpecsTests.specVersion); diff --git a/packages/beacon-node/test/e2e/api/impl/getBlobSidecars.test.ts b/packages/beacon-node/test/e2e/api/impl/getBlobSidecars.test.ts deleted file mode 100644 index 60b960f85acb..000000000000 --- a/packages/beacon-node/test/e2e/api/impl/getBlobSidecars.test.ts +++ /dev/null @@ -1,35 +0,0 @@ -import {expect} from "chai"; -import {config} from "@lodestar/config/default"; -import {ssz} from "@lodestar/types"; -import {GENESIS_SLOT} from "@lodestar/params"; - -import {setupApiImplTestServer, ApiImplTestModules} from "../../../unit/api/impl/index.test.js"; -import {zeroProtoBlock} from "../../../utils/mocks/chain.js"; - -describe("getBlobSideCar", function () { - let server: ApiImplTestModules; - - before(function () { - server = setupApiImplTestServer(); - }); - - // TODO: Write actual tests against the real BeaconChain class, this test is useless - it.skip("getBlobSideCar From BlobSidecars", async () => { - const block = config.getForkTypes(GENESIS_SLOT).SignedBeaconBlock.defaultValue(); - const blobSidecars = ssz.deneb.BlobSidecars.defaultValue(); - const wrappedBlobSidecars = { - blockRoot: ssz.Root.defaultValue(), - slot: block.message.slot, - blobSidecars, - }; - - server.forkChoiceStub.getFinalizedBlock.returns(zeroProtoBlock); - - server.dbStub.blockArchive.get.resolves(block); - server.dbStub.blobSidecars.get.resolves(wrappedBlobSidecars); - - const returnedBlobSideCars = await server.blockApi.getBlobSidecars("genesis"); - - expect(returnedBlobSideCars.data).to.equal(blobSidecars); - }); -}); diff --git a/packages/beacon-node/test/e2e/api/lodestar/lodestar.test.ts b/packages/beacon-node/test/e2e/api/lodestar/lodestar.test.ts index 2a79daae914c..852413ac4c89 100644 --- a/packages/beacon-node/test/e2e/api/lodestar/lodestar.test.ts +++ b/packages/beacon-node/test/e2e/api/lodestar/lodestar.test.ts @@ -38,8 +38,7 @@ describe("api / impl / validator", function () { const genesisValidatorsRoot = Buffer.alloc(32, 0xaa); const config = createBeaconConfig(chainConfig, genesisValidatorsRoot); - const testLoggerOpts: TestLoggerOpts = {level: LogLevel.info}; - const loggerNodeA = testLogger("Node-A", testLoggerOpts); + const loggerNodeA = testLogger("Node-A"); const bn = await getDevBeaconNode({ params: testParams, diff --git a/packages/beacon-node/test/e2e/chain/bls/multithread.test.ts b/packages/beacon-node/test/e2e/chain/bls/multithread.test.ts index 27ea9e094382..3bf32d05702e 100644 --- a/packages/beacon-node/test/e2e/chain/bls/multithread.test.ts +++ b/packages/beacon-node/test/e2e/chain/bls/multithread.test.ts @@ -78,6 +78,7 @@ describe("chain / bls / multithread queue", function () { expect(isValid).to.deep.equal([true, true, true], `sig set ${i} returned invalid`); } } + await pool.close(); } for (const priority of [true, false]) { @@ -122,6 +123,7 @@ describe("chain / bls / multithread queue", function () { for (const [i, isValid] of isValidArr.entries()) { expect(isValid).to.equal(true, `sig set ${i} returned invalid`); } + await pool.close(); }); } }); diff --git a/packages/beacon-node/test/e2e/chain/lightclient.test.ts b/packages/beacon-node/test/e2e/chain/lightclient.test.ts index d5b645b39dd0..1a9edbefc432 100644 --- a/packages/beacon-node/test/e2e/chain/lightclient.test.ts +++ b/packages/beacon-node/test/e2e/chain/lightclient.test.ts @@ -23,7 +23,8 @@ describe("chain / lightclient", function () { const maxLcHeadTrackingDiffSlots = 4; const validatorCount = 8; const validatorClientCount = 4; - const targetSyncCommittee = 3; + // Reduced from 3 to 1, so test can complete in 10 epoch vs 27 epoch + const targetSyncCommittee = 1; /** N sync committee periods + 1 epoch of margin */ const finalizedEpochToReach = targetSyncCommittee * EPOCHS_PER_SYNC_COMMITTEE_PERIOD + 1; /** Given 100% participation the fastest epoch to reach finalization is +2 epochs. -1 for margin */ @@ -53,7 +54,7 @@ describe("chain / lightclient", function () { // delay a bit so regular sync sees it's up to date and sync is completed from the beginning // also delay to allow bls workers to be transpiled/initialized - const genesisSlotsDelay = 16; + const genesisSlotsDelay = 7; const genesisTime = Math.floor(Date.now() / 1000) + genesisSlotsDelay * testParams.SECONDS_PER_SLOT; const testLoggerOpts: TestLoggerOpts = { diff --git a/packages/beacon-node/test/e2e/doppelganger/doppelganger.test.ts b/packages/beacon-node/test/e2e/doppelganger/doppelganger.test.ts index 610072ebafe3..65c6eb387393 100644 --- a/packages/beacon-node/test/e2e/doppelganger/doppelganger.test.ts +++ b/packages/beacon-node/test/e2e/doppelganger/doppelganger.test.ts @@ -21,6 +21,7 @@ import {BeaconNode} from "../../../src/node/index.js"; // // Attempting to do both 1. and 2. in this e2e test more expensive than necessary. // Unit tests in the validator cover 2., so some test in lodestar package should cover 1. +// https://github.com/ChainSafe/lodestar/issues/5967 describe.skip("doppelganger / doppelganger test", function () { const afterEachCallbacks: (() => Promise | void)[] = []; afterEach(async () => { diff --git a/packages/beacon-node/test/e2e/eth1/eth1ForBlockProduction.test.ts b/packages/beacon-node/test/e2e/eth1/eth1ForBlockProduction.test.ts index cb537b14563f..1c67788e3fb6 100644 --- a/packages/beacon-node/test/e2e/eth1/eth1ForBlockProduction.test.ts +++ b/packages/beacon-node/test/e2e/eth1/eth1ForBlockProduction.test.ts @@ -27,6 +27,7 @@ const pyrmontDepositsDataRoot = [ "0x61cef7d8a3f7c590a2dc066ae1c95def5ce769b3e9471fdb34f36f7a7246965e", ]; +// https://github.com/ChainSafe/lodestar/issues/5967 describe.skip("eth1 / Eth1Provider", function () { this.timeout("2 min"); diff --git a/packages/beacon-node/test/e2e/eth1/eth1MergeBlockTracker.test.ts b/packages/beacon-node/test/e2e/eth1/eth1MergeBlockTracker.test.ts index 67d392500cd5..868a06724894 100644 --- a/packages/beacon-node/test/e2e/eth1/eth1MergeBlockTracker.test.ts +++ b/packages/beacon-node/test/e2e/eth1/eth1MergeBlockTracker.test.ts @@ -15,6 +15,7 @@ import {getGoerliRpcUrl} from "../../testParams.js"; // This test is constantly failing. We must unblock PR so this issue is a TODO to debug it and re-enable latter. // It's OKAY to disable temporarily since this functionality is tested indirectly by the sim merge tests. // See https://github.com/ChainSafe/lodestar/issues/4197 +// https://github.com/ChainSafe/lodestar/issues/5967 describe.skip("eth1 / Eth1MergeBlockTracker", function () { this.timeout("2 min"); diff --git a/packages/beacon-node/test/e2e/eth1/eth1Provider.test.ts b/packages/beacon-node/test/e2e/eth1/eth1Provider.test.ts index c5c94f49712c..52f9dd4f264d 100644 --- a/packages/beacon-node/test/e2e/eth1/eth1Provider.test.ts +++ b/packages/beacon-node/test/e2e/eth1/eth1Provider.test.ts @@ -8,6 +8,7 @@ import {Eth1Provider, parseEth1Block} from "../../../src/eth1/provider/eth1Provi import {Eth1Block} from "../../../src/eth1/interface.js"; import {getGoerliRpcUrl} from "../../testParams.js"; +// https://github.com/ChainSafe/lodestar/issues/5967 describe.skip("eth1 / Eth1Provider", function () { this.timeout("2 min"); diff --git a/packages/beacon-node/test/e2e/eth1/stream.test.ts b/packages/beacon-node/test/e2e/eth1/stream.test.ts index ca4d48a302cc..372f9abdb935 100644 --- a/packages/beacon-node/test/e2e/eth1/stream.test.ts +++ b/packages/beacon-node/test/e2e/eth1/stream.test.ts @@ -6,6 +6,7 @@ import {Eth1Provider} from "../../../src/eth1/provider/eth1Provider.js"; import {getGoerliRpcUrl} from "../../testParams.js"; import {Eth1Options} from "../../../src/eth1/options.js"; +// https://github.com/ChainSafe/lodestar/issues/5967 describe.skip("Eth1 streams", function () { this.timeout("2 min"); diff --git a/packages/beacon-node/test/e2e/network/gossipsub.test.ts b/packages/beacon-node/test/e2e/network/gossipsub.test.ts index 49ba6c42d90e..eed9f68cd4ce 100644 --- a/packages/beacon-node/test/e2e/network/gossipsub.test.ts +++ b/packages/beacon-node/test/e2e/network/gossipsub.test.ts @@ -19,7 +19,7 @@ describe("gossipsub / worker", function () { function runTests(this: Mocha.Suite, {useWorker}: {useWorker: boolean}): void { if (this.timeout() < 20 * 1000) this.timeout(150 * 1000); - this.retries(0); // This test fail sometimes, with a 5% rate. + this.retries(2); // This test fail sometimes, with a 5% rate. const afterEachCallbacks: (() => Promise | void)[] = []; afterEach(async () => { diff --git a/packages/beacon-node/test/e2e/network/mdns.test.ts b/packages/beacon-node/test/e2e/network/mdns.test.ts index f08e57a25045..a18e939cfda5 100644 --- a/packages/beacon-node/test/e2e/network/mdns.test.ts +++ b/packages/beacon-node/test/e2e/network/mdns.test.ts @@ -24,6 +24,7 @@ import {memoOnce} from "../../utils/cache.js"; let port = 9000; const mu = "/ip4/127.0.0.1/tcp/0"; +// https://github.com/ChainSafe/lodestar/issues/5967 // eslint-disable-next-line mocha/no-skipped-tests describe.skip("mdns", function () { this.timeout(50000); diff --git a/packages/beacon-node/test/e2e/sync/unknownBlockSync.test.ts b/packages/beacon-node/test/e2e/sync/unknownBlockSync.test.ts index 97d4b45c7558..95ebcaa955fb 100644 --- a/packages/beacon-node/test/e2e/sync/unknownBlockSync.test.ts +++ b/packages/beacon-node/test/e2e/sync/unknownBlockSync.test.ts @@ -47,7 +47,7 @@ describe("sync / unknown block sync", function () { this.timeout("10 min"); // the node needs time to transpile/initialize bls worker threads - const genesisSlotsDelay = 16; + const genesisSlotsDelay = 7; const genesisTime = Math.floor(Date.now() / 1000) + genesisSlotsDelay * testParams.SECONDS_PER_SLOT; const testLoggerOpts: TestLoggerOpts = { level: LogLevel.info, diff --git a/packages/beacon-node/test/spec/presets/epoch_processing.ts b/packages/beacon-node/test/spec/presets/epoch_processing.test.ts similarity index 81% rename from packages/beacon-node/test/spec/presets/epoch_processing.ts rename to packages/beacon-node/test/spec/presets/epoch_processing.test.ts index f804062f56a0..554001bfbde8 100644 --- a/packages/beacon-node/test/spec/presets/epoch_processing.ts +++ b/packages/beacon-node/test/spec/presets/epoch_processing.test.ts @@ -1,3 +1,4 @@ +import path from "node:path"; import {expect} from "chai"; import { CachedBeaconStateAllForks, @@ -7,11 +8,14 @@ import { } from "@lodestar/state-transition"; import * as epochFns from "@lodestar/state-transition/epoch"; import {ssz} from "@lodestar/types"; +import {ACTIVE_PRESET} from "@lodestar/params"; import {createCachedBeaconStateTest} from "../../utils/cachedBeaconState.js"; import {expectEqualBeaconState, inputTypeSszTreeViewDU} from "../utils/expectEqualBeaconState.js"; import {getConfig} from "../../utils/config.js"; -import {TestRunnerFn} from "../utils/types.js"; +import {RunnerType, TestRunnerFn} from "../utils/types.js"; import {assertCorrectProgressiveBalances} from "../config.js"; +import {ethereumConsensusSpecsTests} from "../specTestVersioning.js"; +import {specTestIterator} from "../utils/specTestIterator.js"; export type EpochTransitionFn = (state: CachedBeaconStateAllForks, epochTransitionCache: EpochTransitionCache) => void; @@ -47,7 +51,7 @@ type EpochTransitionCacheingTestCase = { * @param fork * @param epochTransitionFns Describe with which function to run each directory of tests */ -export const epochProcessing = +const epochProcessing = (skipTestNames?: string[]): TestRunnerFn => (fork, testName) => { const config = getConfig(fork); @@ -92,3 +96,15 @@ export const epochProcessing = }, }; }; + +specTestIterator(path.join(ethereumConsensusSpecsTests.outputDir, "tests", ACTIVE_PRESET), { + epoch_processing: { + type: RunnerType.default, + fn: epochProcessing([ + // TODO: invalid_large_withdrawable_epoch asserts an overflow on a u64 for its exit epoch. + // Currently unable to reproduce in Lodestar, skipping for now + // https://github.com/ethereum/consensus-specs/blob/3212c419f6335e80ed825b4855a071f76bef70c3/tests/core/pyspec/eth2spec/test/phase0/epoch_processing/test_process_registry_updates.py#L349 + "invalid_large_withdrawable_epoch", + ]), + }, +}); diff --git a/packages/beacon-node/test/spec/presets/finality.ts b/packages/beacon-node/test/spec/presets/finality.test.ts similarity index 83% rename from packages/beacon-node/test/spec/presets/finality.ts rename to packages/beacon-node/test/spec/presets/finality.test.ts index 132318083f3d..5bfd32ea6a7e 100644 --- a/packages/beacon-node/test/spec/presets/finality.ts +++ b/packages/beacon-node/test/spec/presets/finality.test.ts @@ -1,3 +1,4 @@ +import path from "node:path"; import { BeaconStateAllForks, DataAvailableStatus, @@ -5,16 +6,18 @@ import { stateTransition, } from "@lodestar/state-transition"; import {altair, bellatrix, ssz} from "@lodestar/types"; -import {ForkName} from "@lodestar/params"; +import {ACTIVE_PRESET, ForkName} from "@lodestar/params"; import {createCachedBeaconStateTest} from "../../utils/cachedBeaconState.js"; import {expectEqualBeaconState, inputTypeSszTreeViewDU} from "../utils/expectEqualBeaconState.js"; -import {shouldVerify, TestRunnerFn} from "../utils/types.js"; +import {RunnerType, shouldVerify, TestRunnerFn} from "../utils/types.js"; import {getConfig} from "../../utils/config.js"; import {assertCorrectProgressiveBalances} from "../config.js"; +import {ethereumConsensusSpecsTests} from "../specTestVersioning.js"; +import {specTestIterator} from "../utils/specTestIterator.js"; /* eslint-disable @typescript-eslint/naming-convention */ -export const finality: TestRunnerFn = (fork) => { +const finality: TestRunnerFn = (fork) => { return { testFunction: (testcase) => { let state = createCachedBeaconStateTest(testcase.pre, getConfig(fork)); @@ -80,3 +83,7 @@ type FinalityTestCase = { pre: BeaconStateAllForks; post?: BeaconStateAllForks; }; + +specTestIterator(path.join(ethereumConsensusSpecsTests.outputDir, "tests", ACTIVE_PRESET), { + finality: {type: RunnerType.default, fn: finality}, +}); diff --git a/packages/beacon-node/test/spec/presets/fork.ts b/packages/beacon-node/test/spec/presets/fork.test.ts similarity index 82% rename from packages/beacon-node/test/spec/presets/fork.ts rename to packages/beacon-node/test/spec/presets/fork.test.ts index 5fb241c26e89..228ab6a38935 100644 --- a/packages/beacon-node/test/spec/presets/fork.ts +++ b/packages/beacon-node/test/spec/presets/fork.test.ts @@ -1,3 +1,4 @@ +import path from "node:path"; import { BeaconStateAllForks, CachedBeaconStateBellatrix, @@ -7,13 +8,15 @@ import { } from "@lodestar/state-transition"; import * as slotFns from "@lodestar/state-transition/slot"; import {phase0, ssz} from "@lodestar/types"; -import {ForkName} from "@lodestar/params"; +import {ACTIVE_PRESET, ForkName} from "@lodestar/params"; import {createChainForkConfig, ChainForkConfig} from "@lodestar/config"; import {expectEqualBeaconState, inputTypeSszTreeViewDU} from "../utils/expectEqualBeaconState.js"; import {createCachedBeaconStateTest} from "../../utils/cachedBeaconState.js"; -import {TestRunnerFn} from "../utils/types.js"; +import {RunnerType, TestRunnerFn} from "../utils/types.js"; +import {ethereumConsensusSpecsTests} from "../specTestVersioning.js"; +import {specTestIterator} from "../utils/specTestIterator.js"; -export const fork: TestRunnerFn = (forkNext) => { +const fork: TestRunnerFn = (forkNext) => { const config = createChainForkConfig({}); const forkPrev = getPreviousFork(config, forkNext); @@ -66,3 +69,7 @@ export function getPreviousFork(config: ChainForkConfig, fork: ForkName): ForkNa } return config.forksAscendingEpochOrder[forkIndex - 1].name; } + +specTestIterator(path.join(ethereumConsensusSpecsTests.outputDir, "tests", ACTIVE_PRESET), { + fork: {type: RunnerType.default, fn: fork}, +}); diff --git a/packages/beacon-node/test/spec/presets/fork_choice.ts b/packages/beacon-node/test/spec/presets/fork_choice.test.ts similarity index 96% rename from packages/beacon-node/test/spec/presets/fork_choice.ts rename to packages/beacon-node/test/spec/presets/fork_choice.test.ts index 10bbac4a19bc..7b2dca6e4ede 100644 --- a/packages/beacon-node/test/spec/presets/fork_choice.ts +++ b/packages/beacon-node/test/spec/presets/fork_choice.test.ts @@ -1,3 +1,4 @@ +import path from "node:path"; import {expect} from "chai"; import {toHexString} from "@chainsafe/ssz"; import {BeaconStateAllForks, isExecutionStateType} from "@lodestar/state-transition"; @@ -6,13 +7,13 @@ import {CheckpointWithHex, ForkChoice} from "@lodestar/fork-choice"; import {phase0, allForks, bellatrix, ssz, RootHex} from "@lodestar/types"; import {bnToNum} from "@lodestar/utils"; import {createBeaconConfig} from "@lodestar/config"; -import {ForkSeq, isForkBlobs} from "@lodestar/params"; +import {ACTIVE_PRESET, ForkSeq, isForkBlobs} from "@lodestar/params"; import {BeaconChain} from "../../../src/chain/index.js"; import {ClockEvent} from "../../../src/util/clock.js"; import {createCachedBeaconStateTest} from "../../utils/cachedBeaconState.js"; import {testLogger} from "../../utils/logger.js"; import {getConfig} from "../../utils/config.js"; -import {TestRunnerFn} from "../utils/types.js"; +import {RunnerType, TestRunnerFn} from "../utils/types.js"; import {Eth1ForBlockProductionDisabled} from "../../../src/eth1/index.js"; import {getExecutionEngineFromBackend} from "../../../src/execution/index.js"; import {ExecutionPayloadStatus} from "../../../src/execution/engine/interface.js"; @@ -25,6 +26,8 @@ import {ZERO_HASH_HEX} from "../../../src/constants/constants.js"; import {PowMergeBlock} from "../../../src/eth1/interface.js"; import {assertCorrectProgressiveBalances} from "../config.js"; import {initCKZG, loadEthereumTrustedSetup} from "../../../src/util/kzg.js"; +import {ethereumConsensusSpecsTests} from "../specTestVersioning.js"; +import {specTestIterator} from "../utils/specTestIterator.js"; /* eslint-disable @typescript-eslint/naming-convention */ @@ -37,7 +40,7 @@ const ATTESTER_SLASHING_FILE_NAME = "^(attester_slashing)_([0-9a-zA-Z])+$"; const logger = testLogger("spec-test"); -export const forkChoiceTest = +const forkChoiceTest = (opts: {onlyPredefinedResponses: boolean}): TestRunnerFn => (fork) => { return { @@ -460,3 +463,8 @@ class Eth1ForBlockProductionMock extends Eth1ForBlockProductionDisabled { }); } } + +specTestIterator(path.join(ethereumConsensusSpecsTests.outputDir, "tests", ACTIVE_PRESET), { + fork_choice: {type: RunnerType.default, fn: forkChoiceTest({onlyPredefinedResponses: false})}, + sync: {type: RunnerType.default, fn: forkChoiceTest({onlyPredefinedResponses: true})}, +}); diff --git a/packages/beacon-node/test/spec/presets/genesis.ts b/packages/beacon-node/test/spec/presets/genesis.test.ts similarity index 91% rename from packages/beacon-node/test/spec/presets/genesis.ts rename to packages/beacon-node/test/spec/presets/genesis.test.ts index d80b56dbe65f..ef3006bd6221 100644 --- a/packages/beacon-node/test/spec/presets/genesis.ts +++ b/packages/beacon-node/test/spec/presets/genesis.test.ts @@ -1,3 +1,4 @@ +import path from "node:path"; import {expect} from "chai"; import {phase0, Root, ssz, TimeSeconds, allForks, deneb} from "@lodestar/types"; import {InputType} from "@lodestar/spec-test-util"; @@ -10,15 +11,20 @@ import { import {bnToNum} from "@lodestar/utils"; import {ForkName} from "@lodestar/params"; +import {ACTIVE_PRESET} from "@lodestar/params"; import {expectEqualBeaconState} from "../utils/expectEqualBeaconState.js"; import {TestRunnerFn} from "../utils/types.js"; import {getConfig} from "../../utils/config.js"; + +import {RunnerType} from "../utils/types.js"; +import {specTestIterator} from "../utils/specTestIterator.js"; +import {ethereumConsensusSpecsTests} from "../specTestVersioning.js"; // The aim of the genesis tests is to provide a baseline to test genesis-state initialization and test if the // proposed genesis-validity conditions are working. /* eslint-disable @typescript-eslint/naming-convention */ -export const genesis: TestRunnerFn = (fork, testName, testSuite) => { +const genesis: TestRunnerFn = (fork, testName, testSuite) => { const testFn = genesisTestFns[testName]; if (testFn === undefined) { throw Error(`Unknown genesis test ${testName}`); @@ -145,3 +151,7 @@ type GenesisInitCase = { }; type ExecutionFork = Exclude; + +specTestIterator(path.join(ethereumConsensusSpecsTests.outputDir, "tests", ACTIVE_PRESET), { + genesis: {type: RunnerType.default, fn: genesis}, +}); diff --git a/packages/beacon-node/test/spec/presets/index.test.ts b/packages/beacon-node/test/spec/presets/index.test.ts deleted file mode 100644 index c45f859ec1e5..000000000000 --- a/packages/beacon-node/test/spec/presets/index.test.ts +++ /dev/null @@ -1,79 +0,0 @@ -import path from "node:path"; -import {ACTIVE_PRESET} from "@lodestar/params"; - -import {RunnerType} from "../utils/types.js"; -import {SkipOpts, specTestIterator} from "../utils/specTestIterator.js"; -import {ethereumConsensusSpecsTests} from "../specTestVersioning.js"; -import {epochProcessing} from "./epoch_processing.js"; -import {finality} from "./finality.js"; -import {fork} from "./fork.js"; -import {forkChoiceTest} from "./fork_choice.js"; -import {genesis} from "./genesis.js"; -import {lightClient} from "./light_client/index.js"; -import {merkle} from "./merkle.js"; -import {operations} from "./operations.js"; -import {rewards} from "./rewards.js"; -import {sanity, sanityBlocks} from "./sanity.js"; -import {shuffling} from "./shuffling.js"; -import {sszStatic} from "./ssz_static.js"; -import {transition} from "./transition.js"; - -// NOTE: You MUST always provide a detailed reason of why a spec test is skipped plus link -// to an issue marking it as pending to re-enable and an aproximate timeline of when it will -// be fixed. -// NOTE: Comment the minimum set of test necessary to unblock PRs: For example, instead of -// skipping all `bls_to_execution_change` tests, just skip for a fork setting: -// ``` -// skippedPrefixes: [ -// // Skipped since this only test that withdrawals are de-activated -// "eip4844/operations/bls_to_execution_change", -// ], -// ``` -const skipOpts: SkipOpts = { - skippedForks: ["eip6110"], - // TODO: capella - // BeaconBlockBody proof in lightclient is the new addition in v1.3.0-rc.2-hotfix - // Skip them for now to enable subsequently - skippedPrefixes: [ - "capella/light_client/single_merkle_proof/BeaconBlockBody", - "deneb/light_client/single_merkle_proof/BeaconBlockBody", - ], -}; - -/* eslint-disable @typescript-eslint/naming-convention */ - -specTestIterator( - path.join(ethereumConsensusSpecsTests.outputDir, "tests", ACTIVE_PRESET), - { - epoch_processing: { - type: RunnerType.default, - fn: epochProcessing([ - // TODO: invalid_large_withdrawable_epoch asserts an overflow on a u64 for its exit epoch. - // Currently unable to reproduce in Lodestar, skipping for now - // https://github.com/ethereum/consensus-specs/blob/3212c419f6335e80ed825b4855a071f76bef70c3/tests/core/pyspec/eth2spec/test/phase0/epoch_processing/test_process_registry_updates.py#L349 - "invalid_large_withdrawable_epoch", - ]), - }, - finality: {type: RunnerType.default, fn: finality}, - fork: {type: RunnerType.default, fn: fork}, - fork_choice: {type: RunnerType.default, fn: forkChoiceTest({onlyPredefinedResponses: false})}, - genesis: {type: RunnerType.default, fn: genesis}, - light_client: {type: RunnerType.default, fn: lightClient}, - merkle: {type: RunnerType.default, fn: merkle}, - operations: {type: RunnerType.default, fn: operations}, - random: {type: RunnerType.default, fn: sanityBlocks}, - rewards: {type: RunnerType.default, fn: rewards}, - sanity: {type: RunnerType.default, fn: sanity}, - shuffling: {type: RunnerType.default, fn: shuffling}, - ssz_static: { - type: RunnerType.custom, - fn: sszStatic(), - }, - sync: {type: RunnerType.default, fn: forkChoiceTest({onlyPredefinedResponses: true})}, - transition: { - type: RunnerType.default, - fn: transition(), - }, - }, - skipOpts -); diff --git a/packages/beacon-node/test/spec/presets/light_client/index.ts b/packages/beacon-node/test/spec/presets/light_client/index.test.ts similarity index 51% rename from packages/beacon-node/test/spec/presets/light_client/index.ts rename to packages/beacon-node/test/spec/presets/light_client/index.test.ts index ce2a0ab5a8fd..0a44772cab4b 100644 --- a/packages/beacon-node/test/spec/presets/light_client/index.ts +++ b/packages/beacon-node/test/spec/presets/light_client/index.test.ts @@ -1,11 +1,15 @@ -import {TestRunnerFn} from "../../utils/types.js"; +import path from "node:path"; +import {ACTIVE_PRESET} from "@lodestar/params"; +import {ethereumConsensusSpecsTests} from "../../specTestVersioning.js"; +import {specTestIterator} from "../../utils/specTestIterator.js"; +import {RunnerType, TestRunnerFn} from "../../utils/types.js"; import {singleMerkleProof} from "./single_merkle_proof.js"; import {sync} from "./sync.js"; import {updateRanking} from "./update_ranking.js"; /* eslint-disable @typescript-eslint/naming-convention */ -export const lightClient: TestRunnerFn = (fork, testName, testSuite) => { +const lightClient: TestRunnerFn = (fork, testName, testSuite) => { const testFn = lightclientTestFns[testName]; if (testFn === undefined) { throw Error(`Unknown lightclient test ${testName}`); @@ -19,3 +23,7 @@ const lightclientTestFns: Record> = { sync: sync, update_ranking: updateRanking, }; + +specTestIterator(path.join(ethereumConsensusSpecsTests.outputDir, "tests", ACTIVE_PRESET), { + light_client: {type: RunnerType.default, fn: lightClient}, +}); diff --git a/packages/beacon-node/test/spec/presets/merkle.ts b/packages/beacon-node/test/spec/presets/merkle.test.ts similarity index 80% rename from packages/beacon-node/test/spec/presets/merkle.ts rename to packages/beacon-node/test/spec/presets/merkle.test.ts index 8570e1ca4663..089ffcec97b3 100644 --- a/packages/beacon-node/test/spec/presets/merkle.ts +++ b/packages/beacon-node/test/spec/presets/merkle.test.ts @@ -1,3 +1,4 @@ +import path from "node:path"; import {expect} from "chai"; import {ProofType, SingleProof, Tree} from "@chainsafe/persistent-merkle-tree"; import {fromHexString, toHexString} from "@chainsafe/ssz"; @@ -5,11 +6,14 @@ import {ssz} from "@lodestar/types"; import {BeaconStateAllForks} from "@lodestar/state-transition"; import {InputType} from "@lodestar/spec-test-util"; import {verifyMerkleBranch} from "@lodestar/utils"; -import {TestRunnerFn} from "../utils/types.js"; +import {ACTIVE_PRESET} from "@lodestar/params"; +import {RunnerType, TestRunnerFn} from "../utils/types.js"; +import {ethereumConsensusSpecsTests} from "../specTestVersioning.js"; +import {specTestIterator} from "../utils/specTestIterator.js"; /* eslint-disable @typescript-eslint/naming-convention */ -export const merkle: TestRunnerFn = (fork) => { +const merkle: TestRunnerFn = (fork) => { return { testFunction: (testcase) => { const {proof: specTestProof, state} = testcase; @@ -62,3 +66,7 @@ interface IProof { leaf_index: bigint; branch: string[]; } + +specTestIterator(path.join(ethereumConsensusSpecsTests.outputDir, "tests", ACTIVE_PRESET), { + merkle: {type: RunnerType.default, fn: merkle}, +}); diff --git a/packages/beacon-node/test/spec/presets/operations.ts b/packages/beacon-node/test/spec/presets/operations.test.ts similarity index 90% rename from packages/beacon-node/test/spec/presets/operations.ts rename to packages/beacon-node/test/spec/presets/operations.test.ts index 0dc9739e31b3..cb1b5a0df3f0 100644 --- a/packages/beacon-node/test/spec/presets/operations.ts +++ b/packages/beacon-node/test/spec/presets/operations.test.ts @@ -1,3 +1,4 @@ +import path from "node:path"; import { BeaconStateAllForks, CachedBeaconStateAllForks, @@ -10,12 +11,14 @@ import { import * as blockFns from "@lodestar/state-transition/block"; import {ssz, phase0, altair, bellatrix, capella} from "@lodestar/types"; import {InputType} from "@lodestar/spec-test-util"; -import {ForkName} from "@lodestar/params"; +import {ACTIVE_PRESET, ForkName} from "@lodestar/params"; import {createCachedBeaconStateTest} from "../../utils/cachedBeaconState.js"; import {expectEqualBeaconState, inputTypeSszTreeViewDU} from "../utils/expectEqualBeaconState.js"; import {getConfig} from "../../utils/config.js"; -import {BaseSpecTest, shouldVerify, TestRunnerFn} from "../utils/types.js"; +import {BaseSpecTest, RunnerType, shouldVerify, TestRunnerFn} from "../utils/types.js"; +import {ethereumConsensusSpecsTests} from "../specTestVersioning.js"; +import {specTestIterator} from "../utils/specTestIterator.js"; /* eslint-disable @typescript-eslint/naming-convention */ @@ -95,7 +98,7 @@ export type OperationsTestCase = { execution: {execution_valid: boolean}; }; -export const operations: TestRunnerFn = (fork, testName) => { +const operations: TestRunnerFn = (fork, testName) => { const operationFn = operationFns[testName]; if (operationFn === undefined) { throw Error(`No operationFn for ${testName}`); @@ -144,3 +147,7 @@ export const operations: TestRunnerFn = }; type ExecutionFork = Exclude; + +specTestIterator(path.join(ethereumConsensusSpecsTests.outputDir, "tests", ACTIVE_PRESET), { + operations: {type: RunnerType.default, fn: operations}, +}); diff --git a/packages/beacon-node/test/spec/presets/rewards.ts b/packages/beacon-node/test/spec/presets/rewards.test.ts similarity index 87% rename from packages/beacon-node/test/spec/presets/rewards.ts rename to packages/beacon-node/test/spec/presets/rewards.test.ts index 9352b10a7737..086dab797c13 100644 --- a/packages/beacon-node/test/spec/presets/rewards.ts +++ b/packages/beacon-node/test/spec/presets/rewards.test.ts @@ -1,19 +1,23 @@ +import path from "node:path"; import {expect} from "chai"; import {VectorCompositeType} from "@chainsafe/ssz"; import {BeaconStateAllForks, beforeProcessEpoch} from "@lodestar/state-transition"; import {getRewardsAndPenalties} from "@lodestar/state-transition/epoch"; import {ssz} from "@lodestar/types"; +import {ACTIVE_PRESET} from "@lodestar/params"; import {createCachedBeaconStateTest} from "../../utils/cachedBeaconState.js"; import {inputTypeSszTreeViewDU} from "../utils/expectEqualBeaconState.js"; import {getConfig} from "../../utils/config.js"; -import {TestRunnerFn} from "../utils/types.js"; +import {RunnerType, TestRunnerFn} from "../utils/types.js"; import {assertCorrectProgressiveBalances} from "../config.js"; +import {ethereumConsensusSpecsTests} from "../specTestVersioning.js"; +import {specTestIterator} from "../utils/specTestIterator.js"; /* eslint-disable @typescript-eslint/naming-convention */ const deltasType = new VectorCompositeType(ssz.phase0.Balances, 2); -export const rewards: TestRunnerFn = (fork) => { +const rewards: TestRunnerFn = (fork) => { return { testFunction: (testcase) => { const config = getConfig(fork); @@ -85,3 +89,7 @@ function sumDeltas(deltasArr: Deltas[]): Deltas { } return totalDeltas; } + +specTestIterator(path.join(ethereumConsensusSpecsTests.outputDir, "tests", ACTIVE_PRESET), { + rewards: {type: RunnerType.default, fn: rewards}, +}); diff --git a/packages/beacon-node/test/spec/presets/sanity.ts b/packages/beacon-node/test/spec/presets/sanity.test.ts similarity index 85% rename from packages/beacon-node/test/spec/presets/sanity.ts rename to packages/beacon-node/test/spec/presets/sanity.test.ts index b57f509211b9..91836f67ccf8 100644 --- a/packages/beacon-node/test/spec/presets/sanity.ts +++ b/packages/beacon-node/test/spec/presets/sanity.test.ts @@ -1,3 +1,4 @@ +import path from "node:path"; import {InputType} from "@lodestar/spec-test-util"; import { BeaconStateAllForks, @@ -7,17 +8,19 @@ import { stateTransition, } from "@lodestar/state-transition"; import {allForks, deneb, ssz} from "@lodestar/types"; -import {ForkName} from "@lodestar/params"; +import {ACTIVE_PRESET, ForkName} from "@lodestar/params"; import {bnToNum} from "@lodestar/utils"; import {createCachedBeaconStateTest} from "../../utils/cachedBeaconState.js"; import {expectEqualBeaconState, inputTypeSszTreeViewDU} from "../utils/expectEqualBeaconState.js"; -import {shouldVerify, TestRunnerFn} from "../utils/types.js"; +import {RunnerType, shouldVerify, TestRunnerFn} from "../utils/types.js"; import {getConfig} from "../../utils/config.js"; import {assertCorrectProgressiveBalances} from "../config.js"; +import {ethereumConsensusSpecsTests} from "../specTestVersioning.js"; +import {specTestIterator} from "../utils/specTestIterator.js"; /* eslint-disable @typescript-eslint/naming-convention */ -export const sanity: TestRunnerFn = (fork, testName, testSuite) => { +const sanity: TestRunnerFn = (fork, testName, testSuite) => { switch (testName) { case "slots": return sanitySlots(fork, testName, testSuite); @@ -55,7 +58,7 @@ const sanitySlots: TestRunnerFn = (for }; }; -export const sanityBlocks: TestRunnerFn = (fork) => { +const sanityBlocks: TestRunnerFn = (fork) => { return { testFunction: (testcase) => { const stateTB = testcase.pre; @@ -119,3 +122,8 @@ type SanitySlotsTestCase = { post?: BeaconStateAllForks; slots: bigint; }; + +specTestIterator(path.join(ethereumConsensusSpecsTests.outputDir, "tests", ACTIVE_PRESET), { + sanity: {type: RunnerType.default, fn: sanity}, + random: {type: RunnerType.default, fn: sanityBlocks}, +}); diff --git a/packages/beacon-node/test/spec/presets/shuffling.ts b/packages/beacon-node/test/spec/presets/shuffling.test.ts similarity index 62% rename from packages/beacon-node/test/spec/presets/shuffling.ts rename to packages/beacon-node/test/spec/presets/shuffling.test.ts index d487c71072f2..06e7d4717d06 100644 --- a/packages/beacon-node/test/spec/presets/shuffling.ts +++ b/packages/beacon-node/test/spec/presets/shuffling.test.ts @@ -1,9 +1,13 @@ +import path from "node:path"; import {unshuffleList} from "@lodestar/state-transition"; import {InputType} from "@lodestar/spec-test-util"; import {bnToNum, fromHex} from "@lodestar/utils"; -import {TestRunnerFn} from "../utils/types.js"; +import {ACTIVE_PRESET} from "@lodestar/params"; +import {RunnerType, TestRunnerFn} from "../utils/types.js"; +import {ethereumConsensusSpecsTests} from "../specTestVersioning.js"; +import {specTestIterator} from "../utils/specTestIterator.js"; -export const shuffling: TestRunnerFn = () => { +const shuffling: TestRunnerFn = () => { return { testFunction: (testcase) => { const seed = fromHex(testcase.mapping.seed); @@ -28,3 +32,7 @@ type ShufflingTestCase = { mapping: bigint[]; }; }; + +specTestIterator(path.join(ethereumConsensusSpecsTests.outputDir, "tests", ACTIVE_PRESET), { + shuffling: {type: RunnerType.default, fn: shuffling}, +}); diff --git a/packages/beacon-node/test/spec/presets/ssz_static.ts b/packages/beacon-node/test/spec/presets/ssz_static.test.ts similarity index 85% rename from packages/beacon-node/test/spec/presets/ssz_static.ts rename to packages/beacon-node/test/spec/presets/ssz_static.test.ts index 014e7d6293e0..55587f6e9375 100644 --- a/packages/beacon-node/test/spec/presets/ssz_static.ts +++ b/packages/beacon-node/test/spec/presets/ssz_static.test.ts @@ -6,6 +6,9 @@ import {ACTIVE_PRESET, ForkName, ForkLightClient} from "@lodestar/params"; import {replaceUintTypeWithUintBigintType} from "../utils/replaceUintTypeWithUintBigintType.js"; import {parseSszStaticTestcase} from "../utils/sszTestCaseParser.js"; import {runValidSszTest} from "../utils/runValidSszTest.js"; +import {ethereumConsensusSpecsTests} from "../specTestVersioning.js"; +import {specTestIterator} from "../utils/specTestIterator.js"; +import {RunnerType} from "../utils/types.js"; // ssz_static // | Attestation @@ -26,7 +29,7 @@ type Types = Record>; // tests / mainnet / altair / ssz_static / Validator / ssz_random / case_0/roots.yaml // -export const sszStatic = +const sszStatic = (skippedTypes?: string[]) => (fork: ForkName, typeName: string, testSuite: string, testSuiteDirpath: string): void => { // Do not manually skip tests here, do it in packages/beacon-node/test/spec/presets/index.test.ts @@ -63,3 +66,11 @@ export const sszStatic = }); } }; + +specTestIterator(path.join(ethereumConsensusSpecsTests.outputDir, "tests", ACTIVE_PRESET), { + // eslint-disable-next-line @typescript-eslint/naming-convention + ssz_static: { + type: RunnerType.custom, + fn: sszStatic(), + }, +}); diff --git a/packages/beacon-node/test/spec/presets/transition.ts b/packages/beacon-node/test/spec/presets/transition.test.ts similarity index 89% rename from packages/beacon-node/test/spec/presets/transition.ts rename to packages/beacon-node/test/spec/presets/transition.test.ts index 323b8bea7a5b..3124116b2f4d 100644 --- a/packages/beacon-node/test/spec/presets/transition.ts +++ b/packages/beacon-node/test/spec/presets/transition.test.ts @@ -1,3 +1,4 @@ +import path from "node:path"; import { BeaconStateAllForks, DataAvailableStatus, @@ -6,16 +7,18 @@ import { } from "@lodestar/state-transition"; import {allForks, ssz} from "@lodestar/types"; import {createChainForkConfig, ChainConfig} from "@lodestar/config"; -import {ForkName} from "@lodestar/params"; +import {ACTIVE_PRESET, ForkName} from "@lodestar/params"; import {bnToNum} from "@lodestar/utils"; import {config} from "@lodestar/config/default"; import {expectEqualBeaconState, inputTypeSszTreeViewDU} from "../utils/expectEqualBeaconState.js"; import {createCachedBeaconStateTest} from "../../utils/cachedBeaconState.js"; -import {TestRunnerFn} from "../utils/types.js"; +import {RunnerType, TestRunnerFn} from "../utils/types.js"; import {assertCorrectProgressiveBalances} from "../config.js"; -import {getPreviousFork} from "./fork.js"; +import {ethereumConsensusSpecsTests} from "../specTestVersioning.js"; +import {specTestIterator} from "../utils/specTestIterator.js"; +import {getPreviousFork} from "./fork.test.js"; -export const transition = +const transition = (skipTestNames?: string[]): TestRunnerFn => (forkNext) => { if (forkNext === ForkName.phase0) { @@ -116,3 +119,10 @@ type TransitionTestCase = { pre: BeaconStateAllForks; post: BeaconStateAllForks; }; + +specTestIterator(path.join(ethereumConsensusSpecsTests.outputDir, "tests", ACTIVE_PRESET), { + transition: { + type: RunnerType.default, + fn: transition(), + }, +}); diff --git a/packages/beacon-node/test/spec/utils/specTestIterator.ts b/packages/beacon-node/test/spec/utils/specTestIterator.ts index d03e34dfe64a..a9310d53ac81 100644 --- a/packages/beacon-node/test/spec/utils/specTestIterator.ts +++ b/packages/beacon-node/test/spec/utils/specTestIterator.ts @@ -19,6 +19,53 @@ export interface SkipOpts { skippedHandlers?: string[]; } +/** + * Because we want to execute the spec tests in parallel so one or two runners will be executed + * in isolation at a time and would not be available how many runners are there in total. + * This list is curated manually and should be updated when new runners are added. + * It will make sure if specs introduce new runner, we should cover in our spec tests. + */ +const coveredTestRunners = [ + "light_client", + "epoch_processing", + "finality", + "fork", + "fork_choice", + "sync", + "fork", + "genesis", + "merkle", + "operations", + "rewards", + "sanity", + "random", + "shuffling", + "ssz_static", + "transition", +]; + +// NOTE: You MUST always provide a detailed reason of why a spec test is skipped plus link +// to an issue marking it as pending to re-enable and an aproximate timeline of when it will +// be fixed. +// NOTE: Comment the minimum set of test necessary to unblock PRs: For example, instead of +// skipping all `bls_to_execution_change` tests, just skip for a fork setting: +// ``` +// skippedPrefixes: [ +// // Skipped since this only test that withdrawals are de-activated +// "eip4844/operations/bls_to_execution_change", +// ], +// ``` +export const defaultSkipOpts: SkipOpts = { + skippedForks: ["eip6110"], + // TODO: capella + // BeaconBlockBody proof in lightclient is the new addition in v1.3.0-rc.2-hotfix + // Skip them for now to enable subsequently + skippedPrefixes: [ + "capella/light_client/single_merkle_proof/BeaconBlockBody", + "deneb/light_client/single_merkle_proof/BeaconBlockBody", + ], +}; + /** * This helper ensures that strictly all tests are run. There's no hardcoded value beyond "config". * Any additional unknown fork, testRunner, testHandler, or testSuite will result in an error. @@ -48,7 +95,7 @@ export interface SkipOpts { export function specTestIterator( configDirpath: string, testRunners: Record, - opts?: SkipOpts + opts: SkipOpts = defaultSkipOpts ): void { for (const forkStr of readdirSyncSpec(configDirpath)) { if (opts?.skippedForks?.includes(forkStr)) { @@ -65,6 +112,17 @@ export function specTestIterator( const testRunnerDirpath = path.join(forkDirpath, testRunnerName); const testRunner = testRunners[testRunnerName]; + if (testRunner === undefined && coveredTestRunners.includes(testRunnerName)) { + // That runner is not part of the current call to specTestIterator + continue; + } + + if (testRunner === undefined && !coveredTestRunners.includes(testRunnerName)) { + throw new Error( + `No test runner for ${testRunnerName}. Please make sure it is covered in "coveredTestRunners" if you added new runner.` + ); + } + for (const testHandler of readdirSyncSpec(testRunnerDirpath)) { if (opts?.skippedHandlers?.includes(testHandler)) { continue; @@ -78,8 +136,6 @@ export function specTestIterator( displaySkipTest(testId); } else if (fork === undefined) { displayFailTest(testId, `Unknown fork ${forkStr}`); - } else if (testRunner === undefined) { - displayFailTest(testId, `No test runner for ${testRunnerName}`); } else { const testSuiteDirpath = path.join(testHandlerDirpath, testSuite); // Specific logic for ssz_static since it has one extra level of directories diff --git a/packages/cli/package.json b/packages/cli/package.json index a4a387fc670b..496f29a964e3 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -32,7 +32,7 @@ "lint:fix": "yarn run lint --fix", "pretest": "yarn run check-types", "test:unit": "nyc --cache-dir .nyc_output/.cache -e .ts mocha 'test/unit/**/*.test.ts'", - "test:e2e": "mocha --timeout 30000 'test/e2e/**/*.test.ts'", + "test:e2e": "LODESTAR_PRESET=minimal mocha --timeout 30000 'test/e2e/**/*.test.ts'", "test:sim:multifork": "LODESTAR_PRESET=minimal node --loader ts-node/esm test/sim/multi_fork.test.ts", "test:sim:mixedclient": "LODESTAR_PRESET=minimal node --loader ts-node/esm test/sim/mixed_client.test.ts", "test:sim:endpoints": "LODESTAR_PRESET=minimal node --loader ts-node/esm test/sim/endpoints.test.ts", diff --git a/packages/config/src/genesisConfig/index.ts b/packages/config/src/genesisConfig/index.ts index 23c9e08d1e8e..52fdd03880a6 100644 --- a/packages/config/src/genesisConfig/index.ts +++ b/packages/config/src/genesisConfig/index.ts @@ -3,7 +3,7 @@ import {ForkName, SLOTS_PER_EPOCH, DOMAIN_VOLUNTARY_EXIT} from "@lodestar/params import {DomainType, ForkDigest, phase0, Root, Slot, ssz, Version} from "@lodestar/types"; import {ChainForkConfig} from "../beaconConfig.js"; import {ForkDigestHex, CachedGenesis} from "./types.js"; -export {ForkDigestContext} from "./types.js"; +export type {ForkDigestContext} from "./types.js"; export function createCachedGenesis(chainForkConfig: ChainForkConfig, genesisValidatorsRoot: Root): CachedGenesis { const domainCache = new Map>(); diff --git a/packages/db/src/controller/index.ts b/packages/db/src/controller/index.ts index 4dbe95621d1b..d1142c15379c 100644 --- a/packages/db/src/controller/index.ts +++ b/packages/db/src/controller/index.ts @@ -1,3 +1,3 @@ -export {Db, DbReqOpts, DatabaseController, FilterOptions, KeyValue} from "./interface.js"; +export type {Db, DbReqOpts, DatabaseController, FilterOptions, KeyValue} from "./interface.js"; export {LevelDbController} from "./level.js"; -export {LevelDbControllerMetrics} from "./metrics.js"; +export type {LevelDbControllerMetrics} from "./metrics.js"; diff --git a/packages/fork-choice/src/index.ts b/packages/fork-choice/src/index.ts index 922e624bae97..ff0711599a54 100644 --- a/packages/fork-choice/src/index.ts +++ b/packages/fork-choice/src/index.ts @@ -1,28 +1,33 @@ export {ProtoArray} from "./protoArray/protoArray.js"; -export { +export type { ProtoBlock, ProtoNode, - ExecutionStatus, MaybeValidExecutionStatus, BlockExecution, LVHValidResponse, LVHInvalidResponse, } from "./protoArray/interface.js"; +export {ExecutionStatus} from "./protoArray/interface.js"; -export {ForkChoice, ForkChoiceOpts, assertValidTerminalPowBlock} from "./forkChoice/forkChoice.js"; +export {ForkChoice, type ForkChoiceOpts, assertValidTerminalPowBlock} from "./forkChoice/forkChoice.js"; export { - IForkChoice, - PowBlockHex, + type IForkChoice, + type PowBlockHex, EpochDifference, - AncestorResult, + type AncestorResult, AncestorStatus, - ForkChoiceMetrics, + type ForkChoiceMetrics, } from "./forkChoice/interface.js"; -export {ForkChoiceStore, IForkChoiceStore, CheckpointWithHex, JustifiedBalancesGetter} from "./forkChoice/store.js"; export { - InvalidAttestation, + ForkChoiceStore, + type IForkChoiceStore, + type CheckpointWithHex, + type JustifiedBalancesGetter, +} from "./forkChoice/store.js"; +export { + type InvalidAttestation, InvalidAttestationCode, - InvalidBlock, + type InvalidBlock, InvalidBlockCode, ForkChoiceError, ForkChoiceErrorCode, diff --git a/packages/light-client/src/index.ts b/packages/light-client/src/index.ts index b38cc66894ae..deac9f66f4d9 100644 --- a/packages/light-client/src/index.ts +++ b/packages/light-client/src/index.ts @@ -18,7 +18,7 @@ import {LightClientTransport} from "./transport/interface.js"; // Re-export types export {LightclientEvent} from "./events.js"; -export {SyncCommitteeFast} from "./types.js"; +export type {SyncCommitteeFast} from "./types.js"; export {upgradeLightClientFinalityUpdate, upgradeLightClientOptimisticUpdate} from "./spec/utils.js"; export type GenesisData = { diff --git a/packages/light-client/src/spec/index.ts b/packages/light-client/src/spec/index.ts index 2cd58c42883e..e81dba437dea 100644 --- a/packages/light-client/src/spec/index.ts +++ b/packages/light-client/src/spec/index.ts @@ -6,7 +6,8 @@ import {getSyncCommitteeAtPeriod, processLightClientUpdate, ProcessUpdateOpts} f import {ILightClientStore, LightClientStore, LightClientStoreEvents} from "./store.js"; import {ZERO_FINALITY_BRANCH, ZERO_HEADER, ZERO_NEXT_SYNC_COMMITTEE_BRANCH, ZERO_SYNC_COMMITTEE} from "./utils.js"; -export {isBetterUpdate, toLightClientUpdateSummary, LightClientUpdateSummary} from "./isBetterUpdate.js"; +export {isBetterUpdate, toLightClientUpdateSummary} from "./isBetterUpdate.js"; +export type {LightClientUpdateSummary} from "./isBetterUpdate.js"; export {upgradeLightClientHeader} from "./utils.js"; export class LightclientSpec { diff --git a/packages/logger/package.json b/packages/logger/package.json index 838e3385d4e4..79ac91120f99 100644 --- a/packages/logger/package.json +++ b/packages/logger/package.json @@ -58,7 +58,7 @@ "pretest": "yarn run check-types", "test:unit": "mocha 'test/unit/**/*.test.ts'", "test:browsers": "yarn karma start karma.config.cjs", - "test:e2e": "mocha 'test/e2e/**/*.test.ts'", + "test:e2e": "LODESTAR_PRESET=minimal mocha 'test/e2e/**/*.test.ts'", "check-readme": "typescript-docs-verifier" }, "types": "lib/index.d.ts", diff --git a/packages/logger/src/interface.ts b/packages/logger/src/interface.ts index 9b413accd0ad..8f270b0dc4ee 100644 --- a/packages/logger/src/interface.ts +++ b/packages/logger/src/interface.ts @@ -2,7 +2,8 @@ import {LEVEL, MESSAGE} from "triple-beam"; import {LogLevel, Logger, LogHandler, LogData} from "@lodestar/utils"; -export {LogLevel, Logger, LogHandler, LogData, LEVEL, MESSAGE}; +export {LogLevel, LEVEL, MESSAGE}; +export type {Logger, LogHandler, LogData}; export const logLevelNum: {[K in LogLevel]: number} = { [LogLevel.error]: 0, diff --git a/packages/params/package.json b/packages/params/package.json index 180b58990ca9..abaa37d87894 100644 --- a/packages/params/package.json +++ b/packages/params/package.json @@ -55,7 +55,7 @@ "test": "yarn run check-types", "test:unit": "mocha 'test/unit/**/*.test.ts'", "test:browsers": "yarn karma start karma.config.cjs", - "test:e2e": "mocha 'test/e2e/**/*.test.ts'", + "test:e2e": "LODESTAR_PRESET=minimal mocha 'test/e2e/**/*.test.ts'", "check-readme": "typescript-docs-verifier" }, "repository": { diff --git a/packages/params/src/index.ts b/packages/params/src/index.ts index b167f25ffd97..cdf9d7e8d144 100644 --- a/packages/params/src/index.ts +++ b/packages/params/src/index.ts @@ -5,18 +5,9 @@ import {gnosisPreset} from "./presets/gnosis.js"; import {presetStatus} from "./presetStatus.js"; import {userSelectedPreset, userOverrides} from "./setPreset.js"; -export {BeaconPreset} from "./types.js"; -export { - ForkName, - ForkSeq, - ForkLightClient, - ForkExecution, - ForkBlobs, - isForkExecution, - isForkWithdrawals, - isForkBlobs, - isForkLightClient, -} from "./forkName.js"; +export type {BeaconPreset} from "./types.js"; +export type {ForkLightClient, ForkExecution, ForkBlobs} from "./forkName.js"; +export {ForkName, ForkSeq, isForkExecution, isForkWithdrawals, isForkBlobs, isForkLightClient} from "./forkName.js"; export {presetToJson} from "./json.js"; export {PresetName}; diff --git a/packages/params/test/e2e/overridePreset.test.ts b/packages/params/test/e2e/overridePreset.test.ts index e16dd97a08ef..c03e54a480da 100644 --- a/packages/params/test/e2e/overridePreset.test.ts +++ b/packages/params/test/e2e/overridePreset.test.ts @@ -24,6 +24,9 @@ describe("Override preset", function () { this.timeout(30_000); it("Should correctly override preset", async () => { + // These commands can not run with minimal preset + if (process.env.LODESTAR_PRESET === "minimal") delete process.env.LODESTAR_PRESET; + await exec(`node --loader ts-node/esm ${path.join(__dirname, scriptNames.ok)}`); }); diff --git a/packages/params/test/e2e/setPreset.test.ts b/packages/params/test/e2e/setPreset.test.ts index 2b7ff271cd94..38942d2ee514 100644 --- a/packages/params/test/e2e/setPreset.test.ts +++ b/packages/params/test/e2e/setPreset.test.ts @@ -24,6 +24,9 @@ describe("setPreset", function () { this.timeout(30_000); it("Should correctly set preset", async () => { + // These commands can not run with minimal preset + if (process.env.LODESTAR_PRESET === "minimal") delete process.env.LODESTAR_PRESET; + await exec(`node --loader ts-node/esm ${path.join(__dirname, scriptNames.ok)}`); }); diff --git a/packages/prover/src/interfaces.ts b/packages/prover/src/interfaces.ts index 1f191be8bf4f..334bc48837a8 100644 --- a/packages/prover/src/interfaces.ts +++ b/packages/prover/src/interfaces.ts @@ -5,7 +5,7 @@ import {ProofProvider} from "./proof_provider/proof_provider.js"; import {JsonRpcRequest, JsonRpcRequestOrBatch, JsonRpcResponse, JsonRpcResponseOrBatch} from "./types.js"; import {ELRpc} from "./utils/rpc.js"; -export {NetworkName} from "@lodestar/config/networks"; +export type {NetworkName} from "@lodestar/config/networks"; export enum LCTransport { Rest = "Rest", P2P = "P2P", diff --git a/packages/reqresp/package.json b/packages/reqresp/package.json index d24fc6379462..42ebf3ea29a5 100644 --- a/packages/reqresp/package.json +++ b/packages/reqresp/package.json @@ -49,7 +49,7 @@ "lint": "eslint --color --ext .ts src/ test/", "lint:fix": "yarn run lint --fix", "pretest": "yarn run check-types", - "test": "yarn test:unit && yarn test:e2e", + "test": "yarn test:unit", "test:unit": "nyc --cache-dir .nyc_output/.cache -e .ts mocha 'test/unit/**/*.test.ts'", "check-readme": "typescript-docs-verifier" }, diff --git a/packages/reqresp/src/index.ts b/packages/reqresp/src/index.ts index 9a39d4fe0d5f..9bb07c1a4fce 100644 --- a/packages/reqresp/src/index.ts +++ b/packages/reqresp/src/index.ts @@ -1,5 +1,7 @@ -export {ReqResp, ReqRespOpts} from "./ReqResp.js"; -export {getMetrics, Metrics, MetricsRegister} from "./metrics.js"; +export {ReqResp} from "./ReqResp.js"; +export type {ReqRespOpts} from "./ReqResp.js"; +export {getMetrics} from "./metrics.js"; +export type {Metrics, MetricsRegister} from "./metrics.js"; export {Encoding as ReqRespEncoding} from "./types.js"; // Expose enums renamed export * from "./types.js"; export * from "./interface.js"; diff --git a/packages/state-transition/src/index.ts b/packages/state-transition/src/index.ts index 8c9a296ebd9f..f9db0bb84887 100644 --- a/packages/state-transition/src/index.ts +++ b/packages/state-transition/src/index.ts @@ -2,9 +2,9 @@ export * from "./stateTransition.js"; export * from "./constants/index.js"; export * from "./util/index.js"; export * from "./signatureSets/index.js"; -export {BeaconStateTransitionMetrics} from "./metrics.js"; +export type {BeaconStateTransitionMetrics} from "./metrics.js"; -export { +export type { CachedBeaconStatePhase0, CachedBeaconStateAltair, CachedBeaconStateBellatrix, @@ -25,25 +25,25 @@ export { // Main state caches export { createCachedBeaconState, - BeaconStateCache, + type BeaconStateCache, isCachedBeaconState, isStateBalancesNodesPopulated, isStateValidatorsNodesPopulated, } from "./cache/stateCache.js"; export { EpochCache, - EpochCacheImmutableData, + type EpochCacheImmutableData, createEmptyEpochCacheImmutableData, EpochCacheError, EpochCacheErrorCode, } from "./cache/epochCache.js"; -export {EpochTransitionCache, beforeProcessEpoch} from "./cache/epochTransitionCache.js"; +export {type EpochTransitionCache, beforeProcessEpoch} from "./cache/epochTransitionCache.js"; // Aux data-structures -export {PubkeyIndexMap, Index2PubkeyCache} from "./cache/pubkeyCache.js"; +export {PubkeyIndexMap, type Index2PubkeyCache} from "./cache/pubkeyCache.js"; export { - EffectiveBalanceIncrements, + type EffectiveBalanceIncrements, getEffectiveBalanceIncrementsZeroed, getEffectiveBalanceIncrementsWithLen, } from "./cache/effectiveBalanceIncrements.js"; @@ -53,7 +53,7 @@ export {isValidVoluntaryExit} from "./block/processVoluntaryExit.js"; export {isValidBlsToExecutionChange} from "./block/processBlsToExecutionChange.js"; export {assertValidProposerSlashing} from "./block/processProposerSlashing.js"; export {assertValidAttesterSlashing} from "./block/processAttesterSlashing.js"; -export {ExecutionPayloadStatus, DataAvailableStatus, BlockExternalData} from "./block/externalData.js"; +export {ExecutionPayloadStatus, DataAvailableStatus, type BlockExternalData} from "./block/externalData.js"; // BeaconChain, to prepare new blocks export {becomesNewEth1Data} from "./block/processEth1Data.js"; diff --git a/packages/state-transition/src/types.ts b/packages/state-transition/src/types.ts index 3271253ee8d3..6b6b1f6260b2 100644 --- a/packages/state-transition/src/types.ts +++ b/packages/state-transition/src/types.ts @@ -1,7 +1,7 @@ export {EpochCache} from "./cache/epochCache.js"; -export {EpochTransitionCache} from "./cache/epochTransitionCache.js"; +export type {EpochTransitionCache} from "./cache/epochTransitionCache.js"; -export { +export type { CachedBeaconStateAllForks, CachedBeaconStateExecutions, CachedBeaconStatePhase0, @@ -11,7 +11,7 @@ export { CachedBeaconStateDeneb, } from "./cache/stateCache.js"; -export { +export type { BeaconStateAllForks, BeaconStateExecutions, BeaconStatePhase0, diff --git a/packages/test-utils/src/mocha.ts b/packages/test-utils/src/mocha.ts index a469cd373afa..edf8053a60df 100644 --- a/packages/test-utils/src/mocha.ts +++ b/packages/test-utils/src/mocha.ts @@ -1,7 +1,7 @@ import type {Suite} from "mocha"; import {Logger} from "@lodestar/utils"; import {TestContext} from "./interfaces.js"; -export {TestContext} from "./interfaces.js"; +export type {TestContext} from "./interfaces.js"; /** * Create a Mocha context object that can be used to register callbacks that will be executed diff --git a/packages/utils/src/index.ts b/packages/utils/src/index.ts index 8e622b310c31..be939673845c 100644 --- a/packages/utils/src/index.ts +++ b/packages/utils/src/index.ts @@ -9,12 +9,12 @@ export * from "./logger.js"; export * from "./map.js"; export * from "./math.js"; export * from "./objects.js"; -export {retry, RetryOptions} from "./retry.js"; +export {retry, type RetryOptions} from "./retry.js"; export * from "./notNullish.js"; export * from "./sleep.js"; export * from "./sort.js"; export * from "./timeout.js"; -export {RecursivePartial, bnToNum} from "./types.js"; +export {type RecursivePartial, bnToNum} from "./types.js"; export * from "./validation.js"; export * from "./verifyMerkleBranch.js"; export * from "./promise.js"; diff --git a/packages/validator/package.json b/packages/validator/package.json index ed1433cf48c3..862962a6e02a 100644 --- a/packages/validator/package.json +++ b/packages/validator/package.json @@ -32,7 +32,7 @@ "test": "yarn test:unit", "test:e2e:only": "mocha 'test/e2e/**/*.test.ts'", "test:spec": "mocha 'test/spec/**/*.test.ts'", - "test:e2e": "yarn run download-spec-tests && yarn test:spec && yarn test:e2e:only", + "test:e2e": "LODESTAR_PRESET=minimal yarn run download-spec-tests && yarn test:spec && yarn test:e2e:only", "download-spec-tests": "node --loader=ts-node/esm test/spec/downloadTests.ts", "coverage": "codecov -F lodestar-validator", "check-readme": "typescript-docs-verifier" diff --git a/packages/validator/src/index.ts b/packages/validator/src/index.ts index a6f3f878d358..35e05303e615 100644 --- a/packages/validator/src/index.ts +++ b/packages/validator/src/index.ts @@ -1,17 +1,14 @@ -export {Validator, ValidatorOptions} from "./validator.js"; -export { - ValidatorStore, - SignerType, +export {Validator, type ValidatorOptions} from "./validator.js"; +export {ValidatorStore, SignerType, defaultOptions, BuilderSelection} from "./services/validatorStore.js"; +export type { Signer, SignerLocal, SignerRemote, ValidatorProposerConfig, - defaultOptions, ProposerConfig, - BuilderSelection, } from "./services/validatorStore.js"; export {waitForGenesis} from "./genesis.js"; -export {getMetrics, Metrics, MetricsRegister} from "./metrics.js"; +export {getMetrics, type Metrics, type MetricsRegister} from "./metrics.js"; // Remote signer client export { @@ -21,7 +18,7 @@ export { } from "./util/externalSignerClient.js"; // Types -export {ProcessShutdownCallback} from "./types.js"; +export type {ProcessShutdownCallback} from "./types.js"; export * from "./slashingProtection/index.js"; export * from "./repositories/index.js"; diff --git a/packages/validator/src/slashingProtection/index.ts b/packages/validator/src/slashingProtection/index.ts index 505a0981a212..7186e5d67d9c 100644 --- a/packages/validator/src/slashingProtection/index.ts +++ b/packages/validator/src/slashingProtection/index.ts @@ -22,8 +22,9 @@ import {SlashingProtectionBlock, SlashingProtectionAttestation} from "./types.js export {InvalidAttestationError, InvalidAttestationErrorCode} from "./attestation/index.js"; export {InvalidBlockError, InvalidBlockErrorCode} from "./block/index.js"; -export {InterchangeError, InterchangeErrorErrorCode, Interchange, InterchangeFormat} from "./interchange/index.js"; -export {ISlashingProtection, InterchangeFormatVersion, SlashingProtectionBlock, SlashingProtectionAttestation}; +export {InterchangeError, InterchangeErrorErrorCode} from "./interchange/index.js"; +export type {Interchange, InterchangeFormat} from "./interchange/index.js"; +export type {ISlashingProtection, InterchangeFormatVersion, SlashingProtectionBlock, SlashingProtectionAttestation}; /** * Handles slashing protection for validator proposer and attester duties as well as slashing protection * during a validator interchange import/export process. diff --git a/tsconfig.e2e.json b/tsconfig.e2e.json index 1432f2311d41..14cdc4bf044b 100644 --- a/tsconfig.e2e.json +++ b/tsconfig.e2e.json @@ -24,5 +24,8 @@ "declarationMap": true, "incremental": true, "preserveWatchOutput": true + }, + "ts-node": { + "transpileOnly": true } } diff --git a/tsconfig.json b/tsconfig.json index 2b57da687efe..c2cf3e5f258a 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -7,6 +7,14 @@ "typeRoots": ["node_modules/@types", "./types"], "noEmit": true, // To be used in the test fixtures - "resolveJsonModule": true + "resolveJsonModule": true, + + // We want to speed up the CI run for all tests, which require us to use the + // `transpileOnly` mode for the `ts-node`. This change requires to treat types for each module + // independently, which is done by setting the `isolatedModules` flag to `true`. + "isolatedModules": true, + }, + "ts-node": { + "transpileOnly": true } } diff --git a/yarn.lock b/yarn.lock index 8d6155b15fec..8b1a108000a0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5019,6 +5019,11 @@ commander@^2.20.0: resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== +commander@^9.3.0: + version "9.5.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-9.5.0.tgz#bc08d1eb5cedf7ccb797a96199d41c7bc3e60d30" + integrity sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ== + commander@~2.9.0: version "2.9.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" @@ -13801,6 +13806,15 @@ void-elements@^2.0.0: resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec" integrity sha512-qZKX4RnBzH2ugr8Lxa7x+0V6XD9Sb/ouARtiasEQCHB1EVU4NXtmHsDDrx1dO4ne5fc3J6EW05BP1Dl0z0iung== +wait-port@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/wait-port/-/wait-port-1.0.4.tgz#6f9474645ddbf7701ac100ab6762438edf6e5689" + integrity sha512-w8Ftna3h6XSFWWc2JC5gZEgp64nz8bnaTp5cvzbJSZ53j+omktWTDdwXxEF0jM8YveviLgFWvNGrSvRHnkyHyw== + dependencies: + chalk "^4.1.2" + commander "^9.3.0" + debug "^4.3.4" + walk-up-path@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/walk-up-path/-/walk-up-path-1.0.0.tgz#d4745e893dd5fd0dbb58dd0a4c6a33d9c9fec53e"