diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 000000000000..ba02b753af34 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,9 @@ +# top-most EditorConfig file +root = true + +# Unix-style newlines with a newline ending every file +[*] +end_of_line = lf +insert_final_newline = true +indent_style = space +indent_size = 2 diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index 46aca2515c83..000000000000 --- a/.eslintrc.js +++ /dev/null @@ -1,275 +0,0 @@ -module.exports = { - root: true, - env: { - browser: true, - es6: true, - node: true, - // Performance tests still use mocha - mocha: true, - }, - globals: { - BigInt: true, - }, - parser: "@typescript-eslint/parser", - parserOptions: { - ecmaVersion: 10, - project: "./tsconfig.json", - sourceType: "module", - }, - ignorePatterns: [ - "webEsmBundle.browser.test.ts" - ], - plugins: ["@typescript-eslint", "eslint-plugin-import", "@chainsafe/eslint-plugin-node", "prettier"], - extends: [ - "eslint:recommended", - "plugin:@typescript-eslint/recommended", - "plugin:import/errors", - "plugin:import/typescript", - "plugin:import/warnings", - ], - rules: { - "@chainsafe/node/file-extension-in-import": ["error", "always", {esm: true}], - "@chainsafe/node/no-deprecated-api": "error", - "@typescript-eslint/await-thenable": "error", - "@typescript-eslint/ban-ts-comment": "error", - "@typescript-eslint/explicit-function-return-type": ["error", {allowExpressions: true}], - "@typescript-eslint/explicit-member-accessibility": ["error", {accessibility: "no-public"}], - "@typescript-eslint/func-call-spacing": "error", - // TODO after upgrading es-lint, member-ordering is now leading to lint errors. Set to warning now and fix in another PR - "@typescript-eslint/member-ordering": "off", - "@typescript-eslint/naming-convention": [ - "error", - {selector: "default", format: ["camelCase"]}, - { - selector: ["classProperty", "objectLiteralProperty", "classMethod", "parameter"], - format: ["camelCase"], - leadingUnderscore: "allow", - }, - //variable must be in camel or upper case - {selector: "variable", format: ["camelCase", "UPPER_CASE"], leadingUnderscore: "allow"}, - //classes and types must be in PascalCase - {selector: ["typeLike", "enum"], format: ["PascalCase"]}, - {selector: "enumMember", format: null}, - //ignore rule for quoted stuff - { - selector: [ - "classProperty", - "objectLiteralProperty", - "typeProperty", - "classMethod", - "objectLiteralMethod", - "typeMethod", - "accessor", - "enumMember", - ], - format: null, - modifiers: ["requiresQuotes"], - }, - //ignore rules on destructured params - {selector: "variable", modifiers: ["destructured"], format: null}, - { - selector: "import", - format: ["camelCase", "PascalCase"], - }, - ], - "@typescript-eslint/no-explicit-any": "error", - "@typescript-eslint/no-floating-promises": "error", - "@typescript-eslint/no-non-null-assertion": "error", - "@typescript-eslint/no-require-imports": "error", - // We usually type-cast these standard types because the concerned function accepts any type - // and we want to TS detect error if original variable type changes - "@typescript-eslint/no-unnecessary-type-assertion": ["error", {typesToIgnore: ["string", "bigint", "number"]}], - "@typescript-eslint/no-unsafe-assignment": "error", - "@typescript-eslint/no-unsafe-call": "error", - "@typescript-eslint/no-unsafe-member-access": "error", - "@typescript-eslint/no-unsafe-return": "error", - "@typescript-eslint/no-unused-expressions": "error", - "@typescript-eslint/no-unused-vars": ["error", {varsIgnorePattern: "^_", argsIgnorePattern: "^_"}], - "@typescript-eslint/no-use-before-define": "off", - "@typescript-eslint/restrict-template-expressions": [ - "error", - {allowNumber: true, allowBoolean: true, allowNullish: true, allowNever: true, allowRegExp: true}, - ], - "@typescript-eslint/return-await": "error", - "@typescript-eslint/semi": "error", - "@typescript-eslint/strict-boolean-expressions": [ - "error", - {allowNullableBoolean: true, allowNullableString: true, allowAny: true}, - ], - - "@typescript-eslint/type-annotation-spacing": "error", - "constructor-super": "off", - "func-call-spacing": "off", - // Force to add names to all functions to ease CPU profiling - "func-names": ["error", "always"], - "import/namespace": "off", - //if --fix is run it messes imports like /lib/presets/minimal & /lib/presets/mainnet - "import/no-duplicates": "off", - "import/no-extraneous-dependencies": [ - "error", - { - devDependencies: false, - optionalDependencies: false, - peerDependencies: false, - }, - ], - "import/no-relative-packages": "error", - // TEMP Disabled while eslint-plugin-import support ESM (Typescript does support it) https://github.com/import-js/eslint-plugin-import/issues/2170 - "import/no-unresolved": "off", - "import/order": [ - "error", - { - groups: ["builtin", "external", "internal", "parent", "sibling", "index"], - pathGroups: [ - {pattern: "@lodestar/**", group: "internal"}, - // We want mocks to be imported before any internal code - {pattern: "**/mocks/**", group: "internal"}, - ], - pathGroupsExcludedImportTypes: ["builtin"], - }, - ], - //doesnt work, it reports false errors - "new-parens": "error", - "no-bitwise": "off", - "no-caller": "error", - "no-cond-assign": "error", - "no-consecutive-blank-lines": 0, - "no-console": "error", - "no-loss-of-precision": "error", - "no-prototype-builtins": 0, - "no-restricted-globals": [ - "error", - { - name: "fetch", - message: "Please use 'fetch' from '@lodestar/api' instead.", - }, - ], - "no-restricted-imports": [ - "error", - { - patterns: ["../lib/*", "@chainsafe/*/lib/*"], - paths: [ - ...restrictNodeModuleImports( - "child_process", - "crypto", - "fs", - "http", - "net", - "os", - "path", - "stream", - "util", - "url", - "worker_threads" - ), - ], - }, - ], - "no-restricted-syntax": ["error", ...restrictImportDestructuring("node:fs", "node:os", "node:path")], - // superseded by @typescript-eslint/return-await, must be disabled as it can report incorrect errors - "no-return-await": "off", - "no-var": "error", - "object-curly-spacing": ["error", "never"], - "object-literal-sort-keys": 0, - "prefer-const": "error", - "prettier/prettier": "error", - quotes: ["error", "double"], - semi: "off", - }, - settings: { - "import/core-modules": [ - "node:child_process", - "node:crypto", - "node:fs", - "node:http", - "node:net", - "node:os", - "node:path", - "node:stream", - "node:util", - "node:url", - ], - "import/resolver": { - typescript: { - project: "packages/*/tsconfig.json", - }, - }, - }, - overrides: [ - { - files: [ - "**/*.config.js", - "**/*.config.mjs", - "**/*.config.cjs", - "**/*.config.ts", - "scripts/vitest/**/*.ts", - "scripts/vite/**/*.ts", - ], - rules: { - "@typescript-eslint/naming-convention": "off", - // Allow require in CJS modules - "@typescript-eslint/no-require-imports": "off", - // Allow require in CJS modules - "@typescript-eslint/no-var-requires": "off", - // Allow importing packages from dev dependencies - "import/no-extraneous-dependencies": "off", - // Allow importing and mixing different configurations - "import/no-relative-packages": "off", - }, - }, - { - files: ["**/test/**/*.ts"], - rules: { - "@typescript-eslint/no-explicit-any": "off", - "func-names": "off", - "import/no-extraneous-dependencies": "off", - // Turned off as it floods log with warnings. Underlying issue is not critical so switching off is acceptable - "import/no-named-as-default-member": "off", - }, - }, - { - files: ["**/perf/**/*.ts"], - rules: { - // A lot of benchmarks just need to execute expressions without using the result - "@typescript-eslint/no-unused-expressions": "off", - }, - }, - { - files: ["**/test/**/*.test.ts"], - plugins: ["vitest"], - extends: ["plugin:vitest/recommended"], - rules: { - "vitest/consistent-test-it": ["error", {fn: "it", withinDescribe: "it"}], - // We use a lot dynamic assertions so tests may not have usage of expect - "vitest/expect-expect": "off", - "vitest/no-disabled-tests": "warn", - "vitest/no-focused-tests": "error", - "vitest/prefer-called-with": "error", - "vitest/prefer-spy-on": "error", - // Our usage contains dynamic test title, this rule enforce static string value - "vitest/valid-title": "off", - }, - }, - { - files: ["**/types/**/*.ts"], - rules: { - "@typescript-eslint/naming-convention": [ - "off", - {selector: "interface", prefix: ["I"]}, - {selector: "interface", format: ["PascalCase"], prefix: ["I"]}, - ], - }, - }, - ], -}; - -function restrictNodeModuleImports(...modules) { - return modules.map((module) => ({name: module, message: `Please use 'node:${module}' instead.`})); -} - -function restrictImportDestructuring(...modules) { - return modules.map((module) => ({ - selector: `ImportDeclaration[source.value='${module}'] ImportSpecifier`, - message: `Importing from '${module}' using destructuring is restricted.`, - })); -} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c801b0462d60..5514f6e896b7 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -64,9 +64,6 @@ jobs: - 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 diff --git a/.prettierignore b/.prettierignore index 7871bd5d3ad7..3934e7720067 100644 --- a/.prettierignore +++ b/.prettierignore @@ -2,4 +2,6 @@ **/.nyc_output /packages/*/spec-tests node_modules -**/node_modules \ No newline at end of file +**/node_modules +*.js +*.ts diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 000000000000..d2b074c6eea1 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,6 @@ +{ + "recommendations": [ + "biomejs.biome", + "esbenp.prettier-vscode" + ] +} diff --git a/.wordlist.txt b/.wordlist.txt index 11a5a3746476..a2e642a926a0 100644 --- a/.wordlist.txt +++ b/.wordlist.txt @@ -26,7 +26,6 @@ EIPs EL ENR ENRs -ESLint ETH Edgington Erigon diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9592f3bb0237..24d087810980 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -31,7 +31,7 @@ To run tests: - :test_tube: Run `yarn test:spec` for spec tests. - :test_tube: Run `yarn test` to run all tests. - :test_tube: Run `yarn check-types` to check TypeScript types. -- :test_tube: Run `yarn lint` to run the linter (ESLint). +- :test_tube: Run `yarn lint` to run the linter. Note that to run `test:e2e`, first ensure that the environment is correctly setup by running the `run_e2e_env.sh` script. This script requires a running docker engine. diff --git a/biome.jsonc b/biome.jsonc new file mode 100644 index 000000000000..de0689f2d761 --- /dev/null +++ b/biome.jsonc @@ -0,0 +1,294 @@ +{ + "$schema": "https://biomejs.dev/schemas/1.9.3/schema.json", + "vcs": { + "clientKind": "git", + "enabled": true, + "useIgnoreFile": true + }, + "files": { + "include": ["packages/*/src/**/*.ts", "packages/*/test/**/*.ts"] + }, + "formatter": { + "enabled": true, + "formatWithErrors": true, + "useEditorconfig": true, + "lineWidth": 120, + "attributePosition": "auto", + "bracketSpacing": false, + "ignore": ["**/lib", "**/.nyc_output", "./packages/*/spec-tests", "**/node_modules", "./packages/*/node_modules/**"] + }, + "organizeImports": { + "enabled": false + }, + "linter": { + "enabled": true, + "rules": { + "recommended": true, + "correctness": { + "noUnusedVariables": "error", + "useImportExtensions": { + "level": "error", + "options": { + "suggestedExtensions": { + "ts": { + "module": "js", + "component": "jsx" + } + } + } + }, + "useArrayLiterals": "error", + "noUndeclaredVariables": "error" + }, + "performance": { + // This rule should be enabled but with considerations and careful review + "noDelete": "off" + }, + "style": { + // The code usage looks suspicious so it should be enabled in a separate PR + "noCommaOperator": "off", + // There are a lot of places we mutate params, should be fixed in an independent PR. + "noParameterAssign": "off", + "noRestrictedGlobals": { + "level": "error", + "options": { + "deniedGlobals": ["fetch"] + } + }, + // We prefer to use `Math.pow` over `**` operator + "useExponentiationOperator": "off", + // In some cases the enums are initialized with values of other enums + "useLiteralEnumMembers": "off", + // We prefer to have multiple declarations lines + "useSingleVarDeclarator": "off", + // We use `+` operator for string concatenation a lot + "useTemplate": "off", + // We use to export types and object without differentiating + "useExportType": "off", + // We use to import types and object without differentiating + "useImportType": "off", + // It's nice to use `Number` namespace but should be done in a separate PR + "useNumberNamespace": "off", + // We prefer to auto-initialize enums + "useEnumInitializers": "off", + // Namespaces are deprecated way to organize modules in TS + "noNamespace": "error", + "useNamingConvention": { + "level": "error", + "options": { + "strictCase": false, + "requireAscii": true, + "conventions": [ + // Skip __dirname and any variable starting with _, for rest check next convention + { + "selector": { + "kind": "variable" + }, + "match": "(?:__dirname)|(?:_.*)|(.*)" + }, + { + "selector": { + "kind": "variable" + }, + "formats": ["camelCase", "PascalCase", "CONSTANT_CASE"] + }, + { + "selector": { + "kind": "typeLike" + }, + "formats": ["camelCase", "snake_case", "PascalCase", "CONSTANT_CASE"] + }, + { + "selector": { + "kind": "enum" + }, + "formats": ["PascalCase"] + }, + { + "selector": { + "kind": "objectLiteralProperty" + }, + "formats": ["camelCase", "snake_case", "PascalCase", "CONSTANT_CASE"] + }, + { + "selector": { + "kind": "objectLiteralMethod" + }, + "formats": ["camelCase", "snake_case", "PascalCase", "CONSTANT_CASE"] + }, + // Skip any property starting with _ and then check for next convention + { + "selector": { + "kind": "classProperty" + }, + "match": "(?:_.*)|(.*)" + }, + { + "selector": { + "kind": "classProperty" + }, + "formats": ["camelCase", "snake_case", "PascalCase", "CONSTANT_CASE"] + }, + { + "selector": { + "kind": "typeProperty" + }, + "formats": ["camelCase", "snake_case", "PascalCase", "CONSTANT_CASE"] + }, + { + "selector": { + "kind": "typeMethod" + }, + "formats": ["camelCase", "snake_case", "PascalCase", "CONSTANT_CASE"] + }, + { + "selector": { + "kind": "enumMember" + }, + "formats": ["camelCase", "snake_case", "PascalCase", "CONSTANT_CASE"] + }, + { + "selector": { + "kind": "indexParameter" + }, + "formats": ["camelCase", "PascalCase"] + }, + { + "selector": { + "kind": "function" + }, + "formats": ["camelCase", "PascalCase"] + } + ] + } + } + }, + "suspicious": { + // `void` as type is useful in our case when used as generic constraint e.g. K extends number | void + "noConfusingVoidType": "off", + // There is a lot of empty code blocks, should be enabled and clean up separately. + "noEmptyBlockStatements": "off", + "noConsoleLog": "error" + }, + "nursery": { + "useConsistentMemberAccessibility": { + "level": "error", + "options": { + "accessibility": "noPublic" + } + }, + "noCommonJs": "error", + "noRestrictedImports": { + "level": "error", + "options": { + "paths": { + "child_process": "Please use node:child_process instead.", + "crypto": "Please use node:crypto instead.", + "fs": "Please use node:fs instead.", + "http": "Please use node:https instead.", + "net": "Please use node:net instead.", + "os": "Please use node:os instead.", + "path": "Please use node:path instead.", + "stream": "Please use node:stream instead.", + "util": "Please use node:util instead.", + "url": "Please use node:url instead.", + "worker_threads": "Please use node:worker_threads instead." + } + } + }, + "noDuplicateElseIf": "error", + "noUselessEscapeInRegex": "error", + "noIrregularWhitespace": "error", + "noOctalEscape": "error", + // Need to enable this rule with exception to anonymous functions + "useExplicitFunctionReturnType": "off" + } + } + }, + "javascript": { + "formatter": { + "jsxQuoteStyle": "double", + "quoteProperties": "asNeeded", + "trailingCommas": "es5", + "semicolons": "always", + "arrowParentheses": "always", + "bracketSpacing": false, + "bracketSameLine": false, + "quoteStyle": "double", + "attributePosition": "auto", + "enabled": true + }, + "linter": { + "enabled": true + }, + "globals": ["BigInt"] + }, + "overrides": [ + // Code using console output + { + "include": ["packages/cli/src/", "packages/test-utils/src", "packages/flare/src"], + "linter": { + "rules": { + "suspicious": { + "noConsoleLog": "off" + } + } + } + }, + // All test files + { + "include": ["**/test/**/*.ts", "packages/spec-test-util/src"], + "linter": { + "rules": { + "complexity": { + // During tests we often need to use private/protected attributes, which is only possible with literal keys + "useLiteralKeys": "off" + }, + "suspicious": { + // During tests it's quicker to define variables with `let` without specifying types + "noImplicitAnyLet": "off", + // During testing we use `any` type for quick assignments + "noExplicitAny": "off", + // Console logging is often used in tests + "noConsoleLog": "off" + } + } + } + }, + // Dependencies still using mocha + { + "include": ["packages/**/test/perf/**/*.test.ts", "packages/state-transition/test/utils/beforeValueMocha.ts"], + "javascript": { + // These are used by mocha + "globals": ["describe", "it", "before", "after"] + } + }, + { + "include": [ + // These files are using mix cases e.g. `engine_newPayloadV4` + // It's a mix of snake_case and camelCase, which can't validated by biome + "packages/beacon-node/src/db/buckets.ts", + "packages/beacon-node/src/execution/engine/mock.ts", + "packages/beacon-node/src/execution/engine/types.ts", + "packages/beacon-node/src/eth1/provider/eth1Provider.ts", + "packages/validator/src/buckets.ts", + "packages/prover/src/types.ts", + "prover/src/utils/process.ts", + "prover/src/verified_requests/**/*.ts", + "packages/types/src/utils/**/*.ts", + // This file is using snake_case function names + "packages/beacon-node/test/spec/bls/bls.ts" + ], + "linter": { + "rules": { + "style": { + "useNamingConvention": { + "level": "off", + "options": {} + } + } + } + } + } + ] +} diff --git a/dashboards/lodestar_block_processor.json b/dashboards/lodestar_block_processor.json index 3258efa72fc0..a945916308ab 100644 --- a/dashboards/lodestar_block_processor.json +++ b/dashboards/lodestar_block_processor.json @@ -3985,10 +3985,10 @@ "calcs": [], "displayMode": "list", "placement": "bottom", - "showLegend": false + "showLegend": true }, "tooltip": { - "mode": "single", + "mode": "multi", "sort": "none" }, "tooltipOptions": { @@ -4001,10 +4001,12 @@ "type": "prometheus", "uid": "${DS_PROMETHEUS}" }, + "editorMode": "code", "exemplar": false, "expr": "rate(beacon_fork_choice_find_head_seconds_sum[$rate_interval])/rate(beacon_fork_choice_find_head_seconds_count[$rate_interval])", "interval": "", - "legendFormat": "find head", + "legendFormat": "{{caller}}", + "range": true, "refId": "A" } ], @@ -4103,10 +4105,12 @@ "type": "prometheus", "uid": "${DS_PROMETHEUS}" }, + "editorMode": "code", "exemplar": false, "expr": "beacon_fork_choice_errors_total", "interval": "", "legendFormat": "", + "range": true, "refId": "A" } ], @@ -4189,10 +4193,10 @@ "calcs": [], "displayMode": "list", "placement": "bottom", - "showLegend": true + "showLegend": false }, "tooltip": { - "mode": "single", + "mode": "multi", "sort": "none" }, "tooltipOptions": { @@ -4205,10 +4209,12 @@ "type": "prometheus", "uid": "${DS_PROMETHEUS}" }, + "editorMode": "code", "exemplar": false, "expr": "12 * rate(beacon_fork_choice_find_head_seconds_count[$rate_interval])", "interval": "", - "legendFormat": "updateHead calls", + "legendFormat": "{{caller}}_updateHead_calls", + "range": true, "refId": "A" }, { @@ -4228,11 +4234,13 @@ "type": "prometheus", "uid": "${DS_PROMETHEUS}" }, + "editorMode": "code", "exemplar": false, "expr": "rate(beacon_fork_choice_find_head_seconds_sum[$rate_interval])", "hide": false, "interval": "", - "legendFormat": "usage rate", + "legendFormat": "{{caller}}_usage_rate", + "range": true, "refId": "C" } ], diff --git a/dashboards/lodestar_block_production.json b/dashboards/lodestar_block_production.json index 58c7ba3f3684..3ec4a164f748 100644 --- a/dashboards/lodestar_block_production.json +++ b/dashboards/lodestar_block_production.json @@ -90,6 +90,7 @@ "mode": "palette-classic" }, "custom": { + "axisBorderShow": false, "axisCenteredZero": false, "axisColorMode": "text", "axisLabel": "", @@ -252,7 +253,6 @@ } ], "title": "Full block production avg time with steps", - "transformations": [], "type": "timeseries" }, { @@ -266,6 +266,7 @@ "mode": "palette-classic" }, "custom": { + "axisBorderShow": false, "axisCenteredZero": false, "axisColorMode": "text", "axisLabel": "", @@ -428,7 +429,6 @@ } ], "title": "Blinded block production avg time with steps", - "transformations": [], "type": "timeseries" }, { @@ -442,6 +442,7 @@ "mode": "palette-classic" }, "custom": { + "axisBorderShow": false, "axisCenteredZero": false, "axisColorMode": "text", "axisLabel": "", @@ -599,6 +600,7 @@ "mode": "palette-classic" }, "custom": { + "axisBorderShow": false, "axisCenteredZero": false, "axisColorMode": "text", "axisLabel": "", @@ -683,6 +685,7 @@ "mode": "palette-classic" }, "custom": { + "axisBorderShow": false, "axisCenteredZero": false, "axisColorMode": "text", "axisLabel": "", @@ -822,7 +825,8 @@ }, "showValue": "never", "tooltip": { - "show": true, + "mode": "single", + "showColorScale": false, "yHistogram": false }, "yAxis": { @@ -831,7 +835,7 @@ "unit": "s" } }, - "pluginVersion": "10.1.1", + "pluginVersion": "10.4.1", "reverseYBuckets": false, "targets": [ { @@ -874,6 +878,7 @@ "mode": "palette-classic" }, "custom": { + "axisBorderShow": false, "axisCenteredZero": false, "axisColorMode": "text", "axisLabel": "", @@ -1028,145 +1033,159 @@ "type": "timeseries" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" }, - "fill": 1, - "fillGradient": 1, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "points", + "fillOpacity": 10, + "gradientMode": "opacity", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 3, + "scaleDistribution": { + "log": 2, + "type": "log" + }, + "showPoints": "always", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "unit": "none" + }, + "overrides": [] + }, "gridPos": { "h": 8, "w": 12, "x": 12, "y": 25 }, - "hiddenSeries": false, "id": 378, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": false, - "linewidth": 1, - "nullPointMode": "null", "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "10.1.1", - "pointradius": 0.5, - "points": true, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "pluginVersion": "10.4.1", "targets": [ { "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" }, + "editorMode": "code", "exemplar": false, - "expr": "12 * rate(lodestar_api_rest_response_time_seconds_count{operationId=~\"produceBlindedBlock|publishBlindedBlock|registerValidator\"}[$rate_interval])", + "expr": "12 * rate(lodestar_builder_http_client_request_time_seconds_count[$rate_interval])", "hide": false, "interval": "", - "legendFormat": "{{operationId}}", + "legendFormat": "{{routeId}}", + "range": true, "refId": "D" } ], - "thresholds": [], - "timeRegions": [], "title": "Builder API queries / slot", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:580", - "format": "none", - "logBase": 2, - "show": true - }, - { - "$$hashKey": "object:581", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "type": "timeseries" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" }, "fieldConfig": { "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "opacity", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], "unit": "s" }, "overrides": [] }, - "fill": 1, - "fillGradient": 1, "gridPos": { "h": 8, "w": 12, "x": 0, "y": 33 }, - "hiddenSeries": false, "id": 376, - "legend": { - "avg": false, - "current": false, - "hideEmpty": false, - "hideZero": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": false, - "linewidth": 1, - "nullPointMode": "null", "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "10.1.1", - "pointradius": 0.5, - "points": true, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "10.4.1", "targets": [ { "datasource": { @@ -1175,45 +1194,16 @@ }, "editorMode": "code", "exemplar": false, - "expr": "rate(lodestar_api_rest_response_time_seconds_sum{operationId=~\"produceBlindedBlock|publishBlindedBlock|registerValidator\"}[$rate_interval])\n/\nrate(lodestar_api_rest_response_time_seconds_count{operationId=~\"produceBlindedBlock|publishBlindedBlock|registerValidator\"}[$rate_interval])", + "expr": "rate(lodestar_builder_http_client_request_time_seconds_sum[$rate_interval])\n/\nrate(lodestar_builder_http_client_request_time_seconds_count[$rate_interval])", "hide": false, "interval": "", - "legendFormat": "{{operationId}}", + "legendFormat": "{{routeId}}", "range": true, "refId": "B" } ], - "thresholds": [], - "timeRegions": [], - "title": "Builder API response times", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:87", - "format": "s", - "logBase": 2, - "show": true - }, - { - "$$hashKey": "object:88", - "format": "s", - "logBase": 1, - "show": false - } - ], - "yaxis": { - "align": false - } + "title": "Builder API request times", + "type": "timeseries" }, { "datasource": { @@ -1226,6 +1216,7 @@ "mode": "palette-classic" }, "custom": { + "axisBorderShow": false, "axisCenteredZero": false, "axisColorMode": "text", "axisLabel": "", @@ -1328,6 +1319,7 @@ "mode": "palette-classic" }, "custom": { + "axisBorderShow": false, "axisCenteredZero": false, "axisColorMode": "text", "axisLabel": "", @@ -1436,6 +1428,7 @@ "mode": "palette-classic" }, "custom": { + "axisBorderShow": false, "axisCenteredZero": false, "axisColorMode": "text", "axisLabel": "", @@ -1540,10 +1533,12 @@ "fields": "", "values": false }, + "showPercentChange": false, "text": {}, - "textMode": "auto" + "textMode": "auto", + "wideLayout": true }, - "pluginVersion": "9.3.2", + "pluginVersion": "10.4.1", "targets": [ { "exemplar": false, @@ -1567,6 +1562,7 @@ "mode": "palette-classic" }, "custom": { + "axisBorderShow": false, "axisCenteredZero": false, "axisColorMode": "text", "axisLabel": "", @@ -1580,6 +1576,7 @@ "tooltip": false, "viz": false }, + "insertNulls": false, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 5, @@ -1683,6 +1680,7 @@ "mode": "palette-classic" }, "custom": { + "axisBorderShow": false, "axisCenteredZero": false, "axisColorMode": "text", "axisLabel": "", @@ -1766,6 +1764,7 @@ "mode": "palette-classic" }, "custom": { + "axisBorderShow": false, "axisCenteredZero": false, "axisColorMode": "text", "axisLabel": "", @@ -1903,7 +1902,8 @@ "layout": "auto" }, "tooltip": { - "show": true, + "mode": "single", + "showColorScale": false, "yHistogram": false }, "yAxis": { @@ -1911,7 +1911,7 @@ "reverse": false } }, - "pluginVersion": "9.3.2", + "pluginVersion": "10.4.1", "targets": [ { "datasource": { @@ -1981,7 +1981,8 @@ "layout": "auto" }, "tooltip": { - "show": true, + "mode": "single", + "showColorScale": false, "yHistogram": false }, "yAxis": { @@ -1989,7 +1990,7 @@ "reverse": false } }, - "pluginVersion": "9.3.2", + "pluginVersion": "10.4.1", "targets": [ { "datasource": { @@ -2018,6 +2019,7 @@ "mode": "palette-classic" }, "custom": { + "axisBorderShow": false, "axisCenteredZero": false, "axisColorMode": "text", "axisLabel": "", @@ -2031,6 +2033,7 @@ "tooltip": false, "viz": false }, + "insertNulls": false, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 5, @@ -2055,7 +2058,7 @@ "h": 8, "w": 12, "x": 0, - "y": 65 + "y": 73 }, "id": 539, "options": { @@ -2100,8 +2103,7 @@ } ], "refresh": "10s", - "schemaVersion": 38, - "style": "dark", + "schemaVersion": 39, "tags": [ "lodestar" ], diff --git a/docs/yarn.lock b/docs/yarn.lock index 27123932fe26..dad4d8ef1c07 100644 --- a/docs/yarn.lock +++ b/docs/yarn.lock @@ -3187,7 +3187,14 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" -braces@^3.0.2, braces@~3.0.2: +braces@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789" + integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA== + dependencies: + fill-range "^7.1.1" + +braces@~3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== @@ -4772,6 +4779,13 @@ fill-range@^7.0.1: dependencies: to-regex-range "^5.0.1" +fill-range@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292" + integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg== + dependencies: + to-regex-range "^5.0.1" + finalhandler@1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.3.1.tgz#0c575f1d1d324ddd1da35ad7ece3df7d19088019" @@ -6965,11 +6979,11 @@ micromark@^4.0.0: micromark-util-types "^2.0.0" micromatch@^4.0.2, micromatch@^4.0.4, micromatch@^4.0.5: - version "4.0.5" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" - integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== + version "4.0.8" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.8.tgz#d66fa18f3a47076789320b9b1af32bd86d9fa202" + integrity sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA== dependencies: - braces "^3.0.2" + braces "^3.0.3" picomatch "^2.3.1" mime-db@1.52.0, "mime-db@>= 1.43.0 < 2": diff --git a/lodestar.code-workspace b/lodestar.code-workspace new file mode 100644 index 000000000000..7030ab8d7270 --- /dev/null +++ b/lodestar.code-workspace @@ -0,0 +1,12 @@ +{ + "settings": { + "window.title": "${activeEditorShort}${separator}${rootName}${separator}${profileName}${separator}[${activeRepositoryBranchName}]", + "editor.defaultFormatter": "esbenp.prettier-vscode", + "[javascript]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "[typescript]": { + "editor.defaultFormatter": "biomejs.biome" + }, + } +} diff --git a/package.json b/package.json index 85d9662ab920..e6de076cf494 100644 --- a/package.json +++ b/package.json @@ -15,8 +15,8 @@ "build:bundle": "lerna run build:bundle", "build:watch": "lerna exec --parallel -- 'yarn run build:watch'", "build:ifchanged": "lerna exec -- ../../scripts/build_if_changed.sh", - "lint": "eslint --report-unused-disable-directives --color --ext .ts packages/*/src packages/*/test", - "lint:fix": "yarn lint --fix", + "lint": "biome check", + "lint:fix": "yarn lint --write", "lint-dashboards": "node scripts/lint-grafana-dashboards.mjs ./dashboards", "check-build": "lerna run check-build", "check-bundle": "lerna run check-bundle", @@ -48,26 +48,19 @@ }, "devDependencies": { "@actions/core": "^1.10.1", - "@chainsafe/eslint-plugin-node": "^11.2.3", "@dapplion/benchmark": "^0.2.4", + "@biomejs/biome": "^1.9.3", "@types/mocha": "^10.0.6", "@types/node": "^20.12.8", - "@typescript-eslint/eslint-plugin": "^7.2.0", - "@typescript-eslint/parser": "^7.2.0", "@vitest/browser": "^2.0.4", "@vitest/coverage-v8": "^2.0.4", "crypto-browserify": "^3.12.0", "dotenv": "^16.4.5", "electron": "^26.2.2", - "eslint": "^8.57.0", - "eslint-import-resolver-typescript": "^3.6.1", - "eslint-plugin-import": "^2.29.1", - "eslint-plugin-prettier": "^5.1.3", - "eslint-plugin-vitest": "^0.3.26", "https-browserify": "^1.0.0", "jsdom": "^23.0.1", "lerna": "^7.3.0", - "libp2p": "1.4.3", + "libp2p": "2.1.7", "mocha": "^10.2.0", "node-gyp": "^9.4.0", "npm-run-all": "^4.1.5", diff --git a/packages/api/package.json b/packages/api/package.json index 7d851d9513ba..58566a0b23f6 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -63,8 +63,8 @@ "build:release": "yarn clean && yarn run build", "check-build": "node -e \"(async function() { await import('./lib/index.js') })()\"", "check-types": "tsc", - "lint": "eslint --color --ext .ts src/ test/", - "lint:fix": "yarn run lint --fix", + "lint": "biome check src/ test/", + "lint:fix": "yarn run lint --write", "test": "yarn test:unit", "test:unit": "vitest --run --dir test/unit/", "check-readme": "typescript-docs-verifier" diff --git a/packages/api/src/beacon/client/events.ts b/packages/api/src/beacon/client/events.ts index 34f14f2e8397..9937b850b49a 100644 --- a/packages/api/src/beacon/client/events.ts +++ b/packages/api/src/beacon/client/events.ts @@ -16,10 +16,15 @@ export function getClient(config: ChainForkConfig, baseUrl: string): ApiClient { const eventSerdes = getEventSerdes(config); return { - eventstream: async ({topics, signal, onEvent, onError, onClose}) => { + eventstream: async ({ + topics, + signal, + onEvent, + onError, + onClose, + }): Promise> => { const query = stringifyQuery({topics}); const url = `${urlJoin(baseUrl, definitions.eventstream.url)}?${query}`; - // eslint-disable-next-line @typescript-eslint/naming-convention const EventSource = await getEventSource(); const eventSource = new EventSource(url); @@ -40,7 +45,7 @@ export function getClient(config: ChainForkConfig, baseUrl: string): ApiClient { // EventSource will try to reconnect always on all errors // `eventSource.onerror` events are informative but don't indicate the EventSource closed // The only way to abort the connection from the client is via eventSource.close() - eventSource.onerror = function onerror(err) { + eventSource.onerror = function onerror(err): void { const errEs = err as unknown as EventSourceError; // Ignore noisy errors due to beacon node being offline diff --git a/packages/api/src/beacon/routes/beacon/block.ts b/packages/api/src/beacon/routes/beacon/block.ts index be6789753e0f..04d42cdab81e 100644 --- a/packages/api/src/beacon/routes/beacon/block.ts +++ b/packages/api/src/beacon/routes/beacon/block.ts @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/naming-convention */ import {ContainerType, ListCompositeType, ValueOf} from "@chainsafe/ssz"; import {ChainForkConfig} from "@lodestar/config"; import { @@ -225,7 +224,7 @@ export type Endpoints = { >; }; -// eslint-disable-next-line @typescript-eslint/no-explicit-any +// biome-ignore lint/suspicious/noExplicitAny: const blockIdOnlyReq: RequestCodec> = { writeReq: ({blockId}) => ({params: {block_id: blockId.toString()}}), parseReq: ({params}) => ({blockId: params.block_id}), diff --git a/packages/api/src/beacon/routes/beacon/pool.ts b/packages/api/src/beacon/routes/beacon/pool.ts index 4fe3efd4daf2..3f0b8ac74284 100644 --- a/packages/api/src/beacon/routes/beacon/pool.ts +++ b/packages/api/src/beacon/routes/beacon/pool.ts @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/naming-convention */ import {ValueOf} from "@chainsafe/ssz"; import {ChainForkConfig} from "@lodestar/config"; import {isForkPostElectra} from "@lodestar/params"; diff --git a/packages/api/src/beacon/routes/beacon/rewards.ts b/packages/api/src/beacon/routes/beacon/rewards.ts index c65282625343..d41b5ef705f0 100644 --- a/packages/api/src/beacon/routes/beacon/rewards.ts +++ b/packages/api/src/beacon/routes/beacon/rewards.ts @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/naming-convention */ import {ContainerType, ValueOf} from "@chainsafe/ssz"; import {ChainForkConfig} from "@lodestar/config"; import {Epoch, ssz} from "@lodestar/types"; diff --git a/packages/api/src/beacon/routes/beacon/state.ts b/packages/api/src/beacon/routes/beacon/state.ts index 1489f48c297e..4127bb1ce793 100644 --- a/packages/api/src/beacon/routes/beacon/state.ts +++ b/packages/api/src/beacon/routes/beacon/state.ts @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/naming-convention */ import {ContainerType, ValueOf} from "@chainsafe/ssz"; import {ChainForkConfig} from "@lodestar/config"; import {MAX_VALIDATORS_PER_COMMITTEE} from "@lodestar/params"; @@ -269,7 +268,7 @@ export type Endpoints = { >; }; -// eslint-disable-next-line @typescript-eslint/no-explicit-any +// biome-ignore lint/suspicious/noExplicitAny: const stateIdOnlyReq: RequestCodec> = { writeReq: ({stateId}) => ({params: {state_id: stateId.toString()}}), parseReq: ({params}) => ({stateId: params.state_id}), diff --git a/packages/api/src/beacon/routes/config.ts b/packages/api/src/beacon/routes/config.ts index f8a606af1431..afce0898908c 100644 --- a/packages/api/src/beacon/routes/config.ts +++ b/packages/api/src/beacon/routes/config.ts @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/naming-convention */ import {ContainerType, ValueOf} from "@chainsafe/ssz"; import {ChainForkConfig} from "@lodestar/config"; import {ssz} from "@lodestar/types"; diff --git a/packages/api/src/beacon/routes/debug.ts b/packages/api/src/beacon/routes/debug.ts index 590ecf71dd9c..349684f62ccd 100644 --- a/packages/api/src/beacon/routes/debug.ts +++ b/packages/api/src/beacon/routes/debug.ts @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/naming-convention */ import {ContainerType, Type, ValueOf} from "@chainsafe/ssz"; import {ChainForkConfig} from "@lodestar/config"; import {ssz, StringType, BeaconState} from "@lodestar/types"; diff --git a/packages/api/src/beacon/routes/events.ts b/packages/api/src/beacon/routes/events.ts index 1f041aa30194..5fa218bc02f3 100644 --- a/packages/api/src/beacon/routes/events.ts +++ b/packages/api/src/beacon/routes/events.ts @@ -188,7 +188,6 @@ export type TypeJson = { }; export function getTypeByEvent(config: ChainForkConfig): {[K in EventType]: TypeJson} { - // eslint-disable-next-line @typescript-eslint/naming-convention const WithVersion = (getType: (fork: ForkName) => TypeJson): TypeJson<{data: T; version: ForkName}> => { return { toJson: ({data, version}) => ({ @@ -289,7 +288,6 @@ export function getTypeByEvent(config: ChainForkConfig): {[K in EventType]: Type }; } -// eslint-disable-next-line @typescript-eslint/explicit-function-return-type export function getEventSerdes(config: ChainForkConfig) { const typeByEvent = getTypeByEvent(config); diff --git a/packages/api/src/beacon/routes/lightclient.ts b/packages/api/src/beacon/routes/lightclient.ts index ab45323f8f64..bac73b43ddb2 100644 --- a/packages/api/src/beacon/routes/lightclient.ts +++ b/packages/api/src/beacon/routes/lightclient.ts @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/naming-convention */ import {ListCompositeType, ValueOf} from "@chainsafe/ssz"; import { LightClientBootstrap, @@ -8,10 +7,12 @@ import { ssz, SyncPeriod, } from "@lodestar/types"; -import {ForkName} from "@lodestar/params"; -import {ChainForkConfig} from "@lodestar/config"; +import {fromHex} from "@lodestar/utils"; +import {ForkName, ZERO_HASH} from "@lodestar/params"; +import {BeaconConfig, ChainForkConfig, createBeaconConfig} from "@lodestar/config"; +import {genesisData, NetworkName} from "@lodestar/config/networks"; import {Endpoint, RouteDefinitions, Schema} from "../../utils/index.js"; -import {VersionCodec, VersionMeta} from "../../utils/metadata.js"; +import {MetaHeader, VersionCodec, VersionMeta} from "../../utils/metadata.js"; import {getLightClientForkTypes, toForkName} from "../../utils/fork.js"; import { EmptyArgs, @@ -20,7 +21,6 @@ import { EmptyMetaCodec, EmptyRequest, WithVersion, - JsonOnlyResp, } from "../../utils/codecs.js"; // See /packages/api/src/routes/index.ts for reasoning and instructions to add new routes @@ -91,7 +91,18 @@ export type Endpoints = { >; }; -export function getDefinitions(_config: ChainForkConfig): RouteDefinitions { +export function getDefinitions(config: ChainForkConfig): RouteDefinitions { + // Cache config so fork digests don't need to be recomputed + let beaconConfig: BeaconConfig | undefined; + + const cachedBeaconConfig = (): BeaconConfig => { + if (beaconConfig === undefined) { + const genesisValidatorsRoot = genesisData[config.CONFIG_NAME as NetworkName]?.genesisValidatorsRoot; + beaconConfig = createBeaconConfig(config, genesisValidatorsRoot ? fromHex(genesisValidatorsRoot) : ZERO_HASH); + } + return beaconConfig; + }; + return { getLightClientUpdatesByRange: { url: "/eth/v1/beacon/light_client/updates", @@ -101,7 +112,7 @@ export function getDefinitions(_config: ChainForkConfig): RouteDefinitions ({startPeriod: query.start_period, count: query.count}), schema: {query: {start_period: Schema.UintRequired, count: Schema.UintRequired}}, }, - resp: JsonOnlyResp({ + resp: { data: { toJson: (data, meta) => { const json: unknown[] = []; @@ -119,12 +130,44 @@ export function getDefinitions(_config: ChainForkConfig): RouteDefinitions { + const chunks: Uint8Array[] = []; + for (const [i, update] of data.entries()) { + const version = meta.versions[i]; + const forkDigest = cachedBeaconConfig().forkName2ForkDigest(version); + const serialized = getLightClientForkTypes(version).LightClientUpdate.serialize(update); + const length = ssz.UintNum64.serialize(4 + serialized.length); + chunks.push(length, forkDigest, serialized); + } + return Buffer.concat(chunks); + }, + deserialize: (data) => { + let offset = 0; + const updates: LightClientUpdate[] = []; + while (offset < data.length) { + const length = ssz.UintNum64.deserialize(data.subarray(offset, offset + 8)); + const forkDigest = ssz.ForkDigest.deserialize(data.subarray(offset + 8, offset + 12)); + const version = cachedBeaconConfig().forkDigest2ForkName(forkDigest); + updates.push( + getLightClientForkTypes(version).LightClientUpdate.deserialize( + data.subarray(offset + 12, offset + 8 + length) + ) + ); + offset += 8 + length; + } + return updates; + }, }, meta: { toJson: (meta) => meta, fromJson: (val) => val as {versions: ForkName[]}, - toHeadersObject: () => ({}), - fromHeaders: () => ({versions: []}), + toHeadersObject: (meta) => ({ + [MetaHeader.Version]: meta.versions.join(","), + }), + fromHeaders: (headers) => { + const versions = headers.getOrDefault(MetaHeader.Version, ""); + return {versions: versions === "" ? [] : (versions.split(",") as ForkName[])}; + }, }, transform: { toResponse: (data, meta) => { @@ -148,7 +191,7 @@ export function getDefinitions(_config: ChainForkConfig): RouteDefinitions batches: any[]; }; diff --git a/packages/api/src/beacon/routes/node.ts b/packages/api/src/beacon/routes/node.ts index 0744b5f07452..c7a6c2e36361 100644 --- a/packages/api/src/beacon/routes/node.ts +++ b/packages/api/src/beacon/routes/node.ts @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/naming-convention */ import {ContainerType, ValueOf} from "@chainsafe/ssz"; import {ChainForkConfig} from "@lodestar/config"; import {ssz, stringType} from "@lodestar/types"; diff --git a/packages/api/src/beacon/routes/proof.ts b/packages/api/src/beacon/routes/proof.ts index 2ef4dad15e81..0c6d5a058cea 100644 --- a/packages/api/src/beacon/routes/proof.ts +++ b/packages/api/src/beacon/routes/proof.ts @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/naming-convention */ import {CompactMultiProof, ProofType} from "@chainsafe/persistent-merkle-tree"; import {ByteListType, ContainerType} from "@chainsafe/ssz"; import {fromHex, toHex} from "@lodestar/utils"; diff --git a/packages/api/src/beacon/routes/validator.ts b/packages/api/src/beacon/routes/validator.ts index a9a1423e4da2..cf30d5748a46 100644 --- a/packages/api/src/beacon/routes/validator.ts +++ b/packages/api/src/beacon/routes/validator.ts @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/naming-convention */ import {ContainerType, Type, ValueOf} from "@chainsafe/ssz"; import {ChainForkConfig} from "@lodestar/config"; import {isForkBlobs, isForkPostElectra} from "@lodestar/params"; diff --git a/packages/api/src/beacon/server/events.ts b/packages/api/src/beacon/server/events.ts index 96212f006d8f..b9027ab1879d 100644 --- a/packages/api/src/beacon/server/events.ts +++ b/packages/api/src/beacon/server/events.ts @@ -23,9 +23,9 @@ export function getRoutes(config: ChainForkConfig, methods: ApplicationMethods { + for (const [key, value] of Object.entries(res.getHeaders())) { if (value !== undefined) res.raw.setHeader(key, value); - }); + } res.raw.setHeader("Content-Type", "text/event-stream"); res.raw.setHeader("Cache-Control", "no-cache,no-transform"); diff --git a/packages/api/src/beacon/server/index.ts b/packages/api/src/beacon/server/index.ts index 21c0607d3f14..304f4d42be17 100644 --- a/packages/api/src/beacon/server/index.ts +++ b/packages/api/src/beacon/server/index.ts @@ -25,7 +25,7 @@ export function registerRoutes( // Enforces that we are declaring routes for every routeId in `Endpoints` [K in keyof Endpoints]: () => { // The Endpoints are enforced in each getRoutes return type - // eslint-disable-next-line @typescript-eslint/no-explicit-any + // biome-ignore lint/suspicious/noExplicitAny: [K2 in keyof Endpoints[K]]: FastifyRoute; }; } = { diff --git a/packages/api/src/builder/routes.ts b/packages/api/src/builder/routes.ts index 7459e46abd0b..018110e5eded 100644 --- a/packages/api/src/builder/routes.ts +++ b/packages/api/src/builder/routes.ts @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/naming-convention */ import { ssz, bellatrix, diff --git a/packages/api/src/keymanager/routes.ts b/packages/api/src/keymanager/routes.ts index b6abe8928d77..0db096d14e83 100644 --- a/packages/api/src/keymanager/routes.ts +++ b/packages/api/src/keymanager/routes.ts @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/naming-convention */ import {ContainerType, ValueOf} from "@chainsafe/ssz"; import {ChainForkConfig} from "@lodestar/config"; import {Epoch, phase0, ssz, stringType} from "@lodestar/types"; diff --git a/packages/api/src/utils/client/eventSource.ts b/packages/api/src/utils/client/eventSource.ts index 6b5b75124034..f023a0ec5f0b 100644 --- a/packages/api/src/utils/client/eventSource.ts +++ b/packages/api/src/utils/client/eventSource.ts @@ -1,9 +1,7 @@ // This function switches between the native web implementation and a nodejs implemnetation export async function getEventSource(): Promise { - // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions if (globalThis.EventSource) { return EventSource; - } else { - return (await import("eventsource")).default as unknown as typeof EventSource; } + return (await import("eventsource")).default as unknown as typeof EventSource; } diff --git a/packages/api/src/utils/client/fetch.ts b/packages/api/src/utils/client/fetch.ts index a338d82e521f..31e52cdbd67f 100644 --- a/packages/api/src/utils/client/fetch.ts +++ b/packages/api/src/utils/client/fetch.ts @@ -6,7 +6,7 @@ async function wrappedFetch(url: string | URL, init?: RequestInit): Promise { try { // This function wraps global `fetch` which should only be directly called here - // eslint-disable-next-line no-restricted-globals + // biome-ignore lint/style/noRestrictedGlobals: return await fetch(url, init); } catch (e) { throw new FetchError(url, e); diff --git a/packages/api/src/utils/client/httpClient.ts b/packages/api/src/utils/client/httpClient.ts index e11e35dc85c7..33b93e3a9d41 100644 --- a/packages/api/src/utils/client/httpClient.ts +++ b/packages/api/src/utils/client/httpClient.ts @@ -155,12 +155,10 @@ export class HttpClient implements IHttpClient { if (init.retries > 0) { return this.requestWithRetries(definition, args, init); - } else { - return this.getRequestMethod(init)(definition, args, init); } - } else { - return this.requestWithFallbacks(definition, args, localInit); + return this.getRequestMethod(init)(definition, args, init); } + return this.requestWithFallbacks(definition, args, localInit); } /** @@ -198,8 +196,8 @@ export class HttpClient implements IHttpClient { this.logger?.debug("Requesting fallback URL", {routeId, baseUrl: printableUrl, score: this.urlsScore[i]}); } - // eslint-disable-next-line @typescript-eslint/naming-convention - const i_ = i; // Keep local copy of i variable to index urlScore after requestMethod() resolves + // biome-ignore lint/style/useNamingConvention: Author preferred this format + const i_ = i; // Keep local copy of i variable to index urlScore after requestWithBody() resolves const urlInit = this.urlsInits[i]; if (urlInit === undefined) { @@ -253,19 +251,16 @@ export class HttpClient implements IHttpClient { }); if (res.ok) { return res; - } else { - if (i >= this.urlsInits.length - 1) { - return res; - } else { - this.logger?.debug("Request error, retrying", {}, res.error() as Error); - } } + if (i >= this.urlsInits.length - 1) { + return res; + } + this.logger?.debug("Request error, retrying", {}, res.error() as Error); } catch (e) { if (i >= this.urlsInits.length - 1) { throw e; - } else { - this.logger?.debug("Request error, retrying", {}, e as Error); } + this.logger?.debug("Request error, retrying", {}, e as Error); } } @@ -353,7 +348,9 @@ export class HttpClient implements IHttpClient { // Attach global/local signal to this request's controller const onSignalAbort = (): void => controller.abort(); - abortSignals.forEach((s) => s?.addEventListener("abort", onSignalAbort)); + for (const s of abortSignals) { + s?.addEventListener("abort", onSignalAbort); + } const routeId = definition.operationId; const {printableUrl, requestWireFormat, responseWireFormat} = init; @@ -390,19 +387,20 @@ export class HttpClient implements IHttpClient { if (isAbortedError(e)) { if (abortSignals.some((s) => s?.aborted)) { throw new ErrorAborted(`${routeId} request`); - } else if (controller.signal.aborted) { + } + if (controller.signal.aborted) { throw new TimeoutError(`${routeId} request`); - } else { - throw Error("Unknown aborted error"); } - } else { - throw e; + throw Error("Unknown aborted error"); } + throw e; } finally { timer?.(); clearTimeout(timeout); - abortSignals.forEach((s) => s?.removeEventListener("abort", onSignalAbort)); + for (const s of abortSignals) { + s?.removeEventListener("abort", onSignalAbort); + } } } diff --git a/packages/api/src/utils/client/response.ts b/packages/api/src/utils/client/response.ts index fdcb2afda943..626252b9aaca 100644 --- a/packages/api/src/utils/client/response.ts +++ b/packages/api/src/utils/client/response.ts @@ -26,16 +26,17 @@ export class ApiResponse extends Response { wireFormat(): WireFormat | null { if (this._wireFormat === undefined) { if (this.definition.resp.isEmpty) { - return (this._wireFormat = null); + this._wireFormat = null; + return this._wireFormat; } const contentType = this.headers.get(HttpHeader.ContentType); if (contentType === null) { if (this.status === HttpStatusCode.NO_CONTENT) { - return (this._wireFormat = null); - } else { - throw Error("Content-Type header is required in response"); + this._wireFormat = null; + return this._wireFormat; } + throw Error("Content-Type header is required in response"); } const mediaType = parseContentTypeHeader(contentType); @@ -195,10 +196,9 @@ export class ApiResponse extends Response { return `${errJson.message}\n` + errJson.failures.map((e) => e.message).join("\n"); } return errJson.message; - } else { - return errBody; } - } catch (e) { + return errBody; + } catch (_e) { return errBody || this.statusText; } } diff --git a/packages/api/src/utils/codecs.ts b/packages/api/src/utils/codecs.ts index 36d905583098..c075d8592a46 100644 --- a/packages/api/src/utils/codecs.ts +++ b/packages/api/src/utils/codecs.ts @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/naming-convention */ import {ArrayType, ListBasicType, ListCompositeType, Type, isBasicType, isCompositeType} from "@chainsafe/ssz"; import {ForkName} from "@lodestar/params"; import {objectToExpectedCase} from "@lodestar/utils"; @@ -20,11 +19,11 @@ export type EmptyRequest = Record; export type EmptyResponseData = void; export type EmptyMeta = void; -// eslint-disable-next-line @typescript-eslint/no-explicit-any +// biome-ignore lint/suspicious/noExplicitAny: We can not use `unknown` type here export type AnyEndpoint = Endpoint; -// eslint-disable-next-line @typescript-eslint/no-explicit-any +// biome-ignore lint/suspicious/noExplicitAny: We can not use `unknown` type here export type EmptyRequestEndpoint = Endpoint; -// eslint-disable-next-line @typescript-eslint/no-explicit-any +// biome-ignore lint/suspicious/noExplicitAny: We can not use `unknown` type here export type EmptyResponseEndpoint = Endpoint; /** Shortcut for routes that have no params, query */ @@ -72,11 +71,11 @@ export const EmptyResponseCodec: ResponseCodec = { export function ArrayOf(elementType: Type, limit = Infinity): ArrayType, unknown, unknown> { if (isCompositeType(elementType)) { return new ListCompositeType(elementType, limit) as unknown as ArrayType, unknown, unknown>; - } else if (isBasicType(elementType)) { + } + if (isBasicType(elementType)) { return new ListBasicType(elementType, limit) as unknown as ArrayType, unknown, unknown>; - } else { - throw Error(`Unknown type ${elementType.typeName}`); } + throw Error(`Unknown type ${elementType.typeName}`); } export function WithMeta(getType: (m: M) => Type): ResponseDataCodec { diff --git a/packages/api/src/utils/headers.ts b/packages/api/src/utils/headers.ts index 5f3c6e3e1dfc..7547ac022a7a 100644 --- a/packages/api/src/utils/headers.ts +++ b/packages/api/src/utils/headers.ts @@ -70,7 +70,7 @@ export function parseAcceptHeader(accept?: string, supported = SUPPORTED_MEDIA_T } const qvalue = +weight.replace("q=", ""); - if (isNaN(qvalue) || qvalue > 1 || qvalue <= 0) { + if (Number.isNaN(qvalue) || qvalue > 1 || qvalue <= 0) { // If we can't convert the qvalue to a valid number, move on return best; } diff --git a/packages/api/src/utils/httpStatusCode.ts b/packages/api/src/utils/httpStatusCode.ts index 572562e7da3d..2316f3d1db87 100644 --- a/packages/api/src/utils/httpStatusCode.ts +++ b/packages/api/src/utils/httpStatusCode.ts @@ -1,5 +1,3 @@ -"use strict"; - /** * Hypertext Transfer Protocol (HTTP) response status codes. * @see {@link https://www.rfc-editor.org/rfc/rfc7231#section-6} diff --git a/packages/api/src/utils/metadata.ts b/packages/api/src/utils/metadata.ts index 1eaa4132119f..2ee9b2f51f0e 100644 --- a/packages/api/src/utils/metadata.ts +++ b/packages/api/src/utils/metadata.ts @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/naming-convention */ import {ContainerType, ValueOf} from "@chainsafe/ssz"; import {ForkName} from "@lodestar/params"; import {StringType, ssz, stringType} from "@lodestar/types"; diff --git a/packages/api/src/utils/serdes.ts b/packages/api/src/utils/serdes.ts index 282c2514e00d..9fb772a0bc63 100644 --- a/packages/api/src/utils/serdes.ts +++ b/packages/api/src/utils/serdes.ts @@ -18,9 +18,8 @@ export function querySerializeProofPathsArr(paths: JsonPath[]): string[] { export function queryParseProofPathsArr(pathStrs: string | string[]): JsonPath[] { if (Array.isArray(pathStrs)) { return pathStrs.map((pathStr) => queryParseProofPaths(pathStr)); - } else { - return [queryParseProofPaths(pathStrs)]; } + return [queryParseProofPaths(pathStrs)]; } /** @@ -50,7 +49,7 @@ export type U64Str = string; export function fromU64Str(u64Str: U64Str): number { const u64 = parseInt(u64Str, 10); - if (!isFinite(u64)) { + if (!Number.isFinite(u64)) { throw Error(`Invalid uin64 ${u64Str}`); } return u64; @@ -104,7 +103,7 @@ export function fromGraffitiHex(hex?: string): string | undefined { } try { return new TextDecoder("utf8").decode(fromHex(hex)); - } catch { + } catch (_e) { // allow malformed graffiti hex string return hex; } diff --git a/packages/api/src/utils/server/handler.ts b/packages/api/src/utils/server/handler.ts index a3cd9a43a56a..035f4328141a 100644 --- a/packages/api/src/utils/server/handler.ts +++ b/packages/api/src/utils/server/handler.ts @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/naming-convention */ import type * as fastify from "fastify"; import {HttpHeader, MediaType, SUPPORTED_MEDIA_TYPES, parseAcceptHeader, parseContentTypeHeader} from "../headers.js"; import { diff --git a/packages/api/src/utils/server/method.ts b/packages/api/src/utils/server/method.ts index 080c78869798..6fc99cc49a72 100644 --- a/packages/api/src/utils/server/method.ts +++ b/packages/api/src/utils/server/method.ts @@ -12,10 +12,9 @@ type ApplicationResponseObject = { : {data: E["return"] | (E["return"] extends undefined ? undefined : Uint8Array)}) & (E["meta"] extends EmptyMeta ? {meta?: never} : {meta: E["meta"]}); -export type ApplicationResponse = - HasOnlyOptionalProps> extends true - ? ApplicationResponseObject | void - : ApplicationResponseObject; +export type ApplicationResponse = HasOnlyOptionalProps> extends true + ? ApplicationResponseObject | void + : ApplicationResponseObject; export type ApiContext = { /** diff --git a/packages/api/src/utils/types.ts b/packages/api/src/utils/types.ts index abe2f358320d..aef18b47d940 100644 --- a/packages/api/src/utils/types.ts +++ b/packages/api/src/utils/types.ts @@ -6,7 +6,7 @@ import {WireFormat} from "./wireFormat.js"; export type HasOnlyOptionalProps = { [K in keyof T]-?: object extends Pick ? never : K; -} extends {[_ in keyof T]: never} +} extends {[K2 in keyof T]: never} ? true : false; diff --git a/packages/api/test/perf/compileRouteUrlFormater.test.ts b/packages/api/test/perf/compileRouteUrlFormater.test.ts index ab16e1a5d14e..60d9e3fea8ee 100644 --- a/packages/api/test/perf/compileRouteUrlFormater.test.ts +++ b/packages/api/test/perf/compileRouteUrlFormater.test.ts @@ -1,7 +1,5 @@ import {compileRouteUrlFormatter} from "../../src/utils/urlFormat.js"; -/* eslint-disable no-console */ - describe("route parse", () => { it.skip("Benchmark compileRouteUrlFormatter", () => { const path = "/eth/v1/validator/:name/attester/:epoch"; diff --git a/packages/api/test/unit/beacon/genericServerTest/beacon.test.ts b/packages/api/test/unit/beacon/genericServerTest/beacon.test.ts index a722e72a4c27..f8c13b33afb6 100644 --- a/packages/api/test/unit/beacon/genericServerTest/beacon.test.ts +++ b/packages/api/test/unit/beacon/genericServerTest/beacon.test.ts @@ -8,7 +8,6 @@ import {testData} from "../testData/beacon.js"; describe("beacon / beacon", () => { runGenericServerTest( - // eslint-disable-next-line @typescript-eslint/naming-convention createChainForkConfig({...defaultChainConfig, ALTAIR_FORK_EPOCH: 1, BELLATRIX_FORK_EPOCH: 2}), getClient, getRoutes, diff --git a/packages/api/test/unit/beacon/genericServerTest/config.test.ts b/packages/api/test/unit/beacon/genericServerTest/config.test.ts index 8b924cf07693..91075f96d1e3 100644 --- a/packages/api/test/unit/beacon/genericServerTest/config.test.ts +++ b/packages/api/test/unit/beacon/genericServerTest/config.test.ts @@ -6,8 +6,6 @@ import {getRoutes} from "../../../../src/beacon/server/config.js"; import {runGenericServerTest} from "../../../utils/genericServerTest.js"; import {testData} from "../testData/config.js"; -/* eslint-disable @typescript-eslint/naming-convention */ - describe("beacon / config", () => { runGenericServerTest(config, getClient, getRoutes, testData); diff --git a/packages/api/test/unit/beacon/oapiSpec.test.ts b/packages/api/test/unit/beacon/oapiSpec.test.ts index 2b8a8254dd6b..f6a38505e264 100644 --- a/packages/api/test/unit/beacon/oapiSpec.test.ts +++ b/packages/api/test/unit/beacon/oapiSpec.test.ts @@ -18,7 +18,6 @@ import {testData as validatorTestData} from "./testData/validator.js"; // Global variable __dirname no longer available in ES6 modules. // Solutions: https://stackoverflow.com/questions/46745014/alternative-for-dirname-in-node-js-when-using-es6-modules -// eslint-disable-next-line @typescript-eslint/naming-convention const __dirname = path.dirname(fileURLToPath(import.meta.url)); const version = "v3.0.0-alpha.6"; @@ -28,7 +27,6 @@ const openApiFile: OpenApiFile = { version: RegExp(version), }; -// eslint-disable-next-line @typescript-eslint/naming-convention const config = createChainForkConfig({...defaultChainConfig, ALTAIR_FORK_EPOCH: 1, BELLATRIX_FORK_EPOCH: 2}); const definitions = { @@ -57,8 +55,6 @@ const ignoredOperations = [ /* missing route */ "getDepositSnapshot", // Won't fix for now, see https://github.com/ChainSafe/lodestar/issues/5697 "getNextWithdrawals", // https://github.com/ChainSafe/lodestar/issues/5696 - /* Must support ssz response body */ - "getLightClientUpdatesByRange", // https://github.com/ChainSafe/lodestar/issues/6841 ]; const ignoredProperties: Record = { diff --git a/packages/api/test/unit/beacon/testData/events.ts b/packages/api/test/unit/beacon/testData/events.ts index 8a7610a26836..3d2ffb708965 100644 --- a/packages/api/test/unit/beacon/testData/events.ts +++ b/packages/api/test/unit/beacon/testData/events.ts @@ -5,8 +5,6 @@ import {GenericServerTestCases} from "../../../utils/genericServerTest.js"; const abortController = new AbortController(); -/* eslint-disable @typescript-eslint/naming-convention */ - export const testData: GenericServerTestCases = { eventstream: { args: {topics: [EventType.head, EventType.chainReorg], signal: abortController.signal, onEvent: () => {}}, diff --git a/packages/api/test/unit/beacon/testData/lightclient.ts b/packages/api/test/unit/beacon/testData/lightclient.ts index b86e1f338329..f405d514fc5d 100644 --- a/packages/api/test/unit/beacon/testData/lightclient.ts +++ b/packages/api/test/unit/beacon/testData/lightclient.ts @@ -14,7 +14,7 @@ const signatureSlot = ssz.Slot.defaultValue(); export const testData: GenericServerTestCases = { getLightClientUpdatesByRange: { args: {startPeriod: 1, count: 2}, - res: {data: [lightClientUpdate], meta: {versions: [ForkName.bellatrix]}}, + res: {data: [lightClientUpdate, lightClientUpdate], meta: {versions: [ForkName.altair, ForkName.altair]}}, }, getLightClientOptimisticUpdate: { args: undefined, diff --git a/packages/api/test/unit/builder/builder.test.ts b/packages/api/test/unit/builder/builder.test.ts index 045a66496b6f..d2e25916069e 100644 --- a/packages/api/test/unit/builder/builder.test.ts +++ b/packages/api/test/unit/builder/builder.test.ts @@ -10,7 +10,6 @@ describe("builder", () => { runGenericServerTest( createChainForkConfig({ ...defaultChainConfig, - /* eslint-disable @typescript-eslint/naming-convention */ ALTAIR_FORK_EPOCH: 0, BELLATRIX_FORK_EPOCH: 0, DENEB_FORK_EPOCH: 0, diff --git a/packages/api/test/unit/builder/oapiSpec.test.ts b/packages/api/test/unit/builder/oapiSpec.test.ts index 60168f71d8d8..d972b64905e5 100644 --- a/packages/api/test/unit/builder/oapiSpec.test.ts +++ b/packages/api/test/unit/builder/oapiSpec.test.ts @@ -10,7 +10,6 @@ import {testData} from "./testData.js"; // Global variable __dirname no longer available in ES6 modules. // Solutions: https://stackoverflow.com/questions/46745014/alternative-for-dirname-in-node-js-when-using-es6-modules -// eslint-disable-next-line @typescript-eslint/naming-convention const __dirname = path.dirname(fileURLToPath(import.meta.url)); const version = "v0.2.0"; @@ -23,7 +22,6 @@ const openApiFile: OpenApiFile = { }; const definitions = getDefinitions( - // eslint-disable-next-line @typescript-eslint/naming-convention createChainForkConfig({...defaultChainConfig, ALTAIR_FORK_EPOCH: 0, BELLATRIX_FORK_EPOCH: 0}) ); diff --git a/packages/api/test/unit/client/fetch.test.ts b/packages/api/test/unit/client/fetch.test.ts index 80e5f58b164a..1faf7d979a02 100644 --- a/packages/api/test/unit/client/fetch.test.ts +++ b/packages/api/test/unit/client/fetch.test.ts @@ -3,7 +3,7 @@ import http from "node:http"; import {describe, it, expect, afterEach} from "vitest"; import {FetchError, FetchErrorType, fetch} from "../../../src/utils/client/fetch.js"; -describe("FetchError", function () { +describe("FetchError", () => { const port = 37421; const randomHex = crypto.randomBytes(32).toString("hex"); @@ -87,12 +87,11 @@ describe("FetchError", function () { const afterHooks: (() => Promise)[] = []; - afterEach(async function () { + afterEach(async () => { while (afterHooks.length) { const afterHook = afterHooks.pop(); if (afterHook) await afterHook().catch((e: Error) => { - // eslint-disable-next-line no-console console.error("Error in afterEach hook", e); }); } @@ -101,7 +100,7 @@ describe("FetchError", function () { for (const testCase of testCases) { const {id, url = `http://localhost:${port}`, requestListener, signalHandler} = testCase; - it(id, async function () { + it(id, async () => { if (requestListener) { const server = http.createServer(requestListener); await new Promise((resolve) => server.listen(port, resolve)); diff --git a/packages/api/test/unit/client/httpClientFallback.test.ts b/packages/api/test/unit/client/httpClientFallback.test.ts index ea20c3f33982..9fcde27de072 100644 --- a/packages/api/test/unit/client/httpClientFallback.test.ts +++ b/packages/api/test/unit/client/httpClientFallback.test.ts @@ -56,12 +56,12 @@ describe("httpClient fallback", () => { // which is handled separately from network errors // but the fallback logic should be the same return new Response(null, {status: 500}); - } else { - throw Error(`test_error_server_${i}`); } - } else { - return new Response(null, {status: 200}); + + throw Error(`test_error_server_${i}`); } + + return new Response(null, {status: 200}); }); }); @@ -81,7 +81,6 @@ describe("httpClient fallback", () => { fetchStub.mockClear(); - // eslint-disable-next-line no-console if (DEBUG_LOGS) console.log("completed assertions step", step); } diff --git a/packages/api/test/unit/client/urlFormat.test.ts b/packages/api/test/unit/client/urlFormat.test.ts index dc86e2674e13..5132044b7631 100644 --- a/packages/api/test/unit/client/urlFormat.test.ts +++ b/packages/api/test/unit/client/urlFormat.test.ts @@ -7,8 +7,6 @@ import { urlToTokens, } from "../../../src/utils/urlFormat.js"; -/* eslint-disable @typescript-eslint/naming-convention */ - describe("utils / urlFormat", () => { const testCases: { urlTemplate: string; diff --git a/packages/api/test/unit/keymanager/oapiSpec.test.ts b/packages/api/test/unit/keymanager/oapiSpec.test.ts index 97011f5d3660..aab4e1823ab0 100644 --- a/packages/api/test/unit/keymanager/oapiSpec.test.ts +++ b/packages/api/test/unit/keymanager/oapiSpec.test.ts @@ -9,7 +9,6 @@ import {testData} from "./testData.js"; // Global variable __dirname no longer available in ES6 modules. // Solutions: https://stackoverflow.com/questions/46745014/alternative-for-dirname-in-node-js-when-using-es6-modules -// eslint-disable-next-line @typescript-eslint/naming-convention const __dirname = path.dirname(fileURLToPath(import.meta.url)); const version = "v1.1.0"; diff --git a/packages/api/test/utils/checkAgainstSpec.ts b/packages/api/test/utils/checkAgainstSpec.ts index 5e339efcb822..a3f943ad4816 100644 --- a/packages/api/test/utils/checkAgainstSpec.ts +++ b/packages/api/test/utils/checkAgainstSpec.ts @@ -93,13 +93,13 @@ export function runTestCheckAgainstSpec>( } }); - it(`${operationId}_route`, function () { + it(`${operationId}_route`, () => { expect(routeDef.method.toLowerCase()).toBe(routeSpec.method.toLowerCase()); expect(routeDef.url).toBe(routeSpec.url); }); if (requestSchema != null) { - it(`${operationId}_request`, function () { + it(`${operationId}_request`, () => { const reqJson = isRequestWithoutBody(routeDef) ? routeDef.req.writeReq(testData.args) : (routeDef.req as RequestWithBodyCodec).writeReqJson(testData.args); @@ -127,7 +127,7 @@ export function runTestCheckAgainstSpec>( expect(reqSsz.body).toBeInstanceOf(Uint8Array); expect(reqCodec.onlySupport).not.toBe(WireFormat.json); - } catch { + } catch (_e) { throw Error("Must support ssz request body"); } } @@ -135,7 +135,7 @@ export function runTestCheckAgainstSpec>( } if (responseOkSchema) { - it(`${operationId}_response`, function () { + it(`${operationId}_response`, () => { const data = routeDef.resp.data.toJson(testData.res?.data, testData.res?.meta); const metaJson = routeDef.resp.meta.toJson(testData.res?.meta); const headers = parseHeaders(routeDef.resp.meta.toHeadersObject(testData.res?.meta)); @@ -167,7 +167,7 @@ export function runTestCheckAgainstSpec>( expect(sszBytes).toBeInstanceOf(Uint8Array); expect(routeDef.resp.onlySupport).not.toBe(WireFormat.json); - } catch { + } catch (_e) { throw Error("Must support ssz response body"); } } @@ -183,7 +183,6 @@ function validateSchema(schema: Parameters[0], json: unknown try { validate = ajv.compile(schema); } catch (e) { - // eslint-disable-next-line no-console console.error(JSON.stringify(schema, null, 2)); (e as Error).message = `${id} schema - ${(e as Error).message}`; throw e; @@ -219,7 +218,9 @@ type StringifiedProperty = string | StringifiedProperty[]; function stringifyProperty(value: unknown): StringifiedProperty { if (typeof value === "number") { return value.toString(10); - } else if (Array.isArray(value)) { + } + + if (Array.isArray(value)) { return value.map(stringifyProperty); } return String(value); diff --git a/packages/api/test/utils/parseOpenApiSpec.ts b/packages/api/test/utils/parseOpenApiSpec.ts index 7527fb61abaa..d04827fd2011 100644 --- a/packages/api/test/utils/parseOpenApiSpec.ts +++ b/packages/api/test/utils/parseOpenApiSpec.ts @@ -105,7 +105,6 @@ export function parseOpenApiSpec(openApiJson: OpenApiJson): Map { - if (obj.allOf && obj.allOf.every((s) => s.enum)) { + if (obj.allOf?.every((s) => s.enum)) { obj.allOf = [obj.allOf[0]]; } }); diff --git a/packages/api/test/utils/utils.ts b/packages/api/test/utils/utils.ts index d78378e57e19..d3ecbc964435 100644 --- a/packages/api/test/utils/utils.ts +++ b/packages/api/test/utils/utils.ts @@ -14,15 +14,14 @@ export function getTestServer(): {server: FastifyInstance; start: () => Promise< addSszContentTypeParser(server); server.addHook("onError", (_request, _reply, error, done) => { - // eslint-disable-next-line no-console console.log(`onError: ${error.toString()}`); done(); }); const start = (): Promise => new Promise((resolve, reject) => { - server.listen({port: 0}, function (err, address) { - if (err !== null && err != undefined) { + server.listen({port: 0}, (err, address) => { + if (err != null) { reject(err); } else { resolve(address); diff --git a/packages/beacon-node/package.json b/packages/beacon-node/package.json index 6894e4a7d8b6..8361aff26e48 100644 --- a/packages/beacon-node/package.json +++ b/packages/beacon-node/package.json @@ -75,8 +75,8 @@ "build:release": "yarn clean && yarn run build", "check-build": "node -e \"(async function() { await import('./lib/index.js') })()\"", "check-types": "tsc", - "lint": "eslint --color --ext .ts src/ test/", - "lint:fix": "yarn run lint --fix", + "lint": "biome check src/ test/", + "lint:fix": "yarn run lint --write", "test": "yarn test:unit && yarn test:e2e", "test:unit:minimal": "LODESTAR_PRESET=minimal vitest --run --dir test/unit/", "test:unit:mainnet": "LODESTAR_PRESET=mainnet vitest --run --dir test/unit-mainnet", @@ -96,11 +96,10 @@ "dependencies": { "@chainsafe/as-sha256": "^0.5.0", "@chainsafe/blst": "^2.0.3", - "@chainsafe/discv5": "^9.0.0", - "@chainsafe/enr": "^3.0.0", - "@chainsafe/libp2p-gossipsub": "^13.0.0", - "@chainsafe/libp2p-identify": "^1.0.0", - "@chainsafe/libp2p-noise": "^15.0.0", + "@chainsafe/discv5": "^10.0.1", + "@chainsafe/enr": "^4.0.1", + "@chainsafe/libp2p-gossipsub": "^14.1.0", + "@chainsafe/libp2p-noise": "^16.0.0", "@chainsafe/persistent-merkle-tree": "^0.8.0", "@chainsafe/prometheus-gc-stats": "^1.0.0", "@chainsafe/ssz": "^0.17.1", @@ -111,15 +110,15 @@ "@fastify/cors": "^10.0.1", "@fastify/swagger": "^9.0.0", "@fastify/swagger-ui": "^5.0.1", - "@libp2p/bootstrap": "^10.0.21", - "@libp2p/identify": "^1.0.20", - "@libp2p/interface": "^1.3.0", - "@libp2p/mdns": "^10.0.21", - "@libp2p/mplex": "^10.0.21", - "@libp2p/peer-id": "^4.1.0", - "@libp2p/peer-id-factory": "^4.1.0", - "@libp2p/prometheus-metrics": "^3.0.21", - "@libp2p/tcp": "9.0.23", + "@libp2p/bootstrap": "^11.0.4", + "@libp2p/crypto": "^5.0.4", + "@libp2p/identify": "^3.0.4", + "@libp2p/interface": "^2.1.2", + "@libp2p/mdns": "^11.0.4", + "@libp2p/mplex": "^11.0.4", + "@libp2p/peer-id": "^5.0.4", + "@libp2p/prometheus-metrics": "^4.1.2", + "@libp2p/tcp": "10.0.4", "@lodestar/api": "^1.22.0", "@lodestar/config": "^1.22.0", "@lodestar/db": "^1.22.0", @@ -134,15 +133,15 @@ "@lodestar/validator": "^1.22.0", "@multiformats/multiaddr": "^12.1.3", "c-kzg": "^2.1.2", - "datastore-core": "^9.1.1", - "datastore-level": "^10.1.1", + "datastore-core": "^10.0.0", + "datastore-level": "^11.0.0", "deepmerge": "^4.3.1", "fastify": "^5.0.0", - "interface-datastore": "^8.2.7", + "interface-datastore": "^8.3.0", "it-all": "^3.0.4", "it-pipe": "^3.0.1", "jwt-simple": "0.5.6", - "libp2p": "1.4.3", + "libp2p": "2.1.7", "multiformats": "^11.0.1", "prom-client": "^15.1.0", "qs": "^6.11.1", diff --git a/packages/beacon-node/src/api/impl/beacon/blocks/index.ts b/packages/beacon-node/src/api/impl/beacon/blocks/index.ts index 65e7b9373a22..b54e8752a437 100644 --- a/packages/beacon-node/src/api/impl/beacon/blocks/index.ts +++ b/packages/beacon-node/src/api/impl/beacon/blocks/index.ts @@ -176,9 +176,8 @@ export function getBeaconBlockApi({ const message = `Equivocation checks not yet implemented for broadcastValidation=${broadcastValidation}`; if (chain.opts.broadcastValidationStrictness === "error") { throw Error(message); - } else { - chain.logger.warn(message, valLogMeta); } + chain.logger.warn(message, valLogMeta); } break; } @@ -193,9 +192,8 @@ export function getBeaconBlockApi({ const message = `Broadcast validation of ${broadcastValidation} type not implemented yet`; if (chain.opts.broadcastValidationStrictness === "error") { throw Error(message); - } else { - chain.logger.warn(message, valLogMeta); } + chain.logger.warn(message, valLogMeta); } } @@ -224,15 +222,17 @@ export function getBeaconBlockApi({ () => network.publishBeaconBlock(signedBlock) as Promise, () => // there is no rush to persist block since we published it to gossip anyway - chain.processBlock(blockForImport, {...opts, eagerPersistBlock: false}).catch((e) => { - if (e instanceof BlockError && e.type.code === BlockErrorCode.PARENT_UNKNOWN) { - network.events.emit(NetworkEvent.unknownBlockParent, { - blockInput: blockForImport, - peer: IDENTITY_PEER_ID, - }); - } - throw e; - }), + chain + .processBlock(blockForImport, {...opts, eagerPersistBlock: false}) + .catch((e) => { + if (e instanceof BlockError && e.type.code === BlockErrorCode.PARENT_UNKNOWN) { + network.events.emit(NetworkEvent.unknownBlockParent, { + blockInput: blockForImport, + peer: IDENTITY_PEER_ID, + }); + } + throw e; + }), ]; await promiseAllMaybeAsync(publishPromises); }; @@ -258,25 +258,25 @@ export function getBeaconBlockApi({ chain.logger.debug("Reconstructing signedBlockOrContents", {slot, blockRoot, source}); const contents = executionPayload - ? chain.producedContentsCache.get(toRootHex(executionPayload.blockHash)) ?? null + ? (chain.producedContentsCache.get(toRootHex(executionPayload.blockHash)) ?? null) : null; const signedBlockOrContents = reconstructFullBlockOrContents(signedBlindedBlock, {executionPayload, contents}); chain.logger.info("Publishing assembled block", {slot, blockRoot, source}); return publishBlock({signedBlockOrContents}, {...context, sszBytes: null}, opts); - } else { - const source = ProducedBlockSource.builder; - chain.logger.debug("Reconstructing signedBlockOrContents", {slot, blockRoot, source}); + } - const signedBlockOrContents = await reconstructBuilderBlockOrContents(chain, signedBlindedBlock); + const source = ProducedBlockSource.builder; + chain.logger.debug("Reconstructing signedBlockOrContents", {slot, blockRoot, source}); - // the full block is published by relay and it's possible that the block is already known to us - // by gossip - // - // see: https://github.com/ChainSafe/lodestar/issues/5404 - chain.logger.info("Publishing assembled block", {slot, blockRoot, source}); - return publishBlock({signedBlockOrContents}, {...context, sszBytes: null}, {...opts, ignoreIfKnown: true}); - } + const signedBlockOrContents = await reconstructBuilderBlockOrContents(chain, signedBlindedBlock); + + // the full block is published by relay and it's possible that the block is already known to us + // by gossip + // + // see: https://github.com/ChainSafe/lodestar/issues/5404 + chain.logger.info("Publishing assembled block", {slot, blockRoot, source}); + return publishBlock({signedBlockOrContents}, {...context, sszBytes: null}, {...opts, ignoreIfKnown: true}); }; return { diff --git a/packages/beacon-node/src/api/impl/beacon/blocks/utils.ts b/packages/beacon-node/src/api/impl/beacon/blocks/utils.ts index fe4fc5ca3dc0..44152ff4b8a9 100644 --- a/packages/beacon-node/src/api/impl/beacon/blocks/utils.ts +++ b/packages/beacon-node/src/api/impl/beacon/blocks/utils.ts @@ -50,7 +50,7 @@ export function resolveBlockId(forkChoice: IForkChoice, blockId: routes.beacon.B // block id must be slot const blockSlot = parseInt(blockId, 10); - if (isNaN(blockSlot) && isNaN(blockSlot - 0)) { + if (Number.isNaN(blockSlot) && Number.isNaN(blockSlot - 0)) { throw new ValidationError(`Invalid block id '${blockId}'`, "blockId"); } return blockSlot; diff --git a/packages/beacon-node/src/api/impl/beacon/pool/index.ts b/packages/beacon-node/src/api/impl/beacon/pool/index.ts index e01b172f1e72..9343dd67a399 100644 --- a/packages/beacon-node/src/api/impl/beacon/pool/index.ts +++ b/packages/beacon-node/src/api/impl/beacon/pool/index.ts @@ -94,7 +94,6 @@ export function getBeaconPoolApi({ signedAttestations.map(async (attestation, i) => { try { const fork = chain.config.getForkName(chain.clock.currentSlot); - // eslint-disable-next-line @typescript-eslint/explicit-function-return-type const validateFn = () => validateApiAttestation(fork, chain, {attestation, serializedData: null}); const {slot, beaconBlockRoot} = attestation.data; // when a validator is configured with multiple beacon node urls, this attestation data may come from another beacon node diff --git a/packages/beacon-node/src/api/impl/beacon/state/index.ts b/packages/beacon-node/src/api/impl/beacon/state/index.ts index 2bf758a8e286..8cce896e1087 100644 --- a/packages/beacon-node/src/api/impl/beacon/state/index.ts +++ b/packages/beacon-node/src/api/impl/beacon/state/index.ts @@ -103,7 +103,9 @@ export function getBeaconStateApi({ data: validatorResponses, meta: {executionOptimistic, finalized}, }; - } else if (statuses.length) { + } + + if (statuses.length) { const validatorsByStatus = filterStateValidatorsByStatus(statuses, state, pubkey2index, currentEpoch); return { data: validatorsByStatus, diff --git a/packages/beacon-node/src/api/impl/beacon/state/utils.ts b/packages/beacon-node/src/api/impl/beacon/state/utils.ts index 5e9d3be01221..392262a563be 100644 --- a/packages/beacon-node/src/api/impl/beacon/state/utils.ts +++ b/packages/beacon-node/src/api/impl/beacon/state/utils.ts @@ -34,7 +34,7 @@ export function resolveStateId( // id must be slot const blockSlot = parseInt(String(stateId), 10); - if (isNaN(blockSlot) && isNaN(blockSlot - 0)) { + if (Number.isNaN(blockSlot) && Number.isNaN(blockSlot - 0)) { throw new ValidationError(`Invalid block id '${stateId}'`, "blockId"); } @@ -83,6 +83,28 @@ export async function getStateResponseWithRegen( return res; } +type GeneralValidatorStatus = "active" | "pending" | "exited" | "withdrawal"; + +function mapToGeneralStatus(subStatus: routes.beacon.ValidatorStatus): GeneralValidatorStatus { + switch (subStatus) { + case "active_ongoing": + case "active_exiting": + case "active_slashed": + return "active"; + case "pending_initialized": + case "pending_queued": + return "pending"; + case "exited_slashed": + case "exited_unslashed": + return "exited"; + case "withdrawal_possible": + case "withdrawal_done": + return "withdrawal"; + default: + throw new Error(`Unknown substatus: ${subStatus}`); + } +} + export function toValidatorResponse( index: ValidatorIndex, validator: phase0.Validator, @@ -109,9 +131,10 @@ export function filterStateValidatorsByStatus( for (const validator of validatorsArr) { const validatorStatus = getValidatorStatus(validator, currentEpoch); + const generalStatus = mapToGeneralStatus(validatorStatus); const resp = getStateValidatorIndex(validator.pubkey, state, pubkey2index); - if (resp.valid && statusSet.has(validatorStatus)) { + if (resp.valid && (statusSet.has(validatorStatus) || statusSet.has(generalStatus))) { responses.push( toValidatorResponse(resp.validatorIndex, validator, state.balances.get(resp.validatorIndex), currentEpoch) ); @@ -134,7 +157,7 @@ export function getStateValidatorIndex( if (id.startsWith("0x")) { try { id = fromHex(id); - } catch (e) { + } catch (_e) { return {valid: false, code: 400, reason: "Invalid pubkey hex encoding"}; } } else { diff --git a/packages/beacon-node/src/api/impl/config/constants.ts b/packages/beacon-node/src/api/impl/config/constants.ts index 14ecade15b2e..e951da35bdd2 100644 --- a/packages/beacon-node/src/api/impl/config/constants.ts +++ b/packages/beacon-node/src/api/impl/config/constants.ts @@ -41,8 +41,6 @@ import { FULL_EXIT_REQUEST_AMOUNT, } from "@lodestar/params"; -/* eslint-disable @typescript-eslint/naming-convention */ - /** * Hand-picked list of constants declared in consensus-spec .md files. * This list is asserted to be up-to-date with the test `test/e2e/api/impl/config.test.ts` diff --git a/packages/beacon-node/src/api/impl/events/index.ts b/packages/beacon-node/src/api/impl/events/index.ts index 25659743ddf3..55a49fe0c7e3 100644 --- a/packages/beacon-node/src/api/impl/events/index.ts +++ b/packages/beacon-node/src/api/impl/events/index.ts @@ -10,11 +10,10 @@ export function getEventsApi({ const onAbortFns: (() => void)[] = []; for (const topic of topics) { - // eslint-disable-next-line @typescript-eslint/no-explicit-any + // biome-ignore lint/suspicious/noExplicitAny: const handler = (data: any): void => { // TODO: What happens if this handler throws? Does it break the other chain.emitter listeners? - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment onEvent({type: topic, message: data}); }; diff --git a/packages/beacon-node/src/api/impl/lodestar/index.ts b/packages/beacon-node/src/api/impl/lodestar/index.ts index 0e8d2b1fa94b..f89959ad9da6 100644 --- a/packages/beacon-node/src/api/impl/lodestar/index.ts +++ b/packages/beacon-node/src/api/impl/lodestar/index.ts @@ -109,6 +109,7 @@ export function getLodestarApi({ async getBlockProcessorQueueItems() { return { + // biome-ignore lint/complexity/useLiteralKeys: The `blockProcessor` is a protected attribute data: (chain as BeaconChain)["blockProcessor"].jobQueue.getItems().map((item) => { const [blockInputs, opts] = item.args; return { @@ -173,6 +174,7 @@ export function getLodestarApi({ async dumpDbBucketKeys({bucket}) { for (const repo of Object.values(db) as IBeaconDb[keyof IBeaconDb][]) { if (repo instanceof Repository) { + // biome-ignore lint/complexity/useLiteralKeys: `bucket` is protected and `bucketId` is private if (String(repo["bucket"]) === bucket || repo["bucketId"] === bucket) { return {data: stringifyKeys(await repo.keys())}; } @@ -218,8 +220,7 @@ function stringifyKeys(keys: (Uint8Array | number | string)[]): string[] { return keys.map((key) => { if (key instanceof Uint8Array) { return toHex(key); - } else { - return `${key}`; } + return `${key}`; }); } diff --git a/packages/beacon-node/src/api/impl/node/index.ts b/packages/beacon-node/src/api/impl/node/index.ts index 370bba9b3c79..bd1fb85522de 100644 --- a/packages/beacon-node/src/api/impl/node/index.ts +++ b/packages/beacon-node/src/api/impl/node/index.ts @@ -76,10 +76,9 @@ export function getNodeApi( if (isSyncing || isOptimistic || elOffline) { // 206: Node is syncing but can serve incomplete data return {status: syncingStatus ?? routes.node.NodeHealth.SYNCING}; - } else { - // 200: Node is ready - return {status: routes.node.NodeHealth.READY}; } + // 200: Node is ready + return {status: routes.node.NodeHealth.READY}; // else { // 503: Node not initialized or having issues // NOTE: Lodestar does not start its API until fully initialized, so this status can never be served diff --git a/packages/beacon-node/src/api/impl/node/utils.ts b/packages/beacon-node/src/api/impl/node/utils.ts index f26539eb0b36..27978a03ec39 100644 --- a/packages/beacon-node/src/api/impl/node/utils.ts +++ b/packages/beacon-node/src/api/impl/node/utils.ts @@ -44,6 +44,7 @@ function getPeerState(status: StreamStatus): routes.node.PeerState { case "closing": return "disconnecting"; case "closed": + return "disconnected"; default: return "disconnected"; } diff --git a/packages/beacon-node/src/api/impl/validator/index.ts b/packages/beacon-node/src/api/impl/validator/index.ts index 8a500125ad06..1bf3c4f6f659 100644 --- a/packages/beacon-node/src/api/impl/validator/index.ts +++ b/packages/beacon-node/src/api/impl/validator/index.ts @@ -1,3 +1,4 @@ +import {PubkeyIndexMap} from "@chainsafe/pubkey-index-map"; import {routes} from "@lodestar/api"; import {ApplicationMethods} from "@lodestar/api/server"; import { @@ -10,6 +11,8 @@ import { computeEpochAtSlot, getCurrentSlot, beaconBlockToBlinded, + createCachedBeaconState, + loadState, } from "@lodestar/state-transition"; import { GENESIS_SLOT, @@ -62,6 +65,7 @@ import {validateSyncCommitteeGossipContributionAndProof} from "../../../chain/va import {CommitteeSubscription} from "../../../network/subnets/index.js"; import {ApiModules} from "../types.js"; import {RegenCaller} from "../../../chain/regen/index.js"; +import {getStateResponseWithRegen} from "../beacon/state/utils.js"; import {validateGossipFnRetryUnknownRoot} from "../../../network/processor/gossipHandlers.js"; import {SCHEDULER_LOOKAHEAD_FACTOR} from "../../../chain/prepareNextSlot.js"; import {ChainEvent, CheckpointHex, CommonBlockBody} from "../../../chain/index.js"; @@ -85,7 +89,7 @@ import {computeSubnetForCommitteesAtSlot, getPubkeysForIndices, selectBlockProdu export const SYNC_TOLERANCE_EPOCHS = 1; /** - * Cutoff time to wait for execution and builder block production apis to resolve + * Cutoff time to wait from start of the slot for execution and builder block production apis to resolve * Post this time, race execution and builder to pick whatever resolves first * * Empirically the builder block resolves in ~1.5+ seconds, and execution should resolve <1 sec. @@ -164,7 +168,9 @@ export function getValidatorApi( if (msToSlot > MAX_API_CLOCK_DISPARITY_MS) { throw Error(`Requested slot ${slot} is in the future`); - } else if (msToSlot > 0) { + } + + if (msToSlot > 0) { await chain.clock.waitForSlot(slot); } @@ -211,19 +217,19 @@ export function getValidatorApi( consensusBlockValue: prettyWeiToEth(consensusValue), blockTotalValue: prettyWeiToEth(totalValue), }; - } else if (source === ProducedBlockSource.builder) { + } + if (source === ProducedBlockSource.builder) { return { builderExecutionPayloadValue: prettyWeiToEth(executionValue), builderConsensusBlockValue: prettyWeiToEth(consensusValue), builderBlockTotalValue: prettyWeiToEth(totalValue), }; - } else { - return { - engineExecutionPayloadValue: prettyWeiToEth(executionValue), - engineConsensusBlockValue: prettyWeiToEth(consensusValue), - engineBlockTotalValue: prettyWeiToEth(totalValue), - }; } + return { + engineExecutionPayloadValue: prettyWeiToEth(executionValue), + engineConsensusBlockValue: prettyWeiToEth(consensusValue), + engineBlockTotalValue: prettyWeiToEth(totalValue), + }; } /** @@ -290,9 +296,9 @@ export function getValidatorApi( const headSlot = chain.forkChoice.getHead().slot; if (currentSlot - headSlot > SYNC_TOLERANCE_EPOCHS * SLOTS_PER_EPOCH) { throw new NodeIsSyncing(`headSlot ${headSlot} currentSlot ${currentSlot}`); - } else { - return; } + + return; } case SyncState.Synced: @@ -389,17 +395,13 @@ export function getValidatorApi( notWhileSyncing(); await waitForSlot(slot); // Must never request for a future slot > currentSlot - // Process the queued attestations in the forkchoice for correct head estimation - // forkChoice.updateTime() might have already been called by the onSlot clock - // handler, in which case this should just return. - chain.forkChoice.updateTime(slot); parentBlockRoot = fromHex(chain.getProposerHead(slot).blockRoot); } else { parentBlockRoot = inParentBlockRoot; } notOnOutOfRangeData(parentBlockRoot); - let timer; + let timer: undefined | ((opts: {source: ProducedBlockSource}) => number); try { timer = metrics?.blockProductionTime.startTimer(); const {block, executionPayloadValue, consensusBlockValue} = await chain.produceBlindedBlock({ @@ -459,17 +461,13 @@ export function getValidatorApi( notWhileSyncing(); await waitForSlot(slot); // Must never request for a future slot > currentSlot - // Process the queued attestations in the forkchoice for correct head estimation - // forkChoice.updateTime() might have already been called by the onSlot clock - // handler, in which case this should just return. - chain.forkChoice.updateTime(slot); parentBlockRoot = fromHex(chain.getProposerHead(slot).blockRoot); } else { parentBlockRoot = inParentBlockRoot; } notOnOutOfRangeData(parentBlockRoot); - let timer; + let timer: undefined | ((opts: {source: ProducedBlockSource}) => number); try { timer = metrics?.blockProductionTime.startTimer(); const {block, executionPayloadValue, consensusBlockValue, shouldOverrideBuilder} = await chain.produceBlock({ @@ -515,9 +513,9 @@ export function getValidatorApi( consensusBlockValue, shouldOverrideBuilder, }; - } else { - return {data: block, version, executionPayloadValue, consensusBlockValue, shouldOverrideBuilder}; } + + return {data: block, version, executionPayloadValue, consensusBlockValue, shouldOverrideBuilder}; } finally { if (timer) timer({source}); } @@ -535,10 +533,6 @@ export function getValidatorApi( notWhileSyncing(); await waitForSlot(slot); // Must never request for a future slot > currentSlot - // Process the queued attestations in the forkchoice for correct head estimation - // forkChoice.updateTime() might have already been called by the onSlot clock - // handler, in which case this should just return. - chain.forkChoice.updateTime(slot); const parentBlockRoot = fromHex(chain.getProposerHead(slot).blockRoot); notOnOutOfRangeData(parentBlockRoot); @@ -595,9 +589,12 @@ export function getValidatorApi( }); logger.debug("Produced common block body", loggerContext); + // Calculate cutoff time based on start of the slot + const cutoffMs = Math.max(0, BLOCK_PRODUCTION_RACE_CUTOFF_MS - Math.round(chain.clock.secFromSlot(slot) * 1000)); + logger.verbose("Block production race (builder vs execution) starting", { ...loggerContext, - cutoffMs: BLOCK_PRODUCTION_RACE_CUTOFF_MS, + cutoffMs, timeoutMs: BLOCK_PRODUCTION_RACE_TIMEOUT_MS, }); @@ -643,7 +640,7 @@ export function getValidatorApi( : Promise.reject(new Error("Engine disabled")); const [builder, engine] = await resolveOrRacePromises([builderPromise, enginePromise], { - resolveTimeoutMs: BLOCK_PRODUCTION_RACE_CUTOFF_MS, + resolveTimeoutMs: cutoffMs, raceTimeoutMs: BLOCK_PRODUCTION_RACE_TIMEOUT_MS, signal: controller.signal, }); @@ -734,13 +731,13 @@ export function getValidatorApi( executionPayloadBlinded: false, executionPayloadSource, }; - } else { - return { - ...builder.value, - executionPayloadBlinded: true, - executionPayloadSource, - }; } + + return { + ...builder.value, + executionPayloadBlinded: true, + executionPayloadSource, + }; } throw Error("Unreachable error occurred during the builder and execution block production"); @@ -765,25 +762,25 @@ export function getValidatorApi( if (opts.blindedLocal === true && ForkSeq[meta.version] >= ForkSeq.bellatrix) { if (meta.executionPayloadBlinded) { return {data, meta}; - } else { - if (isBlockContents(data)) { - const {block} = data; - const blindedBlock = beaconBlockToBlinded(config, block as BeaconBlock); - return { - data: blindedBlock, - meta: {...meta, executionPayloadBlinded: true}, - }; - } else { - const blindedBlock = beaconBlockToBlinded(config, data as BeaconBlock); - return { - data: blindedBlock, - meta: {...meta, executionPayloadBlinded: true}, - }; - } } - } else { - return {data, meta}; + + if (isBlockContents(data)) { + const {block} = data; + const blindedBlock = beaconBlockToBlinded(config, block as BeaconBlock); + return { + data: blindedBlock, + meta: {...meta, executionPayloadBlinded: true}, + }; + } + + const blindedBlock = beaconBlockToBlinded(config, data as BeaconBlock); + return { + data: blindedBlock, + meta: {...meta, executionPayloadBlinded: true}, + }; } + + return {data, meta}; }, async produceBlindedBlock({slot, randaoReveal, graffiti}) { @@ -796,12 +793,14 @@ export function getValidatorApi( const {block} = data; const blindedBlock = beaconBlockToBlinded(config, block as BeaconBlock); return {data: blindedBlock, meta: {version}}; - } else if (isBlindedBeaconBlock(data)) { + } + + if (isBlindedBeaconBlock(data)) { return {data, meta: {version}}; - } else { - const blindedBlock = beaconBlockToBlinded(config, data as BeaconBlock); - return {data: blindedBlock, meta: {version}}; } + + const blindedBlock = beaconBlockToBlinded(config, data as BeaconBlock); + return {data: blindedBlock, meta: {version}}; }, async produceAttestationData({committeeIndex, slot}) { @@ -900,15 +899,16 @@ export function getValidatorApi( async getProposerDuties({epoch}) { notWhileSyncing(); - // Early check that epoch is within [current_epoch, current_epoch + 1], or allow for pre-genesis + // Early check that epoch is no more than current_epoch + 1, or allow for pre-genesis const currentEpoch = currentEpochWithDisparity(); const nextEpoch = currentEpoch + 1; - if (currentEpoch >= 0 && epoch !== currentEpoch && epoch !== nextEpoch) { - throw Error(`Requested epoch ${epoch} must equal current ${currentEpoch} or next epoch ${nextEpoch}`); + if (currentEpoch >= 0 && epoch > nextEpoch) { + throw new ApiError(400, `Requested epoch ${epoch} must not be more than one epoch in the future`); } const head = chain.forkChoice.getHead(); let state: CachedBeaconStateAllForks | undefined = undefined; + const startSlot = computeStartSlotAtEpoch(epoch); const slotMs = config.SECONDS_PER_SLOT * 1000; const prepareNextSlotLookAheadMs = slotMs / SCHEDULER_LOOKAHEAD_FACTOR; const toNextEpochMs = msToNextEpoch(); @@ -926,21 +926,65 @@ export function getValidatorApi( } if (!state) { - state = await chain.getHeadStateAtCurrentEpoch(RegenCaller.getDuties); + if (epoch >= currentEpoch - 1) { + // Cached beacon state stores proposers for previous, current and next epoch. The + // requested epoch is within that range, we can use the head state at current epoch + state = await chain.getHeadStateAtCurrentEpoch(RegenCaller.getDuties); + } else { + const res = await getStateResponseWithRegen(chain, startSlot); + + const stateViewDU = + res.state instanceof Uint8Array + ? loadState(config, chain.getHeadState(), res.state).state + : res.state.clone(); + + state = createCachedBeaconState( + stateViewDU, + { + config: chain.config, + // Not required to compute proposers + pubkey2index: new PubkeyIndexMap(), + index2pubkey: [], + }, + {skipSyncPubkeys: true, skipSyncCommitteeCache: true} + ); + + if (state.epochCtx.epoch !== epoch) { + throw Error(`Loaded state epoch ${state.epochCtx.epoch} does not match requested epoch ${epoch}`); + } + } } const stateEpoch = state.epochCtx.epoch; let indexes: ValidatorIndex[] = []; - if (epoch === stateEpoch) { - indexes = state.epochCtx.getBeaconProposers(); - } else if (epoch === stateEpoch + 1) { - // Requesting duties for next epoch is allow since they can be predicted with high probabilities. - // @see `epochCtx.getBeaconProposersNextEpoch` JSDocs for rationale. - indexes = state.epochCtx.getBeaconProposersNextEpoch(); - } else { - // Should never happen, epoch is checked to be in bounds above - throw Error(`Proposer duties for epoch ${epoch} not supported, current epoch ${stateEpoch}`); + switch (epoch) { + case stateEpoch: + indexes = state.epochCtx.getBeaconProposers(); + break; + + case stateEpoch + 1: + // make sure shuffling is calculated and ready for next call to calculate nextProposers + await chain.shufflingCache.get(state.epochCtx.nextEpoch, state.epochCtx.nextDecisionRoot); + // Requesting duties for next epoch is allowed since they can be predicted with high probabilities. + // @see `epochCtx.getBeaconProposersNextEpoch` JSDocs for rationale. + indexes = state.epochCtx.getBeaconProposersNextEpoch(); + break; + + case stateEpoch - 1: { + const indexesPrevEpoch = state.epochCtx.getBeaconProposersPrevEpoch(); + if (indexesPrevEpoch === null) { + // Should not happen as previous proposer duties should be initialized for head state + // and if we load state from `Uint8Array` it will always be the state of requested epoch + throw Error(`Proposer duties for previous epoch ${epoch} not yet initialized`); + } + indexes = indexesPrevEpoch; + break; + } + + default: + // Should never happen, epoch is checked to be in bounds above + throw Error(`Proposer duties for epoch ${epoch} not supported, current epoch ${stateEpoch}`); } // NOTE: this is the fastest way of getting compressed pubkeys. @@ -949,7 +993,6 @@ export function getValidatorApi( // TODO: Add a flag to just send 0x00 as pubkeys since the Lodestar validator does not need them. const pubkeys = getPubkeysForIndices(state.validators, indexes); - const startSlot = computeStartSlotAtEpoch(epoch); const duties: routes.validator.ProposerDuty[] = []; for (let i = 0; i < SLOTS_PER_EPOCH; i++) { duties.push({slot: startSlot + i, validatorIndex: indexes[i], pubkey: pubkeys[i]}); @@ -1147,7 +1190,6 @@ export function getValidatorApi( signedAggregateAndProofs.map(async (signedAggregateAndProof, i) => { try { // TODO: Validate in batch - // eslint-disable-next-line @typescript-eslint/explicit-function-return-type const validateFn = () => validateApiAggregateAndProof(fork, chain, signedAggregateAndProof); const {slot, beaconBlockRoot} = signedAggregateAndProof.message.aggregate.data; // when a validator is configured with multiple beacon node urls, this attestation may come from another beacon node @@ -1191,7 +1233,9 @@ export function getValidatorApi( if (errors.length > 1) { throw Error("Multiple errors on publishAggregateAndProofs\n" + errors.map((e) => e.message).join("\n")); - } else if (errors.length === 1) { + } + + if (errors.length === 1) { throw errors[0]; } }, @@ -1247,7 +1291,9 @@ export function getValidatorApi( if (errors.length > 1) { throw Error("Multiple errors on publishContributionAndProofs\n" + errors.map((e) => e.message).join("\n")); - } else if (errors.length === 1) { + } + + if (errors.length === 1) { throw errors[0]; } }, @@ -1364,7 +1410,6 @@ export function getValidatorApi( const validator = headState.validators.getReadonly(validatorIndex); const status = getValidatorStatus(validator, currentEpoch); return ( - status === "active" || status === "active_exiting" || status === "active_ongoing" || status === "active_slashed" || diff --git a/packages/beacon-node/src/api/rest/activeSockets.ts b/packages/beacon-node/src/api/rest/activeSockets.ts index 9f1b0f1a78a3..e6a9aa382333 100644 --- a/packages/beacon-node/src/api/rest/activeSockets.ts +++ b/packages/beacon-node/src/api/rest/activeSockets.ts @@ -93,7 +93,7 @@ export class HttpActiveSocketsTracker { await waitFor(() => this.sockets.size === 0, { timeout: GRACEFUL_TERMINATION_TIMEOUT, }); - } catch { + } catch (_e) { // Ignore timeout error } finally { for (const socket of this.sockets) { diff --git a/packages/beacon-node/src/api/rest/swaggerUI.ts b/packages/beacon-node/src/api/rest/swaggerUI.ts index c48f4e51860d..b4db3e43e6b1 100644 --- a/packages/beacon-node/src/api/rest/swaggerUI.ts +++ b/packages/beacon-node/src/api/rest/swaggerUI.ts @@ -41,15 +41,13 @@ async function getAsset(name: string): Promise { const path = await import("node:path"); const fs = await import("node:fs/promises"); const url = await import("node:url"); - // eslint-disable-next-line @typescript-eslint/naming-convention const __dirname = path.dirname(url.fileURLToPath(import.meta.url)); return await fs.readFile(path.join(__dirname, "../../../../../assets/", name)); - } catch (e) { + } catch (_e) { return undefined; } } -// eslint-disable-next-line @typescript-eslint/explicit-function-return-type export async function getFavicon() { const content = await getAsset("round-icon.ico"); if (!content) { @@ -67,7 +65,6 @@ export async function getFavicon() { ]; } -// eslint-disable-next-line @typescript-eslint/explicit-function-return-type export async function getLogo() { const content = await getAsset("lodestar_icon_text_white.png"); if (!content) { diff --git a/packages/beacon-node/src/chain/balancesCache.ts b/packages/beacon-node/src/chain/balancesCache.ts index 50a86b31b6c8..d29a6998f600 100644 --- a/packages/beacon-node/src/chain/balancesCache.ts +++ b/packages/beacon-node/src/chain/balancesCache.ts @@ -35,7 +35,7 @@ export class CheckpointBalancesCache { const epochBoundaryRoot = epochBoundarySlot === state.slot ? blockRootHex : toRootHex(getBlockRootAtSlot(state, epochBoundarySlot)); - const index = this.items.findIndex((item) => item.epoch === epoch && item.rootHex == epochBoundaryRoot); + const index = this.items.findIndex((item) => item.epoch === epoch && item.rootHex === epochBoundaryRoot); if (index === -1) { if (this.items.length === MAX_BALANCE_CACHE_SIZE) { this.items.shift(); diff --git a/packages/beacon-node/src/chain/blocks/importBlock.ts b/packages/beacon-node/src/chain/blocks/importBlock.ts index d19d6a60c564..596f01f391a4 100644 --- a/packages/beacon-node/src/chain/blocks/importBlock.ts +++ b/packages/beacon-node/src/chain/blocks/importBlock.ts @@ -19,6 +19,7 @@ import {ChainEvent, ReorgEventData} from "../emitter.js"; import {REPROCESS_MIN_TIME_TO_NEXT_SLOT_SEC} from "../reprocess.js"; import type {BeaconChain} from "../chain.js"; import {callInNextEventLoop} from "../../util/eventLoop.js"; +import {ForkchoiceCaller} from "../forkChoice/index.js"; import {FullyVerifiedBlock, ImportBlockOpts, AttestationImportOpt, BlockInputType} from "./types.js"; import {getCheckpointFromState} from "./utils/checkpoint.js"; import {writeBlockInputToDb} from "./writeBlockInputToDb.js"; @@ -208,7 +209,7 @@ export async function importBlock( // 5. Compute head. If new head, immediately stateCache.setHeadState() const oldHead = this.forkChoice.getHead(); - const newHead = this.recomputeForkChoiceHead(); + const newHead = this.recomputeForkChoiceHead(ForkchoiceCaller.importBlock); const currFinalizedEpoch = this.forkChoice.getFinalizedCheckpoint().epoch; if (newHead.blockRoot !== oldHead.blockRoot) { diff --git a/packages/beacon-node/src/chain/blocks/index.ts b/packages/beacon-node/src/chain/blocks/index.ts index a7a2ced2ad7a..f64e4b1f3813 100644 --- a/packages/beacon-node/src/chain/blocks/index.ts +++ b/packages/beacon-node/src/chain/blocks/index.ts @@ -53,7 +53,9 @@ export async function processBlocks( ): Promise { if (blocks.length === 0) { return; // TODO: or throw? - } else if (blocks.length > 1) { + } + + if (blocks.length > 1) { assertLinearChainSegment(this.config, blocks); } @@ -161,11 +163,13 @@ export async function processBlocks( function getBlockError(e: unknown, block: SignedBeaconBlock): BlockError { if (e instanceof BlockError) { return e; - } else if (e instanceof Error) { + } + + if (e instanceof Error) { const blockError = new BlockError(block, {code: BlockErrorCode.BEACON_CHAIN_ERROR, error: e}); blockError.stack = e.stack; return blockError; - } else { - return new BlockError(block, {code: BlockErrorCode.BEACON_CHAIN_ERROR, error: e as Error}); } + + return new BlockError(block, {code: BlockErrorCode.BEACON_CHAIN_ERROR, error: e as Error}); } diff --git a/packages/beacon-node/src/chain/blocks/verifyBlocksDataAvailability.ts b/packages/beacon-node/src/chain/blocks/verifyBlocksDataAvailability.ts index 8393c91063de..98bfae2c1ce3 100644 --- a/packages/beacon-node/src/chain/blocks/verifyBlocksDataAvailability.ts +++ b/packages/beacon-node/src/chain/blocks/verifyBlocksDataAvailability.ts @@ -78,12 +78,12 @@ async function maybeValidateBlobs( case BlockInputType.outOfRangeData: return {dataAvailabilityStatus: DataAvailabilityStatus.OutOfRange, availableBlockInput: blockInput}; + // biome-ignore lint/suspicious/noFallthroughSwitchClause: We need fall-through behavior here case BlockInputType.availableData: if (opts.validBlobSidecars === BlobSidecarValidation.Full) { return {dataAvailabilityStatus: DataAvailabilityStatus.Available, availableBlockInput: blockInput}; } - // eslint-disable-next-line no-fallthrough case BlockInputType.dataPromise: { // run full validation const {block} = blockInput; @@ -136,7 +136,7 @@ async function raceWithCutoff( try { await Promise.race([availabilityPromise, cutoffTimeout]); - } catch (e) { + } catch (_e) { // throw unavailable so that the unknownblock/blobs can be triggered to pull the block throw new BlockError(block, {code: BlockErrorCode.DATA_UNAVAILABLE}); } diff --git a/packages/beacon-node/src/chain/blocks/verifyBlocksSanityChecks.ts b/packages/beacon-node/src/chain/blocks/verifyBlocksSanityChecks.ts index 573dfa52ce8b..22b20a55fb67 100644 --- a/packages/beacon-node/src/chain/blocks/verifyBlocksSanityChecks.ts +++ b/packages/beacon-node/src/chain/blocks/verifyBlocksSanityChecks.ts @@ -45,9 +45,8 @@ export function verifyBlocksSanityChecks( if (blockSlot === 0) { if (opts.ignoreIfKnown) { continue; - } else { - throw new BlockError(block, {code: BlockErrorCode.GENESIS_BLOCK}); } + throw new BlockError(block, {code: BlockErrorCode.GENESIS_BLOCK}); } // Not finalized slot @@ -56,9 +55,8 @@ export function verifyBlocksSanityChecks( if (blockSlot <= finalizedSlot) { if (opts.ignoreIfFinalized) { continue; - } else { - throw new BlockError(block, {code: BlockErrorCode.WOULD_REVERT_FINALIZED_SLOT, blockSlot, finalizedSlot}); } + throw new BlockError(block, {code: BlockErrorCode.WOULD_REVERT_FINALIZED_SLOT, blockSlot, finalizedSlot}); } let parentBlockSlot: Slot; @@ -71,10 +69,9 @@ export function verifyBlocksSanityChecks( parentBlock = chain.forkChoice.getBlockHex(parentRoot); if (!parentBlock) { throw new BlockError(block, {code: BlockErrorCode.PARENT_UNKNOWN, parentRoot}); - } else { - // Parent is known to the fork-choice - parentBlockSlot = parentBlock.slot; } + // Parent is known to the fork-choice + parentBlockSlot = parentBlock.slot; } // Block not in the future, also checks for infinity @@ -89,9 +86,9 @@ export function verifyBlocksSanityChecks( if (chain.forkChoice.hasBlockHex(blockHash)) { if (opts.ignoreIfKnown) { continue; - } else { - throw new BlockError(block, {code: BlockErrorCode.ALREADY_KNOWN, root: blockHash}); } + + throw new BlockError(block, {code: BlockErrorCode.ALREADY_KNOWN, root: blockHash}); } // Block is relevant diff --git a/packages/beacon-node/src/chain/blocks/writeBlockInputToDb.ts b/packages/beacon-node/src/chain/blocks/writeBlockInputToDb.ts index 89cf7ddc7556..010c6a1fabc1 100644 --- a/packages/beacon-node/src/chain/blocks/writeBlockInputToDb.ts +++ b/packages/beacon-node/src/chain/blocks/writeBlockInputToDb.ts @@ -31,7 +31,7 @@ export async function writeBlockInputToDb(this: BeaconChain, blocksInput: BlockI if (blockInput.type === BlockInputType.availableData || blockInput.type === BlockInputType.dataPromise) { const blobSidecars = - blockInput.type == BlockInputType.availableData + blockInput.type === BlockInputType.availableData ? blockInput.blockData.blobs : // At this point of import blobs are available and can be safely awaited (await blockInput.cachedData.availabilityPromise).blobs; diff --git a/packages/beacon-node/src/chain/bls/multithread/index.ts b/packages/beacon-node/src/chain/bls/multithread/index.ts index 3725fa4bcb1c..cb18ca86e42f 100644 --- a/packages/beacon-node/src/chain/bls/multithread/index.ts +++ b/packages/beacon-node/src/chain/bls/multithread/index.ts @@ -3,9 +3,8 @@ import path from "node:path"; import {spawn, Worker} from "@chainsafe/threads"; // `threads` library creates self global variable which breaks `timeout-abort-controller` https://github.com/jacobheun/timeout-abort-controller/issues/9 // Don't add an eslint disable here as a reminder that this has to be fixed eventually -// eslint-disable-next-line // @ts-ignore -// eslint-disable-next-line +// biome-ignore lint/suspicious/noGlobalAssign: self = undefined; import {PublicKey} from "@chainsafe/blst"; import {Logger} from "@lodestar/utils"; @@ -314,7 +313,8 @@ export class BlsMultiThreadWorkerPool implements IBlsVerifier { this.workers[0].status.code === WorkerStatusCode.initializationError && this.workers.every((worker) => worker.status.code === WorkerStatusCode.initializationError) ) { - return job.reject(this.workers[0].status.error); + job.reject(this.workers[0].status.error); + return; } // Append batchable sets to `bufferedJobs`, starting a timeout to push them into `jobs`. diff --git a/packages/beacon-node/src/chain/bls/multithread/poolSize.ts b/packages/beacon-node/src/chain/bls/multithread/poolSize.ts index 9397f97849cd..2c683e191fd6 100644 --- a/packages/beacon-node/src/chain/bls/multithread/poolSize.ts +++ b/packages/beacon-node/src/chain/bls/multithread/poolSize.ts @@ -6,7 +6,7 @@ try { } else { defaultPoolSize = (await import("node:os")).availableParallelism(); } -} catch (e) { +} catch (_e) { defaultPoolSize = 8; } diff --git a/packages/beacon-node/src/chain/bls/multithread/worker.ts b/packages/beacon-node/src/chain/bls/multithread/worker.ts index 9073920df19c..d2794db2e6bf 100644 --- a/packages/beacon-node/src/chain/bls/multithread/worker.ts +++ b/packages/beacon-node/src/chain/bls/multithread/worker.ts @@ -75,7 +75,7 @@ function verifyManySignatureSets(workReqArr: BlsWorkReq[]): BlsWorkResult { // Re-verify all sigs nonBatchableSets.push(...batchableChunk); } - } catch (e) { + } catch (_e) { // TODO: Ignore this error expecting that the same error will happen when re-verifying the set individually // It's not ideal but '@chainsafe/blst' may throw errors on some conditions batchRetries++; diff --git a/packages/beacon-node/src/chain/chain.ts b/packages/beacon-node/src/chain/chain.ts index 371f660abe2e..195b8736b2c3 100644 --- a/packages/beacon-node/src/chain/chain.ts +++ b/packages/beacon-node/src/chain/chain.ts @@ -60,7 +60,7 @@ import { } from "./interface.js"; import {IChainOptions} from "./options.js"; import {QueuedStateRegenerator, RegenCaller} from "./regen/index.js"; -import {initializeForkChoice} from "./forkChoice/index.js"; +import {ForkchoiceCaller, initializeForkChoice} from "./forkChoice/index.js"; import {IBlsVerifier, BlsSingleThreadVerifier, BlsMultiThreadWorkerPool} from "./bls/index.js"; import { SeenAttesters, @@ -464,23 +464,23 @@ export class BeaconChain implements IBeaconChain { executionOptimistic: isOptimisticBlock(block), finalized: slot === finalizedBlock.slot && finalizedBlock.slot !== GENESIS_SLOT, }; - } else { - // Just check if state is already in the cache. If it's not dialed to the correct slot, - // do not bother in advancing the state. restApiCanTriggerRegen == false means do no work - const block = this.forkChoice.getCanonicalBlockAtSlot(slot); - if (!block) { - return null; - } + } - const state = this.regen.getStateSync(block.stateRoot); - return ( - state && { - state, - executionOptimistic: isOptimisticBlock(block), - finalized: slot === finalizedBlock.slot && finalizedBlock.slot !== GENESIS_SLOT, - } - ); + // Just check if state is already in the cache. If it's not dialed to the correct slot, + // do not bother in advancing the state. restApiCanTriggerRegen == false means do no work + const block = this.forkChoice.getCanonicalBlockAtSlot(slot); + if (!block) { + return null; } + + const state = this.regen.getStateSync(block.stateRoot); + return ( + state && { + state, + executionOptimistic: isOptimisticBlock(block), + finalized: slot === finalizedBlock.slot && finalizedBlock.slot !== GENESIS_SLOT, + } + ); } async getHistoricalStateBySlot( @@ -784,9 +784,9 @@ export class BeaconChain implements IBeaconChain { }; } - recomputeForkChoiceHead(): ProtoBlock { + recomputeForkChoiceHead(caller: ForkchoiceCaller): ProtoBlock { this.metrics?.forkChoice.requests.inc(); - const timer = this.metrics?.forkChoice.findHead.startTimer({entrypoint: FindHeadFnName.recomputeForkChoiceHead}); + const timer = this.metrics?.forkChoice.findHead.startTimer({caller}); try { return this.forkChoice.updateAndGetHead({mode: UpdateHeadOpt.GetCanonicialHead}).head; @@ -800,7 +800,7 @@ export class BeaconChain implements IBeaconChain { predictProposerHead(slot: Slot): ProtoBlock { this.metrics?.forkChoice.requests.inc(); - const timer = this.metrics?.forkChoice.findHead.startTimer({entrypoint: FindHeadFnName.predictProposerHead}); + const timer = this.metrics?.forkChoice.findHead.startTimer({caller: FindHeadFnName.predictProposerHead}); try { return this.forkChoice.updateAndGetHead({mode: UpdateHeadOpt.GetPredictedProposerHead, slot}).head; @@ -814,7 +814,7 @@ export class BeaconChain implements IBeaconChain { getProposerHead(slot: Slot): ProtoBlock { this.metrics?.forkChoice.requests.inc(); - const timer = this.metrics?.forkChoice.findHead.startTimer({entrypoint: FindHeadFnName.getProposerHead}); + const timer = this.metrics?.forkChoice.findHead.startTimer({caller: FindHeadFnName.getProposerHead}); const secFromSlot = this.clock.secFromSlot(slot); try { @@ -931,28 +931,27 @@ export class BeaconChain implements IBeaconChain { const effectiveBalances = this.checkpointBalancesCache.get(checkpoint); if (effectiveBalances) { return effectiveBalances; - } else { - // not expected, need metrics - this.metrics?.balancesCache.misses.inc(); - this.logger.debug("checkpointBalances cache miss", { - epoch: checkpoint.epoch, - root: checkpoint.rootHex, - }); - - const {state, stateId, shouldWarn} = this.closestJustifiedBalancesStateToCheckpoint(checkpoint, blockState); - this.metrics?.balancesCache.closestStateResult.inc({stateId}); - if (shouldWarn) { - this.logger.warn("currentJustifiedCheckpoint state not avail, using closest state", { - checkpointEpoch: checkpoint.epoch, - checkpointRoot: checkpoint.rootHex, - stateId, - stateSlot: state.slot, - stateRoot: toRootHex(state.hashTreeRoot()), - }); - } + } + // not expected, need metrics + this.metrics?.balancesCache.misses.inc(); + this.logger.debug("checkpointBalances cache miss", { + epoch: checkpoint.epoch, + root: checkpoint.rootHex, + }); - return getEffectiveBalanceIncrementsZeroInactive(state); + const {state, stateId, shouldWarn} = this.closestJustifiedBalancesStateToCheckpoint(checkpoint, blockState); + this.metrics?.balancesCache.closestStateResult.inc({stateId}); + if (shouldWarn) { + this.logger.warn("currentJustifiedCheckpoint state not avail, using closest state", { + checkpointEpoch: checkpoint.epoch, + checkpointRoot: checkpoint.rootHex, + stateId, + stateSlot: state.slot, + stateRoot: toRootHex(state.hashTreeRoot()), + }); } + + return getEffectiveBalanceIncrementsZeroInactive(state); } /** @@ -1060,8 +1059,8 @@ export class BeaconChain implements IBeaconChain { if (this.forkChoice.irrecoverableError) { this.processShutdownCallback(this.forkChoice.irrecoverableError); } - this.forkChoice.updateTime(slot); + this.forkChoice.updateTime(slot); this.metrics?.clockSlot.set(slot); this.attestationPool.prune(slot); diff --git a/packages/beacon-node/src/chain/emitter.ts b/packages/beacon-node/src/chain/emitter.ts index 9c3ea4a9bf52..10b6455e48f5 100644 --- a/packages/beacon-node/src/chain/emitter.ts +++ b/packages/beacon-node/src/chain/emitter.ts @@ -1,4 +1,4 @@ -import {EventEmitter} from "events"; +import {EventEmitter} from "node:events"; import {StrictEventEmitter} from "strict-event-emitter-types"; import {routes} from "@lodestar/api"; diff --git a/packages/beacon-node/src/chain/forkChoice/index.ts b/packages/beacon-node/src/chain/forkChoice/index.ts index 346a4afe1e7f..839975de4e26 100644 --- a/packages/beacon-node/src/chain/forkChoice/index.ts +++ b/packages/beacon-node/src/chain/forkChoice/index.ts @@ -27,6 +27,11 @@ export type ForkChoiceOpts = RawForkChoiceOpts & { forkchoiceConstructor?: typeof ForkChoice; }; +export enum ForkchoiceCaller { + prepareNextSlot = "prepare_next_slot", + importBlock = "import_block", +} + /** * Fork Choice extended with a ChainEventEmitter */ diff --git a/packages/beacon-node/src/chain/genesis/genesis.ts b/packages/beacon-node/src/chain/genesis/genesis.ts index 979476c69530..0c46f920d614 100644 --- a/packages/beacon-node/src/chain/genesis/genesis.ts +++ b/packages/beacon-node/src/chain/genesis/genesis.ts @@ -124,9 +124,9 @@ export class GenesisBuilder implements IGenesisBuilder { depositTree: this.depositTree, block, }; - } else { - this.throttledLog(`Waiting for min genesis time ${block.timestamp} / ${this.config.MIN_GENESIS_TIME}`); } + + this.throttledLog(`Waiting for min genesis time ${block.timestamp} / ${this.config.MIN_GENESIS_TIME}`); } throw Error("depositsStream stopped without a valid genesis state"); @@ -147,11 +147,11 @@ export class GenesisBuilder implements IGenesisBuilder { if (this.activatedValidatorCount >= this.config.MIN_GENESIS_ACTIVE_VALIDATOR_COUNT) { this.logger.info("Found enough genesis validators", {blockNumber}); return blockNumber; - } else { - this.throttledLog( - `Found ${this.state.validators.length} / ${this.config.MIN_GENESIS_ACTIVE_VALIDATOR_COUNT} validators to genesis` - ); } + + this.throttledLog( + `Found ${this.state.validators.length} / ${this.config.MIN_GENESIS_ACTIVE_VALIDATOR_COUNT} validators to genesis` + ); } throw Error("depositsStream stopped without a valid genesis state"); diff --git a/packages/beacon-node/src/chain/initState.ts b/packages/beacon-node/src/chain/initState.ts index 311806fb1be7..2883cdc8388e 100644 --- a/packages/beacon-node/src/chain/initState.ts +++ b/packages/beacon-node/src/chain/initState.ts @@ -132,7 +132,7 @@ export async function initStateFromEth1({ * Restore the latest beacon state from db */ export async function initStateFromDb( - config: ChainForkConfig, + _config: ChainForkConfig, db: IBeaconDb, logger: Logger ): Promise { diff --git a/packages/beacon-node/src/chain/interface.ts b/packages/beacon-node/src/chain/interface.ts index 531f60dc0e63..3b44ffd594ae 100644 --- a/packages/beacon-node/src/chain/interface.ts +++ b/packages/beacon-node/src/chain/interface.ts @@ -58,6 +58,7 @@ import {ShufflingCache} from "./shufflingCache.js"; import {BlockRewards} from "./rewards/blockRewards.js"; import {AttestationsRewards} from "./rewards/attestationsRewards.js"; import {SyncCommitteeRewards} from "./rewards/syncCommitteeRewards.js"; +import {ForkchoiceCaller} from "./forkChoice/index.js"; export {BlockType, type AssembledBlockType}; export {type ProposerPreparationData}; @@ -204,7 +205,7 @@ export interface IBeaconChain { getStatus(): phase0.Status; - recomputeForkChoiceHead(): ProtoBlock; + recomputeForkChoiceHead(caller: ForkchoiceCaller): ProtoBlock; /** When proposerBoostReorg is enabled, this is called at slot n-1 to predict the head block to build on if we are proposing at slot n */ predictProposerHead(slot: Slot): ProtoBlock; diff --git a/packages/beacon-node/src/chain/lightClient/index.ts b/packages/beacon-node/src/chain/lightClient/index.ts index 30567b5d79b8..0a41ea059e73 100644 --- a/packages/beacon-node/src/chain/lightClient/index.ts +++ b/packages/beacon-node/src/chain/lightClient/index.ts @@ -225,7 +225,7 @@ export class LightClientServer { this.zero = { // Assign the hightest fork's default value because it can always be typecasted down to correct fork finalizedHeader: sszTypesFor(highestFork(forkLightClient)).LightClientHeader.defaultValue(), - finalityBranch: ssz.altair.LightClientUpdate.fields["finalityBranch"].defaultValue(), + finalityBranch: ssz.altair.LightClientUpdate.fields.finalityBranch.defaultValue(), }; if (metrics) { @@ -630,12 +630,12 @@ export class LightClientServer { ? await this.getFinalizedHeader(attestedData.finalizedCheckpoint.root) : null; - let isFinalized, finalityBranch, finalizedHeader; + let isFinalized: boolean, finalityBranch: Uint8Array[], finalizedHeader: LightClientHeader; if ( attestedData.isFinalized && finalizedHeaderAttested && - computeSyncPeriodAtSlot(finalizedHeaderAttested.beacon.slot) == syncPeriod + computeSyncPeriodAtSlot(finalizedHeaderAttested.beacon.slot) === syncPeriod ) { isFinalized = true; finalityBranch = attestedData.finalityBranch; @@ -741,7 +741,7 @@ export function blockToLightClientHeader(fork: ForkName, block: BeaconBlock b.notSeenAttesterCount - a.notSeenAttesterCount).slice(0, maxAttestation); } + + return attestations.sort((a, b) => b.notSeenAttesterCount - a.notSeenAttesterCount).slice(0, maxAttestation); } /** Get attestations for API. */ @@ -636,45 +636,43 @@ export function getNotSeenValidatorsFn(state: CachedBeaconStateAllForks): GetNot } // altair and future forks - else { - // Get attestations to be included in an altair block. - // Attestations are sorted by inclusion distance then number of attesters. - // Attestations should pass the validation when processing attestations in state-transition. - // check for altair block already - const altairState = state as CachedBeaconStateAltair; - const previousParticipation = altairState.previousEpochParticipation.getAll(); - const currentParticipation = altairState.currentEpochParticipation.getAll(); - const stateEpoch = computeEpochAtSlot(state.slot); - // this function could be called multiple times with same slot + committeeIndex - const cachedNotSeenValidators = new Map>(); - - return (epoch: Epoch, slot: Slot, committeeIndex: number) => { - const participationStatus = - epoch === stateEpoch ? currentParticipation : epoch === stateEpoch - 1 ? previousParticipation : null; - - if (participationStatus === null) { - return null; - } - const cacheKey = slot + "_" + committeeIndex; - let notSeenAttestingIndices = cachedNotSeenValidators.get(cacheKey); - if (notSeenAttestingIndices != null) { - // if all validators are seen then return null, we don't need to check for any attestations of same committee again - return notSeenAttestingIndices.size === 0 ? null : notSeenAttestingIndices; - } - - const committee = state.epochCtx.getBeaconCommittee(slot, committeeIndex); - notSeenAttestingIndices = new Set(); - for (const [i, validatorIndex] of committee.entries()) { - // no need to check flagIsTimelySource as if validator is not seen, it's participation status is 0 - if (participationStatus[validatorIndex] === 0) { - notSeenAttestingIndices.add(i); - } - } - cachedNotSeenValidators.set(cacheKey, notSeenAttestingIndices); + // Get attestations to be included in an altair block. + // Attestations are sorted by inclusion distance then number of attesters. + // Attestations should pass the validation when processing attestations in state-transition. + // check for altair block already + const altairState = state as CachedBeaconStateAltair; + const previousParticipation = altairState.previousEpochParticipation.getAll(); + const currentParticipation = altairState.currentEpochParticipation.getAll(); + const stateEpoch = computeEpochAtSlot(state.slot); + // this function could be called multiple times with same slot + committeeIndex + const cachedNotSeenValidators = new Map>(); + + return (epoch: Epoch, slot: Slot, committeeIndex: number) => { + const participationStatus = + epoch === stateEpoch ? currentParticipation : epoch === stateEpoch - 1 ? previousParticipation : null; + + if (participationStatus === null) { + return null; + } + const cacheKey = slot + "_" + committeeIndex; + let notSeenAttestingIndices = cachedNotSeenValidators.get(cacheKey); + if (notSeenAttestingIndices != null) { // if all validators are seen then return null, we don't need to check for any attestations of same committee again return notSeenAttestingIndices.size === 0 ? null : notSeenAttestingIndices; - }; - } + } + + const committee = state.epochCtx.getBeaconCommittee(slot, committeeIndex); + notSeenAttestingIndices = new Set(); + for (const [i, validatorIndex] of committee.entries()) { + // no need to check flagIsTimelySource as if validator is not seen, it's participation status is 0 + if (participationStatus[validatorIndex] === 0) { + notSeenAttestingIndices.add(i); + } + } + cachedNotSeenValidators.set(cacheKey, notSeenAttestingIndices); + // if all validators are seen then return null, we don't need to check for any attestations of same committee again + return notSeenAttestingIndices.size === 0 ? null : notSeenAttestingIndices; + }; } export function extractParticipationPhase0( @@ -716,7 +714,7 @@ export function getValidateAttestationDataFn( const stateEpoch = state.epochCtx.epoch; return (attData: phase0.AttestationData) => { const targetEpoch = attData.target.epoch; - let justifiedCheckpoint; + let justifiedCheckpoint: phase0.Checkpoint; // simple check first if (targetEpoch === stateEpoch) { justifiedCheckpoint = currentJustifiedCheckpoint; @@ -761,7 +759,7 @@ export function isValidAttestationData( data: phase0.AttestationData ): boolean { const {previousJustifiedCheckpoint, currentJustifiedCheckpoint} = state; - let justifiedCheckpoint; + let justifiedCheckpoint: phase0.Checkpoint; const stateEpoch = state.epochCtx.epoch; const targetEpoch = data.target.epoch; diff --git a/packages/beacon-node/src/chain/opPools/attestationPool.ts b/packages/beacon-node/src/chain/opPools/attestationPool.ts index 887448b1e553..8d8fbb92c0f1 100644 --- a/packages/beacon-node/src/chain/opPools/attestationPool.ts +++ b/packages/beacon-node/src/chain/opPools/attestationPool.ts @@ -145,11 +145,10 @@ export class AttestationPool { if (aggregate) { // Aggregate mutating return aggregateAttestationInto(aggregate, attestation); - } else { - // Create new aggregate - aggregateByIndex.set(committeeIndex, attestationToAggregate(attestation)); - return InsertOutcome.NewData; } + // Create new aggregate + aggregateByIndex.set(committeeIndex, attestationToAggregate(attestation)); + return InsertOutcome.NewData; } /** diff --git a/packages/beacon-node/src/chain/opPools/opPool.ts b/packages/beacon-node/src/chain/opPools/opPool.ts index ee66591e9aef..f71186c06d35 100644 --- a/packages/beacon-node/src/chain/opPools/opPool.ts +++ b/packages/beacon-node/src/chain/opPools/opPool.ts @@ -410,10 +410,9 @@ function isVoluntaryExitSignatureIncludable(stateFork: ForkSeq, voluntaryExitFor if (stateFork >= ForkSeq.deneb) { // Exists are perpetually valid https://eips.ethereum.org/EIPS/eip-7044 return true; - } else { - // Can only include exits from the current and previous fork - return voluntaryExitFork === stateFork || voluntaryExitFork === stateFork - 1; } + // Can only include exits from the current and previous fork + return voluntaryExitFork === stateFork || voluntaryExitFork === stateFork - 1; } function isSlashableAtEpoch(validator: phase0.Validator, epoch: Epoch): boolean { diff --git a/packages/beacon-node/src/chain/opPools/syncCommitteeMessagePool.ts b/packages/beacon-node/src/chain/opPools/syncCommitteeMessagePool.ts index bbaba1835dce..4de11e447231 100644 --- a/packages/beacon-node/src/chain/opPools/syncCommitteeMessagePool.ts +++ b/packages/beacon-node/src/chain/opPools/syncCommitteeMessagePool.ts @@ -88,11 +88,11 @@ export class SyncCommitteeMessagePool { if (contribution) { // Aggregate mutating return aggregateSignatureInto(contribution, signature, indexInSubcommittee); - } else { - // Create new aggregate - contributionsByRoot.set(rootHex, signatureToAggregate(subnet, signature, indexInSubcommittee)); - return InsertOutcome.NewData; } + + // Create new aggregate + contributionsByRoot.set(rootHex, signatureToAggregate(subnet, signature, indexInSubcommittee)); + return InsertOutcome.NewData; } /** diff --git a/packages/beacon-node/src/chain/opPools/syncContributionAndProofPool.ts b/packages/beacon-node/src/chain/opPools/syncContributionAndProofPool.ts index ff0feea891e1..81363be218d8 100644 --- a/packages/beacon-node/src/chain/opPools/syncContributionAndProofPool.ts +++ b/packages/beacon-node/src/chain/opPools/syncContributionAndProofPool.ts @@ -90,10 +90,9 @@ export class SyncContributionAndProofPool { const bestContribution = bestContributionBySubnet.get(subnet); if (bestContribution) { return replaceIfBetter(bestContribution, contribution, syncCommitteeParticipants); - } else { - bestContributionBySubnet.set(subnet, contributionToFast(contribution, syncCommitteeParticipants)); - return InsertOutcome.NewData; } + bestContributionBySubnet.set(subnet, contributionToFast(contribution, syncCommitteeParticipants)); + return InsertOutcome.NewData; } /** diff --git a/packages/beacon-node/src/chain/prepareNextSlot.ts b/packages/beacon-node/src/chain/prepareNextSlot.ts index 48724ab25b0b..bda618758842 100644 --- a/packages/beacon-node/src/chain/prepareNextSlot.ts +++ b/packages/beacon-node/src/chain/prepareNextSlot.ts @@ -18,6 +18,7 @@ import {isQueueErrorAborted} from "../util/queue/index.js"; import {prepareExecutionPayload, getPayloadAttributesForSSE} from "./produceBlock/produceBlockBody.js"; import {IBeaconChain} from "./interface.js"; import {RegenCaller} from "./regen/index.js"; +import {ForkchoiceCaller} from "./forkChoice/index.js"; /* With 12s slot times, this scheduler will run 4s before the start of each slot (`12 / 3 = 4`). */ export const SCHEDULER_LOOKAHEAD_FACTOR = 3; @@ -77,7 +78,9 @@ export class PrepareNextSlotScheduler { await sleep(slotMs - slotMs / SCHEDULER_LOOKAHEAD_FACTOR, this.signal); // calling updateHead() here before we produce a block to reduce reorg possibility - const {slot: headSlot, blockRoot: headRoot} = this.chain.recomputeForkChoiceHead(); + const {slot: headSlot, blockRoot: headRoot} = this.chain.recomputeForkChoiceHead( + ForkchoiceCaller.prepareNextSlot + ); // PS: previously this was comparing slots, but that gave no leway on the skipped // slots on epoch bounday. Making it more fluid. diff --git a/packages/beacon-node/src/chain/produceBlock/produceBlockBody.ts b/packages/beacon-node/src/chain/produceBlock/produceBlockBody.ts index ff8221a326e9..37670e4b8f82 100644 --- a/packages/beacon-node/src/chain/produceBlock/produceBlockBody.ts +++ b/packages/beacon-node/src/chain/produceBlock/produceBlockBody.ts @@ -481,26 +481,26 @@ export async function getExecutionPayloadParentHash( if (isMergeTransitionComplete(state)) { // Post-merge, normal payload return {isPremerge: false, parentHash: state.latestExecutionPayloadHeader.blockHash}; - } else { - if ( - !ssz.Root.equals(chain.config.TERMINAL_BLOCK_HASH, ZERO_HASH) && - getCurrentEpoch(state) < chain.config.TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH - ) - throw new Error( - `InvalidMergeTBH epoch: expected >= ${ - chain.config.TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH - }, actual: ${getCurrentEpoch(state)}` - ); + } - const terminalPowBlockHash = await chain.eth1.getTerminalPowBlock(); - if (terminalPowBlockHash === null) { - // Pre-merge, no prepare payload call is needed - return {isPremerge: true}; - } else { - // Signify merge via producing on top of the last PoW block - return {isPremerge: false, parentHash: terminalPowBlockHash}; - } + if ( + !ssz.Root.equals(chain.config.TERMINAL_BLOCK_HASH, ZERO_HASH) && + getCurrentEpoch(state) < chain.config.TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH + ) { + throw new Error( + `InvalidMergeTBH epoch: expected >= ${ + chain.config.TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH + }, actual: ${getCurrentEpoch(state)}` + ); } + + const terminalPowBlockHash = await chain.eth1.getTerminalPowBlock(); + if (terminalPowBlockHash === null) { + // Pre-merge, no prepare payload call is needed + return {isPremerge: true}; + } + // Signify merge via producing on top of the last PoW block + return {isPremerge: false, parentHash: terminalPowBlockHash}; } export async function getPayloadAttributesForSSE( @@ -536,9 +536,9 @@ export async function getPayloadAttributesForSSE( payloadAttributes, }; return ssePayloadAttributes; - } else { - throw Error("The execution is still pre-merge"); } + + throw Error("The execution is still pre-merge"); } function preparePayloadAttributes( diff --git a/packages/beacon-node/src/chain/produceBlock/validateBlobsAndKzgCommitments.ts b/packages/beacon-node/src/chain/produceBlock/validateBlobsAndKzgCommitments.ts index ba086ecafc7e..06f17c92156a 100644 --- a/packages/beacon-node/src/chain/produceBlock/validateBlobsAndKzgCommitments.ts +++ b/packages/beacon-node/src/chain/produceBlock/validateBlobsAndKzgCommitments.ts @@ -5,7 +5,8 @@ import {BlobsBundle} from "../../execution/index.js"; * Optionally sanity-check that the KZG commitments match the versioned hashes in the transactions * https://github.com/ethereum/consensus-specs/blob/11a037fd9227e29ee809c9397b09f8cc3383a8c0/specs/eip4844/validator.md#blob-kzg-commitments */ -export function validateBlobsAndKzgCommitments(payload: ExecutionPayload, blobsBundle: BlobsBundle): void { + +export function validateBlobsAndKzgCommitments(_payload: ExecutionPayload, blobsBundle: BlobsBundle): void { // sanity-check that the KZG commitments match the blobs (as produced by the execution engine) if (blobsBundle.blobs.length !== blobsBundle.commitments.length) { throw Error( diff --git a/packages/beacon-node/src/chain/regen/queued.ts b/packages/beacon-node/src/chain/regen/queued.ts index 57e64bd364ea..694e8635a3b7 100644 --- a/packages/beacon-node/src/chain/regen/queued.ts +++ b/packages/beacon-node/src/chain/regen/queued.ts @@ -336,7 +336,7 @@ export class QueuedStateRegenerator implements IStateRegenerator { caller: regenRequest.args[regenRequest.args.length - 1] as RegenCaller, entrypoint: regenRequest.key as RegenFnName, }; - let timer; + let timer: (() => number) | undefined; try { timer = this.metrics?.regenFnCallDuration.startTimer(metricsLabels); switch (regenRequest.key) { diff --git a/packages/beacon-node/src/chain/rewards/attestationsRewards.ts b/packages/beacon-node/src/chain/rewards/attestationsRewards.ts index 70fb27de239a..588b310f87ea 100644 --- a/packages/beacon-node/src/chain/rewards/attestationsRewards.ts +++ b/packages/beacon-node/src/chain/rewards/attestationsRewards.ts @@ -36,9 +36,9 @@ const defaultAttestationsReward = {head: 0, target: 0, source: 0, inclusionDelay const defaultAttestationsPenalty = {target: 0, source: 0}; export async function computeAttestationsRewards( - epoch: Epoch, + _epoch: Epoch, state: CachedBeaconStateAllForks, - config: BeaconConfig, + _config: BeaconConfig, validatorIds?: (ValidatorIndex | string)[] ): Promise { const fork = state.config.getForkName(state.slot); @@ -85,7 +85,7 @@ function computeIdealAttestationsRewardsAndPenaltiesAltair( for (let i = 0; i < PARTICIPATION_FLAG_WEIGHTS.length; i++) { const weight = PARTICIPATION_FLAG_WEIGHTS[i]; - let unslashedStakeByIncrement; + let unslashedStakeByIncrement: number; let flagName: keyof IdealAttestationsReward; switch (i) { diff --git a/packages/beacon-node/src/chain/rewards/blockRewards.ts b/packages/beacon-node/src/chain/rewards/blockRewards.ts index 65dc23496070..19a59aaa028e 100644 --- a/packages/beacon-node/src/chain/rewards/blockRewards.ts +++ b/packages/beacon-node/src/chain/rewards/blockRewards.ts @@ -90,9 +90,9 @@ function computeSyncAggregateReward(block: altair.BeaconBlock, preState: CachedB const {syncProposerReward} = preState.epochCtx; return syncCommitteeBits.getTrueBitIndexes().length * Math.floor(syncProposerReward); // syncProposerReward should already be integer - } else { - return 0; // phase0 block does not have syncAggregate } + + return 0; // phase0 block does not have syncAggregate } /** diff --git a/packages/beacon-node/src/chain/rewards/syncCommitteeRewards.ts b/packages/beacon-node/src/chain/rewards/syncCommitteeRewards.ts index 89ef84af43a2..71d345e32811 100644 --- a/packages/beacon-node/src/chain/rewards/syncCommitteeRewards.ts +++ b/packages/beacon-node/src/chain/rewards/syncCommitteeRewards.ts @@ -51,7 +51,7 @@ export async function computeSyncCommitteeRewards( return rewards.filter( (reward) => filtersSet.has(reward.validatorIndex) || filtersSet.has(index2pubkey[reward.validatorIndex].toHex()) ); - } else { - return rewards; } + + return rewards; } diff --git a/packages/beacon-node/src/chain/seenCache/seenGossipBlockInput.ts b/packages/beacon-node/src/chain/seenCache/seenGossipBlockInput.ts index 3806668436d8..1c03979b7d77 100644 --- a/packages/beacon-node/src/chain/seenCache/seenGossipBlockInput.ts +++ b/packages/beacon-node/src/chain/seenCache/seenGossipBlockInput.ts @@ -72,9 +72,9 @@ export class SeenGossipBlockInput { blockInput: NullBlockInput; blockInputMeta: {pending: GossipedInputType.block; haveBlobs: number; expectedBlobs: null}; } { - let blockHex; - let blockCache; - let fork; + let blockHex: RootHex; + let blockCache: BlockInputCacheType; + let fork: ForkName; if (gossipedInput.type === GossipedInputType.block) { const {signedBlock, blockBytes} = gossipedInput; @@ -149,42 +149,42 @@ export class SeenGossipBlockInput { blockInput, blockInputMeta: {pending: null, haveBlobs: allBlobs.blobs.length, expectedBlobs: blobKzgCommitments.length}, }; - } else { - const blockInput = getBlockInput.dataPromise( - config, - signedBlock, - BlockSource.gossip, - blockBytes ?? null, - cachedData - ); - - resolveBlockInput(blockInput); - return { - blockInput, - blockInputMeta: { - pending: GossipedInputType.blob, - haveBlobs: blobsCache.size, - expectedBlobs: blobKzgCommitments.length, - }, - }; - } - } else { - // will need to wait for the block to showup - if (cachedData === undefined) { - throw Error("Missing cachedData for deneb+ blobs"); } - const {blobsCache} = cachedData; + const blockInput = getBlockInput.dataPromise( + config, + signedBlock, + BlockSource.gossip, + blockBytes ?? null, + cachedData + ); + + resolveBlockInput(blockInput); return { - blockInput: { - block: null, - blockRootHex: blockHex, - cachedData, - blockInputPromise, + blockInput, + blockInputMeta: { + pending: GossipedInputType.blob, + haveBlobs: blobsCache.size, + expectedBlobs: blobKzgCommitments.length, }, - blockInputMeta: {pending: GossipedInputType.block, haveBlobs: blobsCache.size, expectedBlobs: null}, }; } + + // will need to wait for the block to showup + if (cachedData === undefined) { + throw Error("Missing cachedData for deneb+ blobs"); + } + const {blobsCache} = cachedData; + + return { + blockInput: { + block: null, + blockRootHex: blockHex, + cachedData, + blockInputPromise, + }, + blockInputMeta: {pending: GossipedInputType.block, haveBlobs: blobsCache.size, expectedBlobs: null}, + }; } } diff --git a/packages/beacon-node/src/chain/shufflingCache.ts b/packages/beacon-node/src/chain/shufflingCache.ts index 6c42228b5356..bdedddacf6db 100644 --- a/packages/beacon-node/src/chain/shufflingCache.ts +++ b/packages/beacon-node/src/chain/shufflingCache.ts @@ -4,11 +4,11 @@ import { IShufflingCache, ShufflingBuildProps, computeEpochShuffling, + computeEpochShufflingAsync, } from "@lodestar/state-transition"; import {Epoch, RootHex} from "@lodestar/types"; import {LodestarError, Logger, MapDef, pruneSetToMax} from "@lodestar/utils"; import {Metrics} from "../metrics/metrics.js"; -import {callInNextEventLoop} from "../util/eventLoop.js"; /** * Same value to CheckpointBalancesCache, with the assumption that we don't have to use it for old epochs. In the worse case: @@ -130,10 +130,9 @@ export class ShufflingCache implements IShufflingCache { if (isShufflingCacheItem(cacheItem)) { this.metrics?.shufflingCache.hit.inc(); return cacheItem.shuffling; - } else { - this.metrics?.shufflingCache.shufflingPromiseNotResolved.inc(); - return cacheItem.promise; } + this.metrics?.shufflingCache.shufflingPromiseNotResolved.inc(); + return cacheItem.promise; } /** @@ -178,14 +177,19 @@ export class ShufflingCache implements IShufflingCache { this.insertPromise(epoch, decisionRoot); /** * TODO: (@matthewkeil) This will get replaced by a proper build queue and a worker to do calculations - * on a NICE thread with a rust implementation + * on a NICE thread */ - callInNextEventLoop(() => { - const timer = this.metrics?.shufflingCache.shufflingCalculationTime.startTimer({source: "build"}); - const shuffling = computeEpochShuffling(state, activeIndices, epoch); - timer?.(); - this.set(shuffling, decisionRoot); - }); + const timer = this.metrics?.shufflingCache.shufflingCalculationTime.startTimer({source: "build"}); + computeEpochShufflingAsync(state, activeIndices, epoch) + .then((shuffling) => { + this.set(shuffling, decisionRoot); + }) + .catch((err) => + this.logger?.error(`error building shuffling for epoch ${epoch} at decisionRoot ${decisionRoot}`, {}, err) + ) + .finally(() => { + timer?.(); + }); } /** diff --git a/packages/beacon-node/src/chain/stateCache/datastore/file.ts b/packages/beacon-node/src/chain/stateCache/datastore/file.ts index f487079ae443..3c978c2355d6 100644 --- a/packages/beacon-node/src/chain/stateCache/datastore/file.ts +++ b/packages/beacon-node/src/chain/stateCache/datastore/file.ts @@ -13,7 +13,7 @@ const CHECKPOINT_FILE_NAME_LENGTH = 82; export class FileCPStateDatastore implements CPStateDatastore { private readonly folderPath: string; - constructor(parentDir: string = ".") { + constructor(parentDir = ".") { // by default use the beacon folder `/beacon/checkpoint_states` this.folderPath = path.join(parentDir, CHECKPOINT_STATES_FOLDER); } diff --git a/packages/beacon-node/src/chain/validation/aggregateAndProof.ts b/packages/beacon-node/src/chain/validation/aggregateAndProof.ts index 39a3700aacf9..6d6eab6ec15a 100644 --- a/packages/beacon-node/src/chain/validation/aggregateAndProof.ts +++ b/packages/beacon-node/src/chain/validation/aggregateAndProof.ts @@ -6,7 +6,7 @@ import { createAggregateSignatureSetFromComponents, } from "@lodestar/state-transition"; import {toRootHex} from "@lodestar/utils"; -import {IBeaconChain} from ".."; +import {IBeaconChain} from "../index.js"; import {AttestationError, AttestationErrorCode, GossipAction} from "../errors/index.js"; import {RegenCaller} from "../regen/index.js"; import {getSelectionProofSignatureSet, getAggregateAndProofSignatureSet} from "./signatureSets/index.js"; @@ -74,7 +74,7 @@ async function validateAggregateAndProof( const seenAttDataKey = serializedData ? getSeenAttDataKeyFromSignedAggregateAndProof(fork, serializedData) : null; const cachedAttData = seenAttDataKey ? chain.seenAttestationDatas.get(attSlot, seenAttDataKey) : null; - let attIndex; + let attIndex: number | null; if (ForkSeq[fork] >= ForkSeq.electra) { attIndex = (aggregate as electra.Attestation).committeeBits.getSingleTrueBit(); // [REJECT] len(committee_indices) == 1, where committee_indices = get_committee_indices(aggregate) diff --git a/packages/beacon-node/src/chain/validation/attestation.ts b/packages/beacon-node/src/chain/validation/attestation.ts index 119a8ee1a899..0b3f490e4129 100644 --- a/packages/beacon-node/src/chain/validation/attestation.ts +++ b/packages/beacon-node/src/chain/validation/attestation.ts @@ -208,19 +208,18 @@ export async function validateApiAttestation( const targetEpoch = attestation.data.target.epoch; chain.seenAttesters.add(targetEpoch, validatorIndex); return step0Result; - } else { - throw new AttestationError(GossipAction.IGNORE, { - code: AttestationErrorCode.INVALID_SIGNATURE, - }); } + + throw new AttestationError(GossipAction.IGNORE, { + code: AttestationErrorCode.INVALID_SIGNATURE, + }); } catch (err) { if (err instanceof EpochCacheError && err.type.code === EpochCacheErrorCode.COMMITTEE_INDEX_OUT_OF_RANGE) { throw new AttestationError(GossipAction.IGNORE, { code: AttestationErrorCode.BAD_TARGET_EPOCH, }); - } else { - throw err; } + throw err; } } @@ -274,7 +273,7 @@ async function validateAttestationNoSignatureCheck( const attEpoch = computeEpochAtSlot(attSlot); const attTarget = attData.target; const targetEpoch = attTarget.epoch; - let committeeIndex; + let committeeIndex: number | null; if (attestationOrCache.attestation) { if (isElectraAttestation(attestationOrCache.attestation)) { // api or first time validation of a gossip attestation @@ -715,27 +714,27 @@ function verifyAttestationTargetRoot(headBlock: ProtoBlock, targetRoot: Root, at targetRoot: toRootHex(targetRoot), expected: null, }); - } else { - const expectedTargetRoot = - headBlockEpoch === attestationEpoch - ? // If the block is in the same epoch as the attestation, then use the target root - // from the block. - headBlock.targetRoot - : // If the head block is from a previous epoch then skip slots will cause the head block - // root to become the target block root. - // - // We know the head block is from a previous epoch due to a previous check. - headBlock.blockRoot; - - // TODO: Do a fast comparision to convert and compare byte by byte - if (expectedTargetRoot !== toRootHex(targetRoot)) { - // Reject any attestation with an invalid target root. - throw new AttestationError(GossipAction.REJECT, { - code: AttestationErrorCode.INVALID_TARGET_ROOT, - targetRoot: toRootHex(targetRoot), - expected: expectedTargetRoot, - }); - } + } + + const expectedTargetRoot = + headBlockEpoch === attestationEpoch + ? // If the block is in the same epoch as the attestation, then use the target root + // from the block. + headBlock.targetRoot + : // If the head block is from a previous epoch then skip slots will cause the head block + // root to become the target block root. + // + // We know the head block is from a previous epoch due to a previous check. + headBlock.blockRoot; + + // TODO: Do a fast comparision to convert and compare byte by byte + if (expectedTargetRoot !== toRootHex(targetRoot)) { + // Reject any attestation with an invalid target root. + throw new AttestationError(GossipAction.REJECT, { + code: AttestationErrorCode.INVALID_TARGET_ROOT, + targetRoot: toRootHex(targetRoot), + expected: expectedTargetRoot, + }); } } diff --git a/packages/beacon-node/src/chain/validation/attesterSlashing.ts b/packages/beacon-node/src/chain/validation/attesterSlashing.ts index 11a499c9bb53..5da146a67a86 100644 --- a/packages/beacon-node/src/chain/validation/attesterSlashing.ts +++ b/packages/beacon-node/src/chain/validation/attesterSlashing.ts @@ -4,7 +4,7 @@ import { assertValidAttesterSlashing, getAttesterSlashingSignatureSets, } from "@lodestar/state-transition"; -import {IBeaconChain} from ".."; +import {IBeaconChain} from "../index.js"; import {AttesterSlashingError, AttesterSlashingErrorCode, GossipAction} from "../errors/index.js"; export async function validateApiAttesterSlashing( diff --git a/packages/beacon-node/src/chain/validation/blsToExecutionChange.ts b/packages/beacon-node/src/chain/validation/blsToExecutionChange.ts index e5ad56daeb5c..fff399aada50 100644 --- a/packages/beacon-node/src/chain/validation/blsToExecutionChange.ts +++ b/packages/beacon-node/src/chain/validation/blsToExecutionChange.ts @@ -4,7 +4,7 @@ import { getBlsToExecutionChangeSignatureSet, CachedBeaconStateCapella, } from "@lodestar/state-transition"; -import {IBeaconChain} from ".."; +import {IBeaconChain} from "../index.js"; import {BlsToExecutionChangeError, BlsToExecutionChangeErrorCode, GossipAction} from "../errors/index.js"; export async function validateApiBlsToExecutionChange( diff --git a/packages/beacon-node/src/chain/validation/lightClientFinalityUpdate.ts b/packages/beacon-node/src/chain/validation/lightClientFinalityUpdate.ts index f4865c73f8e4..0b19495abde6 100644 --- a/packages/beacon-node/src/chain/validation/lightClientFinalityUpdate.ts +++ b/packages/beacon-node/src/chain/validation/lightClientFinalityUpdate.ts @@ -34,9 +34,9 @@ export function validateLightClientFinalityUpdate( } // [IGNORE] The received finality_update matches the locally computed one exactly - const sszType = config.getLightClientForkTypes(gossipedFinalityUpdate.attestedHeader.beacon.slot)[ - "LightClientFinalityUpdate" - ]; + const sszType = config.getLightClientForkTypes( + gossipedFinalityUpdate.attestedHeader.beacon.slot + ).LightClientFinalityUpdate; if (localFinalityUpdate === null || !sszType.equals(gossipedFinalityUpdate, localFinalityUpdate)) { throw new LightClientError(GossipAction.IGNORE, { code: LightClientErrorCode.FINALITY_UPDATE_NOT_MATCHING_LOCAL, diff --git a/packages/beacon-node/src/chain/validation/lightClientOptimisticUpdate.ts b/packages/beacon-node/src/chain/validation/lightClientOptimisticUpdate.ts index 182321984af5..7a7dd7f34a91 100644 --- a/packages/beacon-node/src/chain/validation/lightClientOptimisticUpdate.ts +++ b/packages/beacon-node/src/chain/validation/lightClientOptimisticUpdate.ts @@ -35,9 +35,9 @@ export function validateLightClientOptimisticUpdate( } // [IGNORE] The received optimistic_update matches the locally computed one exactly - const sszType = config.getLightClientForkTypes(gossipedOptimisticUpdate.attestedHeader.beacon.slot)[ - "LightClientOptimisticUpdate" - ]; + const sszType = config.getLightClientForkTypes( + gossipedOptimisticUpdate.attestedHeader.beacon.slot + ).LightClientOptimisticUpdate; if (localOptimisticUpdate === null || !sszType.equals(gossipedOptimisticUpdate, localOptimisticUpdate)) { throw new LightClientError(GossipAction.IGNORE, { code: LightClientErrorCode.OPTIMISTIC_UPDATE_NOT_MATCHING_LOCAL, diff --git a/packages/beacon-node/src/chain/validation/proposerSlashing.ts b/packages/beacon-node/src/chain/validation/proposerSlashing.ts index 7281302aae8d..48fe6db326c9 100644 --- a/packages/beacon-node/src/chain/validation/proposerSlashing.ts +++ b/packages/beacon-node/src/chain/validation/proposerSlashing.ts @@ -1,6 +1,6 @@ import {phase0} from "@lodestar/types"; import {assertValidProposerSlashing, getProposerSlashingSignatureSets} from "@lodestar/state-transition"; -import {IBeaconChain} from ".."; +import {IBeaconChain} from "../index.js"; import {ProposerSlashingError, ProposerSlashingErrorCode, GossipAction} from "../errors/index.js"; export async function validateApiProposerSlashing( diff --git a/packages/beacon-node/src/chain/validation/voluntaryExit.ts b/packages/beacon-node/src/chain/validation/voluntaryExit.ts index 3957b51180d9..2b38b161423e 100644 --- a/packages/beacon-node/src/chain/validation/voluntaryExit.ts +++ b/packages/beacon-node/src/chain/validation/voluntaryExit.ts @@ -1,6 +1,6 @@ import {phase0} from "@lodestar/types"; import {isValidVoluntaryExit, getVoluntaryExitSignatureSet} from "@lodestar/state-transition"; -import {IBeaconChain} from ".."; +import {IBeaconChain} from "../index.js"; import {VoluntaryExitError, VoluntaryExitErrorCode, GossipAction} from "../errors/index.js"; import {RegenCaller} from "../regen/index.js"; diff --git a/packages/beacon-node/src/db/buckets.ts b/packages/beacon-node/src/db/buckets.ts index eff123879037..c35a5a18edf5 100644 --- a/packages/beacon-node/src/db/buckets.ts +++ b/packages/beacon-node/src/db/buckets.ts @@ -65,11 +65,10 @@ export enum Bucket { export function getBucketNameByValue(enumValue: T): keyof typeof Bucket { const keys = Object.keys(Bucket).filter((x) => { - if (isNaN(parseInt(x))) { - return Bucket[x as keyof typeof Bucket] == enumValue; - } else { - return false; + if (Number.isNaN(parseInt(x))) { + return Bucket[x as keyof typeof Bucket] === enumValue; } + return false; }) as (keyof typeof Bucket)[]; if (keys.length > 0) { return keys[0]; diff --git a/packages/beacon-node/src/db/repositories/backfilledRanges.ts b/packages/beacon-node/src/db/repositories/backfilledRanges.ts index 309909b18cb8..f86c20288099 100644 --- a/packages/beacon-node/src/db/repositories/backfilledRanges.ts +++ b/packages/beacon-node/src/db/repositories/backfilledRanges.ts @@ -23,8 +23,7 @@ export class BackfilledRanges extends Repository { return bytesToInt(super.decodeKey(data) as unknown as Uint8Array, "be"); } - // eslint-disable-next-line @typescript-eslint/no-unused-vars - getId(value: Slot): number { + getId(_value: Slot): number { throw new Error("Cannot get the db key from slot"); } } diff --git a/packages/beacon-node/src/db/repositories/blockArchive.ts b/packages/beacon-node/src/db/repositories/blockArchive.ts index 15c07f552b21..427650a37bc3 100644 --- a/packages/beacon-node/src/db/repositories/blockArchive.ts +++ b/packages/beacon-node/src/db/repositories/blockArchive.ts @@ -105,7 +105,7 @@ export class BlockArchiveRepository extends Repository async *valuesStream(opts?: BlockFilterOptions): AsyncIterable { const firstSlot = this.getFirstSlot(opts); const valuesStream = super.valuesStream(opts); - const step = (opts && opts.step) ?? 1; + const step = opts?.step ?? 1; for await (const value of valuesStream) { if ((value.message.slot - firstSlot) % step === 0) { diff --git a/packages/beacon-node/src/db/repositories/blockArchiveIndex.ts b/packages/beacon-node/src/db/repositories/blockArchiveIndex.ts index 797142d09db7..8c2785dbe67c 100644 --- a/packages/beacon-node/src/db/repositories/blockArchiveIndex.ts +++ b/packages/beacon-node/src/db/repositories/blockArchiveIndex.ts @@ -17,7 +17,7 @@ export async function deleteRootIndex( signedBeaconBlockType: SSZTypesFor, block: SignedBeaconBlock ): Promise { - const beaconBlockType = (signedBeaconBlockType as typeof ssz.phase0.SignedBeaconBlock).fields["message"]; + const beaconBlockType = (signedBeaconBlockType as typeof ssz.phase0.SignedBeaconBlock).fields.message; return db.delete(getRootIndexKey(beaconBlockType.hashTreeRoot(block.message))); } diff --git a/packages/beacon-node/src/db/repositories/checkpointState.ts b/packages/beacon-node/src/db/repositories/checkpointState.ts index 8848f4d26d3a..7bace3f3f3fc 100644 --- a/packages/beacon-node/src/db/repositories/checkpointState.ts +++ b/packages/beacon-node/src/db/repositories/checkpointState.ts @@ -11,10 +11,10 @@ import {Bucket, getBucketNameByValue} from "../buckets.js"; export class CheckpointStateRepository extends Repository { constructor(config: ChainForkConfig, db: Db) { // Pick some type but won't be used. Casted to any because no type can match `BeaconStateAllForks` - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-explicit-any - const type = ssz.phase0.BeaconState as any; + const type = ssz.phase0.BeaconState; const bucket = Bucket.allForks_checkpointState; - super(config, db, bucket, type, getBucketNameByValue(bucket)); + // biome-ignore lint/suspicious/noExplicitAny: The type is complex to specify a proper override + super(config, db, bucket, type as any, getBucketNameByValue(bucket)); } getId(): Uint8Array { diff --git a/packages/beacon-node/src/db/repositories/depositDataRoot.ts b/packages/beacon-node/src/db/repositories/depositDataRoot.ts index fa8983f0e5fa..97200ccd0f92 100644 --- a/packages/beacon-node/src/db/repositories/depositDataRoot.ts +++ b/packages/beacon-node/src/db/repositories/depositDataRoot.ts @@ -21,8 +21,7 @@ export class DepositDataRootRepository extends Repository { } // depositDataRoots stored by depositData index - // eslint-disable-next-line @typescript-eslint/no-unused-vars - getId(value: Root): number { + getId(_value: Root): number { throw new Error("Unable to create depositIndex from root"); } @@ -70,7 +69,9 @@ export class DepositDataRootRepository extends Repository { // TODO: Review and fix properly if (index > depositRootTree.length) { throw Error(`Error setting depositRootTree index ${index} > length ${depositRootTree.length}`); - } else if (index === depositRootTree.length) { + } + + if (index === depositRootTree.length) { depositRootTree.push(value); } else { depositRootTree.set(index, value); diff --git a/packages/beacon-node/src/db/repositories/eth1Data.ts b/packages/beacon-node/src/db/repositories/eth1Data.ts index e0a6c14e4022..f87199a0b80e 100644 --- a/packages/beacon-node/src/db/repositories/eth1Data.ts +++ b/packages/beacon-node/src/db/repositories/eth1Data.ts @@ -14,8 +14,7 @@ export class Eth1DataRepository extends Repository { constructor(config: ChainForkConfig, db: Db) { // Pick some type but won't be used. Casted to any because no type can match `BeaconStateAllForks` - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-explicit-any + // biome-ignore lint/suspicious/noExplicitAny: const type = ssz.phase0.BeaconState as any; const bucket = Bucket.allForks_stateArchive; super(config, db, bucket, type, getBucketNameByValue(bucket)); diff --git a/packages/beacon-node/src/db/single/preGenesisStateLastProcessedBlock.ts b/packages/beacon-node/src/db/single/preGenesisStateLastProcessedBlock.ts index c958b9de2f0a..37dcb069acc9 100644 --- a/packages/beacon-node/src/db/single/preGenesisStateLastProcessedBlock.ts +++ b/packages/beacon-node/src/db/single/preGenesisStateLastProcessedBlock.ts @@ -10,7 +10,7 @@ export class PreGenesisStateLastProcessedBlock { private readonly db: Db; private readonly key: Uint8Array; - constructor(config: ChainForkConfig, db: Db) { + constructor(_config: ChainForkConfig, db: Db) { this.db = db; this.type = ssz.UintNum64; this.bucket = Bucket.phase0_preGenesisStateLastProcessedBlock; diff --git a/packages/beacon-node/src/eth1/eth1DataCache.ts b/packages/beacon-node/src/eth1/eth1DataCache.ts index 91b8537d1cc4..7f9bb99a2f16 100644 --- a/packages/beacon-node/src/eth1/eth1DataCache.ts +++ b/packages/beacon-node/src/eth1/eth1DataCache.ts @@ -21,6 +21,6 @@ export class Eth1DataCache { async getHighestCachedBlockNumber(): Promise { const highestEth1Data = await this.db.eth1Data.lastValue(); - return highestEth1Data && highestEth1Data.blockNumber; + return highestEth1Data?.blockNumber ?? null; } } diff --git a/packages/beacon-node/src/eth1/eth1DepositDataTracker.ts b/packages/beacon-node/src/eth1/eth1DepositDataTracker.ts index a38b3f9987d9..674b6b600f31 100644 --- a/packages/beacon-node/src/eth1/eth1DepositDataTracker.ts +++ b/packages/beacon-node/src/eth1/eth1DepositDataTracker.ts @@ -14,7 +14,7 @@ import {Eth1DepositsCache} from "./eth1DepositsCache.js"; import {Eth1DataCache} from "./eth1DataCache.js"; import {getEth1VotesToConsider, pickEth1Vote} from "./utils/eth1Vote.js"; import {getDeposits} from "./utils/deposits.js"; -import {Eth1DataAndDeposits, IEth1Provider} from "./interface.js"; +import {Eth1DataAndDeposits, EthJsonRpcBlockRaw, IEth1Provider} from "./interface.js"; import {Eth1Options} from "./options.js"; import {HttpRpcError} from "./provider/jsonRpcHttpClient.js"; import {parseEth1Block} from "./provider/eth1Provider.js"; @@ -243,7 +243,7 @@ export class Eth1DepositDataTracker { const fromBlock = Math.min(remoteFollowBlock, this.getFromBlockToFetch(lastProcessedDepositBlockNumber)); const toBlock = Math.min(remoteFollowBlock, fromBlock + this.eth1GetLogsBatchSizeDynamic - 1); - let depositEvents; + let depositEvents: phase0.DepositEvent[]; try { depositEvents = await this.eth1Provider.getDepositEvents(fromBlock, toBlock); // Increase the batch size linearly even if we scale down exponentially (half each time) @@ -313,7 +313,7 @@ export class Eth1DepositDataTracker { lastProcessedDepositBlockNumber ); - let blocksRaw; + let blocksRaw: EthJsonRpcBlockRaw[]; try { blocksRaw = await this.eth1Provider.getBlocksByNumber(fromBlock, toBlock); // Increase the batch size linearly even if we scale down exponentially (half each time) @@ -380,26 +380,24 @@ export class Eth1DepositDataTracker { this.eth1FollowDistance = Math.min(this.eth1FollowDistance + delta, this.config.ETH1_FOLLOW_DISTANCE); return true; - } else { - // Blocks are slower than expected, reduce eth1FollowDistance. Limit min CATCHUP_MIN_FOLLOW_DISTANCE - const delta = - this.eth1FollowDistance - - Math.max(this.eth1FollowDistance - ETH1_FOLLOW_DISTANCE_DELTA_IF_SLOW, ETH_MIN_FOLLOW_DISTANCE); - this.eth1FollowDistance = this.eth1FollowDistance - delta; - - // Even if the blocks are slow, when we are all caught up as there is no - // further possibility to reduce follow distance, we need to call it quits - // for now, else it leads to an incessant poll on the EL - return delta === 0; } + // Blocks are slower than expected, reduce eth1FollowDistance. Limit min CATCHUP_MIN_FOLLOW_DISTANCE + const delta = + this.eth1FollowDistance - + Math.max(this.eth1FollowDistance - ETH1_FOLLOW_DISTANCE_DELTA_IF_SLOW, ETH_MIN_FOLLOW_DISTANCE); + this.eth1FollowDistance = this.eth1FollowDistance - delta; + + // Even if the blocks are slow, when we are all caught up as there is no + // further possibility to reduce follow distance, we need to call it quits + // for now, else it leads to an incessant poll on the EL + return delta === 0; } private getFromBlockToFetch(lastCachedBlock: number | null): number { if (lastCachedBlock === null) { return this.eth1Provider.deployBlock ?? 0; - } else { - return lastCachedBlock + 1; } + return lastCachedBlock + 1; } private async getLastProcessedDepositBlockNumber(): Promise { diff --git a/packages/beacon-node/src/eth1/eth1DepositsCache.ts b/packages/beacon-node/src/eth1/eth1DepositsCache.ts index 2fb187d02cf7..13dd29013124 100644 --- a/packages/beacon-node/src/eth1/eth1DepositsCache.ts +++ b/packages/beacon-node/src/eth1/eth1DepositsCache.ts @@ -129,7 +129,7 @@ export class Eth1DepositsCache { */ async getHighestDepositEventBlockNumber(): Promise { const latestEvent = await this.db.depositEvent.lastValue(); - return latestEvent && latestEvent.blockNumber; + return latestEvent?.blockNumber || null; } /** @@ -137,6 +137,6 @@ export class Eth1DepositsCache { */ async getLowestDepositEventBlockNumber(): Promise { const firstEvent = await this.db.depositEvent.firstValue(); - return firstEvent && firstEvent.blockNumber; + return firstEvent?.blockNumber || null; } } diff --git a/packages/beacon-node/src/eth1/eth1MergeBlockTracker.ts b/packages/beacon-node/src/eth1/eth1MergeBlockTracker.ts index 9ba4a09a5549..5bf76625dfe8 100644 --- a/packages/beacon-node/src/eth1/eth1MergeBlockTracker.ts +++ b/packages/beacon-node/src/eth1/eth1MergeBlockTracker.ts @@ -126,11 +126,10 @@ export class Eth1MergeBlockTracker { td: this.latestEth1Block.totalDifficulty, timestamp: this.latestEth1Block.timestamp, }; - } else { - return { - ttdHit: true, - }; } + return { + ttdHit: true, + }; } /** @@ -167,7 +166,6 @@ export class Eth1MergeBlockTracker { this.status = {code: StatusCode.SEARCHING}; this.logger.info("Starting search for terminal POW block", { - // eslint-disable-next-line @typescript-eslint/naming-convention TERMINAL_TOTAL_DIFFICULTY: this.config.TERMINAL_TOTAL_DIFFICULTY, }); @@ -194,7 +192,7 @@ export class Eth1MergeBlockTracker { // Persist found merge block here to affect both caller paths: // - internal searcher // - external caller if STOPPED - if (mergeBlock && this.status.code != StatusCode.FOUND) { + if (mergeBlock && this.status.code !== StatusCode.FOUND) { if (this.status.code === StatusCode.SEARCHING) { this.close(); } @@ -243,61 +241,56 @@ export class Eth1MergeBlockTracker { const block = await this.getPowBlock(terminalBlockHash); if (block) { return block; - } else { - // if a TERMINAL_BLOCK_HASH other than ZERO_HASH is configured and we can't find it, return NONE - return null; } + // if a TERMINAL_BLOCK_HASH other than ZERO_HASH is configured and we can't find it, return NONE + return null; } // Search merge block by TTD - else { - const latestBlockRaw = await this.eth1Provider.getBlockByNumber("latest"); - if (!latestBlockRaw) { - throw Error("getBlockByNumber('latest') returned null"); - } - - let block = toPowBlock(latestBlockRaw); - this.latestEth1Block = {...block, timestamp: quantityToNum(latestBlockRaw.timestamp)}; - this.cacheBlock(block); + const latestBlockRaw = await this.eth1Provider.getBlockByNumber("latest"); + if (!latestBlockRaw) { + throw Error("getBlockByNumber('latest') returned null"); + } - // This code path to look backwards for the merge block is only necessary if: - // - The network has not yet found the merge block - // - There are descendants of the merge block in the eth1 chain - // For the search below to require more than a few hops, multiple block proposers in a row must fail to detect - // an existing merge block. Such situation is extremely unlikely, so this search is left un-optimized. Since - // this class can start eagerly looking for the merge block when not necessary, startPollingMergeBlock() should - // only be called when there is certainty that a mergeBlock search is necessary. - - // eslint-disable-next-line no-constant-condition - while (true) { - if (block.totalDifficulty < this.config.TERMINAL_TOTAL_DIFFICULTY) { - // TTD not reached yet - return null; - } + let block = toPowBlock(latestBlockRaw); + this.latestEth1Block = {...block, timestamp: quantityToNum(latestBlockRaw.timestamp)}; + this.cacheBlock(block); + + // This code path to look backwards for the merge block is only necessary if: + // - The network has not yet found the merge block + // - There are descendants of the merge block in the eth1 chain + // For the search below to require more than a few hops, multiple block proposers in a row must fail to detect + // an existing merge block. Such situation is extremely unlikely, so this search is left un-optimized. Since + // this class can start eagerly looking for the merge block when not necessary, startPollingMergeBlock() should + // only be called when there is certainty that a mergeBlock search is necessary. + + while (true) { + if (block.totalDifficulty < this.config.TERMINAL_TOTAL_DIFFICULTY) { + // TTD not reached yet + return null; + } - // else block.totalDifficulty >= this.config.TERMINAL_TOTAL_DIFFICULTY - // Potential mergeBlock! Must find the first block that passes TTD + // else block.totalDifficulty >= this.config.TERMINAL_TOTAL_DIFFICULTY + // Potential mergeBlock! Must find the first block that passes TTD - // Allow genesis block to reach TTD https://github.com/ethereum/consensus-specs/pull/2719 - if (block.parentHash === ZERO_HASH_HEX) { - return block; - } + // Allow genesis block to reach TTD https://github.com/ethereum/consensus-specs/pull/2719 + if (block.parentHash === ZERO_HASH_HEX) { + return block; + } - const parent = await this.getPowBlock(block.parentHash); - if (!parent) { - throw Error(`Unknown parent of block with TD>TTD ${block.parentHash}`); - } + const parent = await this.getPowBlock(block.parentHash); + if (!parent) { + throw Error(`Unknown parent of block with TD>TTD ${block.parentHash}`); + } - this.metrics?.eth1.eth1ParentBlocksFetched.inc(); + this.metrics?.eth1.eth1ParentBlocksFetched.inc(); - // block.td > TTD && parent.td < TTD => block is mergeBlock - if (parent.totalDifficulty < this.config.TERMINAL_TOTAL_DIFFICULTY) { - // Is terminal total difficulty block AND has verified block -> parent relationship - return block; - } else { - block = parent; - } + // block.td > TTD && parent.td < TTD => block is mergeBlock + if (parent.totalDifficulty < this.config.TERMINAL_TOTAL_DIFFICULTY) { + // Is terminal total difficulty block AND has verified block -> parent relationship + return block; } + block = parent; } } diff --git a/packages/beacon-node/src/eth1/index.ts b/packages/beacon-node/src/eth1/index.ts index 7b2ec17496d3..42b82d03a848 100644 --- a/packages/beacon-node/src/eth1/index.ts +++ b/packages/beacon-node/src/eth1/index.ts @@ -53,9 +53,8 @@ export function initializeEth1ForBlockProduction( logger: modules.logger, signal: modules.signal, }); - } else { - return new Eth1ForBlockProductionDisabled(); } + return new Eth1ForBlockProductionDisabled(); } export class Eth1ForBlockProduction implements IEth1ForBlockProduction { @@ -85,9 +84,8 @@ export class Eth1ForBlockProduction implements IEth1ForBlockProduction { async getEth1DataAndDeposits(state: CachedBeaconStateAllForks): Promise { if (this.eth1DepositDataTracker === null) { return {eth1Data: state.eth1Data, deposits: []}; - } else { - return this.eth1DepositDataTracker.getEth1DataAndDeposits(state); } + return this.eth1DepositDataTracker.getEth1DataAndDeposits(state); } async getTerminalPowBlock(): Promise { @@ -104,11 +102,11 @@ export class Eth1ForBlockProduction implements IEth1ForBlockProduction { } startPollingMergeBlock(): void { - return this.eth1MergeBlockTracker.startPollingMergeBlock(); + this.eth1MergeBlockTracker.startPollingMergeBlock(); } stopPollingEth1Data(): void { - return this.eth1DepositDataTracker?.stopPollingEth1Data(); + this.eth1DepositDataTracker?.stopPollingEth1Data(); } } diff --git a/packages/beacon-node/src/eth1/provider/eth1Provider.ts b/packages/beacon-node/src/eth1/provider/eth1Provider.ts index c86991eb7d15..d284700ddb1d 100644 --- a/packages/beacon-node/src/eth1/provider/eth1Provider.ts +++ b/packages/beacon-node/src/eth1/provider/eth1Provider.ts @@ -21,8 +21,6 @@ import { } from "./jsonRpcHttpClient.js"; import {isJsonRpcTruncatedError, quantityToNum, numToQuantity, dataToBytes} from "./utils.js"; -/* eslint-disable @typescript-eslint/naming-convention */ - /** * Binds return types to Ethereum JSON RPC methods */ diff --git a/packages/beacon-node/src/eth1/provider/jsonRpcHttpClient.ts b/packages/beacon-node/src/eth1/provider/jsonRpcHttpClient.ts index cbe70ecb7e18..f2ceae0d8c19 100644 --- a/packages/beacon-node/src/eth1/provider/jsonRpcHttpClient.ts +++ b/packages/beacon-node/src/eth1/provider/jsonRpcHttpClient.ts @@ -1,4 +1,4 @@ -import {EventEmitter} from "events"; +import {EventEmitter} from "node:events"; import {StrictEventEmitter} from "strict-event-emitter-types"; import {fetch} from "@lodestar/api"; import {ErrorAborted, Gauge, Histogram, TimeoutError, isValidHttpUrl, retry} from "@lodestar/utils"; @@ -268,7 +268,7 @@ export class JsonRpcHttpClient implements IJsonRpcHttpClient { }; const token = encodeJwtToken(jwtClaim, this.jwtSecret); - headers["Authorization"] = `Bearer ${token}`; + headers.Authorization = `Bearer ${token}`; } const res = await fetch(url, { @@ -296,12 +296,10 @@ export class JsonRpcHttpClient implements IJsonRpcHttpClient { // controller will abort on both parent signal abort + timeout of this specific request if (this.opts?.signal?.aborted) { throw new ErrorAborted("request"); - } else { - throw new TimeoutError("request"); } - } else { - throw e; + throw new TimeoutError("request"); } + throw e; } finally { timer?.(); this.metrics?.activeRequests.dec({routeId}, 1); @@ -315,11 +313,11 @@ export class JsonRpcHttpClient implements IJsonRpcHttpClient { function parseRpcResponse(res: RpcResponse, payload: RpcPayload

): R { if (res.result !== undefined) { return res.result; - } else if (res.error !== undefined) { + } + if (res.error !== undefined) { throw new ErrorJsonRpcResponse(res, payload.method); - } else { - throw Error(`Invalid JSON RPC response, no result or error property: ${jsonSerializeTry(res)}`); } + throw Error(`Invalid JSON RPC response, no result or error property: ${jsonSerializeTry(res)}`); } /** diff --git a/packages/beacon-node/src/eth1/provider/jwt.ts b/packages/beacon-node/src/eth1/provider/jwt.ts index da1fc1827cdd..1e267120957f 100644 --- a/packages/beacon-node/src/eth1/provider/jwt.ts +++ b/packages/beacon-node/src/eth1/provider/jwt.ts @@ -2,7 +2,6 @@ import type {TAlgorithm} from "jwt-simple"; // TODO: fix jwt-simple types import jwt from "jwt-simple"; -// eslint-disable-next-line import/no-named-as-default-member const {encode, decode} = jwt; /** diff --git a/packages/beacon-node/src/eth1/provider/utils.ts b/packages/beacon-node/src/eth1/provider/utils.ts index 096f1d7233c8..7010e1377ca6 100644 --- a/packages/beacon-node/src/eth1/provider/utils.ts +++ b/packages/beacon-node/src/eth1/provider/utils.ts @@ -53,7 +53,7 @@ export function numToQuantity(num: number | bigint): QUANTITY { */ export function quantityToNum(hex: QUANTITY, id = ""): number { const num = parseInt(hex, 16); - if (isNaN(num) || num < 0) throw Error(`Invalid hex decimal ${id} '${hex}'`); + if (Number.isNaN(num) || num < 0) throw Error(`Invalid hex decimal ${id} '${hex}'`); return num; } diff --git a/packages/beacon-node/src/eth1/utils/deposits.ts b/packages/beacon-node/src/eth1/utils/deposits.ts index 8d0331fc01d6..36f8c331ebc9 100644 --- a/packages/beacon-node/src/eth1/utils/deposits.ts +++ b/packages/beacon-node/src/eth1/utils/deposits.ts @@ -33,7 +33,9 @@ export async function getDeposits( if (deposits.length < depositsLen) { throw new Eth1Error({code: Eth1ErrorCode.NOT_ENOUGH_DEPOSITS, len: deposits.length, expectedLen: depositsLen}); - } else if (deposits.length > depositsLen) { + } + + if (deposits.length > depositsLen) { throw new Eth1Error({code: Eth1ErrorCode.TOO_MANY_DEPOSITS, len: deposits.length, expectedLen: depositsLen}); } diff --git a/packages/beacon-node/src/eth1/utils/eth1Vote.ts b/packages/beacon-node/src/eth1/utils/eth1Vote.ts index 7a4e3ddca9b6..84d35ae7d434 100644 --- a/packages/beacon-node/src/eth1/utils/eth1Vote.ts +++ b/packages/beacon-node/src/eth1/utils/eth1Vote.ts @@ -72,16 +72,14 @@ export function pickEth1Vote(state: BeaconStateAllForks, votesToConsider: phase0 } // If there's a single winning vote with a majority vote that one - else if (eth1DataRootsMaxVotes.length === 1) { + if (eth1DataRootsMaxVotes.length === 1) { return eth1DataHashToEth1Data.get(eth1DataRootsMaxVotes[0]) ?? state.eth1Data; } // If there are multiple winning votes, vote for the latest one - else { - const latestMostVotedRoot = - eth1DataVotesOrder[Math.max(...eth1DataRootsMaxVotes.map((root) => eth1DataVotesOrder.indexOf(root)))]; - return eth1DataHashToEth1Data.get(latestMostVotedRoot) ?? state.eth1Data; - } + const latestMostVotedRoot = + eth1DataVotesOrder[Math.max(...eth1DataRootsMaxVotes.map((root) => eth1DataVotesOrder.indexOf(root)))]; + return eth1DataHashToEth1Data.get(latestMostVotedRoot) ?? state.eth1Data; } /** diff --git a/packages/beacon-node/src/eth1/utils/optimizeNextBlockDiffForGenesis.ts b/packages/beacon-node/src/eth1/utils/optimizeNextBlockDiffForGenesis.ts index 4dc633693580..961d58680e47 100644 --- a/packages/beacon-node/src/eth1/utils/optimizeNextBlockDiffForGenesis.ts +++ b/packages/beacon-node/src/eth1/utils/optimizeNextBlockDiffForGenesis.ts @@ -13,7 +13,6 @@ export function optimizeNextBlockDiffForGenesis( const numBlocksToGenesis = Math.floor(timeToGenesis / params.SECONDS_PER_ETH1_BLOCK); if (numBlocksToGenesis <= 2) { return 1; - } else { - return Math.max(1, Math.floor(numBlocksToGenesis / 2)); } + return Math.max(1, Math.floor(numBlocksToGenesis / 2)); } diff --git a/packages/beacon-node/src/execution/builder/http.ts b/packages/beacon-node/src/execution/builder/http.ts index 934b874f5ae3..7bc47e354c6c 100644 --- a/packages/beacon-node/src/execution/builder/http.ts +++ b/packages/beacon-node/src/execution/builder/http.ts @@ -37,6 +37,12 @@ export const defaultExecutionBuilderHttpOpts: ExecutionBuilderHttpOpts = { timeout: 12000, }; +/** + * Duration given to the builder to provide a `SignedBuilderBid` before the deadline + * is reached, aborting the external builder flow in favor of the local build process. + */ +const BUILDER_PROPOSAL_DELAY_TOLERANCE = 1000; + export class ExecutionBuilderHttp implements IExecutionBuilder { readonly api: BuilderApi; readonly config: ChainForkConfig; @@ -62,7 +68,7 @@ export class ExecutionBuilderHttp implements IExecutionBuilder { headers: opts.userAgent ? {"User-Agent": opts.userAgent} : undefined, }, }, - {config, metrics: metrics?.builderHttpClient} + {config, metrics: metrics?.builderHttpClient, logger} ); logger?.info("External builder", {url: toPrintableUrl(baseUrl)}); this.config = config; @@ -115,7 +121,9 @@ export class ExecutionBuilderHttp implements IExecutionBuilder { executionPayloadValue: Wei; blobKzgCommitments?: deneb.BlobKzgCommitments; }> { - const signedBuilderBid = (await this.api.getHeader({slot, parentHash, proposerPubkey})).value(); + const signedBuilderBid = ( + await this.api.getHeader({slot, parentHash, proposerPubkey}, {timeoutMs: BUILDER_PROPOSAL_DELAY_TOLERANCE}) + ).value(); if (!signedBuilderBid) { throw Error("No bid received"); diff --git a/packages/beacon-node/src/execution/builder/index.ts b/packages/beacon-node/src/execution/builder/index.ts index 2f584ad7dadd..fff66a3e8bc5 100644 --- a/packages/beacon-node/src/execution/builder/index.ts +++ b/packages/beacon-node/src/execution/builder/index.ts @@ -18,6 +18,7 @@ export function initializeExecutionBuilder( ): IExecutionBuilder { switch (opts.mode) { case "http": + return new ExecutionBuilderHttp(opts, config, metrics, logger); default: return new ExecutionBuilderHttp(opts, config, metrics, logger); } diff --git a/packages/beacon-node/src/execution/engine/http.ts b/packages/beacon-node/src/execution/engine/http.ts index b42424b28998..e5e65746d90f 100644 --- a/packages/beacon-node/src/execution/engine/http.ts +++ b/packages/beacon-node/src/execution/engine/http.ts @@ -258,9 +258,8 @@ export class ExecutionEngineHttp implements IExecutionEngine { ).catch((e: Error) => { if (e instanceof HttpRpcError || e instanceof ErrorJsonRpcResponse) { return {status: ExecutionPayloadStatus.ELERROR, latestValidHash: null, validationError: e.message}; - } else { - return {status: ExecutionPayloadStatus.UNAVAILABLE, latestValidHash: null, validationError: e.message}; } + return {status: ExecutionPayloadStatus.UNAVAILABLE, latestValidHash: null, validationError: e.message}; }); this.updateEngineState(getExecutionEngineState({payloadStatus: status, oldState: this.state})); @@ -379,9 +378,8 @@ export class ExecutionEngineHttp implements IExecutionEngine { // Throw error on syncing if requested to produce a block, else silently ignore if (payloadAttributes) { throw Error("Execution Layer Syncing"); - } else { - return null; } + return null; case ExecutionPayloadStatus.INVALID: throw Error( @@ -437,7 +435,7 @@ export class ExecutionEngineHttp implements IExecutionEngine { this.payloadIdCache.prune(); } - async getPayloadBodiesByHash(fork: ForkName, blockHashes: RootHex[]): Promise<(ExecutionPayloadBody | null)[]> { + async getPayloadBodiesByHash(_fork: ForkName, blockHashes: RootHex[]): Promise<(ExecutionPayloadBody | null)[]> { const method = "engine_getPayloadBodiesByHashV1"; assertReqSizeLimit(blockHashes.length, 32); const response = await this.rpc.fetchWithRetries< @@ -448,7 +446,7 @@ export class ExecutionEngineHttp implements IExecutionEngine { } async getPayloadBodiesByRange( - fork: ForkName, + _fork: ForkName, startBlockNumber: number, blockCount: number ): Promise<(ExecutionPayloadBody | null)[]> { diff --git a/packages/beacon-node/src/execution/engine/index.ts b/packages/beacon-node/src/execution/engine/index.ts index a8b878502aff..dd2de2017c22 100644 --- a/packages/beacon-node/src/execution/engine/index.ts +++ b/packages/beacon-node/src/execution/engine/index.ts @@ -55,6 +55,8 @@ export function initializeExecutionEngine( return getExecutionEngineFromBackend(new ExecutionEngineMockBackend(opts), modules); case "http": + return getExecutionEngineHttp(opts, modules); + default: return getExecutionEngineHttp(opts, modules); } diff --git a/packages/beacon-node/src/execution/engine/mock.ts b/packages/beacon-node/src/execution/engine/mock.ts index 4cff2a8d00f4..8062b68bf572 100644 --- a/packages/beacon-node/src/execution/engine/mock.ts +++ b/packages/beacon-node/src/execution/engine/mock.ts @@ -85,7 +85,6 @@ export class ExecutionEngineMockBackend implements JsonRpcBackend { }); this.handlers = { - /* eslint-disable @typescript-eslint/naming-convention */ engine_newPayloadV1: this.notifyNewPayload.bind(this), engine_newPayloadV2: this.notifyNewPayload.bind(this), engine_newPayloadV3: this.notifyNewPayload.bind(this), @@ -150,7 +149,9 @@ export class ExecutionEngineMockBackend implements JsonRpcBackend { const predefinedResponse = this.predefinedPayloadStatuses.get(blockHash); if (predefinedResponse) { return predefinedResponse; - } else if (this.opts.onlyPredefinedResponses) { + } + + if (this.opts.onlyPredefinedResponses) { throw Error(`No predefined response for blockHash ${blockHash}`); } @@ -213,7 +214,9 @@ export class ExecutionEngineMockBackend implements JsonRpcBackend { payloadStatus: predefinedResponse, payloadId: null, }; - } else if (this.opts.onlyPredefinedResponses) { + } + + if (this.opts.onlyPredefinedResponses) { throw Error(`No predefined response for headBlockHash ${headBlockHash}`); } @@ -345,14 +348,12 @@ export class ExecutionEngineMockBackend implements JsonRpcBackend { } // Don't start build process - else { - // IF the payload is deemed VALID and a build process hasn't been started - // {payloadStatus: {status: VALID, latestValidHash: forkchoiceState.headBlockHash, validationError: null}, payloadId: null} - return { - payloadStatus: {status: ExecutionPayloadStatus.VALID, latestValidHash: null, validationError: null}, - payloadId: null, - }; - } + // IF the payload is deemed VALID and a build process hasn't been started + // {payloadStatus: {status: VALID, latestValidHash: forkchoiceState.headBlockHash, validationError: null}, payloadId: null} + return { + payloadStatus: {status: ExecutionPayloadStatus.VALID, latestValidHash: null, validationError: null}, + payloadId: null, + }; } /** diff --git a/packages/beacon-node/src/execution/engine/types.ts b/packages/beacon-node/src/execution/engine/types.ts index 32fe4cb79d3d..9b4f5e5c83e6 100644 --- a/packages/beacon-node/src/execution/engine/types.ts +++ b/packages/beacon-node/src/execution/engine/types.ts @@ -19,8 +19,6 @@ import { import {ExecutionPayloadStatus, BlobsBundle, PayloadAttributes, VersionedHashes} from "./interface.js"; import {WithdrawalV1} from "./payloadIdCache.js"; -/* eslint-disable @typescript-eslint/naming-convention */ - export type EngineApiRpcParamTypes = { /** * 1. Object - Instance of ExecutionPayload diff --git a/packages/beacon-node/src/execution/engine/utils.ts b/packages/beacon-node/src/execution/engine/utils.ts index b56f62bf602b..4d84eda52c44 100644 --- a/packages/beacon-node/src/execution/engine/utils.ts +++ b/packages/beacon-node/src/execution/engine/utils.ts @@ -12,7 +12,7 @@ import {isQueueErrorAborted} from "../../util/queue/errors.js"; import {ExecutionPayloadStatus, ExecutionEngineState} from "./interface.js"; export type JsonRpcBackend = { - // eslint-disable-next-line @typescript-eslint/no-explicit-any + // biome-ignore lint/suspicious/noExplicitAny: readonly handlers: Record any>; }; @@ -27,8 +27,7 @@ export class ExecutionEngineMockJsonRpcClient implements IJsonRpcHttpClient { if (handler === undefined) { throw Error(`Unknown method ${payload.method}`); } - - // eslint-disable-next-line @typescript-eslint/no-explicit-any + // biome-ignore lint/suspicious/noExplicitAny: return handler(...(payload.params as any[])) as R; }, payload); } diff --git a/packages/beacon-node/src/metrics/metrics/beacon.ts b/packages/beacon-node/src/metrics/metrics/beacon.ts index 949999dbb1f4..685fd56674ad 100644 --- a/packages/beacon-node/src/metrics/metrics/beacon.ts +++ b/packages/beacon-node/src/metrics/metrics/beacon.ts @@ -11,7 +11,6 @@ export type BeaconMetrics = ReturnType; * https://github.com/ethereum/beacon-metrics/ and * https://hackmd.io/D5FmoeFZScim_squBFl8oA */ -// eslint-disable-next-line @typescript-eslint/explicit-function-return-type export function createBeaconMetrics(register: RegistryMetricCreator) { return { // From https://github.com/ethereum/beacon-metrics/blob/master/metrics.md @@ -59,11 +58,11 @@ export function createBeaconMetrics(register: RegistryMetricCreator) { // Non-spec'ed forkChoice: { - findHead: register.histogram<{entrypoint: string}>({ + findHead: register.histogram<{caller: string}>({ name: "beacon_fork_choice_find_head_seconds", help: "Time taken to find head in seconds", buckets: [0.1, 1, 10], - labelNames: ["entrypoint"], + labelNames: ["caller"], }), requests: register.gauge({ name: "beacon_fork_choice_requests_total", @@ -95,7 +94,7 @@ export function createBeaconMetrics(register: RegistryMetricCreator) { }), queuedAttestations: register.gauge({ name: "beacon_fork_choice_queued_attestations_count", - help: "Current count of queued_attestations in fork choice data structures", + help: "Count of queued_attestations in fork choice per slot", }), validatedAttestationDatas: register.gauge({ name: "beacon_fork_choice_validated_attestation_datas_count", diff --git a/packages/beacon-node/src/metrics/metrics/lodestar.ts b/packages/beacon-node/src/metrics/metrics/lodestar.ts index bac740b7ee04..f15e195faa20 100644 --- a/packages/beacon-node/src/metrics/metrics/lodestar.ts +++ b/packages/beacon-node/src/metrics/metrics/lodestar.ts @@ -25,7 +25,6 @@ export type LodestarMetrics = ReturnType; /** * Extra Lodestar custom metrics */ -// eslint-disable-next-line @typescript-eslint/explicit-function-return-type export function createLodestarMetrics( register: RegistryMetricCreator, metadata?: LodestarMetadata, diff --git a/packages/beacon-node/src/metrics/validatorMonitor.ts b/packages/beacon-node/src/metrics/validatorMonitor.ts index 34dfa6b72e03..14a210f62997 100644 --- a/packages/beacon-node/src/metrics/validatorMonitor.ts +++ b/packages/beacon-node/src/metrics/validatorMonitor.ts @@ -814,7 +814,7 @@ function renderAttestationSummary( } // - else if (flags.timelyTarget) { + if (flags.timelyTarget) { // timelyHead == false, means at least one is true // - attestation voted incorrect head // - attestation was included late @@ -870,57 +870,55 @@ function renderAttestationSummary( } // - else if (flags.timelySource) { + if (flags.timelySource) { // timelyTarget == false && timelySource == true means that // - attestation voted the wrong target but distance is <= integer_squareroot(SLOTS_PER_EPOCH) return "wrong_target_timely_source"; } // - else { - // timelySource == false, either: - // - attestation was not included in the block - // - included in block with wrong target (very unlikely) - // - included in block with distance > SLOTS_PER_EPOCH (very unlikely) - - // Validator failed to submit an attestation for this epoch, validator client is probably offline - if (!summary || summary.poolSubmitDelayMinSec === null) { - return "no_submission"; - } + // timelySource == false, either: + // - attestation was not included in the block + // - included in block with wrong target (very unlikely) + // - included in block with distance > SLOTS_PER_EPOCH (very unlikely) + + // Validator failed to submit an attestation for this epoch, validator client is probably offline + if (!summary || summary.poolSubmitDelayMinSec === null) { + return "no_submission"; + } - const canonicalBlockInclusion = summary.blockInclusions.find((block) => isCanonical(rootCache, block)); - if (canonicalBlockInclusion) { - // Canonical block inclusion with no participation flags set means wrong target + late source - return "wrong_target_late_source"; - } + const canonicalBlockInclusion = summary.blockInclusions.find((block) => isCanonical(rootCache, block)); + if (canonicalBlockInclusion) { + // Canonical block inclusion with no participation flags set means wrong target + late source + return "wrong_target_late_source"; + } - const submittedLate = - summary.poolSubmitDelayMinSec > - (INTERVALS_LATE_ATTESTATION_SUBMISSION * config.SECONDS_PER_SLOT) / INTERVALS_PER_SLOT; - - const aggregateInclusion = summary.aggregateInclusionDelaysSec.length > 0; - - if (submittedLate && aggregateInclusion) { - return "late_submit"; - } else if (submittedLate && !aggregateInclusion) { - return "late_submit_no_aggregate_inclusion"; - } else if (!submittedLate && aggregateInclusion) { - // TODO: Why was it missed then? - if (summary.blockInclusions.length) { - return "block_inclusion_but_orphan"; - } else { - return "aggregate_inclusion_but_missed"; - } - // } else if (!submittedLate && !aggregateInclusion) { - } else { - // Did the node had enough peers? - if (summary.poolSubmitSentPeers === 0) { - return "sent_to_zero_peers"; - } else { - return "no_aggregate_inclusion"; - } + const submittedLate = + summary.poolSubmitDelayMinSec > + (INTERVALS_LATE_ATTESTATION_SUBMISSION * config.SECONDS_PER_SLOT) / INTERVALS_PER_SLOT; + + const aggregateInclusion = summary.aggregateInclusionDelaysSec.length > 0; + + if (submittedLate && aggregateInclusion) { + return "late_submit"; + } + if (submittedLate && !aggregateInclusion) { + return "late_submit_no_aggregate_inclusion"; + } + + if (!submittedLate && aggregateInclusion) { + // TODO: Why was it missed then? + if (summary.blockInclusions.length) { + return "block_inclusion_but_orphan"; } + return "aggregate_inclusion_but_missed"; + // } else if (!submittedLate && !aggregateInclusion) { } + // Did the node had enough peers? + if (summary.poolSubmitSentPeers === 0) { + return "sent_to_zero_peers"; + } + return "no_aggregate_inclusion"; } function whyIsHeadVoteWrong(rootCache: RootHexCache, canonicalBlockInclusion: AttestationBlockInclusion): string { @@ -968,9 +966,7 @@ function whyIsHeadVoteWrong(rootCache: RootHexCache, canonicalBlockInclusion: At // \_(A)_(A) // // Vote for different heads on skipped slot - else { - return "wrong_head_vote"; - } + return "wrong_head_vote"; } function whyIsDistanceNotOk( @@ -989,9 +985,7 @@ function whyIsDistanceNotOk( } // - else { - return "late_unknown"; - } + return "late_unknown"; } /** Returns true if the state's root record includes `block` */ diff --git a/packages/beacon-node/src/monitoring/properties.ts b/packages/beacon-node/src/monitoring/properties.ts index 55b94dd159b7..2ab819179863 100644 --- a/packages/beacon-node/src/monitoring/properties.ts +++ b/packages/beacon-node/src/monitoring/properties.ts @@ -140,11 +140,11 @@ export class MetricProperty implements ClientStatsPropert case JsonType.Boolean: if (this.definition.rangeValue != null) { return value === this.definition.rangeValue; - } else if (this.definition.threshold != null) { + } + if (this.definition.threshold != null) { return value >= this.definition.threshold; - } else { - return value > 0; } + return value > 0; } } return value; diff --git a/packages/beacon-node/src/monitoring/service.ts b/packages/beacon-node/src/monitoring/service.ts index 9581c5f11c92..f6a6a2352e02 100644 --- a/packages/beacon-node/src/monitoring/service.ts +++ b/packages/beacon-node/src/monitoring/service.ts @@ -191,11 +191,11 @@ export class MonitoringService { // error was thrown by abort signal if (signal.reason === FetchAbortReason.Close) { throw new ErrorAborted("request"); - } else if (signal.reason === FetchAbortReason.Timeout) { + } + if (signal.reason === FetchAbortReason.Timeout) { throw new TimeoutError("request"); - } else { - throw e; } + throw e; } finally { timer({status: res?.ok ? SendDataStatus.Success : SendDataStatus.Error}); clearTimeout(timeout); @@ -229,7 +229,7 @@ export class MonitoringService { } return url; - } catch { + } catch (_e) { throw new Error(`Monitoring endpoint must be a valid URL: ${endpoint}`); } } diff --git a/packages/beacon-node/src/monitoring/system.ts b/packages/beacon-node/src/monitoring/system.ts index a1a79b1bd277..83507443be01 100644 --- a/packages/beacon-node/src/monitoring/system.ts +++ b/packages/beacon-node/src/monitoring/system.ts @@ -3,7 +3,6 @@ import os from "node:os"; import path from "node:path"; // We want to keep `system` export as it's more readable and easier to understand -// eslint-disable-next-line import/no-named-as-default import system from "systeminformation"; import {Logger} from "@lodestar/utils"; diff --git a/packages/beacon-node/src/network/core/metrics.ts b/packages/beacon-node/src/network/core/metrics.ts index c267ec069d88..7d0ef47d84af 100644 --- a/packages/beacon-node/src/network/core/metrics.ts +++ b/packages/beacon-node/src/network/core/metrics.ts @@ -5,7 +5,6 @@ import {SubnetSource} from "../subnets/attnetsService.js"; export type NetworkCoreMetrics = ReturnType; -// eslint-disable-next-line @typescript-eslint/explicit-function-return-type export function createNetworkCoreMetrics(register: RegistryMetricCreator) { return { register, @@ -254,7 +253,6 @@ export function createNetworkCoreMetrics(register: RegistryMetricCreator) { export type NetworkCoreWorkerMetrics = ReturnType; -// eslint-disable-next-line @typescript-eslint/explicit-function-return-type export function getNetworkCoreWorkerMetrics(register: RegistryMetricCreator) { return { reqRespBridgeRespCallerPending: register.gauge({ diff --git a/packages/beacon-node/src/network/core/networkCore.ts b/packages/beacon-node/src/network/core/networkCore.ts index 83ef4c4fb063..b000d184e0eb 100644 --- a/packages/beacon-node/src/network/core/networkCore.ts +++ b/packages/beacon-node/src/network/core/networkCore.ts @@ -1,4 +1,4 @@ -import {Connection, PeerId} from "@libp2p/interface"; +import {Connection, PrivateKey} from "@libp2p/interface"; import {multiaddr} from "@multiformats/multiaddr"; import {PublishOpts} from "@chainsafe/libp2p-gossipsub/types"; import {PeerScoreStatsDump} from "@chainsafe/libp2p-gossipsub/dist/src/score/peer-score.js"; @@ -55,7 +55,7 @@ type Mods = { export type BaseNetworkInit = { opts: NetworkOptions; config: BeaconConfig; - peerId: PeerId; + privateKey: PrivateKey; peerStoreDir: string | undefined; logger: LoggerNode; metricsRegistry: RegistryMetricCreator | null; @@ -126,7 +126,7 @@ export class NetworkCore implements INetworkCore { static async init({ opts, config, - peerId, + privateKey, peerStoreDir, logger, metricsRegistry, @@ -136,7 +136,7 @@ export class NetworkCore implements INetworkCore { activeValidatorCount, initialStatus, }: BaseNetworkInit): Promise { - const libp2p = await createNodeJsLibp2p(peerId, opts, { + const libp2p = await createNodeJsLibp2p(privateKey, opts, { peerStoreDir, metrics: Boolean(metricsRegistry), metricsRegistry: metricsRegistry ?? undefined, @@ -149,7 +149,7 @@ export class NetworkCore implements INetworkCore { // Bind discv5's ENR to local metadata // resolve circular dependency by setting `discv5` variable after the peer manager is instantiated - // eslint-disable-next-line prefer-const + // biome-ignore lint/style/useConst: let discv5: Discv5Worker | undefined; const onMetadataSetValue = function onMetadataSetValue(key: string, value: Uint8Array): void { discv5?.setEnrValue(key, value).catch((e) => logger.error("error on setEnrValue", {key}, e)); @@ -200,8 +200,9 @@ export class NetworkCore implements INetworkCore { const peerManager = await PeerManager.init( { + privateKey, libp2p, - gossip: gossip, + gossip, reqResp, attnetsService, syncnetsService, @@ -223,6 +224,7 @@ export class NetworkCore implements INetworkCore { reqResp.registerProtocolsAtFork(forkCurrentSlot); // Bind discv5's ENR to local metadata + // biome-ignore lint/complexity/useLiteralKeys: `discovery` is a private attribute discv5 = peerManager["discovery"]?.discv5; // Initialize ENR with clock's fork @@ -276,6 +278,7 @@ export class NetworkCore implements INetworkCore { async scrapeMetrics(): Promise { return [ (await this.metrics?.register.metrics()) ?? "", + // biome-ignore lint/complexity/useLiteralKeys: `discovery` is a private attribute (await this.peerManager["discovery"]?.discv5.scrapeMetrics()) ?? "", ] .filter((str) => str.length > 0) @@ -343,6 +346,7 @@ export class NetworkCore implements INetworkCore { // REST API queries async getNetworkIdentity(): Promise { + // biome-ignore lint/complexity/useLiteralKeys: `discovery` is a private attribute const enr = await this.peerManager["discovery"]?.discv5.enr(); const discoveryAddresses = [ enr?.getLocationMultiaddr("tcp")?.toString() ?? null, @@ -359,7 +363,11 @@ export class NetworkCore implements INetworkCore { } getConnectionsByPeer(): Map { - return getConnectionsMap(this.libp2p); + const m = new Map(); + for (const [k, v] of getConnectionsMap(this.libp2p).entries()) { + m.set(k, v.value); + } + return m; } async getConnectedPeers(): Promise { @@ -405,6 +413,7 @@ export class NetworkCore implements INetworkCore { } async dumpDiscv5KadValues(): Promise { + // biome-ignore lint/complexity/useLiteralKeys: `discovery` is a private attribute return (await this.peerManager["discovery"]?.discv5?.kadValues())?.map((enr) => enr.encodeTxt()) ?? []; } @@ -421,6 +430,7 @@ export class NetworkCore implements INetworkCore { } async writeDiscv5Profile(durationMs: number, dirpath: string): Promise { + // biome-ignore lint/complexity/useLiteralKeys: `discovery` is a private attribute return this.peerManager["discovery"]?.discv5.writeProfile(durationMs, dirpath) ?? "no discv5"; } @@ -429,6 +439,7 @@ export class NetworkCore implements INetworkCore { } writeDiscv5HeapSnapshot(prefix: string, dirpath: string): Promise { + // biome-ignore lint/complexity/useLiteralKeys: `discovery` is a private attribute return this.peerManager["discovery"]?.discv5.writeHeapSnapshot(prefix, dirpath) ?? Promise.resolve("no discv5"); } diff --git a/packages/beacon-node/src/network/core/networkCoreWorker.ts b/packages/beacon-node/src/network/core/networkCoreWorker.ts index 1df348335582..07b6de828b6c 100644 --- a/packages/beacon-node/src/network/core/networkCoreWorker.ts +++ b/packages/beacon-node/src/network/core/networkCoreWorker.ts @@ -3,7 +3,8 @@ import path from "node:path"; import worker from "node:worker_threads"; import type {ModuleThread} from "@chainsafe/threads"; import {expose} from "@chainsafe/threads/worker"; -import {createFromProtobuf} from "@libp2p/peer-id-factory"; +import {privateKeyFromProtobuf} from "@libp2p/crypto/keys"; +import {peerIdFromPrivateKey} from "@libp2p/peer-id"; import {chainConfigFromJson, createBeaconConfig} from "@lodestar/config"; import {getNodeLogger} from "@lodestar/logger/node"; import {RegistryMetricCreator, collectNodeJSMetrics} from "../../metrics/index.js"; @@ -28,12 +29,12 @@ import { // Cloned data from instantiation const workerData = worker.workerData as NetworkWorkerData; const parentPort = worker.parentPort; -// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions if (!workerData) throw Error("workerData must be defined"); if (!parentPort) throw Error("parentPort must be defined"); const config = createBeaconConfig(chainConfigFromJson(workerData.chainConfigJson), workerData.genesisValidatorsRoot); -const peerId = await createFromProtobuf(workerData.peerIdProto); +const privateKey = privateKeyFromProtobuf(workerData.privateKeyProto); +const peerId = peerIdFromPrivateKey(privateKey); // TODO: Pass options from main thread for logging // TODO: Logging won't be visible in file loggers @@ -93,7 +94,7 @@ if (networkCoreWorkerMetrics) { const core = await NetworkCore.init({ opts: workerData.opts, config, - peerId, + privateKey, peerStoreDir: workerData.peerStoreDir, logger, metricsRegistry: metricsRegister, diff --git a/packages/beacon-node/src/network/core/networkCoreWorkerHandler.ts b/packages/beacon-node/src/network/core/networkCoreWorkerHandler.ts index 19cca27eaaac..e883476b5e65 100644 --- a/packages/beacon-node/src/network/core/networkCoreWorkerHandler.ts +++ b/packages/beacon-node/src/network/core/networkCoreWorkerHandler.ts @@ -3,8 +3,8 @@ import workerThreads from "node:worker_threads"; import {PeerScoreStatsDump} from "@chainsafe/libp2p-gossipsub/dist/src/score/peer-score.js"; import {PublishOpts} from "@chainsafe/libp2p-gossipsub/types"; import {ModuleThread, Thread, Worker, spawn} from "@chainsafe/threads"; -import {PeerId, Secp256k1PeerId} from "@libp2p/interface"; -import {exportToProtobuf} from "@libp2p/peer-id-factory"; +import {PrivateKey} from "@libp2p/interface"; +import {privateKeyToProtobuf} from "@libp2p/crypto/keys"; import {routes} from "@lodestar/api"; import {BeaconConfig, chainConfigToJson} from "@lodestar/config"; import type {LoggerNode} from "@lodestar/logger/node"; @@ -44,7 +44,7 @@ export type WorkerNetworkCoreInitModules = { opts: WorkerNetworkCoreOpts; config: BeaconConfig; logger: LoggerNode; - peerId: PeerId; + privateKey: PrivateKey; events: NetworkEventBus; metrics: Metrics | null; getReqRespHandler: GetReqRespHandlerFn; @@ -103,14 +103,14 @@ export class WorkerNetworkCore implements INetworkCore { } static async init(modules: WorkerNetworkCoreInitModules): Promise { - const {opts, config, peerId} = modules; + const {opts, config, privateKey} = modules; const {genesisTime, peerStoreDir, activeValidatorCount, localMultiaddrs, metricsEnabled, initialStatus} = opts; const workerData: NetworkWorkerData = { opts, chainConfigJson: chainConfigToJson(config), genesisValidatorsRoot: config.genesisValidatorsRoot, - peerIdProto: exportToProtobuf(peerId as Secp256k1PeerId), + privateKeyProto: privateKeyToProtobuf(privateKey), localMultiaddrs, metricsEnabled, peerStoreDir, @@ -136,7 +136,7 @@ export class WorkerNetworkCore implements INetworkCore { resourceLimits: {maxYoungGenerationSizeMb: opts.maxYoungGenerationSizeMb}, } as ConstructorParameters[1]); - // eslint-disable-next-line @typescript-eslint/no-explicit-any + // biome-ignore lint/suspicious/noExplicitAny: const networkThreadApi = (await spawn(worker, { // A Lodestar Node may do very expensive task at start blocking the event loop and causing // the initialization to timeout. The number below is big enough to almost disable the timeout diff --git a/packages/beacon-node/src/network/core/types.ts b/packages/beacon-node/src/network/core/types.ts index 41b7f669eaac..d2f56c8fa2f1 100644 --- a/packages/beacon-node/src/network/core/types.ts +++ b/packages/beacon-node/src/network/core/types.ts @@ -78,7 +78,7 @@ export type NetworkWorkerData = { genesisTime: number; activeValidatorCount: number; initialStatus: phase0.Status; - peerIdProto: Uint8Array; + privateKeyProto: Uint8Array; localMultiaddrs: string[]; metricsEnabled: boolean; peerStoreDir?: string; @@ -90,7 +90,7 @@ export type NetworkWorkerData = { */ export type NetworkWorkerApi = INetworkCorePublic & { // To satisfy the constraint of `ModuleThread` type - // eslint-disable-next-line @typescript-eslint/no-explicit-any + // biome-ignore lint/suspicious/noExplicitAny: [string: string]: (...args: any[]) => Promise | any; // Async method through worker boundary reportPeer(peer: PeerIdStr, action: PeerAction, actionName: string): Promise; diff --git a/packages/beacon-node/src/network/discv5/index.ts b/packages/beacon-node/src/network/discv5/index.ts index b2136658dfe7..34990d404c90 100644 --- a/packages/beacon-node/src/network/discv5/index.ts +++ b/packages/beacon-node/src/network/discv5/index.ts @@ -1,8 +1,8 @@ -import EventEmitter from "events"; -import {PeerId, Secp256k1PeerId} from "@libp2p/interface"; +import EventEmitter from "node:events"; +import {privateKeyToProtobuf} from "@libp2p/crypto/keys"; +import {PrivateKey} from "@libp2p/interface"; import {StrictEventEmitter} from "strict-event-emitter-types"; -import {exportToProtobuf} from "@libp2p/peer-id-factory"; -import {createPrivateKeyFromPeerId, ENR, ENRData, SignableENR} from "@chainsafe/enr"; +import {ENR, ENRData, SignableENR} from "@chainsafe/enr"; import {spawn, Thread, Worker} from "@chainsafe/threads"; import {chainConfigFromJson, chainConfigToJson, BeaconConfig} from "@lodestar/config"; import {LoggerNode} from "@lodestar/logger/node"; @@ -10,7 +10,7 @@ import {NetworkCoreMetrics} from "../core/metrics.js"; import {Discv5WorkerApi, Discv5WorkerData, LodestarDiscv5Opts} from "./types.js"; export type Discv5Opts = { - peerId: PeerId; + privateKey: PrivateKey; discv5: LodestarDiscv5Opts; logger: LoggerNode; config: BeaconConfig; @@ -25,7 +25,6 @@ export type Discv5Events = { * Wrapper class abstracting the details of discv5 worker instantiation and message-passing */ export class Discv5Worker extends (EventEmitter as {new (): StrictEventEmitter}) { - private readonly keypair; private readonly subscription: {unsubscribe: () => void}; private closed = false; @@ -35,14 +34,13 @@ export class Discv5Worker extends (EventEmitter as {new (): StrictEventEmitter this.onDiscovered(enrObj)); } static async init(opts: Discv5Opts): Promise { const workerData: Discv5WorkerData = { enr: opts.discv5.enr, - peerIdProto: exportToProtobuf(opts.peerId as Secp256k1PeerId), + privateKeyProto: privateKeyToProtobuf(opts.privateKey), bindAddrs: opts.discv5.bindAddrs, config: opts.discv5.config ?? {}, bootEnrs: opts.discv5.bootEnrs, @@ -80,7 +78,7 @@ export class Discv5Worker extends (EventEmitter as {new (): StrictEventEmitter { const obj = await this.workerApi.enr(); - return new SignableENR(obj.kvs, obj.seq, this.keypair.privateKey); + return new SignableENR(obj.kvs, obj.seq, this.opts.privateKey.raw); } setEnrValue(key: string, value: Uint8Array): Promise { diff --git a/packages/beacon-node/src/network/discv5/types.ts b/packages/beacon-node/src/network/discv5/types.ts index 63c5cd52b6fe..cbaf2423f87f 100644 --- a/packages/beacon-node/src/network/discv5/types.ts +++ b/packages/beacon-node/src/network/discv5/types.ts @@ -31,7 +31,7 @@ export type LodestarDiscv5Opts = { /** discv5 worker constructor data */ export interface Discv5WorkerData { enr: string; - peerIdProto: Uint8Array; + privateKeyProto: Uint8Array; bindAddrs: BindAddrs; config: Discv5Config; bootEnrs: string[]; diff --git a/packages/beacon-node/src/network/discv5/utils.ts b/packages/beacon-node/src/network/discv5/utils.ts index e5707b483281..699675dfbe38 100644 --- a/packages/beacon-node/src/network/discv5/utils.ts +++ b/packages/beacon-node/src/network/discv5/utils.ts @@ -5,6 +5,7 @@ import {ENRKey} from "../metadata.js"; export enum ENRRelevance { no_tcp = "no_tcp", no_eth2 = "no_eth2", + // biome-ignore lint/style/useNamingConvention: Need to use the this name for network convention unknown_forkDigest = "unknown_forkDigest", relevant = "relevant", } diff --git a/packages/beacon-node/src/network/discv5/worker.ts b/packages/beacon-node/src/network/discv5/worker.ts index be8fdc4af601..40eb08f7af92 100644 --- a/packages/beacon-node/src/network/discv5/worker.ts +++ b/packages/beacon-node/src/network/discv5/worker.ts @@ -1,12 +1,13 @@ import worker from "node:worker_threads"; import path from "node:path"; import fs from "node:fs"; -import {createFromProtobuf} from "@libp2p/peer-id-factory"; import {Multiaddr, multiaddr} from "@multiformats/multiaddr"; import {expose} from "@chainsafe/threads/worker"; import {Observable, Subject} from "@chainsafe/threads/observable"; import {Discv5} from "@chainsafe/discv5"; -import {createPrivateKeyFromPeerId, ENR, ENRData, SignableENR, SignableENRData} from "@chainsafe/enr"; +import {ENR, ENRData, SignableENR, SignableENRData} from "@chainsafe/enr"; +import {privateKeyFromProtobuf} from "@libp2p/crypto/keys"; +import {peerIdFromPrivateKey} from "@libp2p/peer-id"; import {createBeaconConfig} from "@lodestar/config"; import {getNodeLogger} from "@lodestar/logger/node"; import {Gauge} from "@lodestar/utils"; @@ -22,7 +23,6 @@ import {enrRelevance, ENRRelevance} from "./utils.js"; // Cloned data from instatiation const workerData = worker.workerData as Discv5WorkerData; -// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions if (!workerData) throw Error("workerData must be defined"); const logger = getNodeLogger(workerData.loggerOpts); @@ -43,15 +43,15 @@ if (workerData.metrics) { }); } -const peerId = await createFromProtobuf(workerData.peerIdProto); -const keypair = createPrivateKeyFromPeerId(peerId); +const privateKey = privateKeyFromProtobuf(workerData.privateKeyProto); +const peerId = peerIdFromPrivateKey(privateKey); const config = createBeaconConfig(workerData.chainConfig, workerData.genesisValidatorsRoot); // Initialize discv5 const discv5 = Discv5.create({ - enr: SignableENR.decodeTxt(workerData.enr, keypair.privateKey), - peerId, + enr: SignableENR.decodeTxt(workerData.enr, privateKey.raw), + privateKey, bindAddrs: { ip4: (workerData.bindAddrs.ip4 ? multiaddr(workerData.bindAddrs.ip4) : undefined) as Multiaddr, ip6: workerData.bindAddrs.ip6 ? multiaddr(workerData.bindAddrs.ip6) : undefined, diff --git a/packages/beacon-node/src/network/events.ts b/packages/beacon-node/src/network/events.ts index 45759de61073..a95b52394163 100644 --- a/packages/beacon-node/src/network/events.ts +++ b/packages/beacon-node/src/network/events.ts @@ -1,4 +1,4 @@ -import {EventEmitter} from "events"; +import {EventEmitter} from "node:events"; import {PeerId, TopicValidatorResult} from "@libp2p/interface"; import {phase0, RootHex} from "@lodestar/types"; import {BlockInput, NullBlockInput} from "../chain/blocks/types.js"; diff --git a/packages/beacon-node/src/network/forks.ts b/packages/beacon-node/src/network/forks.ts index 47575cf6d9c6..1c613f4cee94 100644 --- a/packages/beacon-node/src/network/forks.ts +++ b/packages/beacon-node/src/network/forks.ts @@ -86,7 +86,6 @@ export function getCurrentAndNextFork( } return { - // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions currentFork: forks[currentForkIdx] || forks[0], nextFork: hasNextFork ? forks[nextForkIdx] : undefined, }; diff --git a/packages/beacon-node/src/network/gossip/encoding.ts b/packages/beacon-node/src/network/gossip/encoding.ts index 7a0c642d8ea4..fe4461f59978 100644 --- a/packages/beacon-node/src/network/gossip/encoding.ts +++ b/packages/beacon-node/src/network/gossip/encoding.ts @@ -29,9 +29,8 @@ const sharedMsgIdBuf = Buffer.alloc(20); export function fastMsgIdFn(rpcMsg: RPC.Message): string { if (rpcMsg.data) { return xxhash.h64Raw(rpcMsg.data, h64Seed).toString(16); - } else { - return "0000000000000000"; } + return "0000000000000000"; } export function msgIdToStrFn(msgId: Uint8Array): string { diff --git a/packages/beacon-node/src/network/gossip/gossipsub.ts b/packages/beacon-node/src/network/gossip/gossipsub.ts index e6977abe8ce6..83bb913325bf 100644 --- a/packages/beacon-node/src/network/gossip/gossipsub.ts +++ b/packages/beacon-node/src/network/gossip/gossipsub.ts @@ -26,7 +26,6 @@ import { GOSSIP_D_LOW, } from "./scoringParameters.js"; -/* eslint-disable @typescript-eslint/naming-convention */ /** As specified in https://github.com/ethereum/consensus-specs/blob/v1.1.10/specs/phase0/p2p-interface.md */ const GOSSIPSUB_HEARTBEAT_INTERVAL = 0.7 * 1000; @@ -122,7 +121,7 @@ export class Eth2Gossipsub extends GossipSub { // TODO: figure out a way to dynamically transition to the size dataTransform: new DataTransformSnappy( gossipTopicCache, - isFinite(config.BELLATRIX_FORK_EPOCH) ? GOSSIP_MAX_SIZE_BELLATRIX : GOSSIP_MAX_SIZE + Number.isFinite(config.BELLATRIX_FORK_EPOCH) ? GOSSIP_MAX_SIZE_BELLATRIX : GOSSIP_MAX_SIZE ), metricsRegister: metricsRegister as MetricsRegister | null, metricsTopicStrToLabel: metricsRegister @@ -136,6 +135,10 @@ export class Eth2Gossipsub extends GossipSub { // if this is false, only publish to mesh peers. If there is not enough GOSSIP_D mesh peers, // publish to some more topic peers to make sure we always publish to at least GOSSIP_D peers floodPublish: !opts?.disableFloodPublish, + // Only send IDONTWANT messages if the message size is larger than this + // This should be large enough to not send IDONTWANT for "small" messages + // See https://github.com/ChainSafe/lodestar/pull/7077#issuecomment-2383679472 + idontwantMinDataSize: 16829, }); this.scoreParams = scoreParams; this.config = config; @@ -181,10 +184,11 @@ export class Eth2Gossipsub extends GossipSub { } private onScrapeLodestarMetrics(metrics: Eth2GossipsubMetrics): void { - const mesh = this["mesh"]; + const mesh = this.mesh; + // biome-ignore lint/complexity/useLiteralKeys: `topics` is a private attribute const topics = this["topics"] as Map>; - const peers = this["peers"]; - const score = this["score"]; + const peers = this.peers; + const score = this.score; const meshPeersByClient = new Map(); const meshPeerIdStrs = new Set(); @@ -321,7 +325,8 @@ export class Eth2Gossipsub extends GossipSub { */ function attSubnetLabel(subnet: number): string { if (subnet > 9) return String(subnet); - else return `0${subnet}`; + + return `0${subnet}`; } function getMetricsTopicStrToLabel(config: BeaconConfig, opts: {disableLightClientServer: boolean}): TopicStrToLabel { diff --git a/packages/beacon-node/src/network/gossip/interface.ts b/packages/beacon-node/src/network/gossip/interface.ts index af5e3888d04f..ff1bfa088c17 100644 --- a/packages/beacon-node/src/network/gossip/interface.ts +++ b/packages/beacon-node/src/network/gossip/interface.ts @@ -203,7 +203,7 @@ export type BatchGossipHandler = ( gossipHandlerParams: GossipHandlerParamGeneric[] ) => Promise<(null | GossipActionError)[]>; -// eslint-disable-next-line @typescript-eslint/no-explicit-any +// biome-ignore lint/suspicious/noExplicitAny: export type ResolvedType Promise> = F extends (...args: any) => Promise ? T : never; diff --git a/packages/beacon-node/src/network/gossip/metrics.ts b/packages/beacon-node/src/network/gossip/metrics.ts index c2b5d0b32338..5ca5d22154c2 100644 --- a/packages/beacon-node/src/network/gossip/metrics.ts +++ b/packages/beacon-node/src/network/gossip/metrics.ts @@ -4,7 +4,6 @@ import {GossipType} from "./interface.js"; export type Eth2GossipsubMetrics = ReturnType; -// eslint-disable-next-line @typescript-eslint/explicit-function-return-type export function createEth2GossipsubMetrics(register: RegistryMetricCreator) { return { gossipPeer: { diff --git a/packages/beacon-node/src/network/gossip/scoringParameters.ts b/packages/beacon-node/src/network/gossip/scoringParameters.ts index 7e1be07f2ca7..3ba32614afeb 100644 --- a/packages/beacon-node/src/network/gossip/scoringParameters.ts +++ b/packages/beacon-node/src/network/gossip/scoringParameters.ts @@ -12,8 +12,6 @@ import {Eth2Context, Eth2GossipsubModules} from "./gossipsub.js"; import {GossipType} from "./interface.js"; import {stringifyGossipTopic} from "./topic.js"; -/* eslint-disable @typescript-eslint/naming-convention */ - export const GOSSIP_D = 8; export const GOSSIP_D_LOW = 6; export const GOSSIP_D_HIGH = 12; diff --git a/packages/beacon-node/src/network/gossip/topic.ts b/packages/beacon-node/src/network/gossip/topic.ts index b7c7425584c5..ed44c8314425 100644 --- a/packages/beacon-node/src/network/gossip/topic.ts +++ b/packages/beacon-node/src/network/gossip/topic.ts @@ -78,7 +78,6 @@ function stringifyGossipTopicType(topic: GossipTopic): string { } } -// eslint-disable-next-line @typescript-eslint/explicit-function-return-type export function getGossipSSZType(topic: GossipTopic) { switch (topic.type) { case GossipType.beacon_block: @@ -120,7 +119,7 @@ export function sszDeserialize(topic: T, serializedData: const sszType = getGossipSSZType(topic); try { return sszType.deserialize(serializedData) as SSZTypeOfGossipTopic; - } catch (e) { + } catch (_e) { throw new GossipActionError(GossipAction.REJECT, {code: GossipErrorCode.INVALID_SERIALIZED_BYTES_ERROR_CODE}); } } @@ -131,14 +130,14 @@ export function sszDeserialize(topic: T, serializedData: export function sszDeserializeAttestation(fork: ForkName, serializedData: Uint8Array): Attestation { try { return sszTypesFor(fork).Attestation.deserialize(serializedData); - } catch (e) { + } catch (_e) { throw new GossipActionError(GossipAction.REJECT, {code: GossipErrorCode.INVALID_SERIALIZED_BYTES_ERROR_CODE}); } } // Parsing -const gossipTopicRegex = new RegExp("^/eth2/(\\w+)/(\\w+)/(\\w+)"); +const gossipTopicRegex = /^\/eth2\/(\w+)\/(\w+)\/(\w+)/; /** * Parse a `GossipTopic` object from its stringified form. diff --git a/packages/beacon-node/src/network/interface.ts b/packages/beacon-node/src/network/interface.ts index 8d73379af221..ccb5ddecb557 100644 --- a/packages/beacon-node/src/network/interface.ts +++ b/packages/beacon-node/src/network/interface.ts @@ -12,10 +12,11 @@ import { PeerRouting, PeerStore, Upgrader, + PrivateKey, } from "@libp2p/interface"; import type {AddressManager, ConnectionManager, Registrar, TransportManager} from "@libp2p/interface-internal"; import type {Datastore} from "interface-datastore"; -import {Identify} from "@chainsafe/libp2p-identify"; +import {Identify} from "@libp2p/identify"; import { LightClientFinalityUpdate, LightClientOptimisticUpdate, @@ -93,6 +94,7 @@ export interface INetwork extends INetworkCorePublic { export type LodestarComponents = { peerId: PeerId; + privateKey: PrivateKey; nodeInfo: NodeInfo; logger: ComponentLogger; events: TypedEventTarget; diff --git a/packages/beacon-node/src/network/libp2p/index.ts b/packages/beacon-node/src/network/libp2p/index.ts index a0d58033cf2f..7697dbcb49a7 100644 --- a/packages/beacon-node/src/network/libp2p/index.ts +++ b/packages/beacon-node/src/network/libp2p/index.ts @@ -1,8 +1,7 @@ -import {PeerId} from "@libp2p/interface"; +import {PrivateKey} from "@libp2p/interface"; import {Registry} from "prom-client"; import {ENR} from "@chainsafe/enr"; -// TODO: We should use this fork until https://github.com/libp2p/js-libp2p/pull/2387 -import {identify} from "@chainsafe/libp2p-identify"; +import {identify} from "@libp2p/identify"; import {bootstrap} from "@libp2p/bootstrap"; import {mdns} from "@libp2p/mdns"; import {createLibp2p} from "libp2p"; @@ -34,7 +33,7 @@ export async function getDiscv5Multiaddrs(bootEnrs: string[]): Promise } export async function createNodeJsLibp2p( - peerId: PeerId, + privateKey: PrivateKey, networkOpts: Partial = {}, nodeJsLibp2pOpts: NodeJsLibp2pOpts = {} ): Promise { @@ -65,12 +64,12 @@ export async function createNodeJsLibp2p( } return createLibp2p({ - peerId, + privateKey, addresses: { listen: localMultiaddrs, announce: [], }, - connectionEncryption: [noise()], + connectionEncrypters: [noise()], // Reject connections when the server's connection count gets high transports: [ tcp({ @@ -99,15 +98,14 @@ export async function createNodeJsLibp2p( maxParallelDials: 100, maxPeerAddrsToDial: 4, dialTimeout: 30_000, - - // Rely entirely on lodestar's peer manager to prune connections - //maxConnections: options.maxConnections, - // DOCS: There is no way to turn off autodial other than setting minConnections to 0 - minConnections: 0, // the maximum number of pending connections libp2p will accept before it starts rejecting incoming connections. // make it the same to backlog option above maxIncomingPendingConnections: 5, }, + // rely on lodestar's peer manager to ping peers + connectionMonitor: { + enabled: false, + }, datastore, services: { identify: identify({ @@ -118,6 +116,7 @@ export async function createNodeJsLibp2p( // and passing it here directly causes problems downstream, not to mention is slowwww components: (components: LodestarComponents) => ({ peerId: components.peerId, + privateKey: components.privateKey, nodeInfo: components.nodeInfo, logger: components.logger, events: components.events, diff --git a/packages/beacon-node/src/network/network.ts b/packages/beacon-node/src/network/network.ts index 1b3ccaaaf75a..73208f497d66 100644 --- a/packages/beacon-node/src/network/network.ts +++ b/packages/beacon-node/src/network/network.ts @@ -1,6 +1,7 @@ -import {PeerId} from "@libp2p/interface"; +import {PeerId, PrivateKey} from "@libp2p/interface"; import {PublishOpts} from "@chainsafe/libp2p-gossipsub/types"; import {PeerScoreStatsDump} from "@chainsafe/libp2p-gossipsub/score"; +import {peerIdFromPrivateKey} from "@libp2p/peer-id"; import {BeaconConfig} from "@lodestar/config"; import {sleep} from "@lodestar/utils"; import {LoggerNode} from "@lodestar/logger/node"; @@ -50,7 +51,7 @@ import {getActiveForks} from "./forks.js"; type NetworkModules = { opts: NetworkOptions; - peerId: PeerId; + privateKey: PrivateKey; config: BeaconConfig; logger: LoggerNode; chain: IBeaconChain; @@ -63,7 +64,7 @@ type NetworkModules = { export type NetworkInitModules = { opts: NetworkOptions; config: BeaconConfig; - peerId: PeerId; + privateKey: PrivateKey; peerStoreDir?: string; logger: LoggerNode; metrics: Metrics | null; @@ -104,7 +105,7 @@ export class Network implements INetwork { private regossipBlsChangesPromise: Promise | null = null; constructor(modules: NetworkModules) { - this.peerId = modules.peerId; + this.peerId = peerIdFromPrivateKey(modules.privateKey); this.config = modules.config; this.logger = modules.logger; this.chain = modules.chain; @@ -134,7 +135,7 @@ export class Network implements INetwork { chain, db, gossipHandlers, - peerId, + privateKey, peerStoreDir, getReqRespHandler, }: NetworkInitModules): Promise { @@ -159,7 +160,7 @@ export class Network implements INetwork { initialStatus, }, config, - peerId, + privateKey, logger, events, metrics, @@ -168,7 +169,7 @@ export class Network implements INetwork { : await NetworkCore.init({ opts, config, - peerId, + privateKey, peerStoreDir, logger, clock: chain.clock, @@ -185,11 +186,12 @@ export class Network implements INetwork { ); const multiaddresses = opts.localMultiaddrs?.join(","); + const peerId = peerIdFromPrivateKey(privateKey); logger.info(`PeerId ${peerIdToString(peerId)}, Multiaddrs ${multiaddresses}`); return new Network({ opts, - peerId, + privateKey, config, logger, chain, diff --git a/packages/beacon-node/src/network/peers/datastore.ts b/packages/beacon-node/src/network/peers/datastore.ts index 762e99dc45b4..e0f2001c26ee 100644 --- a/packages/beacon-node/src/network/peers/datastore.ts +++ b/packages/beacon-node/src/network/peers/datastore.ts @@ -1,3 +1,4 @@ +import {AbortOptions} from "@libp2p/interface"; import {BaseDatastore} from "datastore-core"; import {LevelDatastore} from "datastore-level"; import {Key, KeyQuery, Query, Pair} from "interface-datastore"; @@ -57,7 +58,7 @@ export class Eth2PeerDataStore extends BaseDatastore { return this._dbDatastore.close(); } - async put(key: Key, val: Uint8Array): Promise { + async put(key: Key, val: Uint8Array, _options?: AbortOptions): Promise { return this._put(key, val, false); } @@ -147,8 +148,7 @@ export class Eth2PeerDataStore extends BaseDatastore { if (this._dirtyItems.size >= this._threshold) { try { await this._commitData(); - // eslint-disable-next-line no-empty - } catch (e) {} + } catch (_e) {} } } diff --git a/packages/beacon-node/src/network/peers/discover.ts b/packages/beacon-node/src/network/peers/discover.ts index 79603f780e3d..0ca67caf74fa 100644 --- a/packages/beacon-node/src/network/peers/discover.ts +++ b/packages/beacon-node/src/network/peers/discover.ts @@ -1,5 +1,5 @@ import {Multiaddr} from "@multiformats/multiaddr"; -import type {PeerId, PeerInfo} from "@libp2p/interface"; +import type {PeerId, PeerInfo, PrivateKey} from "@libp2p/interface"; import {ENR} from "@chainsafe/enr"; import {BeaconConfig} from "@lodestar/config"; import {pruneSetToMax, sleep} from "@lodestar/utils"; @@ -27,6 +27,7 @@ export type PeerDiscoveryOpts = { }; export type PeerDiscoveryModules = { + privateKey: PrivateKey; libp2p: Libp2p; peerRpcScores: IPeerRpcScoreStore; metrics: NetworkCoreMetrics | null; @@ -158,7 +159,7 @@ export class PeerDiscovery { static async init(modules: PeerDiscoveryModules, opts: PeerDiscoveryOpts): Promise { const discv5 = await Discv5Worker.init({ discv5: opts.discv5, - peerId: modules.libp2p.peerId, + privateKey: modules.privateKey, metrics: modules.metrics ?? undefined, logger: modules.logger, config: modules.config, @@ -277,9 +278,8 @@ export class PeerDiscovery { if (this.randomNodeQuery.code === QueryStatusCode.Active) { this.metrics?.discovery.findNodeQueryRequests.inc({action: "ignore"}); return; - } else { - this.metrics?.discovery.findNodeQueryRequests.inc({action: "start"}); } + this.metrics?.discovery.findNodeQueryRequests.inc({action: "start"}); // Use async version to prevent blocking the event loop // Time to completion of this function is not critical, in case this async call add extra lag @@ -304,7 +304,6 @@ export class PeerDiscovery { const {id, multiaddrs} = evt.detail; // libp2p may send us PeerInfos without multiaddrs https://github.com/libp2p/js-libp2p/issues/1873 - // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions if (!multiaddrs || multiaddrs.length === 0) { this.metrics?.discovery.discoveredStatus.inc({status: DiscoveredPeerStatus.no_multiaddrs}); return; @@ -324,8 +323,7 @@ export class PeerDiscovery { if (this.randomNodeQuery.code === QueryStatusCode.Active) { this.randomNodeQuery.count++; } - // async due to some crypto that's no longer necessary - const peerId = await enr.peerId(); + const peerId = enr.peerId; // tcp multiaddr is known to be be present, checked inside the worker const multiaddrTCP = enr.getLocationMultiaddr(ENRKey.tcp); if (!multiaddrTCP) { @@ -373,7 +371,7 @@ export class PeerDiscovery { if ( this.libp2p.services.components.connectionManager .getDialQueue() - .find((pendingDial) => pendingDial.peerId && pendingDial.peerId.equals(peerId)) + .find((pendingDial) => pendingDial.peerId?.equals(peerId)) ) { return DiscoveredPeerStatus.already_dialing; } @@ -390,13 +388,13 @@ export class PeerDiscovery { if (this.shouldDialPeer(cachedPeer)) { void this.dialPeer(cachedPeer); return DiscoveredPeerStatus.attempt_dial; - } else { - // Add to pending good peers with a last seen time - this.cachedENRs.set(peerId.toString(), cachedPeer); - const dropped = pruneSetToMax(this.cachedENRs, MAX_CACHED_ENRS); - // If the cache was already full, count the peer as dropped - return dropped > 0 ? DiscoveredPeerStatus.dropped : DiscoveredPeerStatus.cached; } + + // Add to pending good peers with a last seen time + this.cachedENRs.set(peerId.toString(), cachedPeer); + const dropped = pruneSetToMax(this.cachedENRs, MAX_CACHED_ENRS); + // If the cache was already full, count the peer as dropped + return dropped > 0 ? DiscoveredPeerStatus.dropped : DiscoveredPeerStatus.cached; } catch (e) { this.logger.error("Error onDiscovered", {}, e as Error); return DiscoveredPeerStatus.error; @@ -474,7 +472,7 @@ export class PeerDiscovery { /** Check if there is 1+ open connection with this peer */ private isPeerConnected(peerIdStr: PeerIdStr): boolean { const connections = getConnectionsMap(this.libp2p).get(peerIdStr); - return Boolean(connections && connections.some((connection) => connection.status === "open")); + return Boolean(connections?.value.some((connection) => connection.status === "open")); } } diff --git a/packages/beacon-node/src/network/peers/peerManager.ts b/packages/beacon-node/src/network/peers/peerManager.ts index 43fbee723f0e..b076285b0d21 100644 --- a/packages/beacon-node/src/network/peers/peerManager.ts +++ b/packages/beacon-node/src/network/peers/peerManager.ts @@ -1,4 +1,4 @@ -import {Connection, PeerId} from "@libp2p/interface"; +import {Connection, PeerId, PrivateKey} from "@libp2p/interface"; import {BitArray} from "@chainsafe/ssz"; import {SYNC_COMMITTEE_SUBNET_COUNT} from "@lodestar/params"; import {BeaconConfig} from "@lodestar/config"; @@ -94,6 +94,7 @@ export interface IReqRespBeaconNodePeerManager { } export type PeerManagerModules = { + privateKey: PrivateKey; libp2p: Libp2p; logger: LoggerNode; metrics: NetworkCoreMetrics | null; @@ -276,11 +277,14 @@ export class PeerManager { switch (request.method) { case ReqRespMethod.Ping: - return this.onPing(peer, request.body); + this.onPing(peer, request.body); + return; case ReqRespMethod.Goodbye: - return this.onGoodbye(peer, request.body); + this.onGoodbye(peer, request.body); + return; case ReqRespMethod.Status: - return this.onStatus(peer, request.body); + this.onStatus(peer, request.body); + return; } } catch (e) { this.logger.error("Error onRequest handler", {}, e as Error); @@ -383,7 +387,7 @@ export class PeerManager { private async requestMetadata(peer: PeerId): Promise { try { this.onMetadata(peer, await this.reqResp.sendMetadata(peer)); - } catch (e) { + } catch (_e) { // TODO: Downvote peer here or in the reqResp layer } } @@ -395,7 +399,7 @@ export class PeerManager { // If peer replies a PING request also update lastReceivedMsg const peerData = this.connectedPeers.get(peer.toString()); if (peerData) peerData.lastReceivedMsgUnixTsMs = Date.now(); - } catch (e) { + } catch (_e) { // TODO: Downvote peer here or in the reqResp layer } } @@ -403,7 +407,7 @@ export class PeerManager { private async requestStatus(peer: PeerId, localStatus: phase0.Status): Promise { try { this.onStatus(peer, await this.reqResp.sendStatus(peer, localStatus)); - } catch (e) { + } catch (_e) { // TODO: Failed to get peer latest status: downvote but don't disconnect } } @@ -423,7 +427,7 @@ export class PeerManager { * NOTE: Discovery should only add a new query if one isn't already queued. */ private heartbeat(): void { - // timer is safe without a try {} catch {}, in case of error the metric won't register and timer is GC'ed + // timer is safe without a try {} catch (_e) {}, in case of error the metric won't register and timer is GC'ed const timer = this.metrics?.peerManager.heartbeatDuration.startTimer(); const connectedPeers = this.getConnectedPeerIds(); @@ -685,7 +689,7 @@ export class PeerManager { } for (const connections of getConnectionsMap(this.libp2p).values()) { - const openCnx = connections.find((cnx) => cnx.status === "open"); + const openCnx = connections.value.find((cnx) => cnx.status === "open"); if (openCnx) { const direction = openCnx.direction; peersByDirection.set(direction, 1 + (peersByDirection.get(direction) ?? 0)); diff --git a/packages/beacon-node/src/network/peers/utils/getConnectedPeerIds.ts b/packages/beacon-node/src/network/peers/utils/getConnectedPeerIds.ts index 8542df605b06..d001c0d8892a 100644 --- a/packages/beacon-node/src/network/peers/utils/getConnectedPeerIds.ts +++ b/packages/beacon-node/src/network/peers/utils/getConnectedPeerIds.ts @@ -8,7 +8,7 @@ import {getConnectionsMap} from "../../util.js"; export function getConnectedPeerIds(libp2p: Libp2p): PeerId[] { const peerIds: PeerId[] = []; for (const connections of getConnectionsMap(libp2p).values()) { - const openConnection = connections.find(isConnectionOpen); + const openConnection = connections.value.find(isConnectionOpen); if (openConnection) { peerIds.push(openConnection.remotePeer); } @@ -21,7 +21,7 @@ export function getConnectedPeerIds(libp2p: Libp2p): PeerId[] { */ export function hasSomeConnectedPeer(libp2p: Libp2p): boolean { for (const connections of getConnectionsMap(libp2p).values()) { - if (connections.some(isConnectionOpen)) { + if (connections.value.some(isConnectionOpen)) { return true; } } diff --git a/packages/beacon-node/src/network/processor/gossipHandlers.ts b/packages/beacon-node/src/network/processor/gossipHandlers.ts index 90c131a943ed..dab3af0df8ba 100644 --- a/packages/beacon-node/src/network/processor/gossipHandlers.ts +++ b/packages/beacon-node/src/network/processor/gossipHandlers.ts @@ -680,7 +680,6 @@ export async function validateGossipFnRetryUnknownRoot( blockRoot: Root ): Promise { let unknownBlockRootRetries = 0; - // eslint-disable-next-line no-constant-condition while (true) { try { return await fn(); diff --git a/packages/beacon-node/src/network/processor/gossipQueues/index.ts b/packages/beacon-node/src/network/processor/gossipQueues/index.ts index 12596a42b7a1..dfa5b0dd1973 100644 --- a/packages/beacon-node/src/network/processor/gossipQueues/index.ts +++ b/packages/beacon-node/src/network/processor/gossipQueues/index.ts @@ -104,8 +104,7 @@ export function createGossipQueues(): { return mapValues(gossipQueueOpts, (opts) => { if (isIndexedGossipQueueMinSizeOpts(opts)) { return new IndexedGossipQueueMinSize(opts); - } else { - return new LinearGossipQueue(opts); } + return new LinearGossipQueue(opts); }); } diff --git a/packages/beacon-node/src/network/processor/gossipQueues/indexed.ts b/packages/beacon-node/src/network/processor/gossipQueues/indexed.ts index 8edba7dfaadb..a7b23b2ac929 100644 --- a/packages/beacon-node/src/network/processor/gossipQueues/indexed.ts +++ b/packages/beacon-node/src/network/processor/gossipQueues/indexed.ts @@ -123,9 +123,8 @@ export class IndexedGossipQueueMinSize implements GossipQueue { // overload, need to drop more items if (this.opts.dropOpts.type === DropType.count) { return this.dropByCount(this.opts.dropOpts.count); - } else { - this.recentDrop = true; - const droppedCount = this.dropByRatio(this._dropRatio); - // increase drop ratio the next time queue is full - this._dropRatio = Math.min(MAX_DROP_RATIO, this._dropRatio + this.opts.dropOpts.step); - return droppedCount; } + + this.recentDrop = true; + const droppedCount = this.dropByRatio(this._dropRatio); + // increase drop ratio the next time queue is full + this._dropRatio = Math.min(MAX_DROP_RATIO, this._dropRatio + this.opts.dropOpts.step); + return droppedCount; } next(): T | null { diff --git a/packages/beacon-node/src/network/processor/index.ts b/packages/beacon-node/src/network/processor/index.ts index 5cfed6c20346..ec0edf54644f 100644 --- a/packages/beacon-node/src/network/processor/index.ts +++ b/packages/beacon-node/src/network/processor/index.ts @@ -396,7 +396,9 @@ export class NetworkProcessor { if (item) { this.gossipTopicConcurrency[topic] += numMessages; this.processPendingGossipsubMessage(item) - .finally(() => (this.gossipTopicConcurrency[topic] -= numMessages)) + .finally(() => { + this.gossipTopicConcurrency[topic] -= numMessages; + }) .catch((e) => this.logger.error("processGossipAttestations must not throw", {}, e)); jobsSubmitted += numMessages; diff --git a/packages/beacon-node/src/network/reqresp/beaconBlocksMaybeBlobsByRange.ts b/packages/beacon-node/src/network/reqresp/beaconBlocksMaybeBlobsByRange.ts index 4dae4831d716..8c69c21679ba 100644 --- a/packages/beacon-node/src/network/reqresp/beaconBlocksMaybeBlobsByRange.ts +++ b/packages/beacon-node/src/network/reqresp/beaconBlocksMaybeBlobsByRange.ts @@ -37,7 +37,7 @@ export async function beaconBlocksMaybeBlobsByRange( } // Only request blobs if they are recent enough - else if (computeEpochAtSlot(startSlot) >= currentEpoch - config.MIN_EPOCHS_FOR_BLOB_SIDECARS_REQUESTS) { + if (computeEpochAtSlot(startSlot) >= currentEpoch - config.MIN_EPOCHS_FOR_BLOB_SIDECARS_REQUESTS) { const [allBlocks, allBlobSidecars] = await Promise.all([ network.sendBeaconBlocksByRange(peerId, request), network.sendBlobSidecarsByRange(peerId, request), @@ -47,9 +47,7 @@ export async function beaconBlocksMaybeBlobsByRange( } // Post Deneb but old blobs - else { - throw Error("Cannot sync blobs outside of blobs prune window"); - } + throw Error("Cannot sync blobs outside of blobs prune window"); } // Assumes that the blobs are in the same sequence as blocks, doesn't require block to be sorted @@ -80,6 +78,7 @@ export function matchBlockWithBlobs( let blobSidecar: deneb.BlobSidecar; while ( + // biome-ignore lint/suspicious/noAssignInExpressions: (blobSidecar = allBlobSidecars[blobSideCarIndex])?.signedBlockHeader.message.slot === block.data.message.slot ) { blobSidecars.push(blobSidecar); diff --git a/packages/beacon-node/src/network/reqresp/beaconBlocksMaybeBlobsByRoot.ts b/packages/beacon-node/src/network/reqresp/beaconBlocksMaybeBlobsByRoot.ts index b53addab9b43..3d121156d8e6 100644 --- a/packages/beacon-node/src/network/reqresp/beaconBlocksMaybeBlobsByRoot.ts +++ b/packages/beacon-node/src/network/reqresp/beaconBlocksMaybeBlobsByRoot.ts @@ -1,5 +1,5 @@ import {ChainForkConfig} from "@lodestar/config"; -import {phase0, deneb} from "@lodestar/types"; +import {phase0, deneb, SignedBeaconBlock} from "@lodestar/types"; import {ForkSeq} from "@lodestar/params"; import {fromHex} from "@lodestar/utils"; import { @@ -64,7 +64,11 @@ export async function unavailableBeaconBlobsByRoot( } // resolve the block if thats unavailable - let block, blobsCache, blockBytes, resolveAvailability, cachedData; + let block: SignedBeaconBlock, + blobsCache: NullBlockInput["cachedData"]["blobsCache"], + blockBytes: Uint8Array | null, + resolveAvailability: NullBlockInput["cachedData"]["resolveAvailability"], + cachedData: NullBlockInput["cachedData"]; if (unavailableBlockInput.block === null) { const allBlocks = await network.sendBeaconBlocksByRoot(peerId, [fromHex(unavailableBlockInput.blockRootHex)]); block = allBlocks[0].data; diff --git a/packages/beacon-node/src/network/reqresp/handlers/lightClientBootstrap.ts b/packages/beacon-node/src/network/reqresp/handlers/lightClientBootstrap.ts index d14e0945e977..3b50304eb50c 100644 --- a/packages/beacon-node/src/network/reqresp/handlers/lightClientBootstrap.ts +++ b/packages/beacon-node/src/network/reqresp/handlers/lightClientBootstrap.ts @@ -24,8 +24,7 @@ export async function* onLightClientBootstrap(requestBody: Root, chain: IBeaconC } catch (e) { if ((e as LightClientServerError).type?.code === LightClientServerErrorCode.RESOURCE_UNAVAILABLE) { throw new ResponseError(RespStatus.RESOURCE_UNAVAILABLE, (e as Error).message); - } else { - throw new ResponseError(RespStatus.SERVER_ERROR, (e as Error).message); } + throw new ResponseError(RespStatus.SERVER_ERROR, (e as Error).message); } } diff --git a/packages/beacon-node/src/network/reqresp/handlers/lightClientFinalityUpdate.ts b/packages/beacon-node/src/network/reqresp/handlers/lightClientFinalityUpdate.ts index 2468b0b64f4b..4764c6f198f7 100644 --- a/packages/beacon-node/src/network/reqresp/handlers/lightClientFinalityUpdate.ts +++ b/packages/beacon-node/src/network/reqresp/handlers/lightClientFinalityUpdate.ts @@ -9,12 +9,12 @@ export async function* onLightClientFinalityUpdate(chain: IBeaconChain): AsyncIt const update = chain.lightClientServer.getFinalityUpdate(); if (update === null) { throw new ResponseError(RespStatus.RESOURCE_UNAVAILABLE, "No latest finality update available"); - } else { - const fork = chain.config.getForkName(update.signatureSlot); - const type = responseSszTypeByMethod[ReqRespMethod.LightClientFinalityUpdate](fork, 0); - yield { - data: type.serialize(update), - fork, - }; } + + const fork = chain.config.getForkName(update.signatureSlot); + const type = responseSszTypeByMethod[ReqRespMethod.LightClientFinalityUpdate](fork, 0); + yield { + data: type.serialize(update), + fork, + }; } diff --git a/packages/beacon-node/src/network/reqresp/handlers/lightClientOptimisticUpdate.ts b/packages/beacon-node/src/network/reqresp/handlers/lightClientOptimisticUpdate.ts index ba8371910c02..4c030a8e4174 100644 --- a/packages/beacon-node/src/network/reqresp/handlers/lightClientOptimisticUpdate.ts +++ b/packages/beacon-node/src/network/reqresp/handlers/lightClientOptimisticUpdate.ts @@ -9,12 +9,12 @@ export async function* onLightClientOptimisticUpdate(chain: IBeaconChain): Async const update = chain.lightClientServer.getOptimisticUpdate(); if (update === null) { throw new ResponseError(RespStatus.RESOURCE_UNAVAILABLE, "No latest optimistic update available"); - } else { - const fork = chain.config.getForkName(update.signatureSlot); - const type = responseSszTypeByMethod[ReqRespMethod.LightClientOptimisticUpdate](fork, 0); - yield { - data: type.serialize(update), - fork, - }; } + + const fork = chain.config.getForkName(update.signatureSlot); + const type = responseSszTypeByMethod[ReqRespMethod.LightClientOptimisticUpdate](fork, 0); + yield { + data: type.serialize(update), + fork, + }; } diff --git a/packages/beacon-node/src/network/reqresp/handlers/lightClientUpdatesByRange.ts b/packages/beacon-node/src/network/reqresp/handlers/lightClientUpdatesByRange.ts index eb0e3c3d3f4e..89466eca6c21 100644 --- a/packages/beacon-node/src/network/reqresp/handlers/lightClientUpdatesByRange.ts +++ b/packages/beacon-node/src/network/reqresp/handlers/lightClientUpdatesByRange.ts @@ -31,9 +31,8 @@ export async function* onLightClientUpdatesByRange( } catch (e) { if ((e as LightClientServerError).type?.code === LightClientServerErrorCode.RESOURCE_UNAVAILABLE) { throw new ResponseError(RespStatus.RESOURCE_UNAVAILABLE, (e as Error).message); - } else { - throw new ResponseError(RespStatus.SERVER_ERROR, (e as Error).message); } + throw new ResponseError(RespStatus.SERVER_ERROR, (e as Error).message); } } } diff --git a/packages/beacon-node/src/network/reqresp/protocols.ts b/packages/beacon-node/src/network/reqresp/protocols.ts index a0fa9576c93c..e63df4b1341b 100644 --- a/packages/beacon-node/src/network/reqresp/protocols.ts +++ b/packages/beacon-node/src/network/reqresp/protocols.ts @@ -3,8 +3,6 @@ import {ForkDigestContext} from "@lodestar/config"; import {ProtocolNoHandler, ReqRespMethod, Version, requestSszTypeByMethod, responseSszTypeByMethod} from "./types.js"; import {rateLimitQuotas} from "./rateLimit.js"; -/* eslint-disable @typescript-eslint/naming-convention */ - export const Goodbye = toProtocol({ method: ReqRespMethod.Goodbye, version: Version.V1, diff --git a/packages/beacon-node/src/network/reqresp/rateLimit.ts b/packages/beacon-node/src/network/reqresp/rateLimit.ts index 881ab36bc05d..b6dacd6ba8e5 100644 --- a/packages/beacon-node/src/network/reqresp/rateLimit.ts +++ b/packages/beacon-node/src/network/reqresp/rateLimit.ts @@ -76,7 +76,7 @@ function getRequestCountFn( return (reqData: Uint8Array) => { try { return (type && fn(type.deserialize(reqData))) ?? 1; - } catch (e) { + } catch (_e) { return 1; } }; diff --git a/packages/beacon-node/src/network/reqresp/score.ts b/packages/beacon-node/src/network/reqresp/score.ts index c74b645c9909..647481162c78 100644 --- a/packages/beacon-node/src/network/reqresp/score.ts +++ b/packages/beacon-node/src/network/reqresp/score.ts @@ -8,7 +8,6 @@ import {ReqRespMethod} from "./types.js"; * https://github.com/libp2p/js-libp2p/blob/6350a187c7c207086e42436ccbcabd59af6f5e3d/src/errors.js#L32 */ const libp2pErrorCodes = { - // eslint-disable-next-line @typescript-eslint/naming-convention ERR_UNSUPPORTED_PROTOCOL: "ERR_UNSUPPORTED_PROTOCOL", }; diff --git a/packages/beacon-node/src/network/reqresp/types.ts b/packages/beacon-node/src/network/reqresp/types.ts index 02d99dd86933..96ae1558ec07 100644 --- a/packages/beacon-node/src/network/reqresp/types.ts +++ b/packages/beacon-node/src/network/reqresp/types.ts @@ -90,16 +90,16 @@ export type ResponseTypeGetter = (fork: ForkName, version: number) => Type const blocksResponseType: ResponseTypeGetter = (fork, version) => { if (version === Version.V1) { return ssz.phase0.SignedBeaconBlock; - } else { - return ssz[fork].SignedBeaconBlock; } + + return ssz[fork].SignedBeaconBlock; }; export const responseSszTypeByMethod: {[K in ReqRespMethod]: ResponseTypeGetter} = { [ReqRespMethod.Status]: () => ssz.phase0.Status, [ReqRespMethod.Goodbye]: () => ssz.phase0.Goodbye, [ReqRespMethod.Ping]: () => ssz.phase0.Ping, - [ReqRespMethod.Metadata]: (_, version) => (version == Version.V1 ? ssz.phase0.Metadata : ssz.altair.Metadata), + [ReqRespMethod.Metadata]: (_, version) => (version === Version.V1 ? ssz.phase0.Metadata : ssz.altair.Metadata), [ReqRespMethod.BeaconBlocksByRange]: blocksResponseType, [ReqRespMethod.BeaconBlocksByRoot]: blocksResponseType, [ReqRespMethod.BlobSidecarsByRange]: () => ssz.deneb.BlobSidecar, @@ -114,9 +114,8 @@ export const responseSszTypeByMethod: {[K in ReqRespMethod]: ResponseTypeGetter< function onlyLightclientFork(fork: ForkName): ForkLightClient { if (isForkLightClient(fork)) { return fork; - } else { - throw Error(`Not a lightclient fork ${fork}`); } + throw Error(`Not a lightclient fork ${fork}`); } export type RequestTypedContainer = { diff --git a/packages/beacon-node/src/network/util.ts b/packages/beacon-node/src/network/util.ts index dd317b5a0427..f1d6b917b5e4 100644 --- a/packages/beacon-node/src/network/util.ts +++ b/packages/beacon-node/src/network/util.ts @@ -14,13 +14,13 @@ export function prettyPrintPeerIdStr(id: PeerIdStr): string { * Get the connections map from a connection manager */ // Compat function for efficiency reasons -export function getConnectionsMap(libp2p: Libp2p): Map { - // eslint-disable-next-line @typescript-eslint/no-unsafe-return +export function getConnectionsMap(libp2p: Libp2p): Map { + // biome-ignore lint/complexity/useLiteralKeys: `map` is a private attribute return libp2p.services.components.connectionManager.getConnectionsMap()["map"]; } export function getConnection(libp2p: Libp2p, peerIdStr: string): Connection | undefined { - return getConnectionsMap(libp2p).get(peerIdStr)?.[0] ?? undefined; + return getConnectionsMap(libp2p).get(peerIdStr)?.value[0] ?? undefined; } // https://github.com/ChainSafe/js-libp2p-gossipsub/blob/3475242ed254f7647798ab7f36b21909f6cb61da/src/index.ts#L2009 diff --git a/packages/beacon-node/src/node/nodejs.ts b/packages/beacon-node/src/node/nodejs.ts index 088541a6b5d5..0e51b15e514b 100644 --- a/packages/beacon-node/src/node/nodejs.ts +++ b/packages/beacon-node/src/node/nodejs.ts @@ -1,7 +1,7 @@ import {setMaxListeners} from "node:events"; import {Registry} from "prom-client"; -import {PeerId} from "@libp2p/interface"; +import {PrivateKey} from "@libp2p/interface"; import {BeaconConfig} from "@lodestar/config"; import {phase0} from "@lodestar/types"; import {sleep} from "@lodestar/utils"; @@ -49,7 +49,7 @@ export type BeaconNodeInitModules = { db: IBeaconDb; logger: LoggerNode; processShutdownCallback: ProcessShutdownCallback; - peerId: PeerId; + privateKey: PrivateKey; peerStoreDir?: string; anchorState: BeaconStateAllForks; wsCheckpoint?: phase0.Checkpoint; @@ -146,7 +146,7 @@ export class BeaconNode { db, logger, processShutdownCallback, - peerId, + privateKey, peerStoreDir, anchorState, wsCheckpoint, @@ -243,7 +243,7 @@ export class BeaconNode { metrics, chain, db, - peerId, + privateKey, peerStoreDir, getReqRespHandler: getReqRespHandlers({db, chain}), }); @@ -305,7 +305,7 @@ export class BeaconNode { void runNodeNotifier({network, chain, sync, config, logger, signal}); - return new this({ + return new BeaconNode({ opts, config, db, diff --git a/packages/beacon-node/src/node/notifier.ts b/packages/beacon-node/src/node/notifier.ts index 6b9a29817158..20a359a45c49 100644 --- a/packages/beacon-node/src/node/notifier.ts +++ b/packages/beacon-node/src/node/notifier.ts @@ -92,7 +92,7 @@ export async function runNodeNotifier(modules: NodeNotifierModules): Promise msPerHalfSlot ? msToNextSlot - msPerHalfSlot : msToNextSlot + msPerHalfSlot; - } else { - // after the 1st time always wait until middle of next clock slot - return msToNextSlot + msPerHalfSlot; } + // after the 1st time always wait until middle of next clock slot + return msToNextSlot + msPerHalfSlot; } function getHeadExecutionInfo( @@ -181,26 +179,25 @@ function getHeadExecutionInfo( ): string[] { if (clockEpoch < config.BELLATRIX_FORK_EPOCH) { return []; - } else { - const executionStatusStr = headInfo.executionStatus.toLowerCase(); - - // Add execution status to notifier only if head is on/post bellatrix - if (isExecutionCachedStateType(headState)) { - if (isMergeTransitionComplete(headState)) { - const executionPayloadHashInfo = - headInfo.executionStatus !== ExecutionStatus.PreMerge ? headInfo.executionPayloadBlockHash : "empty"; - const executionPayloadNumberInfo = - headInfo.executionStatus !== ExecutionStatus.PreMerge ? headInfo.executionPayloadNumber : NaN; - return [ - `exec-block: ${executionStatusStr}(${executionPayloadNumberInfo} ${prettyBytesShort( - executionPayloadHashInfo - )})`, - ]; - } else { - return [`exec-block: ${executionStatusStr}`]; - } - } else { - return []; + } + + const executionStatusStr = headInfo.executionStatus.toLowerCase(); + + // Add execution status to notifier only if head is on/post bellatrix + if (isExecutionCachedStateType(headState)) { + if (isMergeTransitionComplete(headState)) { + const executionPayloadHashInfo = + headInfo.executionStatus !== ExecutionStatus.PreMerge ? headInfo.executionPayloadBlockHash : "empty"; + const executionPayloadNumberInfo = + headInfo.executionStatus !== ExecutionStatus.PreMerge ? headInfo.executionPayloadNumber : NaN; + return [ + `exec-block: ${executionStatusStr}(${executionPayloadNumberInfo} ${prettyBytesShort( + executionPayloadHashInfo + )})`, + ]; } + return [`exec-block: ${executionStatusStr}`]; } + + return []; } diff --git a/packages/beacon-node/src/sync/backfill/backfill.ts b/packages/beacon-node/src/sync/backfill/backfill.ts index 77d2836bdcc3..9612cf23b615 100644 --- a/packages/beacon-node/src/sync/backfill/backfill.ts +++ b/packages/beacon-node/src/sync/backfill/backfill.ts @@ -1,4 +1,4 @@ -import {EventEmitter} from "events"; +import {EventEmitter} from "node:events"; import {StrictEventEmitter} from "strict-event-emitter-types"; import {BeaconStateAllForks, blockToHeader, computeAnchorCheckpoint} from "@lodestar/state-transition"; import {BeaconConfig, ChainForkConfig} from "@lodestar/config"; @@ -13,7 +13,7 @@ import {INetwork, NetworkEvent, NetworkEventData, PeerAction} from "../../networ import {ItTrigger} from "../../util/itTrigger.js"; import {PeerIdStr} from "../../util/peerId.js"; import {shuffleOne} from "../../util/shuffle.js"; -import {Metrics} from "../../metrics/metrics"; +import {Metrics} from "../../metrics/metrics.js"; import {byteArrayEquals} from "../../util/bytes.js"; import {verifyBlockProposerSignature, verifyBlockSequence, BackfillBlockHeader, BackfillBlock} from "./verify.js"; import {BackfillSyncError, BackfillSyncErrorCode} from "./errors.js"; @@ -262,7 +262,7 @@ export class BackfillSync extends (EventEmitter as {new (): BackfillSyncEmitter} // Load a previous finalized or wsCheckpoint slot from DB below anchorSlot const prevFinalizedCheckpointBlock = await extractPreviousFinOrWsCheckpoint(config, db, anchorSlot, logger); - return new this(opts, { + return new BackfillSync(opts, { syncAnchor, backfillStartFromSlot, backfillRangeWrittenSlot, @@ -457,6 +457,7 @@ export class BackfillSync extends (EventEmitter as {new (): BackfillSyncEmitter} this.status = BackfillSyncStatus.aborted; break; case BackfillSyncErrorCode.NOT_ANCHORED: + // biome-ignore lint/suspicious/noFallthroughSwitchClause: We need fall-through behavior here case BackfillSyncErrorCode.NOT_LINEAR: // Lets try to jump directly to the parent of this anchorBlock as previous // (segment) of blocks could be orphaned/missed @@ -674,12 +675,13 @@ export class BackfillSync extends (EventEmitter as {new (): BackfillSyncEmitter} ); // If possible, read back till anchorBlock > this.prevFinalizedCheckpointBlock - let parentBlock, + let parentBlock: SignedBeaconBlock | null, backCount = 1; let isPrevFinWsConfirmedAnchorParent = false; while ( backCount !== this.opts.backfillBatchSize && + // biome-ignore lint/suspicious/noAssignInExpressions: (parentBlock = await this.db.blockArchive.getByRoot(anchorBlock.message.parentRoot)) ) { // Before moving anchorBlock back, we need check for prevFinalizedCheckpointBlock diff --git a/packages/beacon-node/src/sync/range/range.ts b/packages/beacon-node/src/sync/range/range.ts index 887a86a3aaf2..51e3a5d0f182 100644 --- a/packages/beacon-node/src/sync/range/range.ts +++ b/packages/beacon-node/src/sync/range/range.ts @@ -1,4 +1,4 @@ -import {EventEmitter} from "events"; +import {EventEmitter} from "node:events"; import {StrictEventEmitter} from "strict-event-emitter-types"; import {computeStartSlotAtEpoch} from "@lodestar/state-transition"; import {BeaconConfig} from "@lodestar/config"; @@ -150,17 +150,15 @@ export class RangeSync extends (EventEmitter as {new (): RangeSyncEmitter}) { if (chain.isSyncing) { if (chain.syncType === RangeSyncType.Finalized) { return {status: RangeSyncStatus.Finalized, target: chain.target}; - } else { - syncingHeadTargets.push(chain.target); } + syncingHeadTargets.push(chain.target); } } if (syncingHeadTargets.length > 0) { return {status: RangeSyncStatus.Head, targets: syncingHeadTargets}; - } else { - return {status: RangeSyncStatus.Idle}; } + return {status: RangeSyncStatus.Idle}; } /** Full debug state for lodestar API */ diff --git a/packages/beacon-node/src/sync/range/utils/batches.ts b/packages/beacon-node/src/sync/range/utils/batches.ts index 734c84800b69..c8490ade6317 100644 --- a/packages/beacon-node/src/sync/range/utils/batches.ts +++ b/packages/beacon-node/src/sync/range/utils/batches.ts @@ -113,7 +113,7 @@ export function isSyncChainDone(batches: Batch[], lastEpochWithProcessBlocks: Ep if (lastAwaitingValidation) { return batchStartEpochIsAfterSlot(lastAwaitingValidation.startEpoch + EPOCHS_PER_BATCH, targetSlot); - } else { - return batchStartEpochIsAfterSlot(lastEpochWithProcessBlocks, targetSlot); } + + return batchStartEpochIsAfterSlot(lastEpochWithProcessBlocks, targetSlot); } diff --git a/packages/beacon-node/src/sync/sync.ts b/packages/beacon-node/src/sync/sync.ts index cc8ddc6eb499..1e03431adbbb 100644 --- a/packages/beacon-node/src/sync/sync.ts +++ b/packages/beacon-node/src/sync/sync.ts @@ -99,31 +99,31 @@ export class BeaconSync implements IBeaconSync { isOptimistic: false, elOffline, }; - } else { - const head = this.chain.forkChoice.getHead(); - - switch (this.state) { - case SyncState.SyncingFinalized: - case SyncState.SyncingHead: - case SyncState.Stalled: - return { - headSlot: head.slot, - syncDistance: currentSlot - head.slot, - isSyncing: true, - isOptimistic: isOptimisticBlock(head), - elOffline, - }; - case SyncState.Synced: - return { - headSlot: head.slot, - syncDistance: 0, - isSyncing: false, - isOptimistic: isOptimisticBlock(head), - elOffline, - }; - default: - throw new Error("Node is stopped, cannot get sync status"); - } + } + + const head = this.chain.forkChoice.getHead(); + + switch (this.state) { + case SyncState.SyncingFinalized: + case SyncState.SyncingHead: + case SyncState.Stalled: + return { + headSlot: head.slot, + syncDistance: currentSlot - head.slot, + isSyncing: true, + isOptimistic: isOptimisticBlock(head), + elOffline, + }; + case SyncState.Synced: + return { + headSlot: head.slot, + syncDistance: 0, + isSyncing: false, + isOptimistic: isOptimisticBlock(head), + elOffline, + }; + default: + throw new Error("Node is stopped, cannot get sync status"); } } @@ -163,6 +163,8 @@ export class BeaconSync implements IBeaconSync { return SyncState.SyncingHead; case RangeSyncStatus.Idle: return SyncState.Stalled; + default: + throw new Error("Unreachable code"); } } diff --git a/packages/beacon-node/src/sync/unknownBlock.ts b/packages/beacon-node/src/sync/unknownBlock.ts index a172b5d723db..003b035a898d 100644 --- a/packages/beacon-node/src/sync/unknownBlock.ts +++ b/packages/beacon-node/src/sync/unknownBlock.ts @@ -15,7 +15,7 @@ import { beaconBlocksMaybeBlobsByRoot, unavailableBeaconBlobsByRoot, } from "../network/reqresp/beaconBlocksMaybeBlobsByRoot.js"; -import {wrapError} from "../util/wrapError.js"; +import {Result, wrapError} from "../util/wrapError.js"; import {PendingBlock, PendingBlockStatus, PendingBlockType} from "./interface.js"; import {getDescendantBlocks, getAllDescendantBlocks, getUnknownAndAncestorBlocks} from "./utils/pendingBlocksTree.js"; import {SyncOptions} from "./options.js"; @@ -168,7 +168,7 @@ export class UnknownBlockSync { blockInputOrRootHex: RootHex | BlockInput | NullBlockInput, peerIdStr?: string ): Exclude { - let blockRootHex; + let blockRootHex: RootHex; let blockInput: BlockInput | NullBlockInput | null; let unknownBlockType: Exclude; @@ -285,7 +285,7 @@ export class UnknownBlockSync { block.status = PendingBlockStatus.fetching; - let res; + let res: Result<{blockInput: BlockInput; peerIdStr: string}>; if (block.blockInput === null) { res = await wrapError(this.fetchUnknownBlockRoot(fromHex(block.blockRootHex), connectedPeers)); } else { @@ -493,9 +493,8 @@ export class UnknownBlockSync { if (lastError) { lastError.message = `Error fetching UnknownBlockRoot after ${MAX_ATTEMPTS_PER_BLOCK} attempts: ${lastError.message}`; throw lastError; - } else { - throw Error(`Error fetching UnknownBlockRoot after ${MAX_ATTEMPTS_PER_BLOCK}: unknown error`); } + throw Error(`Error fetching UnknownBlockRoot after ${MAX_ATTEMPTS_PER_BLOCK}: unknown error`); } /** @@ -511,10 +510,10 @@ export class UnknownBlockSync { } const shuffledPeers = shuffle(connectedPeers); - let blockRootHex; - let pendingBlobs; - let blobKzgCommitmentsLen; - let blockRoot; + let blockRootHex: RootHex; + let pendingBlobs: number | undefined; + let blobKzgCommitmentsLen: number | undefined; + let blockRoot: Uint8Array; if (unavailableBlockInput.block === null) { blockRootHex = unavailableBlockInput.blockRootHex; @@ -569,9 +568,9 @@ export class UnknownBlockSync { if (lastError) { lastError.message = `Error fetching UnavailableBlockInput after ${MAX_ATTEMPTS_PER_BLOCK} attempts: ${lastError.message}`; throw lastError; - } else { - throw Error(`Error fetching UnavailableBlockInput after ${MAX_ATTEMPTS_PER_BLOCK}: unknown error`); } + + throw Error(`Error fetching UnavailableBlockInput after ${MAX_ATTEMPTS_PER_BLOCK}: unknown error`); } /** diff --git a/packages/beacon-node/src/sync/utils/remoteSyncType.ts b/packages/beacon-node/src/sync/utils/remoteSyncType.ts index 87cca86375f0..247269ab409a 100644 --- a/packages/beacon-node/src/sync/utils/remoteSyncType.ts +++ b/packages/beacon-node/src/sync/utils/remoteSyncType.ts @@ -49,36 +49,33 @@ export function getPeerSyncType( return PeerSyncType.Behind; } - // - else if (remote.finalizedEpoch > local.finalizedEpoch) { + if (remote.finalizedEpoch > local.finalizedEpoch) { if ( // Peer is in next epoch, and head is within range => SYNCED - (local.finalizedEpoch + 1 == remote.finalizedEpoch && + (local.finalizedEpoch + 1 === remote.finalizedEpoch && withinRangeOf(remote.headSlot, local.headSlot, slotImportTolerance)) || // Peer's head is known => SYNCED forkChoice.hasBlock(remote.headRoot) ) { return PeerSyncType.FullySynced; - } else { - return PeerSyncType.Advanced; } + return PeerSyncType.Advanced; } // remote.finalizedEpoch == local.finalizedEpoch - else { - // NOTE: if a peer has our same `finalizedEpoch` with a different `finalized_root` - // they are not considered relevant and won't be propagated to sync. - // Check if the peer is the peer is inside the tolerance range to be considered synced. - if (remote.headSlot < nearRangeStart) { - return PeerSyncType.Behind; - } else if (remote.headSlot > nearRangeEnd && !forkChoice.hasBlock(remote.headRoot)) { - // This peer has a head ahead enough of ours and we have no knowledge of their best block. - return PeerSyncType.Advanced; - } else { - // This peer is either in the tolerance range, or ahead us with an already rejected block. - return PeerSyncType.FullySynced; - } + // NOTE: if a peer has our same `finalizedEpoch` with a different `finalized_root` + // they are not considered relevant and won't be propagated to sync. + // Check if the peer is the peer is inside the tolerance range to be considered synced. + if (remote.headSlot < nearRangeStart) { + return PeerSyncType.Behind; + } + + if (remote.headSlot > nearRangeEnd && !forkChoice.hasBlock(remote.headRoot)) { + // This peer has a head ahead enough of ours and we have no knowledge of their best block. + return PeerSyncType.Advanced; } + // This peer is either in the tolerance range, or ahead us with an already rejected block. + return PeerSyncType.FullySynced; } export enum RangeSyncType { @@ -99,9 +96,8 @@ export const rangeSyncTypes = Object.keys(RangeSyncType) as RangeSyncType[]; export function getRangeSyncType(local: phase0.Status, remote: phase0.Status, forkChoice: IForkChoice): RangeSyncType { if (remote.finalizedEpoch > local.finalizedEpoch && !forkChoice.hasBlock(remote.finalizedRoot)) { return RangeSyncType.Finalized; - } else { - return RangeSyncType.Head; } + return RangeSyncType.Head; } export function getRangeSyncTarget( @@ -134,16 +130,15 @@ export function getRangeSyncTarget( root: remote.finalizedRoot, }, }; - } else { - return { - syncType: RangeSyncType.Head, - // The new peer has the same finalized (earlier filters should prevent a peer with an - // earlier finalized chain from reaching here). - startEpoch: Math.min(computeEpochAtSlot(local.headSlot), remote.finalizedEpoch), - target: { - slot: remote.headSlot, - root: remote.headRoot, - }, - }; } + return { + syncType: RangeSyncType.Head, + // The new peer has the same finalized (earlier filters should prevent a peer with an + // earlier finalized chain from reaching here). + startEpoch: Math.min(computeEpochAtSlot(local.headSlot), remote.finalizedEpoch), + target: { + slot: remote.headSlot, + root: remote.headRoot, + }, + }; } diff --git a/packages/beacon-node/src/util/asyncIterableToEvents.ts b/packages/beacon-node/src/util/asyncIterableToEvents.ts index 0468ca2b431b..836983d8e4f0 100644 --- a/packages/beacon-node/src/util/asyncIterableToEvents.ts +++ b/packages/beacon-node/src/util/asyncIterableToEvents.ts @@ -46,7 +46,6 @@ export class AsyncIterableBridgeCaller { } getAsyncIterable(callArgs: Args): AsyncIterable { - // eslint-disable-next-line @typescript-eslint/no-this-alias const self = this; return { @@ -67,7 +66,6 @@ export class AsyncIterableBridgeCaller { return { async next() { - // eslint-disable-next-line no-constant-condition while (true) { const item = req.items.shift(); if (item !== null) { diff --git a/packages/beacon-node/src/util/binarySearch.ts b/packages/beacon-node/src/util/binarySearch.ts index db7c03af50b7..459154eb0427 100644 --- a/packages/beacon-node/src/util/binarySearch.ts +++ b/packages/beacon-node/src/util/binarySearch.ts @@ -1,5 +1,5 @@ export function binarySearchLte(items: T[], value: number, getter: (item: T) => number): T { - if (items.length == 0) { + if (items.length === 0) { throw new ErrorNoValues(); } diff --git a/packages/beacon-node/src/util/bitArray.ts b/packages/beacon-node/src/util/bitArray.ts index 364110fe958f..3411886de3ca 100644 --- a/packages/beacon-node/src/util/bitArray.ts +++ b/packages/beacon-node/src/util/bitArray.ts @@ -72,7 +72,7 @@ export function intersectUint8Arrays(aUA: Uint8Array, bUA: Uint8Array): Intersec // subset = MUST subset MAYBE equal if (!someExcludes && !someSuperset && someSubset) return IntersectResult.Subset; // intersect = any other condition - else return IntersectResult.Intersect; + return IntersectResult.Intersect; } /** diff --git a/packages/beacon-node/src/util/kzg.ts b/packages/beacon-node/src/util/kzg.ts index e20a379d62ff..42224d1ebaa6 100644 --- a/packages/beacon-node/src/util/kzg.ts +++ b/packages/beacon-node/src/util/kzg.ts @@ -3,8 +3,6 @@ import fs from "node:fs"; import {fileURLToPath} from "node:url"; import {fromHex, toHex} from "@lodestar/utils"; -/* eslint-disable @typescript-eslint/naming-convention */ - // "c-kzg" has hardcoded the mainnet value, do not use params export const FIELD_ELEMENTS_PER_BLOB_MAINNET = 4096; @@ -61,7 +59,7 @@ export enum TrustedFileMode { */ export function loadEthereumTrustedSetup(mode: TrustedFileMode = TrustedFileMode.Txt, filePath?: string): void { try { - let setupFilePath; + let setupFilePath: string; if (mode === TrustedFileMode.Bin) { const binPath = filePath ?? TRUSTED_SETUP_BIN_FILEPATH; const bytes = fs.readFileSync(binPath); @@ -87,9 +85,10 @@ export function loadEthereumTrustedSetup(mode: TrustedFileMode = TrustedFileMode } } -/* eslint-disable @typescript-eslint/naming-convention */ export interface TrustedSetupJSON { + // biome-ignore lint/style/useNamingConvention: Need to be consistent with KZG pattern setup_G1: string[]; + // biome-ignore lint/style/useNamingConvention: Need to be consistent with KZG pattern setup_G2: string[]; } @@ -123,7 +122,9 @@ export function trustedSetupJsonToBin(data: TrustedSetupJSON): TrustedSetupBin { export function trustedSetupBinToJson(bytes: TrustedSetupBin): TrustedSetupJSON { const data: TrustedSetupJSON = { + // biome-ignore lint/style/useNamingConvention: Need to be consistent with KZG pattern setup_G1: [], + // biome-ignore lint/style/useNamingConvention: Need to be consistent with KZG pattern setup_G2: [], }; @@ -157,7 +158,6 @@ export function trustedSetupJsonToTxt(data: TrustedSetupJSON): TrustedSetupTXT { function strip0xPrefix(hex: string): string { if (hex.startsWith("0x")) { return hex.slice(2); - } else { - return hex; } + return hex; } diff --git a/packages/beacon-node/src/util/map.ts b/packages/beacon-node/src/util/map.ts index 6cc8f37155b1..1b8fc6222032 100644 --- a/packages/beacon-node/src/util/map.ts +++ b/packages/beacon-node/src/util/map.ts @@ -43,7 +43,6 @@ export class OrderedMap { } values(): IterableIterator { - // eslint-disable-next-line @typescript-eslint/no-this-alias const _self = this; return (function* generateValues() { for (const key of _self.keys()) { diff --git a/packages/beacon-node/src/util/peerId.ts b/packages/beacon-node/src/util/peerId.ts index 2afb9bed390e..c62f5416cdfe 100644 --- a/packages/beacon-node/src/util/peerId.ts +++ b/packages/beacon-node/src/util/peerId.ts @@ -12,5 +12,5 @@ export type PeerIdStr = string; export {peerIdFromString}; export function peerIdToString(peerId: PeerId): string { - return base58btc.encode(peerId.multihash.bytes).slice(1); + return base58btc.encode(peerId.toMultihash().bytes).slice(1); } diff --git a/packages/beacon-node/src/util/profile.ts b/packages/beacon-node/src/util/profile.ts index 7085c329c823..ccb5b098be31 100644 --- a/packages/beacon-node/src/util/profile.ts +++ b/packages/beacon-node/src/util/profile.ts @@ -37,7 +37,7 @@ export async function profileNodeJS(durationMs: number): Promise { export async function writeHeapSnapshot(prefix: string, dirpath: string): Promise { // Lazily import NodeJS only modules const fs = await import("node:fs"); - const v8 = await import("v8"); + const v8 = await import("node:v8"); const snapshotStream = v8.getHeapSnapshot(); const filepath = `${dirpath}/${prefix}_${new Date().toISOString()}.heapsnapshot`; const fileStream = fs.createWriteStream(filepath); diff --git a/packages/beacon-node/src/util/queue/errors.ts b/packages/beacon-node/src/util/queue/errors.ts index edb0b3b87374..7117b5629372 100644 --- a/packages/beacon-node/src/util/queue/errors.ts +++ b/packages/beacon-node/src/util/queue/errors.ts @@ -7,11 +7,7 @@ export enum QueueErrorCode { export type QueueErrorCodeType = {code: QueueErrorCode.QUEUE_ABORTED} | {code: QueueErrorCode.QUEUE_MAX_LENGTH}; -export class QueueError extends LodestarError { - constructor(type: QueueErrorCodeType) { - super(type); - } -} +export class QueueError extends LodestarError {} export function isQueueErrorAborted(e: unknown): e is QueueError { return e instanceof QueueError && e.type.code === QueueErrorCode.QUEUE_ABORTED; diff --git a/packages/beacon-node/src/util/queue/fnQueue.ts b/packages/beacon-node/src/util/queue/fnQueue.ts index ec3267bdf93a..80e179f8e8f3 100644 --- a/packages/beacon-node/src/util/queue/fnQueue.ts +++ b/packages/beacon-node/src/util/queue/fnQueue.ts @@ -1,10 +1,10 @@ import {JobItemQueue} from "./itemQueue.js"; import {QueueMetrics, JobQueueOpts} from "./options.js"; -// eslint-disable-next-line @typescript-eslint/no-explicit-any +// biome-ignore lint/suspicious/noExplicitAny: type Fn = (...args: any) => Promise; -// eslint-disable-next-line @typescript-eslint/no-explicit-any +// biome-ignore lint/suspicious/noExplicitAny: export class JobFnQueue extends JobItemQueue<[Fn], any> { constructor(opts: JobQueueOpts, metrics?: QueueMetrics) { super((fn) => fn(), opts, metrics); diff --git a/packages/beacon-node/src/util/queue/itemQueue.ts b/packages/beacon-node/src/util/queue/itemQueue.ts index 7da7b6cdd8cb..f380a15f5eaf 100644 --- a/packages/beacon-node/src/util/queue/itemQueue.ts +++ b/packages/beacon-node/src/util/queue/itemQueue.ts @@ -7,7 +7,8 @@ import {defaultQueueOpts, QueueMetrics, JobQueueOpts, QueueType} from "./options * JobQueue that stores arguments in the job array instead of closures. * Supports a single itemProcessor, for arbitrary functions use the JobFnQueue */ -// eslint-disable-next-line @typescript-eslint/no-explicit-any + +// biome-ignore lint/suspicious/noExplicitAny: export class JobItemQueue { private readonly opts: Required; /** diff --git a/packages/beacon-node/test/e2e/api/impl/beacon/block/endpoint.test.ts b/packages/beacon-node/test/e2e/api/impl/beacon/block/endpoint.test.ts index ee0b17348099..b8939b54c294 100644 --- a/packages/beacon-node/test/e2e/api/impl/beacon/block/endpoint.test.ts +++ b/packages/beacon-node/test/e2e/api/impl/beacon/block/endpoint.test.ts @@ -14,7 +14,7 @@ import {getDevBeaconNode} from "../../../../../utils/node/beacon.js"; import {BeaconNode} from "../../../../../../src/node/nodejs.js"; import {getConfig} from "../../../../../utils/config.js"; -describe("beacon block api", function () { +describe("beacon block api", () => { vi.setConfig({testTimeout: 60_000, hookTimeout: 60_000}); const restPort = 9596; diff --git a/packages/beacon-node/test/e2e/api/impl/beacon/node/endpoints.test.ts b/packages/beacon-node/test/e2e/api/impl/beacon/node/endpoints.test.ts index 2d2a0a37c59e..6dc01870a844 100644 --- a/packages/beacon-node/test/e2e/api/impl/beacon/node/endpoints.test.ts +++ b/packages/beacon-node/test/e2e/api/impl/beacon/node/endpoints.test.ts @@ -9,7 +9,7 @@ import {getDevBeaconNode} from "../../../../../utils/node/beacon.js"; import {BeaconNode} from "../../../../../../src/node/nodejs.js"; import {getAndInitDevValidators} from "../../../../../utils/node/validator.js"; -describe("beacon node api", function () { +describe("beacon node api", () => { vi.setConfig({testTimeout: 60_000}); const restPort = 9596; @@ -67,9 +67,7 @@ describe("beacon node api", function () { const bnElOffline = await getDevBeaconNode({ params: { ...chainConfigDef, - // eslint-disable-next-line @typescript-eslint/naming-convention ALTAIR_FORK_EPOCH: 0, - // eslint-disable-next-line @typescript-eslint/naming-convention BELLATRIX_FORK_EPOCH: 0, }, options: { diff --git a/packages/beacon-node/test/e2e/api/impl/beacon/state/endpoint.test.ts b/packages/beacon-node/test/e2e/api/impl/beacon/state/endpoint.test.ts index 01423d72341f..d8c87a3ba6b8 100644 --- a/packages/beacon-node/test/e2e/api/impl/beacon/state/endpoint.test.ts +++ b/packages/beacon-node/test/e2e/api/impl/beacon/state/endpoint.test.ts @@ -8,7 +8,7 @@ import {LogLevel, testLogger} from "../../../../../utils/logger.js"; import {getDevBeaconNode} from "../../../../../utils/node/beacon.js"; import {BeaconNode} from "../../../../../../src/node/nodejs.js"; -describe("beacon state api", function () { +describe("beacon state api", () => { const restPort = 9596; const config = createBeaconConfig(chainConfigDef, Buffer.alloc(32, 0xaa)); const validatorCount = 512; 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 4bdedfa16391..3ffdbc4beb21 100644 --- a/packages/beacon-node/test/e2e/api/impl/config.test.ts +++ b/packages/beacon-node/test/e2e/api/impl/config.test.ts @@ -14,7 +14,7 @@ const CONSTANT_NAMES_SKIP_LIST = new Set([ "BLOB_SIDECAR_SUBNET_COUNT", ]); -describe("api / impl / config", function () { +describe("api / impl / config", () => { it("Ensure all constants are exposed", async () => { const constantNames = await downloadRemoteConstants(ethereumConsensusSpecsTests.specVersion); diff --git a/packages/beacon-node/test/e2e/api/impl/lightclient/endpoint.test.ts b/packages/beacon-node/test/e2e/api/impl/lightclient/endpoint.test.ts index c746746741cf..effbed19fc2c 100644 --- a/packages/beacon-node/test/e2e/api/impl/lightclient/endpoint.test.ts +++ b/packages/beacon-node/test/e2e/api/impl/lightclient/endpoint.test.ts @@ -13,8 +13,7 @@ import {getAndInitDevValidators} from "../../../../utils/node/validator.js"; import {BeaconNode} from "../../../../../src/node/nodejs.js"; import {waitForEvent} from "../../../../utils/events/resolver.js"; -/* eslint-disable @typescript-eslint/naming-convention */ -describe("lightclient api", function () { +describe("lightclient api", () => { const SECONDS_PER_SLOT = 1; const ALTAIR_FORK_EPOCH = 0; const restPort = 9596; @@ -81,7 +80,7 @@ describe("lightclient api", function () { await sleep(2 * SECONDS_PER_SLOT * 1000); }; - it("getLightClientUpdatesByRange()", async function () { + it("getLightClientUpdatesByRange()", async () => { const client = getClient({baseUrl: `http://127.0.0.1:${restPort}`}, {config}).lightclient; await waitForBestUpdate(); const res = await client.getLightClientUpdatesByRange({startPeriod: 0, count: 1}); @@ -92,7 +91,7 @@ describe("lightclient api", function () { expect(res.meta().versions[0]).toBe(ForkName.altair); }); - it("getLightClientOptimisticUpdate()", async function () { + it("getLightClientOptimisticUpdate()", async () => { await waitForBestUpdate(); const client = getClient({baseUrl: `http://127.0.0.1:${restPort}`}, {config}).lightclient; const res = await client.getLightClientOptimisticUpdate(); @@ -106,7 +105,7 @@ describe("lightclient api", function () { expect(res.headers.get(HttpHeader.ExposeHeaders)?.includes("Eth-Consensus-Version")).toBe(true); }); - it.skip("getLightClientFinalityUpdate()", async function () { + it.skip("getLightClientFinalityUpdate()", async () => { // TODO: not sure how this causes subsequent tests failed await waitForEvent(bn.chain.emitter, routes.events.EventType.finalizedCheckpoint, 240000); await sleep(SECONDS_PER_SLOT * 1000); @@ -115,7 +114,7 @@ describe("lightclient api", function () { expect(finalityUpdate).toBeDefined(); }); - it("getLightClientCommitteeRoot() for the 1st period", async function () { + it("getLightClientCommitteeRoot() for the 1st period", async () => { await waitForBestUpdate(); const lightclient = getClient({baseUrl: `http://127.0.0.1:${restPort}`}, {config}).lightclient; 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 5cccb2aa0772..bc847b47e9a9 100644 --- a/packages/beacon-node/test/e2e/api/lodestar/lodestar.test.ts +++ b/packages/beacon-node/test/e2e/api/lodestar/lodestar.test.ts @@ -10,17 +10,16 @@ import {waitForEvent} from "../../../utils/events/resolver.js"; import {ClockEvent} from "../../../../src/util/clock.js"; import {BeaconNode} from "../../../../src/index.js"; -describe("api / impl / validator", function () { +describe("api / impl / validator", () => { vi.setConfig({testTimeout: 60_000}); - describe("getLiveness endpoint", function () { + describe("getLiveness endpoint", () => { let bn: BeaconNode | undefined; const SECONDS_PER_SLOT = 2; const ALTAIR_FORK_EPOCH = 0; const validatorCount = 8; const restPort = 9596; const testParams: Pick = { - /* eslint-disable @typescript-eslint/naming-convention */ SECONDS_PER_SLOT: SECONDS_PER_SLOT, ALTAIR_FORK_EPOCH: ALTAIR_FORK_EPOCH, }; @@ -31,7 +30,7 @@ describe("api / impl / validator", function () { if (bn) await bn.close(); }); - it("Should return validator indices that are live", async function () { + it("Should return validator indices that are live", async () => { const chainConfig: ChainConfig = {...chainConfigDef, SECONDS_PER_SLOT, ALTAIR_FORK_EPOCH}; const genesisValidatorsRoot = Buffer.alloc(32, 0xaa); const config = createBeaconConfig(chainConfig, genesisValidatorsRoot); @@ -72,7 +71,7 @@ describe("api / impl / validator", function () { ]); }); - it("Should return only for previous, current and next epoch", async function () { + it("Should return only for previous, current and next epoch", async () => { const chainConfig: ChainConfig = {...chainConfigDef, SECONDS_PER_SLOT, ALTAIR_FORK_EPOCH}; const genesisValidatorsRoot = Buffer.alloc(32, 0xaa); const config = createBeaconConfig(chainConfig, genesisValidatorsRoot); 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 25f0d5133bcd..a544b3231e87 100644 --- a/packages/beacon-node/test/e2e/chain/bls/multithread.test.ts +++ b/packages/beacon-node/test/e2e/chain/bls/multithread.test.ts @@ -5,23 +5,11 @@ import {BlsMultiThreadWorkerPool} from "../../../../src/chain/bls/multithread/in import {testLogger} from "../../../utils/logger.js"; import {VerifySignatureOpts} from "../../../../src/chain/bls/interface.js"; -describe("chain / bls / multithread queue", function () { +describe("chain / bls / multithread queue", () => { const logger = testLogger(); let controller: AbortController; - beforeEach(() => { - controller = new AbortController(); - }); - afterEach(() => controller.abort()); - const afterEachCallbacks: (() => Promise | void)[] = []; - afterEach(async () => { - while (afterEachCallbacks.length > 0) { - const callback = afterEachCallbacks.pop(); - if (callback) await callback(); - } - }); - const sets: ISignatureSet[] = []; const sameMessageSets: {publicKey: PublicKey; signature: Uint8Array}[] = []; const sameMessage = Buffer.alloc(32, 100); @@ -45,6 +33,19 @@ describe("chain / bls / multithread queue", function () { } }); + beforeEach(() => { + controller = new AbortController(); + }); + + afterEach(async () => { + controller.abort(); + + while (afterEachCallbacks.length > 0) { + const callback = afterEachCallbacks.pop(); + if (callback) await callback(); + } + }); + async function initializePool(): Promise { const pool = new BlsMultiThreadWorkerPool({}, {logger, metrics: null}); // await terminating all workers diff --git a/packages/beacon-node/test/e2e/chain/lightclient.test.ts b/packages/beacon-node/test/e2e/chain/lightclient.test.ts index c501a2618049..ed698f2844a1 100644 --- a/packages/beacon-node/test/e2e/chain/lightclient.test.ts +++ b/packages/beacon-node/test/e2e/chain/lightclient.test.ts @@ -14,7 +14,7 @@ import {getDevBeaconNode} from "../../utils/node/beacon.js"; import {getAndInitDevValidators} from "../../utils/node/validator.js"; import {HeadEventData} from "../../../src/chain/index.js"; -describe("chain / lightclient", function () { +describe("chain / lightclient", () => { vi.setConfig({testTimeout: 600_000}); /** @@ -34,7 +34,6 @@ describe("chain / lightclient", function () { const restPort = 9000; const testParams: Pick = { - /* eslint-disable @typescript-eslint/naming-convention */ SECONDS_PER_SLOT: 1, ALTAIR_FORK_EPOCH: 0, }; @@ -47,7 +46,7 @@ describe("chain / lightclient", function () { } }); - it("Lightclient track head on server configuration", async function () { + it("Lightclient track head on server configuration", async () => { // 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 = 7; @@ -153,7 +152,9 @@ describe("chain / lightclient", function () { const lcHeadSlot = lightclient.getHead().beacon.slot; if (head.slot - lcHeadSlot > maxLcHeadTrackingDiffSlots) { throw Error(`Lightclient head ${lcHeadSlot} is too far behind the beacon node ${head.slot}`); - } else if (head.slot > targetSlotToReach) { + } + + if (head.slot > targetSlotToReach) { resolve(); } } catch (e) { diff --git a/packages/beacon-node/test/e2e/chain/proposerBoostReorg.test.ts b/packages/beacon-node/test/e2e/chain/proposerBoostReorg.test.ts index 594e20ec4cb0..fd6af72ad6cb 100644 --- a/packages/beacon-node/test/e2e/chain/proposerBoostReorg.test.ts +++ b/packages/beacon-node/test/e2e/chain/proposerBoostReorg.test.ts @@ -12,18 +12,15 @@ import {getAndInitDevValidators} from "../../utils/node/validator.js"; import {waitForEvent} from "../../utils/events/resolver.js"; import {ReorgEventData} from "../../../src/chain/emitter.js"; -describe("proposer boost reorg", function () { +describe("proposer boost reorg", () => { vi.setConfig({testTimeout: 60000}); const validatorCount = 8; const testParams: Pick = { - // eslint-disable-next-line @typescript-eslint/naming-convention SECONDS_PER_SLOT: 2, // need this to make block `reorgSlot - 1` strong enough - // eslint-disable-next-line @typescript-eslint/naming-convention REORG_PARENT_WEIGHT_THRESHOLD: 80, // need this to make block `reorgSlot + 1` to become the head - // eslint-disable-next-line @typescript-eslint/naming-convention PROPOSER_SCORE_BOOST: 120, }; diff --git a/packages/beacon-node/test/e2e/chain/stateCache/nHistoricalStates.test.ts b/packages/beacon-node/test/e2e/chain/stateCache/nHistoricalStates.test.ts index fd14b7b8b8c0..fcac715e1719 100644 --- a/packages/beacon-node/test/e2e/chain/stateCache/nHistoricalStates.test.ts +++ b/packages/beacon-node/test/e2e/chain/stateCache/nHistoricalStates.test.ts @@ -19,12 +19,11 @@ import {ReorgedForkChoice} from "../../../mocks/fork-choice/reorg.js"; * This includes several tests which make >6 min to pass in CI, so let's only run 1 of them and leave remaining ones * for local investigation. */ -describe("regen/reload states with n-historical states configuration", function () { +describe("regen/reload states with n-historical states configuration", () => { vi.setConfig({testTimeout: 96_000}); const validatorCount = 8; const testParams: Pick = { - // eslint-disable-next-line @typescript-eslint/naming-convention SECONDS_PER_SLOT: 2, }; @@ -267,7 +266,7 @@ describe("regen/reload states with n-historical states configuration", function skip, } of testCases) { const wrappedIt = skip ? it.skip : it; - wrappedIt(`${name} reorgedSlot=${reorgedSlot} reorgDistance=${reorgDistance}`, async function () { + wrappedIt(`${name} reorgedSlot=${reorgedSlot} reorgDistance=${reorgDistance}`, async () => { // the node needs time to transpile/initialize bls worker threads const genesisSlotsDelay = 7; const genesisTime = Math.floor(Date.now() / 1000) + genesisSlotsDelay * testParams.SECONDS_PER_SLOT; diff --git a/packages/beacon-node/test/e2e/db/api/beacon/repositories/blockArchive.test.ts b/packages/beacon-node/test/e2e/db/api/beacon/repositories/blockArchive.test.ts index 5ecdc4c8b963..3c7a37e52a8b 100644 --- a/packages/beacon-node/test/e2e/db/api/beacon/repositories/blockArchive.test.ts +++ b/packages/beacon-node/test/e2e/db/api/beacon/repositories/blockArchive.test.ts @@ -4,7 +4,7 @@ import {ssz} from "@lodestar/types"; import {BeaconDb} from "../../../../../../src/db/index.js"; import {startTmpBeaconDb} from "../../../../../utils/db.js"; -describe("BlockArchiveRepository", function () { +describe("BlockArchiveRepository", () => { let db: BeaconDb; const sampleBlock = ssz.phase0.SignedBeaconBlock.defaultValue(); diff --git a/packages/beacon-node/test/e2e/doppelganger/doppelganger.test.ts b/packages/beacon-node/test/e2e/doppelganger/doppelganger.test.ts index ab9061f1eacd..949d0104d641 100644 --- a/packages/beacon-node/test/e2e/doppelganger/doppelganger.test.ts +++ b/packages/beacon-node/test/e2e/doppelganger/doppelganger.test.ts @@ -22,7 +22,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 () { +describe.skip("doppelganger / doppelganger test", () => { const afterEachCallbacks: (() => Promise | void)[] = []; afterEach(async () => { while (afterEachCallbacks.length > 0) { @@ -34,7 +34,6 @@ describe.skip("doppelganger / doppelganger test", function () { const validatorCount = 1; const genesisSlotsDelay = 5; const beaconParams: Pick = { - // eslint-disable-next-line @typescript-eslint/naming-convention SECONDS_PER_SLOT: 2, }; @@ -78,7 +77,7 @@ describe.skip("doppelganger / doppelganger test", function () { return {beaconNode: bn, validators: validatorsWithDoppelganger}; } - it("should not have doppelganger protection if started before genesis", async function () { + it("should not have doppelganger protection if started before genesis", async () => { const committeeIndex = 0; const validatorIndex = 0; @@ -114,7 +113,7 @@ describe.skip("doppelganger / doppelganger test", function () { ); }); - it("should shut down validator if same key is active and started after genesis", async function () { + it("should shut down validator if same key is active and started after genesis", async () => { // set genesis time to allow at least an epoch const genesisTime = Math.floor(Date.now() / 1000) - SLOTS_PER_EPOCH * beaconParams.SECONDS_PER_SLOT; @@ -123,7 +122,7 @@ describe.skip("doppelganger / doppelganger test", function () { doppelgangerProtection: true, }); - const {beaconNode: bn2, validators: validators} = await createBNAndVC({ + const {beaconNode: bn2, validators} = await createBNAndVC({ genesisTime: bn.chain.getHeadState().genesisTime, }); @@ -150,7 +149,7 @@ describe.skip("doppelganger / doppelganger test", function () { ); }); - it("should shut down validator if same key is active with same BN and started after genesis", async function () { + it("should shut down validator if same key is active with same BN and started after genesis", async () => { const doppelgangerProtection = true; const testLoggerOpts: TestLoggerOpts = {level: LogLevel.info}; @@ -195,14 +194,14 @@ describe.skip("doppelganger / doppelganger test", function () { ); }); - it("should not shut down validator if key is different", async function () { + it("should not shut down validator if key is different", async () => { const doppelgangerProtection = true; const {beaconNode: bn, validators: validatorsWithDoppelganger} = await createBNAndVC({ doppelgangerProtection, }); - const {beaconNode: bn2, validators: validators} = await createBNAndVC({ + const {beaconNode: bn2, validators} = await createBNAndVC({ genesisTime: bn.chain.getHeadState().genesisTime, doppelgangerProtection: false, }); @@ -228,7 +227,7 @@ describe.skip("doppelganger / doppelganger test", function () { ); }); - it("should not sign block if doppelganger period has not passed and not started at genesis", async function () { + it("should not sign block if doppelganger period has not passed and not started at genesis", async () => { const doppelgangerProtection = true; // set genesis time to allow at least an epoch @@ -259,7 +258,7 @@ describe.skip("doppelganger / doppelganger test", function () { ).resolves.toBeUndefined(); }); - it("should not sign attestations if doppelganger period has not passed and started after genesis", async function () { + it("should not sign attestations if doppelganger period has not passed and started after genesis", async () => { const doppelgangerProtection = true; // set genesis time to allow at least an epoch diff --git a/packages/beacon-node/test/e2e/eth1/eth1ForBlockProduction.test.ts b/packages/beacon-node/test/e2e/eth1/eth1ForBlockProduction.test.ts index 17692cfcca3a..21cadeb55d2c 100644 --- a/packages/beacon-node/test/e2e/eth1/eth1ForBlockProduction.test.ts +++ b/packages/beacon-node/test/e2e/eth1/eth1ForBlockProduction.test.ts @@ -25,7 +25,7 @@ const pyrmontDepositsDataRoot = [ ]; // https://github.com/ChainSafe/lodestar/issues/5967 -describe.skip("eth1 / Eth1Provider", function () { +describe.skip("eth1 / Eth1Provider", () => { const controller = new AbortController(); const config = getTestnetConfig(); @@ -48,7 +48,7 @@ describe.skip("eth1 / Eth1Provider", function () { await LevelDbController.destroy(dbLocation); }); - it("Should fetch real Pyrmont eth1 data for block proposing", async function () { + it("Should fetch real Pyrmont eth1 data for block proposing", async () => { const eth1Options: Eth1Options = { enabled: true, providerUrls: [getGoerliRpcUrl()], @@ -68,7 +68,6 @@ describe.skip("eth1 / Eth1Provider", function () { // Resolves when Eth1ForBlockProduction has fetched both blocks and deposits const {eth1Datas, deposits} = await (async function resolveWithEth1DataAndDeposits() { - // eslint-disable-next-line no-constant-condition while (true) { const eth1Datas = await db.eth1Data.entries(); const deposits = await db.depositEvent.values(); diff --git a/packages/beacon-node/test/e2e/eth1/eth1MergeBlockTracker.test.ts b/packages/beacon-node/test/e2e/eth1/eth1MergeBlockTracker.test.ts index ae3e0c707542..9423bb716b3f 100644 --- a/packages/beacon-node/test/e2e/eth1/eth1MergeBlockTracker.test.ts +++ b/packages/beacon-node/test/e2e/eth1/eth1MergeBlockTracker.test.ts @@ -10,13 +10,11 @@ import {quantityToBigint} from "../../../src/eth1/provider/utils.js"; import {ZERO_HASH} from "../../../src/constants/index.js"; import {getGoerliRpcUrl} from "../../testParams.js"; -/* eslint-disable @typescript-eslint/naming-convention */ - // 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 () { +describe.skip("eth1 / Eth1MergeBlockTracker", () => { const logger = testLogger(); function getConfig(ttd: bigint): ChainConfig { diff --git a/packages/beacon-node/test/e2e/eth1/eth1Provider.test.ts b/packages/beacon-node/test/e2e/eth1/eth1Provider.test.ts index 8b7e9503485e..606845f40337 100644 --- a/packages/beacon-node/test/e2e/eth1/eth1Provider.test.ts +++ b/packages/beacon-node/test/e2e/eth1/eth1Provider.test.ts @@ -8,7 +8,7 @@ import {Eth1Block} from "../../../src/eth1/interface.js"; import {getGoerliRpcUrl} from "../../testParams.js"; // https://github.com/ChainSafe/lodestar/issues/5967 -describe.skip("eth1 / Eth1Provider", function () { +describe.skip("eth1 / Eth1Provider", () => { let controller: AbortController; beforeEach(() => { controller = new AbortController(); @@ -28,16 +28,16 @@ describe.skip("eth1 / Eth1Provider", function () { return new Eth1Provider(config, eth1Options, controller.signal); } - it("Should validate contract", async function () { + it("Should validate contract", async () => { await getEth1Provider().validateContract(); }); - it("Should get latest block number", async function () { + it("Should get latest block number", async () => { const blockNumber = await getEth1Provider().getBlockNumber(); expect(blockNumber).toBeGreaterThan(0); }); - it("Should get a specific block by number", async function () { + it("Should get a specific block by number", async () => { const goerliGenesisBlock: Eth1Block = { blockHash: fromHexString("0xbf7e331f7f7c1dd2e05159666b3bf8bc7a8a3a9eb1d518969eab529dd9b88c1a"), blockNumber: 0, @@ -47,7 +47,7 @@ describe.skip("eth1 / Eth1Provider", function () { expect(block && parseEth1Block(block)).toEqual(goerliGenesisBlock); }); - it("Should get deposits events for a block range", async function () { + it("Should get deposits events for a block range", async () => { const blockNumbers = goerliTestnetDepositEvents.map((log) => log.blockNumber); const fromBlock = Math.min(...blockNumbers); const toBlock = Math.min(...blockNumbers); @@ -74,26 +74,26 @@ describe.skip("eth1 / Eth1Provider", function () { code: "0x60806040526004361061003f5760003560e01c806301ffc9a71461004457806322895118146100a", }; - it("getBlocksByNumber: Should fetch a block range", async function () { + it("getBlocksByNumber: Should fetch a block range", async () => { const fromBlock = firstGoerliBlocks[0].blockNumber; const toBlock = firstGoerliBlocks[firstGoerliBlocks.length - 1].blockNumber; const blocks = await getEth1Provider().getBlocksByNumber(fromBlock, toBlock); expect(blocks.map(parseEth1Block)).toEqual(firstGoerliBlocks); }); - it("getBlockByNumber: Should fetch a single block", async function () { + it("getBlockByNumber: Should fetch a single block", async () => { const firstGoerliBlock = firstGoerliBlocks[0]; const block = await getEth1Provider().getBlockByNumber(firstGoerliBlock.blockNumber); expect(block && parseEth1Block(block)).toEqual(firstGoerliBlock); }); - it("getBlockNumber: Should fetch latest block number", async function () { + it("getBlockNumber: Should fetch latest block number", async () => { const blockNumber = await getEth1Provider().getBlockNumber(); expect(blockNumber).toBeInstanceOf(Number); expect(blockNumber).toBeGreaterThan(0); }); - it("getCode: Should fetch code for a contract", async function () { + it("getCode: Should fetch code for a contract", async () => { const code = await getEth1Provider().getCode(goerliSampleContract.address); expect(code).toEqual(expect.arrayContaining([goerliSampleContract.code])); }); diff --git a/packages/beacon-node/test/e2e/eth1/jsonRpcHttpClient.test.ts b/packages/beacon-node/test/e2e/eth1/jsonRpcHttpClient.test.ts index 4e290c6d6318..91131a89f379 100644 --- a/packages/beacon-node/test/e2e/eth1/jsonRpcHttpClient.test.ts +++ b/packages/beacon-node/test/e2e/eth1/jsonRpcHttpClient.test.ts @@ -7,7 +7,7 @@ import {JsonRpcHttpClient} from "../../../src/eth1/provider/jsonRpcHttpClient.js import {getGoerliRpcUrl} from "../../testParams.js"; import {RpcPayload} from "../../../src/eth1/interface.js"; -describe("eth1 / jsonRpcHttpClient", function () { +describe("eth1 / jsonRpcHttpClient", () => { vi.setConfig({testTimeout: 10_000}); const port = 36421; @@ -41,13 +41,13 @@ describe("eth1 / jsonRpcHttpClient", function () { { id: "Bad port", url: `http://localhost:${port + 1}`, - requestListener: (req, res) => res.end(), + requestListener: (_req, res) => res.end(), error: "", errorCode: "ECONNREFUSED", }, { id: "Not a JSON RPC endpoint", - requestListener: (req, res) => { + requestListener: (_req, res) => { res.setHeader("Content-Type", "text/html"); res.end(""); }, @@ -55,7 +55,7 @@ describe("eth1 / jsonRpcHttpClient", function () { }, { id: "Endpoint returns HTTP error", - requestListener: (req, res) => { + requestListener: (_req, res) => { res.statusCode = 404; res.end(); }, @@ -63,7 +63,7 @@ describe("eth1 / jsonRpcHttpClient", function () { }, { id: "RPC payload with error", - requestListener: (req, res) => { + requestListener: (_req, res) => { res.setHeader("Content-Type", "application/json"); res.end(JSON.stringify({jsonrpc: "2.0", id: 83, error: noMethodError})); }, @@ -71,7 +71,7 @@ describe("eth1 / jsonRpcHttpClient", function () { }, { id: "RPC payload with non-spec error: error has no message", - requestListener: (req, res) => { + requestListener: (_req, res) => { res.setHeader("Content-Type", "application/json"); res.end(JSON.stringify({jsonrpc: "2.0", id: 83, error: {code: noMethodError.code}})); }, @@ -79,7 +79,7 @@ describe("eth1 / jsonRpcHttpClient", function () { }, { id: "RPC payload with non-spec error: error is a string", - requestListener: (req, res) => { + requestListener: (_req, res) => { res.setHeader("Content-Type", "application/json"); res.end(JSON.stringify({jsonrpc: "2.0", id: 83, error: notInSpecError})); }, @@ -87,7 +87,7 @@ describe("eth1 / jsonRpcHttpClient", function () { }, { id: "RPC payload with no result", - requestListener: (req, res) => { + requestListener: (_req, res) => { res.setHeader("Content-Type", "application/json"); res.end(JSON.stringify({jsonrpc: "2.0", id: 83})); }, @@ -113,7 +113,7 @@ describe("eth1 / jsonRpcHttpClient", function () { const afterHooks: (() => Promise)[] = []; - afterEach(async function () { + afterEach(async () => { while (afterHooks.length) { const afterHook = afterHooks.pop(); if (afterHook) await afterHook(); @@ -124,7 +124,7 @@ describe("eth1 / jsonRpcHttpClient", function () { const {id, requestListener, abort, timeout} = testCase; let {url, payload} = testCase; - it(id, async function () { + it(id, async () => { if (requestListener) { if (!url) url = `http://localhost:${port}`; @@ -162,25 +162,24 @@ describe("eth1 / jsonRpcHttpClient", function () { } }); -describe("eth1 / jsonRpcHttpClient - with retries", function () { +describe("eth1 / jsonRpcHttpClient - with retries", () => { vi.setConfig({testTimeout: 10_000}); const port = 36421; const noMethodError = {code: -32601, message: "Method not found"}; const afterHooks: (() => Promise)[] = []; - afterEach(async function () { + afterEach(async () => { while (afterHooks.length) { const afterHook = afterHooks.pop(); if (afterHook) await afterHook().catch((e: Error) => { - // eslint-disable-next-line no-console console.error("Error in afterEach hook", e); }); } }); - it("should retry ENOTFOUND", async function () { + it("should retry ENOTFOUND", async () => { let retryCount = 0; const url = "https://goerli.fake-website.io"; @@ -202,7 +201,7 @@ describe("eth1 / jsonRpcHttpClient - with retries", function () { expect(retryCount).toBeWithMessage(retries, "ENOTFOUND should be retried before failing"); }); - it("should retry ECONNREFUSED", async function () { + it("should retry ECONNREFUSED", async () => { let retryCount = 0; const url = `http://localhost:${port + 1}`; @@ -224,10 +223,10 @@ describe("eth1 / jsonRpcHttpClient - with retries", function () { expect(retryCount).toBeWithMessage(retries, "code ECONNREFUSED should be retried before failing"); }); - it("should retry 404", async function () { + it("should retry 404", async () => { let requestCount = 0; - const server = http.createServer((req, res) => { + const server = http.createServer((_req, res) => { requestCount++; res.statusCode = 404; res.end(); @@ -254,7 +253,7 @@ describe("eth1 / jsonRpcHttpClient - with retries", function () { expect(requestCount).toBeWithMessage(retries + 1, "404 responses should be retried before failing"); }); - it("should retry timeout", async function () { + it("should retry timeout", async () => { let requestCount = 0; const server = http.createServer(async () => { @@ -285,7 +284,7 @@ describe("eth1 / jsonRpcHttpClient - with retries", function () { expect(requestCount).toBeWithMessage(retries + 1, "Timeout request should be retried before failing"); }); - it("should not retry aborted", async function () { + it("should not retry aborted", async () => { let requestCount = 0; const server = http.createServer(() => { requestCount++; @@ -315,10 +314,10 @@ describe("eth1 / jsonRpcHttpClient - with retries", function () { expect(requestCount).toBeWithMessage(1, "Aborted request should not be retried"); }); - it("should not retry payload error", async function () { + it("should not retry payload error", async () => { let requestCount = 0; - const server = http.createServer((req, res) => { + const server = http.createServer((_req, res) => { requestCount++; res.setHeader("Content-Type", "application/json"); res.end(JSON.stringify({jsonrpc: "2.0", id: 83, error: noMethodError})); diff --git a/packages/beacon-node/test/e2e/eth1/stream.test.ts b/packages/beacon-node/test/e2e/eth1/stream.test.ts index a683e885b453..ce65d4353f0e 100644 --- a/packages/beacon-node/test/e2e/eth1/stream.test.ts +++ b/packages/beacon-node/test/e2e/eth1/stream.test.ts @@ -6,7 +6,7 @@ import {getGoerliRpcUrl} from "../../testParams.js"; import {Eth1Options} from "../../../src/eth1/options.js"; // https://github.com/ChainSafe/lodestar/issues/5967 -describe.skip("Eth1 streams", function () { +describe.skip("Eth1 streams", () => { let controller: AbortController; beforeEach(() => { controller = new AbortController(); @@ -30,7 +30,7 @@ describe.skip("Eth1 streams", function () { const depositsToFetch = 1000; const eth1Params = {...config, maxBlocksPerPoll}; - it(`Should fetch ${depositsToFetch} deposits with getDepositsStream`, async function () { + it(`Should fetch ${depositsToFetch} deposits with getDepositsStream`, async () => { const depositsStream = getDepositsStream( medallaTestnetConfig.blockWithDepositActivity, getEth1Provider(), @@ -49,7 +49,7 @@ describe.skip("Eth1 streams", function () { expect(depositCount).toBeGreaterThan(depositsToFetch); }); - it(`Should fetch ${depositsToFetch} deposits with getDepositsAndBlockStreamForGenesis`, async function () { + it(`Should fetch ${depositsToFetch} deposits with getDepositsAndBlockStreamForGenesis`, async () => { const stream = getDepositsAndBlockStreamForGenesis( medallaTestnetConfig.blockWithDepositActivity, getEth1Provider(), diff --git a/packages/beacon-node/test/e2e/interop/genesisState.test.ts b/packages/beacon-node/test/e2e/interop/genesisState.test.ts index 2287c6a1deb8..739319a4257c 100644 --- a/packages/beacon-node/test/e2e/interop/genesisState.test.ts +++ b/packages/beacon-node/test/e2e/interop/genesisState.test.ts @@ -9,7 +9,6 @@ describe("interop / initDevState", () => { it("Create interop deposits", () => { const deposits = interopDeposits(config, ssz.phase0.DepositDataRootList.defaultViewDU(), 1); - /* eslint-disable @typescript-eslint/naming-convention */ expect(deposits.map((deposit) => ssz.phase0.Deposit.toJson(deposit))).toEqual([ { proof: [ diff --git a/packages/beacon-node/test/e2e/network/gossipsub.test.ts b/packages/beacon-node/test/e2e/network/gossipsub.test.ts index c19f3c7c4388..29a745455561 100644 --- a/packages/beacon-node/test/e2e/network/gossipsub.test.ts +++ b/packages/beacon-node/test/e2e/network/gossipsub.test.ts @@ -8,7 +8,7 @@ import {GossipType, GossipHandlers, GossipHandlerParamGeneric} from "../../../sr import {getNetworkForTest} from "../../utils/networkWithMockDb.js"; import {connect, onPeerConnect} from "../../utils/network.js"; -describe("gossipsub / main thread", function () { +describe("gossipsub / main thread", () => { vi.setConfig({testTimeout: 3000}); runTests({useWorker: false}); @@ -19,7 +19,7 @@ describe("gossipsub / main thread", function () { * Since we use vitest to run tests in parallel, including this causes the test to be unstable. * See https://github.com/ChainSafe/lodestar/issues/6358 */ -describe.skip("gossipsub / worker", function () { +describe.skip("gossipsub / worker", () => { vi.setConfig({testTimeout: 3000}); runTests({useWorker: true}); @@ -35,7 +35,6 @@ function runTests({useWorker}: {useWorker: boolean}): void { }); // Schedule all forks at ALTAIR_FORK_EPOCH to avoid generating the pubkeys cache - /* eslint-disable @typescript-eslint/naming-convention */ const config = createChainForkConfig({ ...defaultChainConfig, ALTAIR_FORK_EPOCH: 1, @@ -44,7 +43,6 @@ function runTests({useWorker}: {useWorker: boolean}): void { }); const START_SLOT = computeStartSlotAtEpoch(config.ALTAIR_FORK_EPOCH); - // eslint-disable-next-line @typescript-eslint/explicit-function-return-type async function mockModules(gossipHandlersPartial?: Partial) { const [netA, closeA] = await getNetworkForTest(`gossipsub-${useWorker ? "worker" : "main"}-A`, config, { opts: {useWorker}, @@ -63,9 +61,11 @@ function runTests({useWorker}: {useWorker: boolean}): void { return {netA, netB}; } - it("Publish and receive a voluntaryExit", async function () { + it("Publish and receive a voluntaryExit", async () => { let onVoluntaryExit: (ve: Uint8Array) => void; - const onVoluntaryExitPromise = new Promise((resolve) => (onVoluntaryExit = resolve)); + const onVoluntaryExitPromise = new Promise((resolve) => { + onVoluntaryExit = resolve; + }); const {netA, netB} = await mockModules({ [GossipType.voluntary_exit]: async ({gossipData}: GossipHandlerParamGeneric) => { @@ -98,9 +98,11 @@ function runTests({useWorker}: {useWorker: boolean}): void { ); }); - it("Publish and receive a blsToExecutionChange", async function () { + it("Publish and receive a blsToExecutionChange", async () => { let onBlsToExecutionChange: (blsToExec: Uint8Array) => void; - const onBlsToExecutionChangePromise = new Promise((resolve) => (onBlsToExecutionChange = resolve)); + const onBlsToExecutionChangePromise = new Promise((resolve) => { + onBlsToExecutionChange = resolve; + }); const {netA, netB} = await mockModules({ [GossipType.bls_to_execution_change]: async ({ @@ -134,9 +136,11 @@ function runTests({useWorker}: {useWorker: boolean}): void { ); }); - it("Publish and receive an attesterSlashing", async function () { + it("Publish and receive an attesterSlashing", async () => { let onAttesterSlashingChange: (payload: Uint8Array) => void; - const onAttesterSlashingChangePromise = new Promise((resolve) => (onAttesterSlashingChange = resolve)); + const onAttesterSlashingChangePromise = new Promise((resolve) => { + onAttesterSlashingChange = resolve; + }); const {netA, netB} = await mockModules({ [GossipType.attester_slashing]: async ({gossipData}: GossipHandlerParamGeneric) => { @@ -166,9 +170,11 @@ function runTests({useWorker}: {useWorker: boolean}): void { expect(Buffer.from(received)).toEqual(Buffer.from(ssz.phase0.AttesterSlashing.serialize(attesterSlashing))); }); - it("Publish and receive a proposerSlashing", async function () { + it("Publish and receive a proposerSlashing", async () => { let onProposerSlashingChange: (payload: Uint8Array) => void; - const onProposerSlashingChangePromise = new Promise((resolve) => (onProposerSlashingChange = resolve)); + const onProposerSlashingChangePromise = new Promise((resolve) => { + onProposerSlashingChange = resolve; + }); const {netA, netB} = await mockModules({ [GossipType.proposer_slashing]: async ({gossipData}: GossipHandlerParamGeneric) => { @@ -198,11 +204,11 @@ function runTests({useWorker}: {useWorker: boolean}): void { expect(Buffer.from(received)).toEqual(Buffer.from(ssz.phase0.ProposerSlashing.serialize(proposerSlashing))); }); - it("Publish and receive a LightClientOptimisticUpdate", async function () { + it("Publish and receive a LightClientOptimisticUpdate", async () => { let onLightClientOptimisticUpdate: (ou: Uint8Array) => void; - const onLightClientOptimisticUpdatePromise = new Promise( - (resolve) => (onLightClientOptimisticUpdate = resolve) - ); + const onLightClientOptimisticUpdatePromise = new Promise((resolve) => { + onLightClientOptimisticUpdate = resolve; + }); const {netA, netB} = await mockModules({ [GossipType.light_client_optimistic_update]: async ({ @@ -237,11 +243,11 @@ function runTests({useWorker}: {useWorker: boolean}): void { ); }); - it("Publish and receive a LightClientFinalityUpdate", async function () { + it("Publish and receive a LightClientFinalityUpdate", async () => { let onLightClientFinalityUpdate: (fu: Uint8Array) => void; - const onLightClientFinalityUpdatePromise = new Promise( - (resolve) => (onLightClientFinalityUpdate = resolve) - ); + const onLightClientFinalityUpdatePromise = new Promise((resolve) => { + onLightClientFinalityUpdate = resolve; + }); const {netA, netB} = await mockModules({ [GossipType.light_client_finality_update]: async ({ diff --git a/packages/beacon-node/test/e2e/network/mdns.test.ts b/packages/beacon-node/test/e2e/network/mdns.test.ts index d8e148e191fe..6a1be8094137 100644 --- a/packages/beacon-node/test/e2e/network/mdns.test.ts +++ b/packages/beacon-node/test/e2e/network/mdns.test.ts @@ -1,8 +1,8 @@ import {describe, it, afterEach, beforeEach, expect, vi} from "vitest"; -import {PeerId} from "@libp2p/interface"; +import {PrivateKey} from "@libp2p/interface"; import {multiaddr} from "@multiformats/multiaddr"; -import {createSecp256k1PeerId} from "@libp2p/peer-id-factory"; import {SignableENR} from "@chainsafe/enr"; +import {generateKeyPair} from "@libp2p/crypto/keys"; import {createBeaconConfig} from "@lodestar/config"; import {config} from "@lodestar/config/default"; import {ssz} from "@lodestar/types"; @@ -21,22 +21,23 @@ let port = 9000; const mu = "/ip4/127.0.0.1/tcp/0"; // https://github.com/ChainSafe/lodestar/issues/5967 -describe.skip("mdns", function () { +describe.skip("mdns", () => { const afterEachCallbacks: (() => Promise | void)[] = []; - afterEach(async () => { - await Promise.all(afterEachCallbacks.map((cb) => cb())); - afterEachCallbacks.splice(0, afterEachCallbacks.length); - }); - let controller: AbortController; + beforeEach(() => { controller = new AbortController(); }); - afterEach(() => controller.abort()); - async function getOpts(peerId: PeerId): Promise { + afterEach(async () => { + await Promise.all(afterEachCallbacks.map((cb) => cb())); + afterEachCallbacks.splice(0, afterEachCallbacks.length); + controller.abort(); + }); + + async function getOpts(privateKey: PrivateKey): Promise { const bindAddrUdp = `/ip4/0.0.0.0/udp/${port++}`; - const enr = SignableENR.createFromPeerId(peerId); + const enr = SignableENR.createFromPrivateKey(privateKey); enr.setLocationMultiaddr(multiaddr(bindAddrUdp)); return { @@ -68,7 +69,6 @@ describe.skip("mdns", function () { return {block, state, config: beaconConfig}; }); - // eslint-disable-next-line @typescript-eslint/explicit-function-return-type async function createTestNode(nodeName: string) { const {config} = getStaticData(); const chain = getMockedBeaconChain(); @@ -81,12 +81,12 @@ describe.skip("mdns", function () { const db = getMockedBeaconDb(); const gossipHandlers = {} as GossipHandlers; - const peerId = await createSecp256k1PeerId(); + const privateKey = await generateKeyPair("secp256k1"); const logger = testLogger(nodeName); - const opts = await getOpts(peerId); + const opts = await getOpts(privateKey); - const modules: Omit = { + const modules: Omit = { config, chain, db, @@ -97,7 +97,7 @@ describe.skip("mdns", function () { const network = await Network.init({ ...modules, - ...(await createNetworkModules(mu, peerId, {...opts, mdns: true})), + ...(await createNetworkModules(mu, privateKey, {...opts, mdns: true})), logger, }); @@ -111,12 +111,11 @@ describe.skip("mdns", function () { return {network, chain}; } - // eslint-disable-next-line @typescript-eslint/explicit-function-return-type async function createTestNodesAB() { return Promise.all([createTestNode("mdns-A"), createTestNode("mdns-B")]); } - it("should connect two peers on a LAN", async function () { + it("should connect two peers on a LAN", async () => { const [{network: netA}, {network: netB}] = await createTestNodesAB(); await Promise.all([onPeerConnect(netA), onPeerConnect(netB)]); expect(netA.getConnectedPeerCount()).toBe(1); diff --git a/packages/beacon-node/test/e2e/network/network.test.ts b/packages/beacon-node/test/e2e/network/network.test.ts index 094a75280e8b..2435b005efa1 100644 --- a/packages/beacon-node/test/e2e/network/network.test.ts +++ b/packages/beacon-node/test/e2e/network/network.test.ts @@ -9,13 +9,13 @@ import {connect, disconnect, onPeerConnect, onPeerDisconnect} from "../../utils/ import {getNetworkForTest} from "../../utils/networkWithMockDb.js"; import {getValidPeerId} from "../../utils/peer.js"; -describe("network / main thread", function () { +describe("network / main thread", () => { vi.setConfig({testTimeout: 3000}); runTests({useWorker: false}); }); -describe("network / worker", function () { +describe("network / worker", () => { vi.setConfig({testTimeout: 10_000}); runTests({useWorker: true}); @@ -38,7 +38,6 @@ function runTests({useWorker}: {useWorker: boolean}): void { }); afterEach(() => controller.abort()); - // eslint-disable-next-line @typescript-eslint/explicit-function-return-type async function createTestNode(nodeName: string) { const [network, closeAll] = await getNetworkForTest(nodeName, config, {opts: {useWorker}}); @@ -67,14 +66,14 @@ function runTests({useWorker}: {useWorker: boolean}): void { expect(networkIdentity.peerId).toBe(network.peerId.toString()); }); - it("should create a peer on connect", async function () { + it("should create a peer on connect", async () => { const [netA, netB] = await createTestNodesAB(); await Promise.all([onPeerConnect(netA), onPeerConnect(netB), connect(netA, netB)]); expect(netA.getConnectedPeerCount()).toBe(1); expect(netB.getConnectedPeerCount()).toBe(1); }); - it("should delete a peer on disconnect", async function () { + it("should delete a peer on disconnect", async () => { const [netA, netB] = await createTestNodesAB(); const connected = Promise.all([onPeerConnect(netA), onPeerConnect(netB)]); await connect(netA, netB); @@ -93,9 +92,9 @@ function runTests({useWorker}: {useWorker: boolean}): void { // Current implementation of discv5 consumer doesn't allow to deterministically force a peer to be found // a random find node lookup can yield no results if there are too few peers in the DHT - it.todo("should connect to new peer by subnet", async function () {}); + it.todo("should connect to new peer by subnet", async () => {}); - it("Should goodbye peers on stop", async function () { + it("Should goodbye peers on stop", async () => { const [netA, netB] = await createTestNodesAB(); const connected = Promise.all([onPeerConnect(netA), onPeerConnect(netB)]); diff --git a/packages/beacon-node/test/e2e/network/onWorker/dataSerialization.test.ts b/packages/beacon-node/test/e2e/network/onWorker/dataSerialization.test.ts index 09c74f1f5dfe..741fd4b46696 100644 --- a/packages/beacon-node/test/e2e/network/onWorker/dataSerialization.test.ts +++ b/packages/beacon-node/test/e2e/network/onWorker/dataSerialization.test.ts @@ -30,7 +30,7 @@ import {CommitteeSubscription} from "../../../../src/network/subnets/interface.j import {EchoWorker, getEchoWorker} from "./workerEchoHandler.js"; // TODO: Need to find the way to load the echoWorker in the test environment -describe.skip("data serialization through worker boundary", function () { +describe.skip("data serialization through worker boundary", () => { let echoWorker: EchoWorker; beforeAll(async () => { diff --git a/packages/beacon-node/test/e2e/network/peers/peerManager.test.ts b/packages/beacon-node/test/e2e/network/peers/peerManager.test.ts index 795a4bf67ecc..b46e151cadb3 100644 --- a/packages/beacon-node/test/e2e/network/peers/peerManager.test.ts +++ b/packages/beacon-node/test/e2e/network/peers/peerManager.test.ts @@ -1,7 +1,7 @@ import {describe, it, afterEach, expect, vi} from "vitest"; import {Connection} from "@libp2p/interface"; -import {CustomEvent} from "@libp2p/interface"; import {BitArray} from "@chainsafe/ssz"; +import {generateKeyPair} from "@libp2p/crypto/keys"; import {config} from "@lodestar/config/default"; import {altair, phase0, ssz} from "@lodestar/types"; import {sleep} from "@lodestar/utils"; @@ -22,7 +22,7 @@ import {LocalStatusCache} from "../../../../src/network/statusCache.js"; const logger = testLogger("peerManager"); -describe("network / peers / PeerManager", function () { +describe("network / peers / PeerManager", () => { const peerId1 = getValidPeerId(); const afterEachCallbacks: (() => Promise | void)[] = []; @@ -33,7 +33,6 @@ describe("network / peers / PeerManager", function () { } }); - // eslint-disable-next-line @typescript-eslint/explicit-function-return-type async function mockModules() { // Setup fake chain const block = ssz.phase0.SignedBeaconBlock.defaultValue(); @@ -48,7 +47,8 @@ describe("network / peers / PeerManager", function () { const clock = new Clock({config: beaconConfig, genesisTime: 0, signal: controller.signal}); const status = ssz.phase0.Status.defaultValue(); const statusCache = new LocalStatusCache(status); - const libp2p = await createNode("/ip4/127.0.0.1/tcp/0"); + const privateKey = await generateKeyPair("secp256k1"); + const libp2p = await createNode("/ip4/127.0.0.1/tcp/0", privateKey); afterEachCallbacks.push(async () => { controller.abort(); @@ -69,6 +69,7 @@ describe("network / peers / PeerManager", function () { const peerManager = new PeerManager( { + privateKey, libp2p, reqResp, logger, @@ -155,11 +156,11 @@ describe("network / peers / PeerManager", function () { remotePeer: peerId1, } as Connection; - it("Should emit peer connected event on relevant peer status", async function () { + it("Should emit peer connected event on relevant peer status", async () => { const {statusCache, libp2p, networkEventBus} = await mockModules(); // Simualate a peer connection, get() should return truthy - getConnectionsMap(libp2p).set(peerId1.toString(), [libp2pConnectionOutboud]); + getConnectionsMap(libp2p).set(peerId1.toString(), {key: peerId1, value: [libp2pConnectionOutboud]}); // Subscribe to `peerConnected` event, which must fire after checking peer relevance const peerConnectedPromise = waitForEvent(networkEventBus, NetworkEvent.peerConnected, 2000); @@ -174,11 +175,11 @@ describe("network / peers / PeerManager", function () { await peerConnectedPromise; }); - it("On peerConnect handshake flow", async function () { + it("On peerConnect handshake flow", async () => { const {statusCache, libp2p, reqResp, peerManager, networkEventBus} = await mockModules(); // Simualate a peer connection, get() should return truthy - getConnectionsMap(libp2p).set(peerId1.toString(), [libp2pConnectionOutboud]); + getConnectionsMap(libp2p).set(peerId1.toString(), {key: peerId1, value: [libp2pConnectionOutboud]}); // Subscribe to `peerConnected` event, which must fire after checking peer relevance const peerConnectedPromise = waitForEvent(networkEventBus, NetworkEvent.peerConnected, 2000); @@ -191,7 +192,7 @@ describe("network / peers / PeerManager", function () { reqResp.sendMetadata.mockResolvedValue(remoteMetadata); // Simualate a peer connection, get() should return truthy - getConnectionsMap(libp2p).set(peerId1.toString(), [libp2pConnectionOutboud]); + getConnectionsMap(libp2p).set(peerId1.toString(), {key: peerId1, value: [libp2pConnectionOutboud]}); libp2p.services.components.events.dispatchEvent( new CustomEvent("connection:open", {detail: libp2pConnectionOutboud}) ); diff --git a/packages/beacon-node/test/e2e/network/reqresp.test.ts b/packages/beacon-node/test/e2e/network/reqresp.test.ts index a3c8b7b66ca0..b7ab190166e7 100644 --- a/packages/beacon-node/test/e2e/network/reqresp.test.ts +++ b/packages/beacon-node/test/e2e/network/reqresp.test.ts @@ -15,13 +15,13 @@ import {PeerIdStr} from "../../../src/util/peerId.js"; /* eslint-disable require-yield, @typescript-eslint/naming-convention */ -describe("network / reqresp / main thread", function () { +describe("network / reqresp / main thread", () => { vi.setConfig({testTimeout: 3000}); runTests({useWorker: false}); }); -describe("network / reqresp / worker", function () { +describe("network / reqresp / worker", () => { vi.setConfig({testTimeout: 30_000}); runTests({useWorker: true}); @@ -76,7 +76,7 @@ function runTests({useWorker}: {useWorker: boolean}): void { return [netA, netB, await getPeerIdOf(netA), await getPeerIdOf(netB)]; } - it("should send/receive signed blocks", async function () { + it("should send/receive signed blocks", async () => { const req: phase0.BeaconBlocksByRangeRequest = {startSlot: 0, step: 1, count: 2}; const blocks: phase0.SignedBeaconBlock[] = []; for (let slot = req.startSlot; slot < req.count; slot++) { @@ -106,7 +106,7 @@ function runTests({useWorker}: {useWorker: boolean}): void { } }); - it("should send/receive a light client bootstrap message", async function () { + it("should send/receive a light client bootstrap message", async () => { const root: Root = ssz.phase0.BeaconBlockHeader.defaultValue().bodyRoot; const expectedValue = ssz.altair.LightClientBootstrap.defaultValue(); @@ -128,7 +128,7 @@ function runTests({useWorker}: {useWorker: boolean}): void { ); }); - it("should send/receive a light client optimistic update message", async function () { + it("should send/receive a light client optimistic update message", async () => { const expectedValue = ssz.altair.LightClientOptimisticUpdate.defaultValue(); const [netA, _, _0, peerIdB] = await createAndConnectPeers( @@ -149,7 +149,7 @@ function runTests({useWorker}: {useWorker: boolean}): void { ); }); - it("should send/receive a light client finality update message", async function () { + it("should send/receive a light client finality update message", async () => { const expectedValue = ssz.altair.LightClientFinalityUpdate.defaultValue(); const [netA, _, _0, peerIdB] = await createAndConnectPeers( @@ -170,7 +170,7 @@ function runTests({useWorker}: {useWorker: boolean}): void { ); }); - it("should send/receive a light client update message", async function () { + it("should send/receive a light client update message", async () => { const req: altair.LightClientUpdatesByRange = {startPeriod: 0, count: 2}; const lightClientUpdates: ResponseOutgoing[] = []; for (let slot = req.startPeriod; slot < req.count; slot++) { @@ -201,10 +201,11 @@ function runTests({useWorker}: {useWorker: boolean}): void { } }); - it("should handle a server error", async function () { + it("should handle a server error", async () => { const testErrorMessage = "TEST_EXAMPLE_ERROR_1234"; const [netA, _, _0, peerIdB] = await createAndConnectPeers( (method) => + // biome-ignore lint/correctness/useYield: No need for yield in test context async function* onRequest() { if (method === ReqRespMethod.BeaconBlocksByRange) { throw Error(testErrorMessage); @@ -218,7 +219,7 @@ function runTests({useWorker}: {useWorker: boolean}): void { ); }); - it("should handle a server error after emitting two blocks", async function () { + it("should handle a server error after emitting two blocks", async () => { const testErrorMessage = "TEST_EXAMPLE_ERROR_1234"; const [netA, _, _0, peerIdB] = await createAndConnectPeers( @@ -241,7 +242,7 @@ function runTests({useWorker}: {useWorker: boolean}): void { ); }); - it("trigger a TTFB_TIMEOUT error", async function () { + it("trigger a TTFB_TIMEOUT error", async () => { const ttfbTimeoutMs = 250; const [netA, _, _0, peerIdB] = await createAndConnectPeers( @@ -262,7 +263,7 @@ function runTests({useWorker}: {useWorker: boolean}): void { ); }); - it("trigger a RESP_TIMEOUT error", async function () { + it("trigger a RESP_TIMEOUT error", async () => { const respTimeoutMs = 250; const [netA, _, _0, peerIdB] = await createAndConnectPeers( @@ -284,9 +285,10 @@ function runTests({useWorker}: {useWorker: boolean}): void { ); }); - it("Sleep infinite on first byte", async function () { + it("Sleep infinite on first byte", async () => { const [netA, _, _0, peerIdB] = await createAndConnectPeers( (method) => + // biome-ignore lint/correctness/useYield: No need for yield in test context async function* onRequest() { if (method === ReqRespMethod.BeaconBlocksByRange) { await sleep(100000000); @@ -301,7 +303,7 @@ function runTests({useWorker}: {useWorker: boolean}): void { ); }); - it("Sleep infinite on second response chunk", async function () { + it("Sleep infinite on second response chunk", async () => { const [netA, _, _0, peerIdB] = await createAndConnectPeers( (method) => async function* onRequest() { diff --git a/packages/beacon-node/test/e2e/network/reqrespEncode.test.ts b/packages/beacon-node/test/e2e/network/reqrespEncode.test.ts index d96f405eae7c..eb994d2e848c 100644 --- a/packages/beacon-node/test/e2e/network/reqrespEncode.test.ts +++ b/packages/beacon-node/test/e2e/network/reqrespEncode.test.ts @@ -35,13 +35,12 @@ describe("reqresp encoder", () => { } }); - // eslint-disable-next-line @typescript-eslint/explicit-function-return-type async function getLibp2p() { const listen = `/ip4/127.0.0.1/tcp/${port++}`; const libp2p = await createLibp2p({ transports: [tcp()], streamMuxers: [mplex()], - connectionEncryption: [noise()], + connectionEncrypters: [noise()], addresses: { listen: [listen], }, @@ -50,11 +49,11 @@ describe("reqresp encoder", () => { return {libp2p, multiaddr: multiaddr(`${listen}/p2p/${libp2p.peerId.toString()}`)}; } - // eslint-disable-next-line @typescript-eslint/explicit-function-return-type async function getReqResp(getHandler?: GetReqRespHandlerFn) { const {libp2p, multiaddr} = await getLibp2p(); const getHandlerNoop: GetReqRespHandlerFn = () => + // biome-ignore lint/correctness/useYield: No need for yield in test context async function* (): AsyncIterable { throw Error("not implemented"); }; @@ -76,7 +75,6 @@ describe("reqresp encoder", () => { return {libp2p, multiaddr, reqresp: new ReqRespBeaconNode(modules)}; } - // eslint-disable-next-line @typescript-eslint/explicit-function-return-type async function dialProtocol({ dialer, toMultiaddr, diff --git a/packages/beacon-node/test/e2e/sync/finalizedSync.test.ts b/packages/beacon-node/test/e2e/sync/finalizedSync.test.ts index 01293285d756..ba98f2a1facd 100644 --- a/packages/beacon-node/test/e2e/sync/finalizedSync.test.ts +++ b/packages/beacon-node/test/e2e/sync/finalizedSync.test.ts @@ -14,13 +14,12 @@ import {ChainEvent} from "../../../src/chain/index.js"; import {connect, onPeerConnect} from "../../utils/network.js"; import {testLogger, LogLevel, TestLoggerOpts} from "../../utils/logger.js"; -describe("sync / finalized sync", function () { +describe("sync / finalized sync", () => { // chain is finalized at slot 32, plus 4 slots for genesis delay => ~72s it should sync pretty fast vi.setConfig({testTimeout: 90_000}); const validatorCount = 8; const testParams: Pick = { - // eslint-disable-next-line @typescript-eslint/naming-convention SECONDS_PER_SLOT: 2, }; @@ -32,7 +31,7 @@ describe("sync / finalized sync", function () { } }); - it("should do a finalized sync from another BN", async function () { + it("should do a finalized sync from another BN", async () => { // single node at beginning, use main thread to verify bls const genesisSlotsDelay = 4; const genesisTime = Math.floor(Date.now() / 1000) + genesisSlotsDelay * testParams.SECONDS_PER_SLOT; @@ -114,7 +113,7 @@ describe("sync / finalized sync", function () { try { await waitForSynced; loggerNodeB.info("Node B synced to Node A, received head block", {slot: head.message.slot}); - } catch (e) { + } catch (_e) { assert.fail("Failed to sync to other node in time"); } }); diff --git a/packages/beacon-node/test/e2e/sync/unknownBlockSync.test.ts b/packages/beacon-node/test/e2e/sync/unknownBlockSync.test.ts index 31f640269db7..290213d2b1ee 100644 --- a/packages/beacon-node/test/e2e/sync/unknownBlockSync.test.ts +++ b/packages/beacon-node/test/e2e/sync/unknownBlockSync.test.ts @@ -17,12 +17,11 @@ import {testLogger, LogLevel, TestLoggerOpts} from "../../utils/logger.js"; import {BlockError, BlockErrorCode} from "../../../src/chain/errors/index.js"; import {BlockSource, getBlockInput} from "../../../src/chain/blocks/types.js"; -describe("sync / unknown block sync", function () { +describe("sync / unknown block sync", () => { vi.setConfig({testTimeout: 40_000}); const validatorCount = 8; const testParams: Pick = { - // eslint-disable-next-line @typescript-eslint/naming-convention SECONDS_PER_SLOT: 2, }; @@ -46,7 +45,7 @@ describe("sync / unknown block sync", function () { ]; for (const {id, event} of testCases) { - it(id, async function () { + it(id, async () => { // the node needs time to transpile/initialize bls worker threads const genesisSlotsDelay = 4; const genesisTime = Math.floor(Date.now() / 1000) + genesisSlotsDelay * testParams.SECONDS_PER_SLOT; diff --git a/packages/beacon-node/test/globalSetup.ts b/packages/beacon-node/test/globalSetup.ts index 8194c76662df..f41a7f249b9b 100644 --- a/packages/beacon-node/test/globalSetup.ts +++ b/packages/beacon-node/test/globalSetup.ts @@ -11,7 +11,6 @@ export async function setup(): Promise { // Override FIELD_ELEMENTS_PER_BLOB if its a dev run, mostly to distinguish from // spec runs if (process.env.LODESTAR_PRESET === "minimal" && process.env.DEV_RUN) { - // eslint-disable-next-line @typescript-eslint/naming-convention setActivePreset(PresetName.minimal, {FIELD_ELEMENTS_PER_BLOB: 4096}); } } diff --git a/packages/beacon-node/test/memory/bytesHex.ts b/packages/beacon-node/test/memory/bytesHex.ts index 44115d345b2c..c7429869dac7 100644 --- a/packages/beacon-node/test/memory/bytesHex.ts +++ b/packages/beacon-node/test/memory/bytesHex.ts @@ -45,7 +45,6 @@ function testRunnerMemoryBpi(testCases: {getInstance: (bytes: number) => unknown convergeFactor: 0.2 / 100, }); - // eslint-disable-next-line no-console console.log(`${id.padEnd(longestId)} - ${bpi.toFixed(1)} bytes / instance`); } } diff --git a/packages/beacon-node/test/memory/pubkeysToIndex.ts b/packages/beacon-node/test/memory/pubkeysToIndex.ts index b647d153dba2..32cdf6e82296 100644 --- a/packages/beacon-node/test/memory/pubkeysToIndex.ts +++ b/packages/beacon-node/test/memory/pubkeysToIndex.ts @@ -52,7 +52,6 @@ function testRunnerMemoryBpi(testCases: {getInstance: (bytes: number) => unknown sampleEvery: 5, }); - // eslint-disable-next-line no-console console.log(`${id.padEnd(longestId)} - ${bpi.toFixed(1)} bytes / instance`); } } diff --git a/packages/beacon-node/test/memory/seenAttestationData.ts b/packages/beacon-node/test/memory/seenAttestationData.ts index c6735bd861e9..44a82dcd5841 100644 --- a/packages/beacon-node/test/memory/seenAttestationData.ts +++ b/packages/beacon-node/test/memory/seenAttestationData.ts @@ -53,7 +53,6 @@ function testRunnerMemoryBpi(testCases: {getInstance: (bytes: number) => unknown sampleEvery: 5, }); - // eslint-disable-next-line no-console console.log(`${id.padEnd(longestId)} - ${bpi.toFixed(1)} bytes / instance`); } } diff --git a/packages/beacon-node/test/memory/testRunnerMemory.ts b/packages/beacon-node/test/memory/testRunnerMemory.ts index a5c4df9e5794..05e7c8afab01 100644 --- a/packages/beacon-node/test/memory/testRunnerMemory.ts +++ b/packages/beacon-node/test/memory/testRunnerMemory.ts @@ -57,7 +57,6 @@ export async function testRunnerMemoryGc(opts: TestRunnerMemoryOpts): Prom usedMemoryArr.push(totalUsedMemoryDiff); const usedMemoryReg = linearRegression(xs, usedMemoryArr); - // eslint-disable-next-line no-console console.log("totalUsedMemoryDiff", totalUsedMemoryDiff, usedMemoryReg); } } @@ -137,7 +136,6 @@ export function testRunnerMemory(opts: TestRunnerMemoryOpts): number { } if (logEachSample) { - // eslint-disable-next-line no-console console.log(i, memoryUsage.rss / maxRssBytes, {m}); } diff --git a/packages/beacon-node/test/memory/unfinalizedPubkey2Index.ts b/packages/beacon-node/test/memory/unfinalizedPubkey2Index.ts index b37967d16ca4..1a317a7fe9d3 100644 --- a/packages/beacon-node/test/memory/unfinalizedPubkey2Index.ts +++ b/packages/beacon-node/test/memory/unfinalizedPubkey2Index.ts @@ -1,4 +1,5 @@ import crypto from "node:crypto"; +// biome-ignore lint/suspicious/noShadowRestrictedNames: We explicitly want `Map` name to be imported import {Map} from "immutable"; import {ValidatorIndex} from "@lodestar/types"; import {toMemoryEfficientHexStr} from "@lodestar/state-transition/src/cache/pubkeyCache.js"; @@ -48,7 +49,6 @@ function testRunnerMemoryBpi(testCases: {getInstance: (bytes: number) => unknown sampleEvery: 5, }); - // eslint-disable-next-line no-console console.log(`${id.padEnd(longestId)} - ${bpi.toFixed(1)} bytes / instance`); } } diff --git a/packages/beacon-node/test/mocks/beaconSyncMock.ts b/packages/beacon-node/test/mocks/beaconSyncMock.ts index 00ef193fdf6e..4d9f11ba90fd 100644 --- a/packages/beacon-node/test/mocks/beaconSyncMock.ts +++ b/packages/beacon-node/test/mocks/beaconSyncMock.ts @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/naming-convention */ import {Mocked, vi} from "vitest"; import {BeaconSync} from "../../src/sync/index.js"; diff --git a/packages/beacon-node/test/mocks/mockedBeaconChain.ts b/packages/beacon-node/test/mocks/mockedBeaconChain.ts index addeacf26a89..a69efc55836c 100644 --- a/packages/beacon-node/test/mocks/mockedBeaconChain.ts +++ b/packages/beacon-node/test/mocks/mockedBeaconChain.ts @@ -1,5 +1,5 @@ -/* eslint-disable @typescript-eslint/naming-convention */ import {vi, Mocked, Mock} from "vitest"; +import {PubkeyIndexMap} from "@chainsafe/pubkey-index-map"; import {config as defaultConfig} from "@lodestar/config/default"; import {ChainForkConfig} from "@lodestar/config"; import {ForkChoice, ProtoBlock, EpochDifference} from "@lodestar/fork-choice"; @@ -120,15 +120,15 @@ vi.mock("../../src/chain/chain.js", async (importActual) => { getClientVersion: vi.fn(), }, executionBuilder: {}, - // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-expect-error eth1: new Eth1ForBlockProduction(), opPool: new OpPool(), aggregatedAttestationPool: new AggregatedAttestationPool(config), - // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-expect-error beaconProposerCache: new BeaconProposerCache(), shufflingCache: new ShufflingCache(), + pubkey2index: new PubkeyIndexMap(), + index2pubkey: [], produceCommonBlockBody: vi.fn(), getProposerHead: vi.fn(), produceBlock: vi.fn(), @@ -138,6 +138,7 @@ vi.mock("../../src/chain/chain.js", async (importActual) => { predictProposerHead: vi.fn(), getHeadStateAtCurrentEpoch: vi.fn(), getHeadState: vi.fn(), + getStateBySlot: vi.fn(), updateBuilderStatus: vi.fn(), processBlock: vi.fn(), regenStateForAttestationVerification: vi.fn(), @@ -169,7 +170,6 @@ export type MockedBeaconChainOptions = { export function getMockedBeaconChain(opts?: Partial): MockedBeaconChain { const {clock, genesisTime, config} = opts ?? {}; - // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-expect-error return new BeaconChain({ clock: clock ?? "fake", diff --git a/packages/beacon-node/test/mocks/mockedBeaconDb.ts b/packages/beacon-node/test/mocks/mockedBeaconDb.ts index 8b99c85d2345..eb209c9b44fb 100644 --- a/packages/beacon-node/test/mocks/mockedBeaconDb.ts +++ b/packages/beacon-node/test/mocks/mockedBeaconDb.ts @@ -62,7 +62,6 @@ vi.mock("../../src/db/index.js", async (importActual) => { return { ...mod, - // eslint-disable-next-line @typescript-eslint/naming-convention BeaconDb: mockedBeaconDb, }; }); diff --git a/packages/beacon-node/test/mocks/mockedNetwork.ts b/packages/beacon-node/test/mocks/mockedNetwork.ts index ddf70aa1b5aa..9258acc9bc1b 100644 --- a/packages/beacon-node/test/mocks/mockedNetwork.ts +++ b/packages/beacon-node/test/mocks/mockedNetwork.ts @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/naming-convention */ import {vi, Mocked} from "vitest"; import {Network, INetwork} from "../../src/network/index.js"; diff --git a/packages/beacon-node/test/perf/api/impl/validator/attester.test.ts b/packages/beacon-node/test/perf/api/impl/validator/attester.test.ts index 803d6c84c408..807e29c55b52 100644 --- a/packages/beacon-node/test/perf/api/impl/validator/attester.test.ts +++ b/packages/beacon-node/test/perf/api/impl/validator/attester.test.ts @@ -1,5 +1,4 @@ import {itBench} from "@dapplion/benchmark"; -// eslint-disable-next-line import/no-relative-packages import {generatePerfTestCachedStatePhase0, numValidators} from "../../../../../../state-transition/test/perf/util.js"; import {getPubkeysForIndices} from "../../../../../src/api/impl/validator/utils.js"; import {linspace} from "../../../../../src/util/numpy.js"; diff --git a/packages/beacon-node/test/perf/bls/bls.test.ts b/packages/beacon-node/test/perf/bls/bls.test.ts index 988052f4a95c..9f1f90a4d879 100644 --- a/packages/beacon-node/test/perf/bls/bls.test.ts +++ b/packages/beacon-node/test/perf/bls/bls.test.ts @@ -11,7 +11,7 @@ import { } from "@chainsafe/blst"; import {linspace} from "../../../src/util/numpy.js"; -describe("BLS ops", function () { +describe("BLS ops", () => { type Keypair = {publicKey: PublicKey; secretKey: SecretKey}; // signature needs to be in Uint8Array to match real situation type BlsSet = {publicKey: PublicKey; message: Uint8Array; signature: Uint8Array}; diff --git a/packages/beacon-node/test/perf/chain/opPools/aggregatedAttestationPool.test.ts b/packages/beacon-node/test/perf/chain/opPools/aggregatedAttestationPool.test.ts index 45fc07281c3b..89bd76f34eb3 100644 --- a/packages/beacon-node/test/perf/chain/opPools/aggregatedAttestationPool.test.ts +++ b/packages/beacon-node/test/perf/chain/opPools/aggregatedAttestationPool.test.ts @@ -13,7 +13,6 @@ import {ExecutionStatus, ForkChoice, IForkChoiceStore, ProtoArray, DataAvailabil import {ssz} from "@lodestar/types"; import {createChainForkConfig, defaultChainConfig} from "@lodestar/config"; -// eslint-disable-next-line import/no-relative-packages import {generatePerfTestCachedStateAltair} from "../../../../../state-transition/test/perf/util.js"; import {AggregatedAttestationPool} from "../../../../src/chain/opPools/aggregatedAttestationPool.js"; diff --git a/packages/beacon-node/test/perf/chain/opPools/opPool.test.ts b/packages/beacon-node/test/perf/chain/opPools/opPool.test.ts index 6e420f0e1011..9d518c03eec9 100644 --- a/packages/beacon-node/test/perf/chain/opPools/opPool.test.ts +++ b/packages/beacon-node/test/perf/chain/opPools/opPool.test.ts @@ -7,7 +7,6 @@ import { } from "@lodestar/params"; import {CachedBeaconStateAltair} from "@lodestar/state-transition"; import {ssz} from "@lodestar/types"; -// eslint-disable-next-line import/no-relative-packages import {generatePerfTestCachedStateAltair} from "../../../../../state-transition/test/perf/util.js"; import {OpPool} from "../../../../src/chain/opPools/opPool.js"; import {generateBlsToExecutionChanges} from "../../../fixtures/capella.js"; diff --git a/packages/beacon-node/test/perf/chain/produceBlock/produceBlockBody.test.ts b/packages/beacon-node/test/perf/chain/produceBlock/produceBlockBody.test.ts index 7bf8c2f7252f..fdd6f60f5a47 100644 --- a/packages/beacon-node/test/perf/chain/produceBlock/produceBlockBody.test.ts +++ b/packages/beacon-node/test/perf/chain/produceBlock/produceBlockBody.test.ts @@ -5,7 +5,6 @@ import {LevelDbController} from "@lodestar/db"; import {SAFE_SLOTS_TO_IMPORT_OPTIMISTICALLY} from "@lodestar/params"; import {defaultOptions as defaultValidatorOptions} from "@lodestar/validator"; import {CachedBeaconStateAltair} from "@lodestar/state-transition"; -// eslint-disable-next-line import/no-relative-packages import {generatePerfTestCachedStateAltair} from "../../../../../state-transition/test/perf/util.js"; import {BeaconChain} from "../../../../src/chain/index.js"; import {BlockType, produceBlockBody} from "../../../../src/chain/produceBlock/produceBlockBody.js"; diff --git a/packages/beacon-node/test/perf/chain/seenCache/seenAggregateAndProof.test.ts b/packages/beacon-node/test/perf/chain/seenCache/seenAggregateAndProof.test.ts index 8ba77ca8692f..49c3123c14dd 100644 --- a/packages/beacon-node/test/perf/chain/seenCache/seenAggregateAndProof.test.ts +++ b/packages/beacon-node/test/perf/chain/seenCache/seenAggregateAndProof.test.ts @@ -3,7 +3,7 @@ import {BitArray} from "@chainsafe/ssz"; import {TARGET_AGGREGATORS_PER_COMMITTEE} from "@lodestar/params"; import {SeenAggregatedAttestations} from "../../../../src/chain/seenCache/seenAggregateAndProof.js"; -describe("SeenAggregatedAttestations perf test", function () { +describe("SeenAggregatedAttestations perf test", () => { const targetEpoch = 2022; const attDataRoot = "0x55e1a1cce2aeb66f85b2285b8cb7aa55dfb67148b5e0067f0692b61ddbd2824b"; const fullByte = 0b11111111; diff --git a/packages/beacon-node/test/perf/chain/stateCache/inMemoryCheckpointsCache.test.ts b/packages/beacon-node/test/perf/chain/stateCache/inMemoryCheckpointsCache.test.ts index 3a4774655e7f..17a46b09af8d 100644 --- a/packages/beacon-node/test/perf/chain/stateCache/inMemoryCheckpointsCache.test.ts +++ b/packages/beacon-node/test/perf/chain/stateCache/inMemoryCheckpointsCache.test.ts @@ -4,7 +4,7 @@ import {ssz, phase0} from "@lodestar/types"; import {generateCachedState} from "../../../utils/state.js"; import {InMemoryCheckpointStateCache, toCheckpointHex} from "../../../../src/chain/stateCache/index.js"; -describe("InMemoryCheckpointStateCache perf tests", function () { +describe("InMemoryCheckpointStateCache perf tests", () => { setBenchOpts({noThreshold: true}); let state: CachedBeaconStateAllForks; diff --git a/packages/beacon-node/test/perf/chain/stateCache/updateUnfinalizedPubkeys.test.ts b/packages/beacon-node/test/perf/chain/stateCache/updateUnfinalizedPubkeys.test.ts index eab66d2bee53..a4bdbe9710cb 100644 --- a/packages/beacon-node/test/perf/chain/stateCache/updateUnfinalizedPubkeys.test.ts +++ b/packages/beacon-node/test/perf/chain/stateCache/updateUnfinalizedPubkeys.test.ts @@ -15,7 +15,7 @@ import {generateCachedElectraState} from "../../../utils/state.js"; // ✔ updateUnfinalizedPubkeys - updating 10 pubkeys 1444.173 ops/s 692.4380 us/op - 1057 runs 6.03 s // ✔ updateUnfinalizedPubkeys - updating 100 pubkeys 189.5965 ops/s 5.274358 ms/op - 57 runs 1.15 s // ✔ updateUnfinalizedPubkeys - updating 1000 pubkeys 12.90495 ops/s 77.48967 ms/op - 13 runs 1.62 s -describe("updateUnfinalizedPubkeys perf tests", function () { +describe("updateUnfinalizedPubkeys perf tests", () => { setBenchOpts({noThreshold: true}); const numPubkeysToBeFinalizedCases = [10, 100, 1000]; diff --git a/packages/beacon-node/test/perf/chain/validation/aggregateAndProof.test.ts b/packages/beacon-node/test/perf/chain/validation/aggregateAndProof.test.ts index 3fc7efe9d675..5e28a7c3b898 100644 --- a/packages/beacon-node/test/perf/chain/validation/aggregateAndProof.test.ts +++ b/packages/beacon-node/test/perf/chain/validation/aggregateAndProof.test.ts @@ -1,6 +1,5 @@ import {itBench} from "@dapplion/benchmark"; import {ssz} from "@lodestar/types"; -// eslint-disable-next-line import/no-relative-packages import {generateTestCachedBeaconStateOnlyValidators} from "../../../../../state-transition/test/perf/util.js"; import {validateApiAggregateAndProof, validateGossipAggregateAndProof} from "../../../../src/chain/validation/index.js"; import {getAggregateAndProofValidData} from "../../../utils/validationData/aggregateAndProof.js"; diff --git a/packages/beacon-node/test/perf/chain/validation/attestation.test.ts b/packages/beacon-node/test/perf/chain/validation/attestation.test.ts index e942e1ea17d0..696b6bdb1871 100644 --- a/packages/beacon-node/test/perf/chain/validation/attestation.test.ts +++ b/packages/beacon-node/test/perf/chain/validation/attestation.test.ts @@ -1,7 +1,6 @@ import {itBench, setBenchOpts} from "@dapplion/benchmark"; import {expect} from "chai"; import {ssz} from "@lodestar/types"; -// eslint-disable-next-line import/no-relative-packages import {generateTestCachedBeaconStateOnlyValidators} from "../../../../../state-transition/test/perf/util.js"; import {validateGossipAttestationsSameAttData} from "../../../../src/chain/validation/index.js"; import {getAttestationValidData} from "../../../utils/validationData/attestation.js"; diff --git a/packages/beacon-node/test/perf/chain/verifyImportBlocks.test.ts b/packages/beacon-node/test/perf/chain/verifyImportBlocks.test.ts index a21c28adaec0..cd4d61b173c7 100644 --- a/packages/beacon-node/test/perf/chain/verifyImportBlocks.test.ts +++ b/packages/beacon-node/test/perf/chain/verifyImportBlocks.test.ts @@ -4,17 +4,9 @@ import {SAFE_SLOTS_TO_IMPORT_OPTIMISTICALLY, SLOTS_PER_EPOCH} from "@lodestar/pa import {LevelDbController} from "@lodestar/db"; import {sleep} from "@lodestar/utils"; import {defaultOptions as defaultValidatorOptions} from "@lodestar/validator"; -// eslint-disable-next-line import/no-relative-packages import {rangeSyncTest} from "../../../../state-transition/test/perf/params.js"; -import { - getNetworkCachedState, - getNetworkCachedBlock, - // eslint-disable-next-line import/no-relative-packages -} from "../../../../state-transition/test/utils/testFileCache.js"; -import { - beforeValue, - // eslint-disable-next-line import/no-relative-packages -} from "../../../../state-transition/test/utils/beforeValueMocha.js"; +import {getNetworkCachedState, getNetworkCachedBlock} from "../../../../state-transition/test/utils/testFileCache.js"; +import {beforeValue} from "../../../../state-transition/test/utils/beforeValueMocha.js"; import {BeaconChain} from "../../../src/chain/index.js"; import {ExecutionEngineDisabled} from "../../../src/execution/engine/index.js"; import {Eth1ForBlockProductionDisabled} from "../../../src/eth1/index.js"; @@ -36,13 +28,22 @@ describe.skip("verify+import blocks - range sync perf test", () => { yieldEventLoopAfterEach: true, // So SubTree(s)'s WeakRef can be garbage collected https://github.com/nodejs/node/issues/39902 }); - before("Check correct params", () => { + let db: BeaconDb; + + before("Check correct params", async () => { // Must start at the first slot of the epoch to have a proper checkpoint state. // Using `computeStartSlotAtEpoch(...) - 1` will cause the chain to initialize with a state that's not the checkpoint // state, so processing the first block of the epoch will cause error `BLOCK_ERROR_WOULD_REVERT_FINALIZED_SLOT` if (rangeSyncTest.startSlot % SLOTS_PER_EPOCH !== 0) { throw Error("startSlot must be the first slot in the epoch"); } + + db = new BeaconDb(config, await LevelDbController.create({name: ".tmpdb"}, {logger})); + }); + + after(async () => { + // If before blocks fail, db won't be declared + if (db !== undefined) await db.close(); }); const blocks = beforeValue( @@ -65,15 +66,6 @@ describe.skip("verify+import blocks - range sync perf test", () => { return state; }, timeoutInfura); - let db: BeaconDb; - before(async () => { - db = new BeaconDb(config, await LevelDbController.create({name: ".tmpdb"}, {logger})); - }); - after(async () => { - // If before blocks fail, db won't be declared - if (db !== undefined) await db.close(); - }); - itBench({ id: `altair verifyImport ${network}_s${startSlot}:${slotCount}`, minRuns: 5, diff --git a/packages/beacon-node/test/perf/network/gossip/encoding.test.ts b/packages/beacon-node/test/perf/network/gossip/encoding.test.ts index 693c91f59249..e8e889de2194 100644 --- a/packages/beacon-node/test/perf/network/gossip/encoding.test.ts +++ b/packages/beacon-node/test/perf/network/gossip/encoding.test.ts @@ -8,7 +8,7 @@ import {toHex} from "@lodestar/utils"; ✔ Buffer.from 6696982 ops/s 149.3210 ns/op - 2023 runs 0.454 s ✔ shared Buffer 1.013911e+7 ops/s 98.62800 ns/op - 3083 runs 0.404 s */ -describe("encoding", function () { +describe("encoding", () => { const msgId = Uint8Array.from(Array.from({length: 20}, (_, i) => i)); const runsFactor = 1000; diff --git a/packages/beacon-node/test/perf/network/noise/sendData.test.ts b/packages/beacon-node/test/perf/network/noise/sendData.test.ts index 35538a417adf..49e37980a598 100644 --- a/packages/beacon-node/test/perf/network/noise/sendData.test.ts +++ b/packages/beacon-node/test/perf/network/noise/sendData.test.ts @@ -1,11 +1,12 @@ import {itBench} from "@dapplion/benchmark"; import {duplexPair} from "it-pair/duplex"; -import {createSecp256k1PeerId} from "@libp2p/peer-id-factory"; import {pipe} from "it-pipe"; import drain from "it-drain"; import {defaultLogger} from "@libp2p/logger"; import {noise} from "@chainsafe/libp2p-noise"; import {Uint8ArrayList} from "uint8arraylist"; +import {generateKeyPair} from "@libp2p/crypto/keys"; +import {peerIdFromPrivateKey} from "@libp2p/peer-id"; describe("network / noise / sendData", () => { const numberOfMessages = 1000; @@ -24,15 +25,17 @@ describe("network / noise / sendData", () => { itBench({ id: `send data - ${numberOfMessages} ${messageLength}B messages`, beforeEach: async () => { - const peerA = await createSecp256k1PeerId(); - const peerB = await createSecp256k1PeerId(); - const noiseA = noise()({logger: defaultLogger()}); - const noiseB = noise()({logger: defaultLogger()}); + const privateKeyA = await generateKeyPair("secp256k1"); + const privateKeyB = await generateKeyPair("secp256k1"); + const peerA = peerIdFromPrivateKey(privateKeyA); + const peerB = peerIdFromPrivateKey(privateKeyB); + const noiseA = noise()({logger: defaultLogger(), privateKey: privateKeyA, peerId: peerA}); + const noiseB = noise()({logger: defaultLogger(), privateKey: privateKeyB, peerId: peerB}); const [inboundConnection, outboundConnection] = duplexPair(); const [outbound, inbound] = await Promise.all([ - noiseA.secureOutbound(peerA, outboundConnection, peerB), - noiseB.secureInbound(peerB, inboundConnection, peerA), + noiseA.secureOutbound(outboundConnection, {remotePeer: peerB}), + noiseB.secureInbound(inboundConnection, {remotePeer: peerA}), ]); return {connA: outbound.conn, connB: inbound.conn, data: new Uint8Array(messageLength)}; diff --git a/packages/beacon-node/test/perf/network/peers/util/prioritizePeers.test.ts b/packages/beacon-node/test/perf/network/peers/util/prioritizePeers.test.ts index a0d648a161ea..18dca2c670cd 100644 --- a/packages/beacon-node/test/perf/network/peers/util/prioritizePeers.test.ts +++ b/packages/beacon-node/test/perf/network/peers/util/prioritizePeers.test.ts @@ -1,6 +1,7 @@ import {itBench} from "@dapplion/benchmark"; import {PeerId} from "@libp2p/interface"; -import {createSecp256k1PeerId} from "@libp2p/peer-id-factory"; +import {generateKeyPair} from "@libp2p/crypto/keys"; +import {peerIdFromPrivateKey} from "@libp2p/peer-id"; import {ATTESTATION_SUBNET_COUNT, SYNC_COMMITTEE_SUBNET_COUNT} from "@lodestar/params"; import {altair, phase0} from "@lodestar/types"; import {defaultNetworkOptions} from "../../../../../src/network/options.js"; @@ -10,9 +11,10 @@ import {getAttnets, getSyncnets} from "../../../../utils/network.js"; describe("prioritizePeers", () => { const seedPeers: {id: PeerId; attnets: phase0.AttestationSubnets; syncnets: altair.SyncSubnets; score: number}[] = []; - before(async function () { + before(async () => { for (let i = 0; i < defaultNetworkOptions.maxPeers; i++) { - const peer = await createSecp256k1PeerId(); + const pk = await generateKeyPair("secp256k1"); + const peer = peerIdFromPrivateKey(pk); peer.toString = () => `peer-${i}`; seedPeers.push({ id: peer, diff --git a/packages/beacon-node/test/perf/util/bytes.test.ts b/packages/beacon-node/test/perf/util/bytes.test.ts index d1d2e968b181..8c692bd3f92d 100644 --- a/packages/beacon-node/test/perf/util/bytes.test.ts +++ b/packages/beacon-node/test/perf/util/bytes.test.ts @@ -1,6 +1,6 @@ import {itBench} from "@dapplion/benchmark"; -describe("bytes utils", function () { +describe("bytes utils", () => { const roots: Uint8Array[] = []; let buffers: Buffer[] = []; const count = 32; diff --git a/packages/beacon-node/test/perf/util/dataview.test.ts b/packages/beacon-node/test/perf/util/dataview.test.ts index e0f28a5079e3..b0e394a0e1c8 100644 --- a/packages/beacon-node/test/perf/util/dataview.test.ts +++ b/packages/beacon-node/test/perf/util/dataview.test.ts @@ -1,6 +1,6 @@ import {itBench} from "@dapplion/benchmark"; -describe("dataview", function () { +describe("dataview", () => { const data = Uint8Array.from([0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]); itBench({ diff --git a/packages/beacon-node/test/perf/util/transferBytes.test.ts b/packages/beacon-node/test/perf/util/transferBytes.test.ts index 1cda12f7acd4..25cecbf770bc 100644 --- a/packages/beacon-node/test/perf/util/transferBytes.test.ts +++ b/packages/beacon-node/test/perf/util/transferBytes.test.ts @@ -1,7 +1,7 @@ import {itBench, setBenchOpts} from "@dapplion/benchmark"; import {expect} from "chai"; -describe("transfer bytes", function () { +describe("transfer bytes", () => { const sizes = [ {size: 84, name: "Status"}, {size: 112, name: "SignedVoluntaryExit"}, diff --git a/packages/beacon-node/test/scripts/blsPubkeyBytesFrequency.ts b/packages/beacon-node/test/scripts/blsPubkeyBytesFrequency.ts index 1889cacf1496..aaf882a86bff 100644 --- a/packages/beacon-node/test/scripts/blsPubkeyBytesFrequency.ts +++ b/packages/beacon-node/test/scripts/blsPubkeyBytesFrequency.ts @@ -58,7 +58,6 @@ function analyzeBytesFrequencies(pubkeys: string[]): void { byte0Freq[byte0] = 1 + (byte0Freq[byte0] ?? 0); } - // eslint-disable-next-line no-console console.log( `Byte[${i}] frequency distribution`, JSON.stringify( @@ -95,7 +94,6 @@ function analyzeBytesCollisions(pubkeys: string[]): void { } } - // eslint-disable-next-line no-console console.log(`bytes ${i}, collision rate ${collisions.size / 256 ** i}`); } } @@ -120,7 +118,6 @@ async function writePubkeys(): Promise { } run().catch((e) => { - // eslint-disable-next-line no-console console.error(e); process.exit(1); }); diff --git a/packages/beacon-node/test/setupPreset.ts b/packages/beacon-node/test/setupPreset.ts index b25c1d87835e..968c6e12c668 100644 --- a/packages/beacon-node/test/setupPreset.ts +++ b/packages/beacon-node/test/setupPreset.ts @@ -7,6 +7,5 @@ if (process.env.LODESTAR_PRESET === undefined) { // Override FIELD_ELEMENTS_PER_BLOB if its a dev run, mostly to distinguish from // spec runs if (process.env.LODESTAR_PRESET === "minimal" && process.env.DEV_RUN) { - // eslint-disable-next-line @typescript-eslint/naming-convention setActivePreset(PresetName.minimal, {FIELD_ELEMENTS_PER_BLOB: 4096}); } diff --git a/packages/beacon-node/test/sim/electra-interop.test.ts b/packages/beacon-node/test/sim/electra-interop.test.ts index 2d08428df558..20fedd3d4b0f 100644 --- a/packages/beacon-node/test/sim/electra-interop.test.ts +++ b/packages/beacon-node/test/sim/electra-interop.test.ts @@ -36,7 +36,7 @@ import {shell} from "./shell.js"; const jwtSecretHex = "0xdc6457099f127cf0bac78de8b297df04951281909db4f58b43def7c7151e765d"; const retries = defaultExecutionEngineHttpOpts.retries; const retryDelay = defaultExecutionEngineHttpOpts.retryDelay; -describe("executionEngine / ExecutionEngineHttp", function () { +describe("executionEngine / ExecutionEngineHttp", () => { if (!process.env.EL_BINARY_DIR || !process.env.EL_SCRIPT_DIR) { throw Error( `EL ENV must be provided, EL_BINARY_DIR: ${process.env.EL_BINARY_DIR}, EL_SCRIPT_DIR: ${process.env.EL_SCRIPT_DIR}` @@ -211,12 +211,12 @@ describe("executionEngine / ExecutionEngineHttp", function () { if (payload.transactions.length !== 1) { throw Error(`Number of transactions mismatched. Expected: 1, actual: ${payload.transactions.length}`); - } else { - const actualTransaction = bytesToData(payload.transactions[0]); + } - if (actualTransaction !== depositTransactionB) { - throw Error(`Transaction mismatched. Expected: ${depositTransactionB}, actual: ${actualTransaction}`); - } + const actualTransaction = bytesToData(payload.transactions[0]); + + if (actualTransaction !== depositTransactionB) { + throw Error(`Transaction mismatched. Expected: ${depositTransactionB}, actual: ${actualTransaction}`); } if (depositRequests === undefined || depositRequests.length !== 1) { @@ -234,7 +234,7 @@ describe("executionEngine / ExecutionEngineHttp", function () { }); // TODO: get this post merge run working - it.skip("Post-merge, run for a few blocks", async function () { + it.skip("Post-merge, run for a few blocks", async () => { console.log("\n\nPost-merge, run for a few blocks\n\n"); const {elClient, tearDownCallBack} = await runEL( {...elSetupConfig, mode: ELStartMode.PostMerge, genesisTemplate: "electra.tmpl"}, @@ -331,7 +331,7 @@ describe("executionEngine / ExecutionEngineHttp", function () { withEth1Credentials: true, }); - afterEachCallbacks.push(async function () { + afterEachCallbacks.push(async () => { await bn.close(); await sleep(1000); }); @@ -355,7 +355,7 @@ describe("executionEngine / ExecutionEngineHttp", function () { valProposerConfig, }); - afterEachCallbacks.push(async function () { + afterEachCallbacks.push(async () => { await Promise.all(validators.map((v) => v.close())); }); diff --git a/packages/beacon-node/test/sim/mergemock.test.ts b/packages/beacon-node/test/sim/mergemock.test.ts index ee9839d58822..64020b070e11 100644 --- a/packages/beacon-node/test/sim/mergemock.test.ts +++ b/packages/beacon-node/test/sim/mergemock.test.ts @@ -29,7 +29,7 @@ import {shell} from "./shell.js"; const jwtSecretHex = "0xdc6457099f127cf0bac78de8b297df04951281909db4f58b43def7c7151e765d"; -describe("executionEngine / ExecutionEngineHttp", function () { +describe("executionEngine / ExecutionEngineHttp", () => { if (!process.env.EL_BINARY_DIR || !process.env.EL_SCRIPT_DIR) { throw Error( `EL ENV must be provided, EL_BINARY_DIR: ${process.env.EL_BINARY_DIR}, EL_SCRIPT_DIR: ${process.env.EL_SCRIPT_DIR}` @@ -64,7 +64,7 @@ describe("executionEngine / ExecutionEngineHttp", function () { }); for (const useProduceBlockV3 of [false, true]) { - it(`Test builder with useProduceBlockV3=${useProduceBlockV3}`, async function () { + it(`Test builder with useProduceBlockV3=${useProduceBlockV3}`, async () => { console.log("\n\nPost-merge, run for a few blocks\n\n"); const {elClient, tearDownCallBack} = await runEL( {...elSetupConfig, mode: ELStartMode.PostMerge}, @@ -173,7 +173,7 @@ describe("executionEngine / ExecutionEngineHttp", function () { // Enable builder by default, else because of circuit breaker we always start it with disabled bn.chain.executionBuilder.updateStatus(true); - afterEachCallbacks.push(async function () { + afterEachCallbacks.push(async () => { await bn.close(); await sleep(1000); }); @@ -204,7 +204,7 @@ describe("executionEngine / ExecutionEngineHttp", function () { useProduceBlockV3, }); - afterEachCallbacks.push(async function () { + afterEachCallbacks.push(async () => { await Promise.all(validators.map((v) => v.close())); }); diff --git a/packages/beacon-node/test/spec/bls/bls.ts b/packages/beacon-node/test/spec/bls/bls.ts index 5af15bcb8eb2..76c511215b61 100644 --- a/packages/beacon-node/test/spec/bls/bls.ts +++ b/packages/beacon-node/test/spec/bls/bls.ts @@ -10,8 +10,6 @@ import { } from "@chainsafe/blst"; import {fromHexString} from "@chainsafe/ssz"; -/* eslint-disable @typescript-eslint/naming-convention */ - export const testFnByType: Record any)> = { aggregate_verify, aggregate, @@ -44,7 +42,7 @@ function aggregate_verify(input: {pubkeys: string[]; messages: string[]; signatu pubkeys.map((pk) => PublicKey.fromHex(pk)), Signature.fromHex(signature) ); - } catch (e) { + } catch (_e) { return false; } } @@ -78,7 +76,7 @@ function fast_aggregate_verify(input: {pubkeys: string[]; message: string; signa pubkeys.map((hex) => PublicKey.fromHex(hex, true)), Signature.fromHex(signature, true) ); - } catch (e) { + } catch (_e) { return false; } } @@ -103,7 +101,7 @@ function batch_verify(input: {pubkeys: string[]; messages: string[]; signatures: sig: Signature.fromHex(signatures[i], true), })) ); - } catch (e) { + } catch (_e) { return false; } } @@ -137,7 +135,7 @@ function verify(input: {pubkey: string; message: string; signature: string}): bo const {pubkey, message, signature} = input; try { return _verify(fromHexString(message), PublicKey.fromHex(pubkey), Signature.fromHex(signature)); - } catch (e) { + } catch (_e) { return false; } } @@ -153,7 +151,7 @@ function deserialization_G1(input: {pubkey: string}): boolean { try { PublicKey.fromHex(input.pubkey, true); return true; - } catch (e) { + } catch (_e) { return false; } } @@ -169,7 +167,7 @@ function deserialization_G2(input: {signature: string}): boolean { try { Signature.fromHex(input.signature, true); return true; - } catch (e) { + } catch (_e) { return false; } } diff --git a/packages/beacon-node/test/spec/bls/index.test.ts b/packages/beacon-node/test/spec/bls/index.test.ts index b781685432e6..32baa00d9fbc 100644 --- a/packages/beacon-node/test/spec/bls/index.test.ts +++ b/packages/beacon-node/test/spec/bls/index.test.ts @@ -35,7 +35,7 @@ for (const fnName of readdirSyncSpec(blsSpecTests.outputDir)) { const fnTestDirpath = path.join(blsSpecTests.outputDir, fnName); for (const testName of readdirSyncSpec(fnTestDirpath)) { - it(`${fnName}/${testName}`, function (context) { + it(`${fnName}/${testName}`, (context) => { if (fn === "skip") { context.skip(); return; diff --git a/packages/beacon-node/test/spec/general/bls.ts b/packages/beacon-node/test/spec/general/bls.ts index 010a5b9be53d..128b5b4f5613 100644 --- a/packages/beacon-node/test/spec/general/bls.ts +++ b/packages/beacon-node/test/spec/general/bls.ts @@ -5,21 +5,19 @@ import { Signature, aggregateSerializedPublicKeys, aggregateSignatures, - aggregateVerify, - fastAggregateVerify, + aggregateVerify as BLSAggregateVerify, + fastAggregateVerify as BLSFastAggregateVerify, verify as _verify, } from "@chainsafe/blst"; import {InputType} from "@lodestar/spec-test-util"; import {TestRunnerFn} from "../utils/types.js"; -/* eslint-disable @typescript-eslint/naming-convention */ - const testFnByType: Record any> = { aggregate, - aggregate_verify, - eth_aggregate_pubkeys, - eth_fast_aggregate_verify, - fast_aggregate_verify, + aggregate_verify: aggregateVerify, + eth_aggregate_pubkeys: ethAggregatePubkeys, + eth_fast_aggregate_verify: ethFastAggregateVerify, + fast_aggregate_verify: fastAggregateVerify, sign, verify, }; @@ -29,7 +27,7 @@ const G2_POINT_AT_INFINITY = const G1_POINT_AT_INFINITY = "0xc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; -export const blsTestRunner: TestRunnerFn = (fork, testName) => { +export const blsTestRunner: TestRunnerFn = (_fork, testName) => { return { testFunction: ({data}) => { const testFn = testFnByType[testName]; @@ -43,9 +41,8 @@ export const blsTestRunner: TestRunnerFn = (fork, testName const {message} = e as Error; if (message.includes("BLST_ERROR") || message === "EMPTY_AGGREGATE_ARRAY" || message === "ZERO_SECRET_KEY") { return null; - } else { - throw e; } + throw e; } }, options: { @@ -75,7 +72,7 @@ function aggregate(input: string[]): string | null { const pks = input.map((pkHex) => Signature.fromHex(pkHex)); const agg = aggregateSignatures(pks); return agg.toHex(); - } catch (e) { + } catch (_e) { return null; } } @@ -89,15 +86,15 @@ function aggregate(input: string[]): string | null { * output: bool -- true (VALID) or false (INVALID) * ``` */ -function aggregate_verify(input: {pubkeys: string[]; messages: string[]; signature: string}): boolean { +function aggregateVerify(input: {pubkeys: string[]; messages: string[]; signature: string}): boolean { const {pubkeys, messages, signature} = input; try { - return aggregateVerify( + return BLSAggregateVerify( messages.map(fromHexString), pubkeys.map((pk) => PublicKey.fromHex(pk)), Signature.fromHex(signature) ); - } catch (e) { + } catch (_e) { return false; } } @@ -108,7 +105,7 @@ function aggregate_verify(input: {pubkeys: string[]; messages: string[]; signatu * output: BLS Signature -- expected output, single BLS signature or empty. * ``` */ -function eth_aggregate_pubkeys(input: string[]): string | null { +function ethAggregatePubkeys(input: string[]): string | null { // Don't add this checks in the source as beacon nodes check the pubkeys for inf when onboarding for (const pk of input) { if (pk === G1_POINT_AT_INFINITY) return null; @@ -116,7 +113,7 @@ function eth_aggregate_pubkeys(input: string[]): string | null { try { return aggregateSerializedPublicKeys(input.map((hex) => fromHexString(hex))).toHex(); - } catch (e) { + } catch (_e) { return null; } } @@ -130,7 +127,7 @@ function eth_aggregate_pubkeys(input: string[]): string | null { * output: bool -- true (VALID) or false (INVALID) * ``` */ -function eth_fast_aggregate_verify(input: {pubkeys: string[]; message: string; signature: string}): boolean { +function ethFastAggregateVerify(input: {pubkeys: string[]; message: string; signature: string}): boolean { const {pubkeys, message, signature} = input; if (pubkeys.length === 0 && signature === G2_POINT_AT_INFINITY) { @@ -143,12 +140,12 @@ function eth_fast_aggregate_verify(input: {pubkeys: string[]; message: string; s } try { - return fastAggregateVerify( + return BLSFastAggregateVerify( fromHexString(message), pubkeys.map((hex) => PublicKey.fromHex(hex)), Signature.fromHex(signature) ); - } catch (e) { + } catch (_e) { return false; } } @@ -162,15 +159,15 @@ function eth_fast_aggregate_verify(input: {pubkeys: string[]; message: string; s * output: bool -- true (VALID) or false (INVALID) * ``` */ -function fast_aggregate_verify(input: {pubkeys: string[]; message: string; signature: string}): boolean | null { +function fastAggregateVerify(input: {pubkeys: string[]; message: string; signature: string}): boolean | null { const {pubkeys, message, signature} = input; try { - return fastAggregateVerify( + return BLSFastAggregateVerify( fromHexString(message), pubkeys.map((hex) => PublicKey.fromHex(hex, true)), Signature.fromHex(signature, true) ); - } catch (e) { + } catch (_e) { return false; } } @@ -185,7 +182,7 @@ function sign(input: {privkey: string; message: string}): string | null { const {privkey, message} = input; try { return SecretKey.fromHex(privkey).sign(fromHexString(message)).toHex(); - } catch (e) { + } catch (_e) { return null; } } @@ -201,7 +198,7 @@ function verify(input: {pubkey: string; message: string; signature: string}): bo const {pubkey, message, signature} = input; try { return _verify(fromHexString(message), PublicKey.fromHex(pubkey), Signature.fromHex(signature)); - } catch (e) { + } catch (_e) { return false; } } diff --git a/packages/beacon-node/test/spec/general/index.test.ts b/packages/beacon-node/test/spec/general/index.test.ts index f6bfb0b7b2a1..063f128c3142 100644 --- a/packages/beacon-node/test/spec/general/index.test.ts +++ b/packages/beacon-node/test/spec/general/index.test.ts @@ -5,8 +5,6 @@ import {ethereumConsensusSpecsTests} from "../specTestVersioning.js"; import {blsTestRunner} from "./bls.js"; import {sszGeneric} from "./ssz_generic.js"; -/* eslint-disable @typescript-eslint/naming-convention */ - // 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. diff --git a/packages/beacon-node/test/spec/general/ssz_generic.ts b/packages/beacon-node/test/spec/general/ssz_generic.ts index e791ca62eefe..64e6b4455941 100644 --- a/packages/beacon-node/test/spec/general/ssz_generic.ts +++ b/packages/beacon-node/test/spec/general/ssz_generic.ts @@ -15,7 +15,7 @@ import {getTestType} from "./ssz_generic_types.js"; export const sszGeneric = (skippedTypes: string[]): TestRunnerCustom => - (fork, typeName, testSuite, testSuiteDirpath) => { + (_fork, typeName, testSuite, testSuiteDirpath) => { if (testSuite === "invalid") { for (const testCase of fs.readdirSync(testSuiteDirpath)) { it(testCase, () => { diff --git a/packages/beacon-node/test/spec/general/ssz_generic_types.ts b/packages/beacon-node/test/spec/general/ssz_generic_types.ts index cd95a5dec79e..fe19f08149b4 100644 --- a/packages/beacon-node/test/spec/general/ssz_generic_types.ts +++ b/packages/beacon-node/test/spec/general/ssz_generic_types.ts @@ -20,8 +20,6 @@ const uint64 = new UintBigintType(8); const uint128 = new UintBigintType(16); const uint256 = new UintBigintType(32); -/* eslint-disable @typescript-eslint/naming-convention */ - // class SingleFieldTestStruct(Container): // A: byte const SingleFieldTestStruct = new ContainerType({ @@ -122,7 +120,7 @@ export function getTestType(testType: string, testCase: string): Type { const elementType = vecElementTypes[elementTypeStr as keyof typeof vecElementTypes]; if (elementType === undefined) throw Error(`No vecElementType for ${elementTypeStr}: '${testCase}'`); const length = parseInt(lengthStr); - if (isNaN(length)) throw Error(`Bad length ${length}: '${testCase}'`); + if (Number.isNaN(length)) throw Error(`Bad length ${length}: '${testCase}'`); return new VectorBasicType(elementType, length); } @@ -175,6 +173,6 @@ export function getTestType(testType: string, testCase: string): Type { function parseSecondNum(str: string, id: string): number { const match = str.match(/[^\W_]+_([0-9]+)/); const num = parseInt((match || [])[1]); - if (isNaN(num)) throw Error(`Bad ${id} ${str}`); + if (Number.isNaN(num)) throw Error(`Bad ${id} ${str}`); return num; } diff --git a/packages/beacon-node/test/spec/presets/epoch_processing.test.ts b/packages/beacon-node/test/spec/presets/epoch_processing.test.ts index 604243400aa0..146131f897ca 100644 --- a/packages/beacon-node/test/spec/presets/epoch_processing.test.ts +++ b/packages/beacon-node/test/spec/presets/epoch_processing.test.ts @@ -20,8 +20,6 @@ import {specTestIterator} from "../utils/specTestIterator.js"; export type EpochTransitionFn = (state: CachedBeaconStateAllForks, epochTransitionCache: EpochTransitionCache) => void; -/* eslint-disable @typescript-eslint/naming-convention */ - const epochTransitionFns: Record = { effective_balance_updates: (state, epochTransitionCache) => { const fork = state.config.getForkSeq(state.slot); @@ -99,12 +97,12 @@ const epochProcessing = post: ssz[fork].BeaconState, }, getExpected: (testCase) => testCase.post, - expectFunc: (testCase, expected, actual) => { + expectFunc: (_testCase, expected, actual) => { expectEqualBeaconState(fork, expected, actual); }, // Do not manually skip tests here, do it in packages/beacon-node/test/spec/presets/index.test.ts shouldSkip: (_testcase, name, _index) => - skipTestNames !== undefined && skipTestNames.some((skipTestName) => name.includes(skipTestName)), + skipTestNames?.some((skipTestName) => name.includes(skipTestName)) ?? false, }, }; }; diff --git a/packages/beacon-node/test/spec/presets/finality.test.ts b/packages/beacon-node/test/spec/presets/finality.test.ts index 0ec4017064f4..1dce91e360e5 100644 --- a/packages/beacon-node/test/spec/presets/finality.test.ts +++ b/packages/beacon-node/test/spec/presets/finality.test.ts @@ -15,8 +15,6 @@ import {assertCorrectProgressiveBalances} from "../config.js"; import {ethereumConsensusSpecsTests} from "../specTestVersioning.js"; import {specTestIterator} from "../utils/specTestIterator.js"; -/* eslint-disable @typescript-eslint/naming-convention */ - const finality: TestRunnerFn = (fork) => { return { testFunction: (testcase) => { @@ -49,7 +47,7 @@ const finality: TestRunnerFn = (fork) => shouldError: (testCase) => !testCase.post, timeout: 10000, getExpected: (testCase) => testCase.post, - expectFunc: (testCase, expected, actual) => { + expectFunc: (_testCase, expected, actual) => { expectEqualBeaconState(fork, expected, actual); }, // Do not manually skip tests here, do it in packages/beacon-node/test/spec/presets/index.test.ts diff --git a/packages/beacon-node/test/spec/presets/fork.test.ts b/packages/beacon-node/test/spec/presets/fork.test.ts index c121e651fcea..626d6477bcb1 100644 --- a/packages/beacon-node/test/spec/presets/fork.test.ts +++ b/packages/beacon-node/test/spec/presets/fork.test.ts @@ -50,7 +50,7 @@ const fork: TestRunnerFn = (forkNext) => { timeout: 10000, shouldError: (testCase) => testCase.post === undefined, getExpected: (testCase) => testCase.post, - expectFunc: (testCase, expected, actual) => { + expectFunc: (_testCase, expected, actual) => { expectEqualBeaconState(forkNext, expected, actual); }, // Do not manually skip tests here, do it in packages/beacon-node/test/spec/presets/index.test.ts diff --git a/packages/beacon-node/test/spec/presets/fork_choice.test.ts b/packages/beacon-node/test/spec/presets/fork_choice.test.ts index 7cb6e3c3d692..72515e703582 100644 --- a/packages/beacon-node/test/spec/presets/fork_choice.test.ts +++ b/packages/beacon-node/test/spec/presets/fork_choice.test.ts @@ -46,8 +46,6 @@ 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 */ - const ANCHOR_STATE_FILE_NAME = "anchor_state"; const ANCHOR_BLOCK_FILE_NAME = "anchor_block"; const BLOCK_FILE_NAME = "^(block)_([0-9a-zA-Z]+)$"; diff --git a/packages/beacon-node/test/spec/presets/genesis.test.ts b/packages/beacon-node/test/spec/presets/genesis.test.ts index 773debe3bb19..140fa3686e67 100644 --- a/packages/beacon-node/test/spec/presets/genesis.test.ts +++ b/packages/beacon-node/test/spec/presets/genesis.test.ts @@ -22,8 +22,6 @@ 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 */ - const genesis: TestRunnerFn = (fork, testName, testSuite) => { const testFn = genesisTestFns[testName]; if (testFn === undefined) { @@ -86,7 +84,7 @@ const genesisInitialization: TestRunnerFn testCase.state, - expectFunc: (testCase, expected, actual) => { + expectFunc: (_testCase, expected, actual) => { expectEqualBeaconState(fork, expected, actual); }, // Do not manually skip tests here, do it in packages/beacon-node/test/spec/presets/index.test.ts @@ -108,7 +106,7 @@ const genesisValidity: TestRunnerFn = (fork) = genesis: ssz[fork].BeaconState, }, getExpected: (testCase) => testCase.is_valid, - expectFunc: (testCase, expected, actual) => { + expectFunc: (_testCase, expected, actual) => { expect(actual).toEqualWithMessage(expected, "isValidGenesisState is not" + expected); }, }, diff --git a/packages/beacon-node/test/spec/presets/light_client/index.test.ts b/packages/beacon-node/test/spec/presets/light_client/index.test.ts index 0a44772cab4b..a8cc12238675 100644 --- a/packages/beacon-node/test/spec/presets/light_client/index.test.ts +++ b/packages/beacon-node/test/spec/presets/light_client/index.test.ts @@ -7,8 +7,6 @@ import {singleMerkleProof} from "./single_merkle_proof.js"; import {sync} from "./sync.js"; import {updateRanking} from "./update_ranking.js"; -/* eslint-disable @typescript-eslint/naming-convention */ - const lightClient: TestRunnerFn = (fork, testName, testSuite) => { const testFn = lightclientTestFns[testName]; if (testFn === undefined) { diff --git a/packages/beacon-node/test/spec/presets/light_client/single_merkle_proof.ts b/packages/beacon-node/test/spec/presets/light_client/single_merkle_proof.ts index d230bc926b0d..08dcd0ab8acf 100644 --- a/packages/beacon-node/test/spec/presets/light_client/single_merkle_proof.ts +++ b/packages/beacon-node/test/spec/presets/light_client/single_merkle_proof.ts @@ -7,8 +7,6 @@ import {ForkName} from "@lodestar/params"; import {toHex} from "@lodestar/utils"; import {TestRunnerFn} from "../../utils/types.js"; -/* eslint-disable @typescript-eslint/naming-convention */ - // https://github.com/ethereum/consensus-specs/blob/da3f5af919be4abb5a6db5a80b235deb8b4b5cba/tests/formats/light_client/single_merkle_proof.md type SingleMerkleProofTestCase = { meta?: any; @@ -23,7 +21,11 @@ type SingleMerkleProofTestCase = { }; }; -export const singleMerkleProof: TestRunnerFn = (fork, testHandler, testSuite) => { +export const singleMerkleProof: TestRunnerFn = ( + fork, + _testHandler, + testSuite +) => { return { testFunction: (testcase) => { // Assert correct proof generation @@ -39,7 +41,7 @@ export const singleMerkleProof: TestRunnerFn testCase.proof.branch, - expectFunc: (testCase, expected, actual) => { + expectFunc: (_testCase, expected, actual) => { expect(actual).deep.equals(expected); }, // Do not manually skip tests here, do it in packages/beacon-node/test/spec/presets/index.test.ts diff --git a/packages/beacon-node/test/spec/presets/light_client/sync.ts b/packages/beacon-node/test/spec/presets/light_client/sync.ts index bfd3d0d0bb3d..3e82256fab1d 100644 --- a/packages/beacon-node/test/spec/presets/light_client/sync.ts +++ b/packages/beacon-node/test/spec/presets/light_client/sync.ts @@ -9,8 +9,6 @@ import {computeSyncPeriodAtSlot} from "@lodestar/state-transition"; import {TestRunnerFn} from "../../utils/types.js"; import {testLogger} from "../../../utils/logger.js"; -/* eslint-disable @typescript-eslint/naming-convention */ - // https://github.com/ethereum/consensus-specs/blob/da3f5af919be4abb5a6db5a80b235deb8b4b5cba/tests/formats/light_client/single_merkle_proof.md type SyncTestCase = { meta: { @@ -130,7 +128,7 @@ export const sync: TestRunnerFn = (fork) => { } const headerSlot = Number(step.process_update.checks.optimistic_header.slot); - const update = config.getLightClientForkTypes(headerSlot)["LightClientUpdate"].deserialize(updateBytes); + const update = config.getLightClientForkTypes(headerSlot).LightClientUpdate.deserialize(updateBytes); logger.debug(`LightclientUpdateSummary: ${JSON.stringify(toLightClientUpdateSummary(update))}`); diff --git a/packages/beacon-node/test/spec/presets/light_client/update_ranking.ts b/packages/beacon-node/test/spec/presets/light_client/update_ranking.ts index a2e60c1cc84a..b51219dd4e54 100644 --- a/packages/beacon-node/test/spec/presets/light_client/update_ranking.ts +++ b/packages/beacon-node/test/spec/presets/light_client/update_ranking.ts @@ -5,8 +5,6 @@ import {InputType} from "@lodestar/spec-test-util"; import {isBetterUpdate, LightClientUpdateSummary, toLightClientUpdateSummary} from "@lodestar/light-client/spec"; import {TestRunnerFn} from "../../utils/types.js"; -/* eslint-disable @typescript-eslint/naming-convention */ - // https://github.com/ethereum/consensus-specs/blob/da3f5af919be4abb5a6db5a80b235deb8b4b5cba/tests/formats/light_client/update_ranking.md type UpdateRankingTestCase = { meta: { diff --git a/packages/beacon-node/test/spec/presets/merkle.test.ts b/packages/beacon-node/test/spec/presets/merkle.test.ts index d3f6890527e9..71cebdbd0b5b 100644 --- a/packages/beacon-node/test/spec/presets/merkle.test.ts +++ b/packages/beacon-node/test/spec/presets/merkle.test.ts @@ -11,8 +11,6 @@ import {RunnerType, TestRunnerFn} from "../utils/types.js"; import {ethereumConsensusSpecsTests} from "../specTestVersioning.js"; import {specTestIterator} from "../utils/specTestIterator.js"; -/* eslint-disable @typescript-eslint/naming-convention */ - const merkle: TestRunnerFn = (fork) => { return { testFunction: (testcase) => { @@ -47,7 +45,7 @@ const merkle: TestRunnerFn = (fork) => { }), timeout: 10000, getExpected: (testCase) => testCase.proof, - expectFunc: (testCase, expected, actual) => { + expectFunc: (_testCase, expected, actual) => { expect(actual).toEqualWithMessage(expected, "incorrect proof"); }, // Do not manually skip tests here, do it in packages/beacon-node/test/spec/presets/index.test.ts diff --git a/packages/beacon-node/test/spec/presets/operations.test.ts b/packages/beacon-node/test/spec/presets/operations.test.ts index 7e2e9c1e9c5d..b6a479ee3794 100644 --- a/packages/beacon-node/test/spec/presets/operations.test.ts +++ b/packages/beacon-node/test/spec/presets/operations.test.ts @@ -20,10 +20,8 @@ import {BaseSpecTest, RunnerType, shouldVerify, TestRunnerFn} from "../utils/typ import {ethereumConsensusSpecsTests} from "../specTestVersioning.js"; import {specTestIterator} from "../utils/specTestIterator.js"; -/* eslint-disable @typescript-eslint/naming-convention */ - // Define above to re-use in sync_aggregate and sync_aggregate_random -const sync_aggregate: BlockProcessFn = ( +const syncAggregate: BlockProcessFn = ( state, testCase: {sync_aggregate: altair.SyncAggregate} ) => { @@ -62,8 +60,8 @@ const operationFns: Record> = blockFns.processProposerSlashing(fork, state, testCase.proposer_slashing); }, - sync_aggregate, - sync_aggregate_random: sync_aggregate, + sync_aggregate: syncAggregate, + sync_aggregate_random: syncAggregate, voluntary_exit: (state, testCase: {voluntary_exit: phase0.SignedVoluntaryExit}) => { const fork = state.config.getForkSeq(state.slot); @@ -156,7 +154,7 @@ const operations: TestRunnerFn = (fork, }, shouldError: (testCase) => testCase.post === undefined, getExpected: (testCase) => testCase.post, - expectFunc: (testCase, expected, actual) => { + expectFunc: (_testCase, expected, actual) => { expectEqualBeaconState(fork, expected, actual); }, // Do not manually skip tests here, do it in packages/beacon-node/test/spec/presets/index.test.ts diff --git a/packages/beacon-node/test/spec/presets/rewards.test.ts b/packages/beacon-node/test/spec/presets/rewards.test.ts index 426245242d84..df43c8ca612e 100644 --- a/packages/beacon-node/test/spec/presets/rewards.test.ts +++ b/packages/beacon-node/test/spec/presets/rewards.test.ts @@ -13,8 +13,6 @@ 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); const rewards: TestRunnerFn = (fork) => { @@ -57,7 +55,7 @@ const rewards: TestRunnerFn = (fork) => { ...(testCase.inclusion_delay_deltas ? [testCase.inclusion_delay_deltas] : []), testCase.inactivity_penalty_deltas, ]), - expectFunc: (testCase, expected, actual) => { + expectFunc: (_testCase, expected, actual) => { expect(actual).toEqual(expected); }, // Do not manually skip tests here, do it in packages/beacon-node/test/spec/presets/index.test.ts diff --git a/packages/beacon-node/test/spec/presets/sanity.test.ts b/packages/beacon-node/test/spec/presets/sanity.test.ts index 3ec1efb84fde..cd266483c7f8 100644 --- a/packages/beacon-node/test/spec/presets/sanity.test.ts +++ b/packages/beacon-node/test/spec/presets/sanity.test.ts @@ -18,8 +18,6 @@ import {assertCorrectProgressiveBalances} from "../config.js"; import {ethereumConsensusSpecsTests} from "../specTestVersioning.js"; import {specTestIterator} from "../utils/specTestIterator.js"; -/* eslint-disable @typescript-eslint/naming-convention */ - const sanity: TestRunnerFn = (fork, testName, testSuite) => { switch (testName) { case "slots": @@ -50,7 +48,7 @@ const sanitySlots: TestRunnerFn = (for shouldError: (testCase) => !testCase.post, timeout: 10000, getExpected: (testCase) => testCase.post, - expectFunc: (testCase, expected, actual) => { + expectFunc: (_testCase, expected, actual) => { expectEqualBeaconState(fork, expected, actual); }, // Do not manually skip tests here, do it in packages/beacon-node/test/spec/presets/index.test.ts @@ -88,7 +86,7 @@ const sanityBlocks: TestRunnerFn = (f shouldError: (testCase) => testCase.post === undefined, timeout: 10000, getExpected: (testCase) => testCase.post, - expectFunc: (testCase, expected, actual) => { + expectFunc: (_testCase, expected, actual) => { expectEqualBeaconState(fork, expected, actual); }, // Do not manually skip tests here, do it in packages/beacon-node/test/spec/presets/index.test.ts diff --git a/packages/beacon-node/test/spec/presets/shuffling.test.ts b/packages/beacon-node/test/spec/presets/shuffling.test.ts index 06e7d4717d06..7b0f38ecf581 100644 --- a/packages/beacon-node/test/spec/presets/shuffling.test.ts +++ b/packages/beacon-node/test/spec/presets/shuffling.test.ts @@ -1,24 +1,27 @@ import path from "node:path"; -import {unshuffleList} from "@lodestar/state-transition"; +import {unshuffleList} from "@chainsafe/swap-or-not-shuffle"; import {InputType} from "@lodestar/spec-test-util"; import {bnToNum, fromHex} from "@lodestar/utils"; -import {ACTIVE_PRESET} from "@lodestar/params"; +import {ACTIVE_PRESET, SHUFFLE_ROUND_COUNT} from "@lodestar/params"; import {RunnerType, TestRunnerFn} from "../utils/types.js"; import {ethereumConsensusSpecsTests} from "../specTestVersioning.js"; import {specTestIterator} from "../utils/specTestIterator.js"; -const shuffling: TestRunnerFn = () => { +const shuffling: TestRunnerFn = () => { return { testFunction: (testcase) => { const seed = fromHex(testcase.mapping.seed); - const output = Array.from({length: bnToNum(testcase.mapping.count)}, (_, i) => i); - unshuffleList(output, seed); - return output; + const output = unshuffleList( + Uint32Array.from(Array.from({length: bnToNum(testcase.mapping.count)}, (_, i) => i)), + seed, + SHUFFLE_ROUND_COUNT + ); + return Buffer.from(output).toString("hex"); }, options: { inputTypes: {mapping: InputType.YAML}, timeout: 10000, - getExpected: (testCase) => testCase.mapping.mapping.map((value) => bnToNum(value)), + getExpected: (testCase) => Buffer.from(testCase.mapping.mapping.map((value) => bnToNum(value))).toString("hex"), // Do not manually skip tests here, do it in packages/beacon-node/test/spec/presets/index.test.ts }, }; diff --git a/packages/beacon-node/test/spec/presets/ssz_static.test.ts b/packages/beacon-node/test/spec/presets/ssz_static.test.ts index 6e43d851ef66..f5cdcc719b6a 100644 --- a/packages/beacon-node/test/spec/presets/ssz_static.test.ts +++ b/packages/beacon-node/test/spec/presets/ssz_static.test.ts @@ -32,7 +32,7 @@ type Types = Record>; const sszStatic = (skippedFork: string, skippedTypes?: string[]) => - (fork: ForkName, typeName: string, testSuite: string, testSuiteDirpath: string): void => { + (fork: ForkName, typeName: string, _testSuite: string, testSuiteDirpath: string): void => { if (fork === skippedFork) { return; } @@ -52,7 +52,7 @@ const sszStatic = (ssz.altair as Types)[typeName] || (ssz.phase0 as Types)[typeName]; - it(`${fork} - ${typeName} type exists`, function () { + it(`${fork} - ${typeName} type exists`, () => { expect(sszType).toEqualWithMessage(expect.any(Type), `SSZ type ${typeName} for fork ${fork} is not defined`); }); @@ -65,7 +65,7 @@ const sszStatic = for (const testCase of fs.readdirSync(testSuiteDirpath)) { // Do not manually skip tests here, do it in packages/beacon-node/test/spec/presets/index.test.ts - it(testCase, function () { + it(testCase, () => { // Mainnet must deal with big full states and hash each one multiple times if (ACTIVE_PRESET === "mainnet") { vi.setConfig({testTimeout: 30 * 1000}); @@ -78,7 +78,6 @@ const sszStatic = }; specTestIterator(path.join(ethereumConsensusSpecsTests.outputDir, "tests", ACTIVE_PRESET), { - // eslint-disable-next-line @typescript-eslint/naming-convention ssz_static: { type: RunnerType.custom, // starting from v1.4.0-beta.6, there is "whisk" fork in ssz_static tests but we ignore them diff --git a/packages/beacon-node/test/spec/presets/transition.test.ts b/packages/beacon-node/test/spec/presets/transition.test.ts index cae7c667b590..76ad772f8dfb 100644 --- a/packages/beacon-node/test/spec/presets/transition.test.ts +++ b/packages/beacon-node/test/spec/presets/transition.test.ts @@ -78,18 +78,16 @@ const transition = shouldError: (testCase) => testCase.post === undefined, timeout: 10000, getExpected: (testCase) => testCase.post, - expectFunc: (testCase, expected, actual) => { + expectFunc: (_testCase, expected, actual) => { expectEqualBeaconState(forkNext, expected, actual); }, // Do not manually skip tests here, do it in packages/beacon-node/test/spec/presets/index.test.ts shouldSkip: (_testcase, name, _index) => - skipTestNames !== undefined && skipTestNames.some((skipTestName) => name.includes(skipTestName)), + skipTestNames?.some((skipTestName) => name.includes(skipTestName)) ?? false, }, }; }; -/* eslint-disable @typescript-eslint/naming-convention */ - function getTransitionConfig(fork: ForkName, forkEpoch: number): Partial { switch (fork) { case ForkName.phase0: diff --git a/packages/beacon-node/test/spec/specTestVersioning.ts b/packages/beacon-node/test/spec/specTestVersioning.ts index d4bc192f6cad..5e15b696e4a1 100644 --- a/packages/beacon-node/test/spec/specTestVersioning.ts +++ b/packages/beacon-node/test/spec/specTestVersioning.ts @@ -11,7 +11,6 @@ import {DownloadTestsOptions} from "@lodestar/spec-test-util/downloadTests"; // Global variable __dirname no longer available in ES6 modules. // Solutions: https://stackoverflow.com/questions/46745014/alternative-for-dirname-in-node-js-when-using-es6-modules -// eslint-disable-next-line @typescript-eslint/naming-convention const __dirname = path.dirname(fileURLToPath(import.meta.url)); export const ethereumConsensusSpecsTests: DownloadTestsOptions = { diff --git a/packages/beacon-node/test/spec/utils/runValidSszTest.ts b/packages/beacon-node/test/spec/utils/runValidSszTest.ts index e5f249ab5257..a8d3060af08d 100644 --- a/packages/beacon-node/test/spec/utils/runValidSszTest.ts +++ b/packages/beacon-node/test/spec/utils/runValidSszTest.ts @@ -21,7 +21,7 @@ export function runValidSszTest(type: Type, testData: ValidTestCaseData console.log( JSON.stringify( testData.jsonValue, - (key, value: unknown) => (typeof value === "bigint" ? value.toString() : value), + (_key, value: unknown) => (typeof value === "bigint" ? value.toString() : value), 2 ) ); @@ -168,9 +168,8 @@ function wrapErr(fn: () => T, prefix: string): T { export function toJsonOrString(value: unknown): unknown { if (typeof value === "number" || typeof value === "bigint") { return value.toString(10); - } else { - return value; } + return value; } function renderTree(node: Node): void { diff --git a/packages/beacon-node/test/spec/utils/types.ts b/packages/beacon-node/test/spec/utils/types.ts index 94ad7b73de3f..00bebffd7d7e 100644 --- a/packages/beacon-node/test/spec/utils/types.ts +++ b/packages/beacon-node/test/spec/utils/types.ts @@ -26,8 +26,6 @@ export type TestRunner = | {type: RunnerType.default; fn: TestRunnerFn} | {type: RunnerType.custom; fn: TestRunnerCustom}; -/* eslint-disable @typescript-eslint/naming-convention */ - export type BaseSpecTest = { meta?: { bls_setting?: bigint; diff --git a/packages/beacon-node/test/tsconfig.json b/packages/beacon-node/test/tsconfig.json index 7e6bad81b22f..f4241fc1fbcd 100644 --- a/packages/beacon-node/test/tsconfig.json +++ b/packages/beacon-node/test/tsconfig.json @@ -3,4 +3,4 @@ "compilerOptions": { "noEmit": false } -} \ No newline at end of file +} diff --git a/packages/beacon-node/test/unit-mainnet/network/gossip/scoringParameters.test.ts b/packages/beacon-node/test/unit-mainnet/network/gossip/scoringParameters.test.ts index 7ef09af2cd89..b3137755857f 100644 --- a/packages/beacon-node/test/unit-mainnet/network/gossip/scoringParameters.test.ts +++ b/packages/beacon-node/test/unit-mainnet/network/gossip/scoringParameters.test.ts @@ -12,7 +12,7 @@ import {ZERO_HASH} from "../../../../src/constants/index.js"; * Refer to Teku tests at * https://github.com/ConsenSys/teku/blob/e18ab9903442410aa04b590c4cc46734e13d3ffd/networking/eth2/src/test/java/tech/pegasys/teku/networking/eth2/gossip/config/GossipScoringConfiguratorTest.java#L38 */ -describe("computeGossipPeerScoreParams", function () { +describe("computeGossipPeerScoreParams", () => { const config = createBeaconConfig(mainnetChainConfig, ZERO_HASH); // Cheap stub on new BeaconConfig instance config.forkName2ForkDigest = () => Buffer.alloc(4, 1); diff --git a/packages/beacon-node/test/unit/api/impl/beacon/beacon.test.ts b/packages/beacon-node/test/unit/api/impl/beacon/beacon.test.ts index a8eaffa42005..99bac5de7ef4 100644 --- a/packages/beacon-node/test/unit/api/impl/beacon/beacon.test.ts +++ b/packages/beacon-node/test/unit/api/impl/beacon/beacon.test.ts @@ -4,17 +4,17 @@ import {ApiTestModules, getApiTestModules} from "../../../../utils/api.js"; import {getBeaconApi} from "../../../../../src/api/impl/beacon/index.js"; import {Mutable} from "../../../../utils/types.js"; -describe("beacon api implementation", function () { +describe("beacon api implementation", () => { let modules: ApiTestModules; let api: ReturnType; - beforeAll(function () { + beforeAll(() => { modules = getApiTestModules(); api = getBeaconApi(modules); }); - describe("getGenesis", function () { - it("success", async function () { + describe("getGenesis", () => { + it("success", async () => { (modules.chain as Mutable).genesisTime = 0; (modules.chain as Mutable).genesisValidatorsRoot = Buffer.alloc(32); diff --git a/packages/beacon-node/test/unit/api/impl/beacon/blocks/getBlockHeaders.test.ts b/packages/beacon-node/test/unit/api/impl/beacon/blocks/getBlockHeaders.test.ts index 9b3c960ff2ec..5e4e8a31ec7f 100644 --- a/packages/beacon-node/test/unit/api/impl/beacon/blocks/getBlockHeaders.test.ts +++ b/packages/beacon-node/test/unit/api/impl/beacon/blocks/getBlockHeaders.test.ts @@ -7,12 +7,12 @@ import {ApiTestModules, getApiTestModules} from "../../../../../utils/api.js"; import {generateProtoBlock, generateSignedBlockAtSlot} from "../../../../../utils/typeGenerator.js"; import {getBeaconBlockApi} from "../../../../../../src/api/impl/beacon/blocks/index.js"; -describe("api - beacon - getBlockHeaders", function () { +describe("api - beacon - getBlockHeaders", () => { let modules: ApiTestModules; let api: ReturnType; const parentRoot = toHexString(Buffer.alloc(32, 1)); - beforeEach(function () { + beforeEach(() => { modules = getApiTestModules(); api = getBeaconBlockApi(modules); @@ -24,7 +24,7 @@ describe("api - beacon - getBlockHeaders", function () { vi.clearAllMocks(); }); - it.skip("no filters - assume head slot", async function () { + it.skip("no filters - assume head slot", async () => { modules.forkChoice.getHead.mockReturnValue(generateProtoBlock({slot: 1})); when(modules.chain.getCanonicalBlockAtSlot) .calledWith(1) @@ -55,13 +55,13 @@ describe("api - beacon - getBlockHeaders", function () { expect(modules.db.block.get).toHaveBeenCalledTimes(1); }); - it("future slot", async function () { + it("future slot", async () => { modules.forkChoice.getHead.mockReturnValue(generateProtoBlock({slot: 1})); const {data: blockHeaders} = await api.getBlockHeaders({slot: 2}); expect(blockHeaders.length).toBe(0); }); - it("finalized slot", async function () { + it("finalized slot", async () => { modules.forkChoice.getHead.mockReturnValue(generateProtoBlock({slot: 2})); when(modules.chain.getCanonicalBlockAtSlot) .calledWith(0) @@ -72,14 +72,14 @@ describe("api - beacon - getBlockHeaders", function () { expect(blockHeaders[0].canonical).toBe(true); }); - it("skip slot", async function () { + it("skip slot", async () => { modules.forkChoice.getHead.mockReturnValue(generateProtoBlock({slot: 2})); when(modules.chain.getCanonicalBlockAtSlot).calledWith(0).thenResolve(null); const {data: blockHeaders} = await api.getBlockHeaders({slot: 0}); expect(blockHeaders.length).toBe(0); }); - it.skip("parent root filter - both finalized and non finalized results", async function () { + it.skip("parent root filter - both finalized and non finalized results", async () => { modules.db.blockArchive.getByParentRoot.mockResolvedValue(ssz.phase0.SignedBeaconBlock.defaultValue()); modules.forkChoice.getBlockSummariesByParentRoot.mockReturnValue([ generateProtoBlock({slot: 2}), @@ -99,7 +99,7 @@ describe("api - beacon - getBlockHeaders", function () { expect(blockHeaders.filter((b) => b.canonical).length).toBe(2); }); - it("parent root - no finalized block", async function () { + it("parent root - no finalized block", async () => { modules.db.blockArchive.getByParentRoot.mockResolvedValue(null); modules.forkChoice.getBlockSummariesByParentRoot.mockReturnValue([generateProtoBlock({slot: 1})]); when(modules.forkChoice.getCanonicalBlockAtSlot).calledWith(1).thenReturn(generateProtoBlock()); @@ -109,14 +109,14 @@ describe("api - beacon - getBlockHeaders", function () { expect(blockHeaders.length).toBe(1); }); - it("parent root - no non finalized blocks", async function () { + it("parent root - no non finalized blocks", async () => { modules.db.blockArchive.getByParentRoot.mockResolvedValue(ssz.phase0.SignedBeaconBlock.defaultValue()); modules.forkChoice.getBlockSummariesByParentRoot.mockReturnValue([]); const {data: blockHeaders} = await api.getBlockHeaders({parentRoot}); expect(blockHeaders.length).toBe(1); }); - it("parent root + slot filter", async function () { + it("parent root + slot filter", async () => { modules.db.blockArchive.getByParentRoot.mockResolvedValue(ssz.phase0.SignedBeaconBlock.defaultValue()); modules.forkChoice.getBlockSummariesByParentRoot.mockReturnValue([ generateProtoBlock({slot: 2}), diff --git a/packages/beacon-node/test/unit/api/impl/beacon/state/utils.test.ts b/packages/beacon-node/test/unit/api/impl/beacon/state/utils.test.ts index 39c936c0d025..958093ffba6d 100644 --- a/packages/beacon-node/test/unit/api/impl/beacon/state/utils.test.ts +++ b/packages/beacon-node/test/unit/api/impl/beacon/state/utils.test.ts @@ -3,7 +3,7 @@ import {toHexString} from "@chainsafe/ssz"; import {getStateValidatorIndex} from "../../../../../../src/api/impl/beacon/state/utils.js"; import {generateCachedAltairState} from "../../../../../utils/state.js"; -describe("beacon state api utils", function () { +describe("beacon state api utils", () => { describe("getStateValidatorIndex", () => { const state = generateCachedAltairState(); const pubkey2index = state.epochCtx.pubkey2index; diff --git a/packages/beacon-node/test/unit/api/impl/config/config.test.ts b/packages/beacon-node/test/unit/api/impl/config/config.test.ts index d6954f632d5e..7d0adebbea89 100644 --- a/packages/beacon-node/test/unit/api/impl/config/config.test.ts +++ b/packages/beacon-node/test/unit/api/impl/config/config.test.ts @@ -3,34 +3,34 @@ import {routes} from "@lodestar/api"; import {config} from "@lodestar/config/default"; import {getConfigApi, renderJsonSpec} from "../../../../../src/api/impl/config/index.js"; -describe("config api implementation", function () { +describe("config api implementation", () => { let api: ReturnType; - beforeEach(function () { + beforeEach(() => { api = getConfigApi({config}); }); - describe("getForkSchedule", function () { - it("should get known scheduled forks", async function () { + describe("getForkSchedule", () => { + it("should get known scheduled forks", async () => { const {data: forkSchedule} = await api.getForkSchedule(); expect(forkSchedule.length).toBe(Object.keys(config.forks).length); }); }); - describe("getDepositContract", function () { - it("should get the deposit contract from config", async function () { + describe("getDepositContract", () => { + it("should get the deposit contract from config", async () => { const {data: depositContract} = (await api.getDepositContract()) as {data: routes.config.DepositContract}; expect(depositContract.address).toBe(config.DEPOSIT_CONTRACT_ADDRESS); expect(depositContract.chainId).toBe(config.DEPOSIT_CHAIN_ID); }); }); - describe("getSpec", function () { + describe("getSpec", () => { it("Ensure spec can be rendered", () => { renderJsonSpec(config); }); - it("should get the spec", async function () { + it("should get the spec", async () => { const {data: specJson} = (await api.getSpec()) as {data: routes.config.Spec}; expect(specJson.SECONDS_PER_ETH1_BLOCK).toBe("14"); diff --git a/packages/beacon-node/test/unit/api/impl/events/events.test.ts b/packages/beacon-node/test/unit/api/impl/events/events.test.ts index e031c3ac9958..5b1686d42f57 100644 --- a/packages/beacon-node/test/unit/api/impl/events/events.test.ts +++ b/packages/beacon-node/test/unit/api/impl/events/events.test.ts @@ -11,7 +11,6 @@ vi.mock("../../../../../src/chain/index.js", async (importActual) => { return { ...mod, - // eslint-disable-next-line @typescript-eslint/naming-convention BeaconChain: vi.spyOn(mod, "BeaconChain").mockImplementation(() => { return { emitter: new ChainEventEmitter(), @@ -23,22 +22,20 @@ vi.mock("../../../../../src/chain/index.js", async (importActual) => { }; }); -describe("Events api impl", function () { - describe("beacon event stream", function () { +describe("Events api impl", () => { + describe("beacon event stream", () => { let chainStub: MockedObject; let chainEventEmmitter: ChainEventEmitter; let api: ReturnType; + let controller: AbortController; - beforeEach(function () { + beforeEach(() => { chainStub = vi.mocked(new BeaconChain({} as any, {} as any), {partial: true, deep: false}); chainEventEmmitter = chainStub.emitter; api = getEventsApi({config, chain: chainStub}); - }); - - let controller: AbortController; - beforeEach(() => { controller = new AbortController(); }); + afterEach(() => controller.abort()); function getEvents(topics: routes.events.EventType[]): routes.events.BeaconEvent[] { @@ -63,7 +60,7 @@ describe("Events api impl", function () { executionOptimistic: false, }; - it("should ignore not sent topics", async function () { + it("should ignore not sent topics", async () => { const events = getEvents([routes.events.EventType.head]); chainEventEmmitter.emit(routes.events.EventType.attestation, ssz.phase0.Attestation.defaultValue()); diff --git a/packages/beacon-node/test/unit/api/impl/validator/duties/proposer.test.ts b/packages/beacon-node/test/unit/api/impl/validator/duties/proposer.test.ts index b101382e01a0..b954f983adcc 100644 --- a/packages/beacon-node/test/unit/api/impl/validator/duties/proposer.test.ts +++ b/packages/beacon-node/test/unit/api/impl/validator/duties/proposer.test.ts @@ -3,6 +3,7 @@ import {routes} from "@lodestar/api"; import {config} from "@lodestar/config/default"; import {MAX_EFFECTIVE_BALANCE, SLOTS_PER_EPOCH} from "@lodestar/params"; import {BeaconStateAllForks} from "@lodestar/state-transition"; +import {Slot} from "@lodestar/types"; import {ApiTestModules, getApiTestModules} from "../../../../../utils/api.js"; import {FAR_FUTURE_EPOCH} from "../../../../../../src/constants/index.js"; import {SYNC_TOLERANCE_EPOCHS, getValidatorApi} from "../../../../../../src/api/impl/validator/index.js"; @@ -12,20 +13,35 @@ import {createCachedBeaconStateTest} from "../../../../../utils/cachedBeaconStat import {SyncState} from "../../../../../../src/sync/interface.js"; import {defaultApiOptions} from "../../../../../../src/api/options.js"; -describe("get proposers api impl", function () { +describe("get proposers api impl", () => { + const currentEpoch = 2; + const currentSlot = SLOTS_PER_EPOCH * currentEpoch; + let api: ReturnType; let modules: ApiTestModules; let state: BeaconStateAllForks; let cachedState: ReturnType; - beforeEach(function () { + beforeEach(() => { vi.useFakeTimers({now: 0}); + vi.advanceTimersByTime(currentSlot * config.SECONDS_PER_SLOT * 1000); modules = getApiTestModules({clock: "real"}); api = getValidatorApi(defaultApiOptions, modules); + initializeState(currentSlot); + + modules.chain.getHeadStateAtCurrentEpoch.mockResolvedValue(cachedState); + modules.forkChoice.getHead.mockReturnValue(zeroProtoBlock); + modules.forkChoice.getFinalizedBlock.mockReturnValue(zeroProtoBlock); + modules.db.block.get.mockResolvedValue({message: {stateRoot: Buffer.alloc(32)}} as any); + + vi.spyOn(modules.sync, "state", "get").mockReturnValue(SyncState.Synced); + }); + + function initializeState(slot: Slot): void { state = generateState( { - slot: 0, + slot, validators: generateValidators(25, { effectiveBalance: MAX_EFFECTIVE_BALANCE, activationEpoch: 0, @@ -37,14 +53,10 @@ describe("get proposers api impl", function () { ); cachedState = createCachedBeaconStateTest(state, config); - modules.chain.getHeadStateAtCurrentEpoch.mockResolvedValue(cachedState); - modules.forkChoice.getHead.mockReturnValue(zeroProtoBlock); - modules.db.block.get.mockResolvedValue({message: {stateRoot: Buffer.alloc(32)}} as any); - - vi.spyOn(modules.sync, "state", "get").mockReturnValue(SyncState.Synced); vi.spyOn(cachedState.epochCtx, "getBeaconProposersNextEpoch"); vi.spyOn(cachedState.epochCtx, "getBeaconProposers"); - }); + vi.spyOn(cachedState.epochCtx, "getBeaconProposersPrevEpoch"); + } afterEach(() => { vi.useRealTimers(); @@ -54,7 +66,7 @@ describe("get proposers api impl", function () { vi.advanceTimersByTime((SYNC_TOLERANCE_EPOCHS * SLOTS_PER_EPOCH + 1) * config.SECONDS_PER_SLOT * 1000); vi.spyOn(modules.sync, "state", "get").mockReturnValue(SyncState.SyncingHead); - await expect(api.getProposerDuties({epoch: 1})).rejects.toThrow("Node is syncing - headSlot 0 currentSlot 9"); + await expect(api.getProposerDuties({epoch: 1})).rejects.toThrow("Node is syncing - headSlot 0 currentSlot 25"); }); it("should raise error if node stalled", async () => { @@ -65,34 +77,61 @@ describe("get proposers api impl", function () { }); it("should get proposers for current epoch", async () => { - const {data: result} = (await api.getProposerDuties({epoch: 0})) as {data: routes.validator.ProposerDutyList}; + const {data: result} = (await api.getProposerDuties({epoch: currentEpoch})) as { + data: routes.validator.ProposerDutyList; + }; expect(result.length).toBe(SLOTS_PER_EPOCH); expect(cachedState.epochCtx.getBeaconProposers).toHaveBeenCalledOnce(); expect(cachedState.epochCtx.getBeaconProposersNextEpoch).not.toHaveBeenCalled(); - expect(result.map((p) => p.slot)).toEqual(Array.from({length: SLOTS_PER_EPOCH}, (_, i) => i)); + expect(cachedState.epochCtx.getBeaconProposersPrevEpoch).not.toHaveBeenCalled(); + expect(result.map((p) => p.slot)).toEqual( + Array.from({length: SLOTS_PER_EPOCH}, (_, i) => currentEpoch * SLOTS_PER_EPOCH + i) + ); }); it("should get proposers for next epoch", async () => { - const {data: result} = (await api.getProposerDuties({epoch: 1})) as {data: routes.validator.ProposerDutyList}; + const nextEpoch = currentEpoch + 1; + const {data: result} = (await api.getProposerDuties({epoch: nextEpoch})) as { + data: routes.validator.ProposerDutyList; + }; expect(result.length).toBe(SLOTS_PER_EPOCH); expect(cachedState.epochCtx.getBeaconProposers).not.toHaveBeenCalled(); expect(cachedState.epochCtx.getBeaconProposersNextEpoch).toHaveBeenCalledOnce(); - expect(result.map((p) => p.slot)).toEqual(Array.from({length: SLOTS_PER_EPOCH}, (_, i) => SLOTS_PER_EPOCH + i)); + expect(cachedState.epochCtx.getBeaconProposersPrevEpoch).not.toHaveBeenCalled(); + expect(result.map((p) => p.slot)).toEqual( + Array.from({length: SLOTS_PER_EPOCH}, (_, i) => nextEpoch * SLOTS_PER_EPOCH + i) + ); + }); + + it("should get proposers for historical epoch", async () => { + const historicalEpoch = currentEpoch - 2; + initializeState(currentSlot - 2 * SLOTS_PER_EPOCH); + modules.chain.getStateBySlot.mockResolvedValue({state, executionOptimistic: false, finalized: true}); + + const {data: result} = (await api.getProposerDuties({epoch: historicalEpoch})) as { + data: routes.validator.ProposerDutyList; + }; + + expect(result.length).toBe(SLOTS_PER_EPOCH); + // Spy won't be called as `getProposerDuties` will create a new cached beacon state + expect(result.map((p) => p.slot)).toEqual( + Array.from({length: SLOTS_PER_EPOCH}, (_, i) => historicalEpoch * SLOTS_PER_EPOCH + i) + ); }); it("should raise error for more than one epoch in the future", async () => { - await expect(api.getProposerDuties({epoch: 2})).rejects.toThrow( - "Requested epoch 2 must equal current 0 or next epoch 1" + await expect(api.getProposerDuties({epoch: currentEpoch + 2})).rejects.toThrow( + "Requested epoch 4 must not be more than one epoch in the future" ); }); it("should have different proposer validator public keys for current and next epoch", async () => { - const {data: currentProposers} = (await api.getProposerDuties({epoch: 0})) as { + const {data: currentProposers} = (await api.getProposerDuties({epoch: currentEpoch})) as { data: routes.validator.ProposerDutyList; }; - const {data: nextProposers} = (await api.getProposerDuties({epoch: 1})) as { + const {data: nextProposers} = (await api.getProposerDuties({epoch: currentEpoch + 1})) as { data: routes.validator.ProposerDutyList; }; @@ -101,10 +140,10 @@ describe("get proposers api impl", function () { }); it("should have different proposer validator indexes for current and next epoch", async () => { - const {data: currentProposers} = (await api.getProposerDuties({epoch: 0})) as { + const {data: currentProposers} = (await api.getProposerDuties({epoch: currentEpoch})) as { data: routes.validator.ProposerDutyList; }; - const {data: nextProposers} = (await api.getProposerDuties({epoch: 1})) as { + const {data: nextProposers} = (await api.getProposerDuties({epoch: currentEpoch + 1})) as { data: routes.validator.ProposerDutyList; }; @@ -112,10 +151,10 @@ describe("get proposers api impl", function () { }); it("should have different proposer slots for current and next epoch", async () => { - const {data: currentProposers} = (await api.getProposerDuties({epoch: 0})) as { + const {data: currentProposers} = (await api.getProposerDuties({epoch: currentEpoch})) as { data: routes.validator.ProposerDutyList; }; - const {data: nextProposers} = (await api.getProposerDuties({epoch: 1})) as { + const {data: nextProposers} = (await api.getProposerDuties({epoch: currentEpoch + 1})) as { data: routes.validator.ProposerDutyList; }; diff --git a/packages/beacon-node/test/unit/api/impl/validator/produceAttestationData.test.ts b/packages/beacon-node/test/unit/api/impl/validator/produceAttestationData.test.ts index 84872ca6045c..fdbfec5ac503 100644 --- a/packages/beacon-node/test/unit/api/impl/validator/produceAttestationData.test.ts +++ b/packages/beacon-node/test/unit/api/impl/validator/produceAttestationData.test.ts @@ -5,16 +5,16 @@ import {ApiTestModules, getApiTestModules} from "../../../../utils/api.js"; import {getValidatorApi} from "../../../../../src/api/impl/validator/index.js"; import {defaultApiOptions} from "../../../../../src/api/options.js"; -describe("api - validator - produceAttestationData", function () { +describe("api - validator - produceAttestationData", () => { let modules: ApiTestModules; let api: ReturnType; - beforeEach(function () { + beforeEach(() => { modules = getApiTestModules(); api = getValidatorApi(defaultApiOptions, modules); }); - it("Should throw when node is not synced", async function () { + it("Should throw when node is not synced", async () => { // Set the node's state to way back from current slot const currentSlot = 100000; const headSlot = 0; @@ -25,7 +25,7 @@ describe("api - validator - produceAttestationData", function () { await expect(api.produceAttestationData({committeeIndex: 0, slot: 0})).rejects.toThrow("Node is syncing"); }); - it("Should throw error when node is stopped", async function () { + it("Should throw error when node is stopped", async () => { const currentSlot = 100000; vi.spyOn(modules.chain.clock, "currentSlot", "get").mockReturnValue(currentSlot); vi.spyOn(modules.sync, "state", "get").mockReturnValue(SyncState.Stalled); diff --git a/packages/beacon-node/test/unit/api/impl/validator/produceBlockV2.test.ts b/packages/beacon-node/test/unit/api/impl/validator/produceBlockV2.test.ts index a23373938f64..306b18481c1f 100644 --- a/packages/beacon-node/test/unit/api/impl/validator/produceBlockV2.test.ts +++ b/packages/beacon-node/test/unit/api/impl/validator/produceBlockV2.test.ts @@ -16,7 +16,7 @@ import {generateProtoBlock} from "../../../../utils/typeGenerator.js"; import {ZERO_HASH_HEX} from "../../../../../src/constants/index.js"; import {defaultApiOptions} from "../../../../../src/api/options.js"; -describe("api/validator - produceBlockV2", function () { +describe("api/validator - produceBlockV2", () => { let api: ReturnType; let modules: ApiTestModules; let state: CachedBeaconStateBellatrix; @@ -32,7 +32,7 @@ describe("api/validator - produceBlockV2", function () { vi.clearAllMocks(); }); - it("correctly pass feeRecipient to produceBlock", async function () { + it("correctly pass feeRecipient to produceBlock", async () => { const fullBlock = ssz.bellatrix.BeaconBlock.defaultValue(); const executionPayloadValue = ssz.Wei.defaultValue(); const consensusBlockValue = ssz.Wei.defaultValue(); diff --git a/packages/beacon-node/test/unit/api/impl/validator/produceBlockV3.test.ts b/packages/beacon-node/test/unit/api/impl/validator/produceBlockV3.test.ts index a7299aa3b956..f705e4b38e14 100644 --- a/packages/beacon-node/test/unit/api/impl/validator/produceBlockV3.test.ts +++ b/packages/beacon-node/test/unit/api/impl/validator/produceBlockV3.test.ts @@ -12,8 +12,7 @@ import {CommonBlockBody} from "../../../../../src/chain/interface.js"; import {zeroProtoBlock} from "../../../../utils/state.js"; import {defaultApiOptions} from "../../../../../src/api/options.js"; -/* eslint-disable @typescript-eslint/naming-convention */ -describe("api/validator - produceBlockV3", function () { +describe("api/validator - produceBlockV3", () => { let modules: ApiTestModules; let api: ReturnType; @@ -65,102 +64,100 @@ describe("api/validator - produceBlockV3", function () { [routes.validator.BuilderSelection.ExecutionOnly, 1, 1, 1, true, "engine"], ]; - testCases.forEach( - ([ - builderSelection, - builderPayloadValue, - enginePayloadValue, - consensusBlockValue, - shouldOverrideBuilder, - finalSelection, - ]) => { - it(`produceBlockV3 - ${finalSelection} produces block`, async () => { - const fullBlock = ssz.bellatrix.BeaconBlock.defaultValue(); - const blindedBlock = ssz.bellatrix.BlindedBeaconBlock.defaultValue(); - - const slot = 1 * SLOTS_PER_EPOCH; - const randaoReveal = fullBlock.body.randaoReveal; - const graffiti = "a".repeat(32); - const feeRecipient = "0xccccccccccccccccccccccccccccccccccccccaa"; - const currentSlot = 1 * SLOTS_PER_EPOCH; - - vi.spyOn(modules.chain.clock, "currentSlot", "get").mockReturnValue(currentSlot); - vi.spyOn(modules.sync, "state", "get").mockReturnValue(SyncState.Synced); - modules.chain.recomputeForkChoiceHead.mockReturnValue({ - blockRoot: toHexString(fullBlock.parentRoot), - } as ProtoBlock); - modules.chain.getProposerHead.mockReturnValue({blockRoot: toHexString(fullBlock.parentRoot)} as ProtoBlock); - modules.chain.forkChoice.getBlock.mockReturnValue(zeroProtoBlock); - - if (enginePayloadValue !== null) { - const commonBlockBody: CommonBlockBody = { - attestations: fullBlock.body.attestations, - attesterSlashings: fullBlock.body.attesterSlashings, - deposits: fullBlock.body.deposits, - proposerSlashings: fullBlock.body.proposerSlashings, - eth1Data: fullBlock.body.eth1Data, - graffiti: fullBlock.body.graffiti, - randaoReveal: fullBlock.body.randaoReveal, - voluntaryExits: fullBlock.body.voluntaryExits, - blsToExecutionChanges: [], - syncAggregate: fullBlock.body.syncAggregate, - }; - - modules.chain.produceCommonBlockBody.mockResolvedValue(commonBlockBody); - - modules.chain.produceBlock.mockResolvedValue({ - block: fullBlock, - executionPayloadValue: BigInt(enginePayloadValue), - consensusBlockValue: BigInt(consensusBlockValue), - shouldOverrideBuilder, - }); - } else { - modules.chain.produceBlock.mockRejectedValue(Error("not produced")); - } - - if (builderPayloadValue !== null) { - modules.chain.produceBlindedBlock.mockResolvedValue({ - block: blindedBlock, - executionPayloadValue: BigInt(builderPayloadValue), - consensusBlockValue: BigInt(consensusBlockValue), - }); - } else { - modules.chain.produceBlindedBlock.mockRejectedValue(Error("not produced")); - } - const _skipRandaoVerification = false; - const produceBlockOpts = { - strictFeeRecipientCheck: false, - builderSelection, - feeRecipient, + for (const [ + builderSelection, + builderPayloadValue, + enginePayloadValue, + consensusBlockValue, + shouldOverrideBuilder, + finalSelection, + ] of testCases) { + it(`produceBlockV3 - ${finalSelection} produces block`, async () => { + const fullBlock = ssz.bellatrix.BeaconBlock.defaultValue(); + const blindedBlock = ssz.bellatrix.BlindedBeaconBlock.defaultValue(); + + const slot = 1 * SLOTS_PER_EPOCH; + const randaoReveal = fullBlock.body.randaoReveal; + const graffiti = "a".repeat(32); + const feeRecipient = "0xccccccccccccccccccccccccccccccccccccccaa"; + const currentSlot = 1 * SLOTS_PER_EPOCH; + + vi.spyOn(modules.chain.clock, "currentSlot", "get").mockReturnValue(currentSlot); + vi.spyOn(modules.sync, "state", "get").mockReturnValue(SyncState.Synced); + modules.chain.recomputeForkChoiceHead.mockReturnValue({ + blockRoot: toHexString(fullBlock.parentRoot), + } as ProtoBlock); + modules.chain.getProposerHead.mockReturnValue({blockRoot: toHexString(fullBlock.parentRoot)} as ProtoBlock); + modules.chain.forkChoice.getBlock.mockReturnValue(zeroProtoBlock); + + if (enginePayloadValue !== null) { + const commonBlockBody: CommonBlockBody = { + attestations: fullBlock.body.attestations, + attesterSlashings: fullBlock.body.attesterSlashings, + deposits: fullBlock.body.deposits, + proposerSlashings: fullBlock.body.proposerSlashings, + eth1Data: fullBlock.body.eth1Data, + graffiti: fullBlock.body.graffiti, + randaoReveal: fullBlock.body.randaoReveal, + voluntaryExits: fullBlock.body.voluntaryExits, + blsToExecutionChanges: [], + syncAggregate: fullBlock.body.syncAggregate, }; - const {data: block, meta} = await api.produceBlockV3({ - slot, - randaoReveal, - graffiti, - skipRandaoVerification: _skipRandaoVerification, - ...produceBlockOpts, - }); - - const expectedBlock = finalSelection === "builder" ? blindedBlock : fullBlock; - const expectedExecution = finalSelection === "builder" ? true : false; - - expect(block).toEqual(expectedBlock); - expect(meta.executionPayloadBlinded).toEqual(expectedExecution); - - // check call counts - if (builderSelection === routes.validator.BuilderSelection.ExecutionOnly) { - expect(modules.chain.produceBlindedBlock).toBeCalledTimes(0); - } else { - expect(modules.chain.produceBlindedBlock).toBeCalledTimes(1); - } + modules.chain.produceCommonBlockBody.mockResolvedValue(commonBlockBody); - if (builderSelection === routes.validator.BuilderSelection.BuilderOnly) { - expect(modules.chain.produceBlock).toBeCalledTimes(0); - } else { - expect(modules.chain.produceBlock).toBeCalledTimes(1); - } + modules.chain.produceBlock.mockResolvedValue({ + block: fullBlock, + executionPayloadValue: BigInt(enginePayloadValue), + consensusBlockValue: BigInt(consensusBlockValue), + shouldOverrideBuilder, + }); + } else { + modules.chain.produceBlock.mockRejectedValue(Error("not produced")); + } + + if (builderPayloadValue !== null) { + modules.chain.produceBlindedBlock.mockResolvedValue({ + block: blindedBlock, + executionPayloadValue: BigInt(builderPayloadValue), + consensusBlockValue: BigInt(consensusBlockValue), + }); + } else { + modules.chain.produceBlindedBlock.mockRejectedValue(Error("not produced")); + } + const _skipRandaoVerification = false; + const produceBlockOpts = { + strictFeeRecipientCheck: false, + builderSelection, + feeRecipient, + }; + + const {data: block, meta} = await api.produceBlockV3({ + slot, + randaoReveal, + graffiti, + skipRandaoVerification: _skipRandaoVerification, + ...produceBlockOpts, }); - } - ); + + const expectedBlock = finalSelection === "builder" ? blindedBlock : fullBlock; + const expectedExecution = finalSelection === "builder"; + + expect(block).toEqual(expectedBlock); + expect(meta.executionPayloadBlinded).toEqual(expectedExecution); + + // check call counts + if (builderSelection === routes.validator.BuilderSelection.ExecutionOnly) { + expect(modules.chain.produceBlindedBlock).toBeCalledTimes(0); + } else { + expect(modules.chain.produceBlindedBlock).toBeCalledTimes(1); + } + + if (builderSelection === routes.validator.BuilderSelection.BuilderOnly) { + expect(modules.chain.produceBlock).toBeCalledTimes(0); + } else { + expect(modules.chain.produceBlock).toBeCalledTimes(1); + } + }); + } }); diff --git a/packages/beacon-node/test/unit/chain/archive/blockArchiver.test.ts b/packages/beacon-node/test/unit/chain/archive/blockArchiver.test.ts index d9c3b93a76ee..dc7c9bb75291 100644 --- a/packages/beacon-node/test/unit/chain/archive/blockArchiver.test.ts +++ b/packages/beacon-node/test/unit/chain/archive/blockArchiver.test.ts @@ -9,14 +9,14 @@ import {archiveBlocks} from "../../../../src/chain/archiver/archiveBlocks.js"; import {MockedBeaconDb, getMockedBeaconDb} from "../../../mocks/mockedBeaconDb.js"; import {MockedBeaconChain, getMockedBeaconChain} from "../../../mocks/mockedBeaconChain.js"; -describe("block archiver task", function () { +describe("block archiver task", () => { const logger = testLogger(); let dbStub: MockedBeaconDb; let forkChoiceStub: MockedBeaconChain["forkChoice"]; let lightclientServer: MockedBeaconChain["lightClientServer"]; - beforeEach(function () { + beforeEach(() => { const chain = getMockedBeaconChain(); dbStub = getMockedBeaconDb(); forkChoiceStub = chain.forkChoice; @@ -30,7 +30,7 @@ describe("block archiver task", function () { vi.clearAllMocks(); }); - it("should archive finalized blocks", async function () { + it("should archive finalized blocks", async () => { const blockBytes = ssz.phase0.SignedBeaconBlock.serialize(ssz.phase0.SignedBeaconBlock.defaultValue()); vi.spyOn(dbStub.block, "getBinary").mockResolvedValue(Buffer.from(blockBytes)); // block i has slot i+1 diff --git a/packages/beacon-node/test/unit/chain/beaconProposerCache.ts b/packages/beacon-node/test/unit/chain/beaconProposerCache.ts index 4545ef0c94b2..b75bbf546a98 100644 --- a/packages/beacon-node/test/unit/chain/beaconProposerCache.ts +++ b/packages/beacon-node/test/unit/chain/beaconProposerCache.ts @@ -1,31 +1,31 @@ -import {expect} from "vitest"; +import {expect, describe, it, beforeEach} from "vitest"; import {BeaconProposerCache} from "../../../src/chain/beaconProposerCache.js"; const suggestedFeeRecipient = "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; -describe("BeaconProposerCache", function () { +describe("BeaconProposerCache", () => { let cache: BeaconProposerCache; - beforeEach(function () { + beforeEach(() => { // max 2 items cache = new BeaconProposerCache({suggestedFeeRecipient}); cache.add(1, {validatorIndex: 23, feeRecipient: "0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"}); cache.add(3, {validatorIndex: 43, feeRecipient: "0xcccccccccccccccccccccccccccccccccccccccc"}); }); - it("get default", function () { + it("get default", () => { expect(cache.get(32)).toBe("0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); }); - it("get what has been set", function () { + it("get what has been set", () => { expect(cache.get(23)).toBe("0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"); }); - it("override and get latest", function () { + it("override and get latest", () => { cache.add(5, {validatorIndex: 23, feeRecipient: "0xdddddddddddddddddddddddddddddddddddddddd"}); expect(cache.get(23)).toBe("0xdddddddddddddddddddddddddddddddddddddddd"); }); - it("prune", function () { + it("prune", () => { cache.prune(4); // Default for what has been pruned diff --git a/packages/beacon-node/test/unit/chain/blocks/verifyBlocksSanityChecks.test.ts b/packages/beacon-node/test/unit/chain/blocks/verifyBlocksSanityChecks.test.ts index a45678e5bf48..1296a79d5eab 100644 --- a/packages/beacon-node/test/unit/chain/blocks/verifyBlocksSanityChecks.test.ts +++ b/packages/beacon-node/test/unit/chain/blocks/verifyBlocksSanityChecks.test.ts @@ -13,7 +13,7 @@ import {ClockStopped} from "../../../mocks/clock.js"; import {BlockSource, getBlockInput} from "../../../../src/chain/blocks/types.js"; import {MockedBeaconChain, getMockedBeaconChain} from "../../../mocks/mockedBeaconChain.js"; -describe("chain / blocks / verifyBlocksSanityChecks", function () { +describe("chain / blocks / verifyBlocksSanityChecks", () => { let forkChoice: MockedBeaconChain["forkChoice"]; let clock: ClockStopped; let modules: {forkChoice: IForkChoice; clock: IClock; config: ChainForkConfig}; diff --git a/packages/beacon-node/test/unit/chain/bls/bls.test.ts b/packages/beacon-node/test/unit/chain/bls/bls.test.ts index 4203d7f9768c..137f2c4dd9df 100644 --- a/packages/beacon-node/test/unit/chain/bls/bls.test.ts +++ b/packages/beacon-node/test/unit/chain/bls/bls.test.ts @@ -5,7 +5,7 @@ import {BlsSingleThreadVerifier} from "../../../../src/chain/bls/singleThread.js import {BlsMultiThreadWorkerPool} from "../../../../src/chain/bls/multithread/index.js"; import {testLogger} from "../../../utils/logger.js"; -describe("BlsVerifier ", function () { +describe("BlsVerifier ", () => { // take time for creating thread pool const numKeys = 3; const secretKeys = Array.from({length: numKeys}, (_, i) => SecretKey.fromKeygen(Buffer.alloc(32, i))); diff --git a/packages/beacon-node/test/unit/chain/forkChoice/forkChoice.test.ts b/packages/beacon-node/test/unit/chain/forkChoice/forkChoice.test.ts index 611673086ce5..7cb5d23ba296 100644 --- a/packages/beacon-node/test/unit/chain/forkChoice/forkChoice.test.ts +++ b/packages/beacon-node/test/unit/chain/forkChoice/forkChoice.test.ts @@ -20,7 +20,7 @@ import {generateValidators} from "../../../utils/validator.js"; // We mock this package globally vi.unmock("@lodestar/fork-choice"); -describe("LodestarForkChoice", function () { +describe("LodestarForkChoice", () => { let forkChoice: ForkChoice; const anchorState = createCachedBeaconStateTest( generateState( @@ -71,7 +71,7 @@ describe("LodestarForkChoice", function () { ); }); - describe("forkchoice", function () { + describe("forkchoice", () => { /** * slot 32(checkpoint) - orphaned (36) * \ diff --git a/packages/beacon-node/test/unit/chain/genesis/genesis.test.ts b/packages/beacon-node/test/unit/chain/genesis/genesis.test.ts index f836e3621cc9..40570fcd26e1 100644 --- a/packages/beacon-node/test/unit/chain/genesis/genesis.test.ts +++ b/packages/beacon-node/test/unit/chain/genesis/genesis.test.ts @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/naming-convention */ import {toHexString} from "@chainsafe/ssz"; import {describe, it, expect} from "vitest"; import {PublicKey, SecretKey} from "@chainsafe/blst"; @@ -12,7 +11,7 @@ import {testLogger} from "../../../utils/logger.js"; import {ZERO_HASH_HEX} from "../../../../src/constants/index.js"; import {Eth1ProviderState, EthJsonRpcBlockRaw, IEth1Provider} from "../../../../src/eth1/interface.js"; -describe("genesis builder", function () { +describe("genesis builder", () => { const logger = testLogger(); const schlesiConfig = Object.assign({}, config, { MIN_GENESIS_TIME: 1587755000, diff --git a/packages/beacon-node/test/unit/chain/lightclient/upgradeLightClientHeader.test.ts b/packages/beacon-node/test/unit/chain/lightclient/upgradeLightClientHeader.test.ts index 6da728be46e9..3c2f5a664c77 100644 --- a/packages/beacon-node/test/unit/chain/lightclient/upgradeLightClientHeader.test.ts +++ b/packages/beacon-node/test/unit/chain/lightclient/upgradeLightClientHeader.test.ts @@ -4,11 +4,10 @@ import {ForkName, ForkSeq} from "@lodestar/params"; import {createBeaconConfig, createChainForkConfig, defaultChainConfig} from "@lodestar/config"; import {upgradeLightClientHeader} from "@lodestar/light-client/spec"; -describe("UpgradeLightClientHeader", function () { +describe("UpgradeLightClientHeader", () => { let lcHeaderByFork: Record; let testSlots: Record; - /* eslint-disable @typescript-eslint/naming-convention */ const chainConfig = createChainForkConfig({ ...defaultChainConfig, ALTAIR_FORK_EPOCH: 1, @@ -21,7 +20,7 @@ describe("UpgradeLightClientHeader", function () { const genesisValidatorsRoot = Buffer.alloc(32, 0xaa); const config = createBeaconConfig(chainConfig, genesisValidatorsRoot); - beforeEach(function () { + beforeEach(() => { lcHeaderByFork = { phase0: ssz.altair.LightClientHeader.defaultValue(), altair: ssz.altair.LightClientHeader.defaultValue(), @@ -46,7 +45,7 @@ describe("UpgradeLightClientHeader", function () { const fromFork = ForkName[ForkSeq[i] as ForkName]; const toFork = ForkName[ForkSeq[j] as ForkName]; - it(`Successful upgrade ${fromFork}=>${toFork}`, function () { + it(`Successful upgrade ${fromFork}=>${toFork}`, () => { lcHeaderByFork[fromFork].beacon.slot = testSlots[fromFork]; lcHeaderByFork[toFork].beacon.slot = testSlots[fromFork]; @@ -61,7 +60,7 @@ describe("UpgradeLightClientHeader", function () { const fromFork = ForkName[ForkSeq[i] as ForkName]; const toFork = ForkName[ForkSeq[j] as ForkName]; - it(`Throw upgrade error ${fromFork}=>${toFork}`, function () { + it(`Throw upgrade error ${fromFork}=>${toFork}`, () => { lcHeaderByFork[fromFork].beacon.slot = testSlots[fromFork]; lcHeaderByFork[toFork].beacon.slot = testSlots[fromFork]; diff --git a/packages/beacon-node/test/unit/chain/opPools/aggregatedAttestationPool.test.ts b/packages/beacon-node/test/unit/chain/opPools/aggregatedAttestationPool.test.ts index f00a300bbe4d..8742d7da9147 100644 --- a/packages/beacon-node/test/unit/chain/opPools/aggregatedAttestationPool.test.ts +++ b/packages/beacon-node/test/unit/chain/opPools/aggregatedAttestationPool.test.ts @@ -34,7 +34,7 @@ const validSignature = fromHexString( "0xb2afb700f6c561ce5e1b4fedaec9d7c06b822d38c720cf588adfda748860a940adf51634b6788f298c552de40183b5a203b2bbe8b7dd147f0bb5bc97080a12efbb631c8888cb31a99cc4706eb3711865b8ea818c10126e4d818b542e9dbf9ae8" ); -describe("AggregatedAttestationPool", function () { +describe("AggregatedAttestationPool", () => { let pool: AggregatedAttestationPool; const fork = ForkName.altair; const config = createChainForkConfig({ @@ -116,7 +116,7 @@ describe("AggregatedAttestationPool", function () { ]; for (const {name, attestingBits, isReturned} of testCases) { - it(name, function () { + it(name, () => { const aggregationBits = new BitArray(new Uint8Array(attestingBits), committeeLength); pool.add( {...attestation, aggregationBits}, @@ -136,7 +136,7 @@ describe("AggregatedAttestationPool", function () { }); } - it("incorrect source", function () { + it("incorrect source", () => { altairState.currentJustifiedCheckpoint.epoch = 1000; // all attesters are not seen const attestingIndices = [2, 3]; @@ -146,7 +146,7 @@ describe("AggregatedAttestationPool", function () { expect(forkchoiceStub.iterateAncestorBlocks).not.toHaveBeenCalledTimes(1); }); - it("incompatible shuffling - incorrect pivot block root", function () { + it("incompatible shuffling - incorrect pivot block root", () => { // all attesters are not seen const attestingIndices = [2, 3]; pool.add(attestation, attDataRootHex, attestingIndices.length, committee); @@ -305,7 +305,7 @@ describe("MatchingDataAttestationGroup.getAttestationsForBlock", () => { } }); -describe("MatchingDataAttestationGroup aggregateInto", function () { +describe("MatchingDataAttestationGroup aggregateInto", () => { const attestationSeed = ssz.phase0.Attestation.defaultValue(); const attestation1 = {...attestationSeed, ...{aggregationBits: BitArray.fromBoolArray([false, true])}}; const attestation2 = {...attestationSeed, ...{aggregationBits: BitArray.fromBoolArray([true, false])}}; @@ -334,7 +334,7 @@ describe("MatchingDataAttestationGroup aggregateInto", function () { }); }); -describe("aggregateConsolidation", function () { +describe("aggregateConsolidation", () => { const sk0 = SecretKey.fromBytes(Buffer.alloc(32, 1)); const sk1 = SecretKey.fromBytes(Buffer.alloc(32, 2)); const sk2 = SecretKey.fromBytes(Buffer.alloc(32, 3)); diff --git a/packages/beacon-node/test/unit/chain/opPools/attestationPool.test.ts b/packages/beacon-node/test/unit/chain/opPools/attestationPool.test.ts index 68efd0751585..98453efaa3b6 100644 --- a/packages/beacon-node/test/unit/chain/opPools/attestationPool.test.ts +++ b/packages/beacon-node/test/unit/chain/opPools/attestationPool.test.ts @@ -8,12 +8,11 @@ import {AttestationPool} from "../../../../src/chain/opPools/attestationPool.js" import {getMockedClock} from "../../../mocks/clock.js"; /** Valid signature of random data to prevent BLS errors */ -export const validSignature = fromHexString( +const validSignature = fromHexString( "0xb2afb700f6c561ce5e1b4fedaec9d7c06b822d38c720cf588adfda748860a940adf51634b6788f298c552de40183b5a203b2bbe8b7dd147f0bb5bc97080a12efbb631c8888cb31a99cc4706eb3711865b8ea818c10126e4d818b542e9dbf9ae8" ); -describe("AttestationPool", function () { - /* eslint-disable @typescript-eslint/naming-convention */ +describe("AttestationPool", () => { const config = createChainForkConfig({ ...defaultChainConfig, ELECTRA_FORK_EPOCH: 5, diff --git a/packages/beacon-node/test/unit/chain/opPools/syncCommittee.test.ts b/packages/beacon-node/test/unit/chain/opPools/syncCommittee.test.ts index 507c78d560b6..e91eaa58aa73 100644 --- a/packages/beacon-node/test/unit/chain/opPools/syncCommittee.test.ts +++ b/packages/beacon-node/test/unit/chain/opPools/syncCommittee.test.ts @@ -7,7 +7,7 @@ import {Clock} from "../../../../src/util/clock.js"; vi.mock("../../../../src/util/clock.js"); -describe("chain / opPools / SyncCommitteeMessagePool", function () { +describe("chain / opPools / SyncCommitteeMessagePool", () => { let cache: SyncCommitteeMessagePool; const subcommitteeIndex = 2; const indexInSubcommittee = 3; @@ -33,7 +33,7 @@ describe("chain / opPools / SyncCommitteeMessagePool", function () { cache.add(subcommitteeIndex, syncCommittee, indexInSubcommittee); }); - afterEach(function () { + afterEach(() => { vi.clearAllTimers(); vi.clearAllMocks(); }); diff --git a/packages/beacon-node/test/unit/chain/opPools/syncCommitteeContribution.test.ts b/packages/beacon-node/test/unit/chain/opPools/syncCommitteeContribution.test.ts index e34a5d006272..e1bd60a2305e 100644 --- a/packages/beacon-node/test/unit/chain/opPools/syncCommitteeContribution.test.ts +++ b/packages/beacon-node/test/unit/chain/opPools/syncCommitteeContribution.test.ts @@ -15,7 +15,7 @@ import {EMPTY_SIGNATURE} from "../../../../src/constants/index.js"; import {renderBitArray} from "../../../utils/render.js"; import {VALID_BLS_SIGNATURE_RAND} from "../../../utils/typeGenerator.js"; -describe("chain / opPools / SyncContributionAndProofPool", function () { +describe("chain / opPools / SyncContributionAndProofPool", () => { let cache: SyncContributionAndProofPool; const beaconBlockRoot = Buffer.alloc(32, 1); const slot = 10; @@ -44,7 +44,7 @@ describe("chain / opPools / SyncContributionAndProofPool", function () { }); }); -describe("replaceIfBetter", function () { +describe("replaceIfBetter", () => { const numParticipants = 2; let bestContribution: SyncContributionFast; // const subnetSize = Math.floor(SYNC_COMMITTEE_SIZE / SYNC_COMMITTEE_SUBNET_COUNT); @@ -77,7 +77,7 @@ describe("replaceIfBetter", function () { }); }); -describe("aggregate", function () { +describe("aggregate", () => { const sks: SecretKey[] = []; let bestContributionBySubnet: Map; beforeAll(async () => { diff --git a/packages/beacon-node/test/unit/chain/prepareNextSlot.test.ts b/packages/beacon-node/test/unit/chain/prepareNextSlot.test.ts index 9ce121e976d0..c7d0a7801fec 100644 --- a/packages/beacon-node/test/unit/chain/prepareNextSlot.test.ts +++ b/packages/beacon-node/test/unit/chain/prepareNextSlot.test.ts @@ -98,7 +98,7 @@ describe("PrepareNextSlot scheduler", () => { scheduler.prepareForNextSlot(2 * SLOTS_PER_EPOCH - 1), vi.advanceTimersByTimeAsync((config.SECONDS_PER_SLOT * 1000 * 2) / 3), ]); - expect(chainStub.recomputeForkChoiceHead).toHaveBeenCalledWith(); + expect(chainStub.recomputeForkChoiceHead).toHaveBeenCalledOnce(); expect(regenStub.getBlockSlotState).not.toHaveBeenCalled(); }); diff --git a/packages/beacon-node/test/unit/chain/reprocess.test.ts b/packages/beacon-node/test/unit/chain/reprocess.test.ts index a8160544f509..927e4cf8d05f 100644 --- a/packages/beacon-node/test/unit/chain/reprocess.test.ts +++ b/packages/beacon-node/test/unit/chain/reprocess.test.ts @@ -1,7 +1,7 @@ import {describe, it, expect, beforeEach} from "vitest"; import {ReprocessController} from "../../../src/chain/reprocess.js"; -describe("ReprocessController", function () { +describe("ReprocessController", () => { let controller: ReprocessController; beforeEach(() => { diff --git a/packages/beacon-node/test/unit/chain/rewards/blockRewards.test.ts b/packages/beacon-node/test/unit/chain/rewards/blockRewards.test.ts index f0d85ce3220f..d417d83e2da9 100644 --- a/packages/beacon-node/test/unit/chain/rewards/blockRewards.test.ts +++ b/packages/beacon-node/test/unit/chain/rewards/blockRewards.test.ts @@ -10,9 +10,7 @@ import { import { generatePerfTestCachedStateAltair, cachedStateAltairPopulateCaches, - // eslint-disable-next-line import/no-relative-packages } from "../../../../../state-transition/test/perf/util.js"; -// eslint-disable-next-line import/no-relative-packages import {BlockAltairOpts, getBlockAltair} from "../../../../../state-transition/test/perf/block/util.js"; import {computeBlockRewards} from "../../../../src/chain/rewards/blockRewards.js"; diff --git a/packages/beacon-node/test/unit/chain/seenCache/aggregateAndProof.test.ts b/packages/beacon-node/test/unit/chain/seenCache/aggregateAndProof.test.ts index 3118fdcadc43..d83433a649ca 100644 --- a/packages/beacon-node/test/unit/chain/seenCache/aggregateAndProof.test.ts +++ b/packages/beacon-node/test/unit/chain/seenCache/aggregateAndProof.test.ts @@ -6,7 +6,7 @@ import { SeenAggregatedAttestations, } from "../../../../src/chain/seenCache/seenAggregateAndProof.js"; -describe("SeenAggregatedAttestations.isKnown", function () { +describe("SeenAggregatedAttestations.isKnown", () => { const testCases: { id: string; seenAttestingBits: number[]; @@ -62,7 +62,7 @@ describe("SeenAggregatedAttestations.isKnown", function () { } }); -describe("insertDesc", function () { +describe("insertDesc", () => { const testCases: { id: string; arr: number[][]; diff --git a/packages/beacon-node/test/unit/chain/seenCache/seenGossipBlockInput.test.ts b/packages/beacon-node/test/unit/chain/seenCache/seenGossipBlockInput.test.ts index 2a3275536f22..27b5eadecf11 100644 --- a/packages/beacon-node/test/unit/chain/seenCache/seenGossipBlockInput.test.ts +++ b/packages/beacon-node/test/unit/chain/seenCache/seenGossipBlockInput.test.ts @@ -5,7 +5,6 @@ import {ssz} from "@lodestar/types"; import {SeenGossipBlockInput} from "../../../../src/chain/seenCache/seenGossipBlockInput.js"; import {BlockInputType, GossipedInputType, BlockInput} from "../../../../src/chain/blocks/types.js"; -/* eslint-disable @typescript-eslint/naming-convention */ describe("SeenGossipBlockInput", () => { const chainConfig = createChainForkConfig({ ...defaultChainConfig, diff --git a/packages/beacon-node/test/unit/chain/seenCache/syncCommittee.test.ts b/packages/beacon-node/test/unit/chain/seenCache/syncCommittee.test.ts index 901c19cad9f8..59c67f9cedc2 100644 --- a/packages/beacon-node/test/unit/chain/seenCache/syncCommittee.test.ts +++ b/packages/beacon-node/test/unit/chain/seenCache/syncCommittee.test.ts @@ -5,7 +5,7 @@ import {SeenSyncCommitteeMessages, SeenContributionAndProof} from "../../../../s const NUM_SLOTS_IN_CACHE = 3; -describe("chain / seenCache / SeenSyncCommittee caches", function () { +describe("chain / seenCache / SeenSyncCommittee caches", () => { describe("SeenSyncCommitteeMessages", () => { const slot = 10; const subnet = 2; diff --git a/packages/beacon-node/test/unit/chain/shufflingCache.test.ts b/packages/beacon-node/test/unit/chain/shufflingCache.test.ts index 62b02cbf2b12..d417e555872c 100644 --- a/packages/beacon-node/test/unit/chain/shufflingCache.test.ts +++ b/packages/beacon-node/test/unit/chain/shufflingCache.test.ts @@ -1,9 +1,8 @@ import {describe, it, expect, beforeEach} from "vitest"; -// eslint-disable-next-line import/no-relative-packages import {generateTestCachedBeaconStateOnlyValidators} from "../../../../state-transition/test/perf/util.js"; import {ShufflingCache} from "../../../src/chain/shufflingCache.js"; -describe("ShufflingCache", function () { +describe("ShufflingCache", () => { const vc = 64; const stateSlot = 100; const state = generateTestCachedBeaconStateOnlyValidators({vc, slot: stateSlot}); @@ -20,11 +19,11 @@ describe("ShufflingCache", function () { ]); }); - it("should get shuffling from cache", async function () { + it("should get shuffling from cache", async () => { expect(await shufflingCache.get(currentEpoch, currentDecisionRoot)).toEqual(state.epochCtx.currentShuffling); }); - it("should bound by maxSize(=1)", async function () { + it("should bound by maxSize(=1)", async () => { expect(await shufflingCache.get(currentEpoch, currentDecisionRoot)).toEqual(state.epochCtx.currentShuffling); // insert promises at the same epoch does not prune the cache shufflingCache.insertPromise(currentEpoch, "0x00"); @@ -35,7 +34,7 @@ describe("ShufflingCache", function () { expect(await shufflingCache.get(currentEpoch, currentDecisionRoot)).toBeNull(); }); - it("should return shuffling from promise", async function () { + it("should return shuffling from promise", async () => { const previousEpoch = state.epochCtx.epoch - 1; const previousDecisionRoot = state.epochCtx.previousDecisionRoot; shufflingCache.insertPromise(previousEpoch, previousDecisionRoot); @@ -46,7 +45,7 @@ describe("ShufflingCache", function () { expect(await shufflingRequest1).toEqual(state.epochCtx.previousShuffling); }); - it("should support up to 2 promises at a time", async function () { + it("should support up to 2 promises at a time", async () => { // insert 2 promises at the same epoch shufflingCache.insertPromise(currentEpoch, "0x00"); shufflingCache.insertPromise(currentEpoch, "0x01"); diff --git a/packages/beacon-node/test/unit/chain/stateCache/blockStateCacheImpl.test.ts b/packages/beacon-node/test/unit/chain/stateCache/blockStateCacheImpl.test.ts index b89a71399237..19dc0f3a2c60 100644 --- a/packages/beacon-node/test/unit/chain/stateCache/blockStateCacheImpl.test.ts +++ b/packages/beacon-node/test/unit/chain/stateCache/blockStateCacheImpl.test.ts @@ -7,7 +7,7 @@ import {BlockStateCacheImpl} from "../../../../src/chain/stateCache/index.js"; import {generateCachedState} from "../../../utils/state.js"; import {ZERO_HASH} from "../../../../src/constants/index.js"; -describe("BlockStateCacheImpl", function () { +describe("BlockStateCacheImpl", () => { let cache: BlockStateCacheImpl; let key1: Root, key2: Root; const shuffling: EpochShuffling = { @@ -18,7 +18,7 @@ describe("BlockStateCacheImpl", function () { committeesPerSlot: 1, }; - beforeEach(function () { + beforeEach(() => { // max 2 items cache = new BlockStateCacheImpl({maxStates: 2}); const state1 = generateCachedState({slot: 0}); @@ -31,7 +31,7 @@ describe("BlockStateCacheImpl", function () { cache.add(state2); }); - it("should prune", function () { + it("should prune", () => { expect(cache.size).toBe(2); const state3 = generateCachedState({slot: 2 * SLOTS_PER_EPOCH}); state3.epochCtx.currentShuffling = {...shuffling, epoch: 2}; @@ -46,7 +46,7 @@ describe("BlockStateCacheImpl", function () { expect(cache.get(toHexString(key2))).toBeDefined(); }); - it("should deleteAllBeforeEpoch", function () { + it("should deleteAllBeforeEpoch", () => { cache.deleteAllBeforeEpoch(2); expect(cache.size).toBe(0); }); diff --git a/packages/beacon-node/test/unit/chain/stateCache/fifoBlockStateCache.test.ts b/packages/beacon-node/test/unit/chain/stateCache/fifoBlockStateCache.test.ts index b4aac92dd9bb..07a8ec12093d 100644 --- a/packages/beacon-node/test/unit/chain/stateCache/fifoBlockStateCache.test.ts +++ b/packages/beacon-node/test/unit/chain/stateCache/fifoBlockStateCache.test.ts @@ -5,7 +5,7 @@ import {SLOTS_PER_EPOCH} from "@lodestar/params"; import {FIFOBlockStateCache} from "../../../../src/chain/stateCache/index.js"; import {generateCachedState} from "../../../utils/state.js"; -describe("FIFOBlockStateCache", function () { +describe("FIFOBlockStateCache", () => { let cache: FIFOBlockStateCache; const shuffling: EpochShuffling = { epoch: 0, @@ -27,7 +27,7 @@ describe("FIFOBlockStateCache", function () { const key3 = toHexString(state3.hashTreeRoot()); state3.epochCtx.currentShuffling = {...shuffling, epoch: 2}; - beforeEach(function () { + beforeEach(() => { // max 2 items cache = new FIFOBlockStateCache({maxBlockStates: 2}, {}); cache.add(state1); diff --git a/packages/beacon-node/test/unit/chain/stateCache/inMemoryCheckpointsCache.test.ts b/packages/beacon-node/test/unit/chain/stateCache/inMemoryCheckpointsCache.test.ts index 59f320178118..23a792bef0a8 100644 --- a/packages/beacon-node/test/unit/chain/stateCache/inMemoryCheckpointsCache.test.ts +++ b/packages/beacon-node/test/unit/chain/stateCache/inMemoryCheckpointsCache.test.ts @@ -9,7 +9,7 @@ import { } from "../../../../src/chain/stateCache/inMemoryCheckpointsCache.js"; import {generateCachedState} from "../../../utils/state.js"; -describe("InMemoryCheckpointStateCache", function () { +describe("InMemoryCheckpointStateCache", () => { let root0a: Buffer, root0b: Buffer, root1: Buffer, root2: Buffer; let cp0a: phase0.Checkpoint, cp0b: phase0.Checkpoint, cp1: phase0.Checkpoint, cp2: phase0.Checkpoint; let cp0aHex: CheckpointHex, cp0bHex: CheckpointHex, cp1Hex: CheckpointHex, cp2Hex: CheckpointHex; diff --git a/packages/beacon-node/test/unit/chain/stateCache/persistentCheckpointsCache.test.ts b/packages/beacon-node/test/unit/chain/stateCache/persistentCheckpointsCache.test.ts index 9614263b4312..f98b180fa983 100644 --- a/packages/beacon-node/test/unit/chain/stateCache/persistentCheckpointsCache.test.ts +++ b/packages/beacon-node/test/unit/chain/stateCache/persistentCheckpointsCache.test.ts @@ -12,7 +12,7 @@ import {getTestDatastore} from "../../../utils/chain/stateCache/datastore.js"; import {CheckpointHex} from "../../../../src/chain/stateCache/types.js"; import {FIFOBlockStateCache, toCheckpointHex} from "../../../../src/chain/index.js"; -describe("PersistentCheckpointStateCache", function () { +describe("PersistentCheckpointStateCache", () => { let root0a: Buffer, root0b: Buffer, root1: Buffer, root2: Buffer; let cp0a: phase0.Checkpoint, cp0b: phase0.Checkpoint, cp1: phase0.Checkpoint, cp2: phase0.Checkpoint; let cp0aHex: CheckpointHex, cp0bHex: CheckpointHex, cp1Hex: CheckpointHex, cp2Hex: CheckpointHex; @@ -135,7 +135,7 @@ describe("PersistentCheckpointStateCache", function () { expect((await cache.getOrReloadLatest(cp0bHex.rootHex, cp0b.epoch - 1))?.serialize()).toBeUndefined(); }); - it("pruneFinalized and getStateOrBytes", async function () { + it("pruneFinalized and getStateOrBytes", async () => { cache.add(cp2, states["cp2"]); expect(((await cache.getStateOrBytes(cp0bHex)) as CachedBeaconStateAllForks).hashTreeRoot()).toEqual( states["cp0b"].hashTreeRoot() @@ -182,7 +182,7 @@ describe("PersistentCheckpointStateCache", function () { // |0b--------root1--------root2 // | // 0a - it("single state at lowest memory epoch", async function () { + it("single state at lowest memory epoch", async () => { cache.add(cp2, states["cp2"]); expect(await cache.processState(toHexString(cp2.root), states["cp2"])).toEqual(1); expect(cache.findSeedStateToReload(cp0aHex)?.hashTreeRoot()).toEqual(states["cp1"].hashTreeRoot()); @@ -198,7 +198,7 @@ describe("PersistentCheckpointStateCache", function () { // 0a------------------------------root3 // ^ ^ // cp1a={0a, 21} {0a, 22}=cp2a - it("multiple states at lowest memory epoch", async function () { + it("multiple states at lowest memory epoch", async () => { cache.add(cp2, states["cp2"]); expect(await cache.processState(toHexString(cp2.root), states["cp2"])).toEqual(1); @@ -259,7 +259,7 @@ describe("PersistentCheckpointStateCache", function () { // |0b--------root1--------root2-----root3 // | // 0a - it("no reorg", async function () { + it("no reorg", async () => { expect(fileApisBuffer.size).toEqual(0); cache.add(cp2, states["cp2"]); expect(await cache.processState(toHexString(cp2.root), states["cp2"])).toEqual(1); @@ -293,7 +293,7 @@ describe("PersistentCheckpointStateCache", function () { // |0b--------root1--------root2-root3 | // | | // 0a |---------root4 - it("reorg in same epoch", async function () { + it("reorg in same epoch", async () => { // mostly the same to the above test expect(fileApisBuffer.size).toEqual(0); cache.add(cp2, states["cp2"]); @@ -338,7 +338,7 @@ describe("PersistentCheckpointStateCache", function () { // 1a ^ // | // {1a, 22}=cp2a - it("reorg 1 epoch", async function () { + it("reorg 1 epoch", async () => { // process root2 state cache.add(cp2, states["cp2"]); expect(await cache.processState(toHexString(cp2.root), states["cp2"])).toEqual(1); @@ -382,7 +382,7 @@ describe("PersistentCheckpointStateCache", function () { // 0a ^ ^ // | | // cp1a={0a, 21} {0a, 22}=cp2a - it("reorg 2 epochs", async function () { + it("reorg 2 epochs", async () => { // process root2 state cache.add(cp2, states["cp2"]); expect(await cache.processState(toHexString(cp2.root), states["cp2"])).toEqual(1); @@ -435,7 +435,7 @@ describe("PersistentCheckpointStateCache", function () { // ^ ^ // | | // cp1a={0a, 21} {0a, 22}=cp2a - it("reorg 3 epochs, persist cp 0a", async function () { + it("reorg 3 epochs, persist cp 0a", async () => { // process root2 state cache.add(cp2, states["cp2"]); expect(await cache.processState(toHexString(cp2.root), states["cp2"])).toEqual(1); @@ -491,7 +491,7 @@ describe("PersistentCheckpointStateCache", function () { // 0a ^ ^ // | | // cp1b={0b, 21} {0b, 22}=cp2b - it("reorg 3 epochs, prune but no persist", async function () { + it("reorg 3 epochs, prune but no persist", async () => { // process root2 state cache.add(cp2, states["cp2"]); expect(await cache.processState(toHexString(cp2.root), states["cp2"])).toEqual(1); diff --git a/packages/beacon-node/test/unit/chain/validation/aggregateAndProof.test.ts b/packages/beacon-node/test/unit/chain/validation/aggregateAndProof.test.ts index f2c20fd5cbe4..e2bc392b4ea2 100644 --- a/packages/beacon-node/test/unit/chain/validation/aggregateAndProof.test.ts +++ b/packages/beacon-node/test/unit/chain/validation/aggregateAndProof.test.ts @@ -2,7 +2,6 @@ import {BitArray, toHexString} from "@chainsafe/ssz"; import {describe, it} from "vitest"; import {SLOTS_PER_EPOCH} from "@lodestar/params"; import {phase0, ssz} from "@lodestar/types"; -// eslint-disable-next-line import/no-relative-packages import {generateTestCachedBeaconStateOnlyValidators} from "../../../../../state-transition/test/perf/util.js"; import {IBeaconChain} from "../../../../src/chain/index.js"; import {AttestationErrorCode} from "../../../../src/chain/errors/index.js"; @@ -24,7 +23,6 @@ describe("chain / validation / aggregateAndProof", () => { const getState = memoOnce(() => generateTestCachedBeaconStateOnlyValidators({vc, slot: stateSlot})); - // eslint-disable-next-line @typescript-eslint/explicit-function-return-type function getValidData(opts?: Partial) { return getAggregateAndProofValidData({ currentSlot: stateSlot, diff --git a/packages/beacon-node/test/unit/chain/validation/attestation/getShufflingForAttestationVerification.test.ts b/packages/beacon-node/test/unit/chain/validation/attestation/getShufflingForAttestationVerification.test.ts index a0eb147db8e8..4ba65270e17a 100644 --- a/packages/beacon-node/test/unit/chain/validation/attestation/getShufflingForAttestationVerification.test.ts +++ b/packages/beacon-node/test/unit/chain/validation/attestation/getShufflingForAttestationVerification.test.ts @@ -1,6 +1,5 @@ import {afterEach, beforeEach, describe, expect, it, vi} from "vitest"; // We need to import the mock before the packages -// eslint-disable-next-line import/order import {MockedBeaconChain, getMockedBeaconChain} from "../../../../mocks/mockedBeaconChain.js"; import {EpochShuffling, computeStartSlotAtEpoch} from "@lodestar/state-transition"; import {EpochDifference, ProtoBlock} from "@lodestar/fork-choice"; @@ -41,17 +40,15 @@ describe("getShufflingForAttestationVerification", () => { forkchoiceStub.getDependentRoot.mockImplementationOnce((block, epochDiff) => { if (block === attHeadBlock && epochDiff === EpochDifference.previous) { return previousDependentRoot; - } else { - throw new Error("Unexpected input"); } + throw new Error("Unexpected input"); }); const expectedShuffling = {epoch: attEpoch} as EpochShuffling; shufflingCacheStub.get.mockImplementationOnce((epoch, root) => { if (epoch === attEpoch && root === previousDependentRoot) { return Promise.resolve(expectedShuffling); - } else { - return Promise.resolve(null); } + return Promise.resolve(null); }); const resultShuffling = await getShufflingForAttestationVerification( chain, @@ -73,17 +70,15 @@ describe("getShufflingForAttestationVerification", () => { forkchoiceStub.getDependentRoot.mockImplementationOnce((block, epochDiff) => { if (block === attHeadBlock && epochDiff === EpochDifference.current) { return currentDependentRoot; - } else { - throw new Error("Unexpected input"); } + throw new Error("Unexpected input"); }); const expectedShuffling = {epoch: attEpoch} as EpochShuffling; shufflingCacheStub.get.mockImplementationOnce((epoch, root) => { if (epoch === attEpoch && root === currentDependentRoot) { return Promise.resolve(expectedShuffling); - } else { - return Promise.resolve(null); } + return Promise.resolve(null); }); const resultShuffling = await getShufflingForAttestationVerification( chain, @@ -108,12 +103,10 @@ describe("getShufflingForAttestationVerification", () => { if (callCount === 0) { callCount++; return Promise.resolve(null); - } else { - return Promise.resolve(expectedShuffling); } - } else { - return Promise.resolve(null); + return Promise.resolve(expectedShuffling); } + return Promise.resolve(null); }); chain.regenStateForAttestationVerification.mockImplementationOnce(() => Promise.resolve(expectedShuffling)); diff --git a/packages/beacon-node/test/unit/chain/validation/attestation/validateAttestation.test.ts b/packages/beacon-node/test/unit/chain/validation/attestation/validateAttestation.test.ts index 90d37a74289d..be9fd3587b7c 100644 --- a/packages/beacon-node/test/unit/chain/validation/attestation/validateAttestation.test.ts +++ b/packages/beacon-node/test/unit/chain/validation/attestation/validateAttestation.test.ts @@ -3,7 +3,6 @@ import {describe, expect, it} from "vitest"; import {ForkName, SLOTS_PER_EPOCH} from "@lodestar/params"; import {ssz} from "@lodestar/types"; import {LodestarError} from "@lodestar/utils"; -// eslint-disable-next-line import/no-relative-packages import {generateTestCachedBeaconStateOnlyValidators} from "../../../../../../state-transition/test/perf/util.js"; import {AttestationErrorCode, GossipErrorCode} from "../../../../../src/chain/errors/index.js"; import {IBeaconChain} from "../../../../../src/chain/index.js"; @@ -31,7 +30,6 @@ describe("validateAttestation", () => { const getState = memoOnce(() => generateTestCachedBeaconStateOnlyValidators({vc, slot: stateSlot})); - // eslint-disable-next-line @typescript-eslint/explicit-function-return-type function getValidData(opts?: Partial) { return getAttestationValidData({ currentSlot: stateSlot, diff --git a/packages/beacon-node/test/unit/chain/validation/block.test.ts b/packages/beacon-node/test/unit/chain/validation/block.test.ts index d90ca4a54d24..f8a2b7245ef7 100644 --- a/packages/beacon-node/test/unit/chain/validation/block.test.ts +++ b/packages/beacon-node/test/unit/chain/validation/block.test.ts @@ -12,7 +12,7 @@ import {EMPTY_SIGNATURE, ZERO_HASH} from "../../../../src/constants/index.js"; import {expectRejectedWithLodestarError} from "../../../utils/errors.js"; import {generateCachedState} from "../../../utils/state.js"; -describe("gossip block validation", function () { +describe("gossip block validation", () => { let chain: MockedBeaconChain; let forkChoice: MockedBeaconChain["forkChoice"]; let regen: Mocked; @@ -25,7 +25,7 @@ describe("gossip block validation", function () { const signature = EMPTY_SIGNATURE; const maxSkipSlots = 10; - beforeEach(function () { + beforeEach(() => { chain = getMockedBeaconChain(); vi.spyOn(chain.clock, "currentSlotWithGossipDisparity", "get").mockReturnValue(clockSlot); forkChoice = chain.forkChoice; @@ -33,7 +33,6 @@ describe("gossip block validation", function () { chain.forkChoice = forkChoice; regen = chain.regen; - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access (chain as any).opts = {maxSkipSlots}; verifySignature = chain.bls.verifySignatureSets; @@ -50,7 +49,7 @@ describe("gossip block validation", function () { job = {signature, message: block}; }); - it("FUTURE_SLOT", async function () { + it("FUTURE_SLOT", async () => { // Set the block slot to after the current clock const signedBlock = {signature, message: {...block, slot: clockSlot + 1}}; @@ -60,7 +59,7 @@ describe("gossip block validation", function () { ); }); - it("WOULD_REVERT_FINALIZED_SLOT", async function () { + it("WOULD_REVERT_FINALIZED_SLOT", async () => { // Set finalized epoch to be greater than block's epoch forkChoice.getFinalizedCheckpoint.mockReturnValue({epoch: Infinity, root: ZERO_HASH, rootHex: ""}); @@ -70,7 +69,7 @@ describe("gossip block validation", function () { ); }); - it("ALREADY_KNOWN", async function () { + it("ALREADY_KNOWN", async () => { // Make the fork choice return a block summary for the proposed block forkChoice.getBlockHex.mockReturnValue({} as ProtoBlock); @@ -80,7 +79,7 @@ describe("gossip block validation", function () { ); }); - it("REPEAT_PROPOSAL", async function () { + it("REPEAT_PROPOSAL", async () => { // Register the proposer as known chain.seenBlockProposers.add(job.message.slot, job.message.proposerIndex); @@ -90,7 +89,7 @@ describe("gossip block validation", function () { ); }); - it("PARENT_UNKNOWN (fork-choice)", async function () { + it("PARENT_UNKNOWN (fork-choice)", async () => { // Return not known for proposed block forkChoice.getBlockHex.mockReturnValueOnce(null); // Return not known for parent block too @@ -102,7 +101,7 @@ describe("gossip block validation", function () { ); }); - it("TOO_MANY_SKIPPED_SLOTS", async function () { + it("TOO_MANY_SKIPPED_SLOTS", async () => { // Return not known for proposed block forkChoice.getBlockHex.mockReturnValueOnce(null); // Return parent block with 1 slot way back than maxSkipSlots @@ -114,7 +113,7 @@ describe("gossip block validation", function () { ); }); - it("NOT_LATER_THAN_PARENT", async function () { + it("NOT_LATER_THAN_PARENT", async () => { // Return not known for proposed block forkChoice.getBlockHex.mockReturnValueOnce(null); // Returned parent block is latter than proposed block @@ -126,7 +125,7 @@ describe("gossip block validation", function () { ); }); - it("PARENT_UNKNOWN (regen)", async function () { + it("PARENT_UNKNOWN (regen)", async () => { // Return not known for proposed block forkChoice.getBlockHex.mockReturnValueOnce(null); // Returned parent block is latter than proposed block @@ -140,7 +139,7 @@ describe("gossip block validation", function () { ); }); - it("PROPOSAL_SIGNATURE_INVALID", async function () { + it("PROPOSAL_SIGNATURE_INVALID", async () => { // Return not known for proposed block forkChoice.getBlockHex.mockReturnValueOnce(null); // Returned parent block is latter than proposed block @@ -156,7 +155,7 @@ describe("gossip block validation", function () { ); }); - it("INCORRECT_PROPOSER", async function () { + it("INCORRECT_PROPOSER", async () => { // Return not known for proposed block forkChoice.getBlockHex.mockReturnValueOnce(null); // Returned parent block is latter than proposed block @@ -175,7 +174,7 @@ describe("gossip block validation", function () { ); }); - it("valid", async function () { + it("valid", async () => { // Return not known for proposed block forkChoice.getBlockHex.mockReturnValueOnce(null); // Returned parent block is latter than proposed block diff --git a/packages/beacon-node/test/unit/chain/validation/lightClientFinalityUpdate.test.ts b/packages/beacon-node/test/unit/chain/validation/lightClientFinalityUpdate.test.ts index ef4364abc366..cbd231c926ce 100644 --- a/packages/beacon-node/test/unit/chain/validation/lightClientFinalityUpdate.test.ts +++ b/packages/beacon-node/test/unit/chain/validation/lightClientFinalityUpdate.test.ts @@ -8,11 +8,10 @@ import {LightClientErrorCode} from "../../../../src/chain/errors/lightClientErro import {IBeaconChain} from "../../../../src/chain/index.js"; import {getMockedBeaconChain} from "../../../mocks/mockedBeaconChain.js"; -describe("Light Client Finality Update validation", function () { +describe("Light Client Finality Update validation", () => { const afterEachCallbacks: (() => Promise | void)[] = []; const config = createChainForkConfig({ ...defaultChainConfig, - /* eslint-disable @typescript-eslint/naming-convention */ ALTAIR_FORK_EPOCH: 1, BELLATRIX_FORK_EPOCH: 3, CAPELLA_FORK_EPOCH: Infinity, diff --git a/packages/beacon-node/test/unit/chain/validation/lightClientOptimisticUpdate.test.ts b/packages/beacon-node/test/unit/chain/validation/lightClientOptimisticUpdate.test.ts index b63a08757380..7665b4f89179 100644 --- a/packages/beacon-node/test/unit/chain/validation/lightClientOptimisticUpdate.test.ts +++ b/packages/beacon-node/test/unit/chain/validation/lightClientOptimisticUpdate.test.ts @@ -8,11 +8,10 @@ import {LightClientErrorCode} from "../../../../src/chain/errors/lightClientErro import {IBeaconChain} from "../../../../src/chain/index.js"; import {getMockedBeaconChain} from "../../../mocks/mockedBeaconChain.js"; -describe("Light Client Optimistic Update validation", function () { +describe("Light Client Optimistic Update validation", () => { const afterEachCallbacks: (() => Promise | void)[] = []; const config = createChainForkConfig({ ...defaultChainConfig, - /* eslint-disable @typescript-eslint/naming-convention */ ALTAIR_FORK_EPOCH: 1, BELLATRIX_FORK_EPOCH: 3, CAPELLA_FORK_EPOCH: Infinity, diff --git a/packages/beacon-node/test/unit/chain/validation/syncCommittee.test.ts b/packages/beacon-node/test/unit/chain/validation/syncCommittee.test.ts index b498333ae738..cbffc2a4ffd9 100644 --- a/packages/beacon-node/test/unit/chain/validation/syncCommittee.test.ts +++ b/packages/beacon-node/test/unit/chain/validation/syncCommittee.test.ts @@ -12,7 +12,7 @@ import {SeenSyncCommitteeMessages} from "../../../../src/chain/seenCache/index.j import {ZERO_HASH} from "../../../../src/constants/constants.js"; // https://github.com/ethereum/consensus-specs/blob/v1.1.10/specs/altair/p2p-interface.md -describe("Sync Committee Signature validation", function () { +describe("Sync Committee Signature validation", () => { let chain: MockedBeaconChain; let clockStub: MockedBeaconChain["clock"]; let forkchoiceStub: MockedBeaconChain["forkChoice"]; @@ -20,21 +20,20 @@ describe("Sync Committee Signature validation", function () { let altairForkEpochBk: Epoch; const altairForkEpoch = 2020; const currentSlot = SLOTS_PER_EPOCH * (altairForkEpoch + 1); - // eslint-disable-next-line @typescript-eslint/naming-convention const config = createChainForkConfig(Object.assign({}, defaultChainConfig, {ALTAIR_FORK_EPOCH: altairForkEpoch})); // all validators have same pubkey const validatorIndexInSyncCommittee = 15; - beforeAll(async function () { + beforeAll(async () => { altairForkEpochBk = config.ALTAIR_FORK_EPOCH; config.ALTAIR_FORK_EPOCH = altairForkEpoch; }); - afterAll(function () { + afterAll(() => { config.ALTAIR_FORK_EPOCH = altairForkEpochBk; }); - beforeEach(function () { + beforeEach(() => { chain = getMockedBeaconChain(); ( chain as { @@ -46,11 +45,11 @@ describe("Sync Committee Signature validation", function () { vi.spyOn(clockStub, "isCurrentSlotGivenGossipDisparity").mockReturnValue(true); }); - afterEach(function () { + afterEach(() => { vi.clearAllMocks(); }); - it("should throw error - the signature's slot is in the past", async function () { + it("should throw error - the signature's slot is in the past", async () => { (clockStub.isCurrentSlotGivenGossipDisparity as Mock).mockReturnValue(false); vi.spyOn(clockStub, "currentSlot", "get").mockReturnValue(100); @@ -61,7 +60,7 @@ describe("Sync Committee Signature validation", function () { ); }); - it("should throw error - messageRoot is same to prevRoot", async function () { + it("should throw error - messageRoot is same to prevRoot", async () => { const syncCommittee = getSyncCommitteeSignature(currentSlot, validatorIndexInSyncCommittee); const headState = generateCachedAltairState({slot: currentSlot}, altairForkEpoch); chain.getHeadState.mockReturnValue(headState); @@ -72,7 +71,7 @@ describe("Sync Committee Signature validation", function () { ); }); - it("should throw error - messageRoot is different to prevRoot but not forkchoice head", async function () { + it("should throw error - messageRoot is different to prevRoot but not forkchoice head", async () => { const syncCommittee = getSyncCommitteeSignature(currentSlot, validatorIndexInSyncCommittee); const headState = generateCachedAltairState({slot: currentSlot}, altairForkEpoch); chain.getHeadState.mockReturnValue(headState); @@ -85,7 +84,7 @@ describe("Sync Committee Signature validation", function () { ); }); - it("should throw error - the validator is not part of the current sync committee", async function () { + it("should throw error - the validator is not part of the current sync committee", async () => { const syncCommittee = getSyncCommitteeSignature(currentSlot, 100); const headState = generateCachedAltairState({slot: currentSlot}, altairForkEpoch); chain.getHeadState.mockReturnValue(headState); @@ -100,7 +99,7 @@ describe("Sync Committee Signature validation", function () { * Skip this spec check: [REJECT] The subnet_id is correct, i.e. subnet_id in compute_subnets_for_sync_committee(state, sync_committee_signature.validator_index) * because it's the same to VALIDATOR_NOT_IN_SYNC_COMMITTEE */ - it.skip("should throw error - incorrect subnet", async function () { + it.skip("should throw error - incorrect subnet", async () => { const syncCommittee = getSyncCommitteeSignature(currentSlot, 1); const headState = generateCachedAltairState({slot: currentSlot}, altairForkEpoch); chain.getHeadState.mockReturnValue(headState); @@ -110,7 +109,7 @@ describe("Sync Committee Signature validation", function () { ); }); - it("should throw error - invalid signature", async function () { + it("should throw error - invalid signature", async () => { const syncCommittee = getSyncCommitteeSignature(currentSlot, validatorIndexInSyncCommittee); const headState = generateCachedAltairState({slot: currentSlot}, altairForkEpoch); @@ -122,7 +121,7 @@ describe("Sync Committee Signature validation", function () { ); }); - it("should pass, no prev root", async function () { + it("should pass, no prev root", async () => { const syncCommittee = getSyncCommitteeSignature(currentSlot, validatorIndexInSyncCommittee); const subnet = 3; const {slot, validatorIndex} = syncCommittee; @@ -143,7 +142,7 @@ describe("Sync Committee Signature validation", function () { ); }); - it("should pass, there is prev root but message root is forkchoice head", async function () { + it("should pass, there is prev root but message root is forkchoice head", async () => { const syncCommittee = getSyncCommitteeSignature(currentSlot, validatorIndexInSyncCommittee); const headState = generateCachedAltairState({slot: currentSlot}, altairForkEpoch); diff --git a/packages/beacon-node/test/unit/db/api/repositories/blockArchive.test.ts b/packages/beacon-node/test/unit/db/api/repositories/blockArchive.test.ts index 532016242f95..b87e9b926fdd 100644 --- a/packages/beacon-node/test/unit/db/api/repositories/blockArchive.test.ts +++ b/packages/beacon-node/test/unit/db/api/repositories/blockArchive.test.ts @@ -9,21 +9,21 @@ import {BlockArchiveRepository} from "../../../../../src/db/repositories/index.j import {testLogger} from "../../../../utils/logger.js"; import {Bucket} from "../../../../../src/db/buckets.js"; -describe("block archive repository", function () { +describe("block archive repository", () => { const testDir = "./.tmp"; let blockArchive: BlockArchiveRepository; let db: LevelDbController; - beforeEach(async function () { + beforeEach(async () => { db = await LevelDbController.create({name: testDir}, {logger: testLogger()}); blockArchive = new BlockArchiveRepository(config, db); }); - afterEach(async function () { + afterEach(async () => { await db.close(); rimraf.sync(testDir); }); - it("should retrieve blocks in order", async function () { + it("should retrieve blocks in order", async () => { await blockArchive.batchPut( Array.from({length: 1001}, (_, i) => { const slot = i; @@ -106,7 +106,7 @@ describe("block archive repository", function () { } }); - it("should store indexes when adding single block", async function () { + it("should store indexes when adding single block", async () => { const spy = vi.spyOn(db, "put"); const block = ssz.phase0.SignedBeaconBlock.defaultValue(); await blockArchive.add(block); @@ -120,7 +120,7 @@ describe("block archive repository", function () { ); }); - it("should store indexes when block batch", async function () { + it("should store indexes when block batch", async () => { const spy = vi.spyOn(db, "put"); const blocks = [ssz.phase0.SignedBeaconBlock.defaultValue(), ssz.phase0.SignedBeaconBlock.defaultValue()]; await blockArchive.batchAdd(blocks); @@ -152,14 +152,14 @@ describe("block archive repository", function () { ); }); - it("should get slot by root", async function () { + it("should get slot by root", async () => { const block = ssz.phase0.SignedBeaconBlock.defaultValue(); await blockArchive.add(block); const slot = await blockArchive.getSlotByRoot(ssz.phase0.BeaconBlock.hashTreeRoot(block.message)); expect(slot).toBe(block.message.slot); }); - it("should get block by root", async function () { + it("should get block by root", async () => { const block = ssz.phase0.SignedBeaconBlock.defaultValue(); await blockArchive.add(block); const retrieved = await blockArchive.getByRoot(ssz.phase0.BeaconBlock.hashTreeRoot(block.message)); @@ -167,14 +167,14 @@ describe("block archive repository", function () { expect(ssz.phase0.SignedBeaconBlock.equals(retrieved, block)).toBe(true); }); - it("should get slot by parent root", async function () { + it("should get slot by parent root", async () => { const block = ssz.phase0.SignedBeaconBlock.defaultValue(); await blockArchive.add(block); const slot = await blockArchive.getSlotByParentRoot(block.message.parentRoot); expect(slot).toBe(block.message.slot); }); - it("should get block by parent root", async function () { + it("should get block by parent root", async () => { const block = ssz.phase0.SignedBeaconBlock.defaultValue(); await blockArchive.add(block); const retrieved = await blockArchive.getByParentRoot(block.message.parentRoot); diff --git a/packages/beacon-node/test/unit/db/api/repository.test.ts b/packages/beacon-node/test/unit/db/api/repository.test.ts index 07c199632125..3b2840b3f0be 100644 --- a/packages/beacon-node/test/unit/db/api/repository.test.ts +++ b/packages/beacon-node/test/unit/db/api/repository.test.ts @@ -11,7 +11,6 @@ vi.mock("@lodestar/db", async (importOriginal) => { return { ...mod, - // eslint-disable-next-line @typescript-eslint/naming-convention LevelDbController: vi.spyOn(mod, "LevelDbController").mockImplementation(() => { return { get: vi.fn(), @@ -31,7 +30,6 @@ interface TestType { bytes: Bytes32; } -// eslint-disable-next-line @typescript-eslint/naming-convention const TestSSZType = new ContainerType({ bool: ssz.Boolean, bytes: ssz.Bytes32, @@ -43,10 +41,10 @@ class TestRepository extends Repository { } } -describe("database repository", function () { +describe("database repository", () => { let repository: TestRepository, controller: MockedObject; - beforeEach(function () { + beforeEach(() => { controller = vi.mocked(new LevelDbController({} as any, {} as any, {} as any)); repository = new TestRepository(controller as unknown as LevelDbController); }); @@ -55,7 +53,7 @@ describe("database repository", function () { vi.clearAllMocks(); }); - it("should get single item", async function () { + it("should get single item", async () => { const item = {bool: true, bytes: Buffer.alloc(32)}; controller.get.mockResolvedValue(TestSSZType.serialize(item) as Buffer); const result = await repository.get("id"); @@ -63,14 +61,14 @@ describe("database repository", function () { expect(controller.get).toHaveBeenCalledTimes(1); }); - it("should return null if item not found", async function () { + it("should return null if item not found", async () => { controller.get.mockResolvedValue(null); const result = await repository.get("id"); expect(result).toEqual(null); expect(controller.get).toHaveBeenCalledTimes(1); }); - it("should return true if item exists", async function () { + it("should return true if item exists", async () => { const item = {bool: true, bytes: Buffer.alloc(32)}; controller.get.mockResolvedValue(TestSSZType.serialize(item) as Buffer); const result = await repository.has("id"); @@ -78,31 +76,31 @@ describe("database repository", function () { expect(controller.get).toHaveBeenCalledTimes(1); }); - it("should return false if item doesnt exists", async function () { + it("should return false if item doesnt exists", async () => { controller.get.mockResolvedValue(null); const result = await repository.has("id"); expect(result).toBe(false); expect(controller.get).toHaveBeenCalledTimes(1); }); - it("should store with hashTreeRoot as id", async function () { + it("should store with hashTreeRoot as id", async () => { const item = {bool: true, bytes: Buffer.alloc(32)}; await expect(repository.add(item)).resolves.toBeUndefined(); expect(controller.put).toHaveBeenCalledTimes(1); }); - it("should store with given id", async function () { + it("should store with given id", async () => { const item = {bool: true, bytes: Buffer.alloc(32)}; await expect(repository.put("1", item)).resolves.toBeUndefined(); expect(controller.put).toHaveBeenCalledTimes(1); }); - it("should delete", async function () { + it("should delete", async () => { await expect(repository.delete("1")).resolves.toBeUndefined(); expect(controller.delete).toHaveBeenCalledTimes(1); }); - it("should return all items", async function () { + it("should return all items", async () => { const item = {bool: true, bytes: Buffer.alloc(32)}; const itemSerialized = TestSSZType.serialize(item); const items = [itemSerialized, itemSerialized, itemSerialized]; @@ -112,24 +110,24 @@ describe("database repository", function () { expect(controller.values).toHaveBeenCalledTimes(1); }); - it("should return range of items", async function () { + it("should return range of items", async () => { await repository.values({gt: "a", lt: "b"}); expect(controller.values).toHaveBeenCalledTimes(1); }); - it("should delete given items", async function () { + it("should delete given items", async () => { await repository.batchDelete(["1", "2", "3"]); expect(controller.batchDelete.mock.calls[0][0]).toHaveLength(3); }); - it("should delete given items by value", async function () { + it("should delete given items by value", async () => { const item = {bool: true, bytes: Buffer.alloc(32)}; await repository.batchRemove([item, item]); expect(controller.batchDelete.mock.calls[0][0]).toHaveLength(2); }); - it("should add multiple values", async function () { + it("should add multiple values", async () => { await repository.batchAdd([ {bool: true, bytes: Buffer.alloc(32)}, {bool: false, bytes: Buffer.alloc(32)}, @@ -138,7 +136,7 @@ describe("database repository", function () { expect(controller.batchPut.mock.calls[0][0]).toHaveLength(2); }); - it("should fetch values stream", async function () { + it("should fetch values stream", async () => { async function* sample(): AsyncGenerator { yield TestSSZType.serialize({bool: true, bytes: Buffer.alloc(32)}) as Buffer; yield TestSSZType.serialize({bool: false, bytes: Buffer.alloc(32)}) as Buffer; diff --git a/packages/beacon-node/test/unit/db/buckets.test.ts b/packages/beacon-node/test/unit/db/buckets.test.ts index 0fb09af95cbc..c7c11d831427 100644 --- a/packages/beacon-node/test/unit/db/buckets.test.ts +++ b/packages/beacon-node/test/unit/db/buckets.test.ts @@ -6,7 +6,7 @@ describe("db buckets", () => { let prevBucket = -1; for (const key of Object.keys(Bucket)) { - if (isNaN(parseInt(key))) { + if (Number.isNaN(parseInt(key))) { const bucket = (Bucket as unknown as Record)[key]; if (bucket < prevBucket) { throw Error(`Bucket ${key} not sorted`); diff --git a/packages/beacon-node/test/unit/eth1/eth1DepositDataTracker.test.ts b/packages/beacon-node/test/unit/eth1/eth1DepositDataTracker.test.ts index d0bd3faffcf8..40988ed21728 100644 --- a/packages/beacon-node/test/unit/eth1/eth1DepositDataTracker.test.ts +++ b/packages/beacon-node/test/unit/eth1/eth1DepositDataTracker.test.ts @@ -8,7 +8,7 @@ import {defaultEth1Options} from "../../../src/eth1/options.js"; import {BeaconDb} from "../../../src/db/beacon.js"; import {getMockedBeaconDb} from "../../mocks/mockedBeaconDb.js"; -describe("Eth1DepositDataTracker", function () { +describe("Eth1DepositDataTracker", () => { const controller = new AbortController(); const logger = testLogger(); @@ -43,7 +43,7 @@ describe("Eth1DepositDataTracker", function () { vi.clearAllMocks(); }); - it("Should dynamically adjust blocks batch size", async function () { + it("Should dynamically adjust blocks batch size", async () => { let expectedSize = 1000; expect(eth1DepositDataTracker["eth1GetBlocksBatchSizeDynamic"]).toBe(expectedSize); @@ -66,7 +66,7 @@ describe("Eth1DepositDataTracker", function () { expect(expectedSize).toBe(1000); }); - it("Should dynamically adjust logs batch size", async function () { + it("Should dynamically adjust logs batch size", async () => { let expectedSize = 1000; expect(eth1DepositDataTracker["eth1GetLogsBatchSizeDynamic"]).toBe(expectedSize); diff --git a/packages/beacon-node/test/unit/eth1/eth1MergeBlockTracker.test.ts b/packages/beacon-node/test/unit/eth1/eth1MergeBlockTracker.test.ts index 151f3931cfde..c7f4c8fb7aa4 100644 --- a/packages/beacon-node/test/unit/eth1/eth1MergeBlockTracker.test.ts +++ b/packages/beacon-node/test/unit/eth1/eth1MergeBlockTracker.test.ts @@ -8,8 +8,6 @@ import {Eth1MergeBlockTracker, StatusCode, toPowBlock} from "../../../src/eth1/e import {Eth1ProviderState, EthJsonRpcBlockRaw} from "../../../src/eth1/interface.js"; import {testLogger} from "../../utils/logger.js"; -/* eslint-disable @typescript-eslint/naming-convention */ - describe("eth1 / Eth1MergeBlockTracker", () => { const logger = testLogger(); @@ -18,9 +16,7 @@ describe("eth1 / Eth1MergeBlockTracker", () => { let controller: AbortController; beforeEach(() => { controller = new AbortController(); - }); - afterEach(() => controller.abort()); - beforeEach(() => { + config = { // Set time units to 0 to make the test as fast as possible SECONDS_PER_ETH1_BLOCK: 0, @@ -31,6 +27,8 @@ describe("eth1 / Eth1MergeBlockTracker", () => { } as Partial as ChainConfig; }); + afterEach(() => controller.abort()); + it("Should find terminal pow block through TERMINAL_BLOCK_HASH", async () => { config.TERMINAL_BLOCK_HASH = Buffer.alloc(32, 1); const block: EthJsonRpcBlockRaw = { @@ -117,9 +115,8 @@ describe("eth1 / Eth1MergeBlockTracker", () => { if (blockNumber === "latest") { if (latestBlockPointer >= blocks.length) { throw Error("Fetched too many blocks"); - } else { - return blocks[latestBlockPointer++]; } + return blocks[latestBlockPointer++]; } return blocks[blockNumber]; }, diff --git a/packages/beacon-node/test/unit/eth1/utils/depositContract.test.ts b/packages/beacon-node/test/unit/eth1/utils/depositContract.test.ts index e36fc865a75a..22ca95765a9a 100644 --- a/packages/beacon-node/test/unit/eth1/utils/depositContract.test.ts +++ b/packages/beacon-node/test/unit/eth1/utils/depositContract.test.ts @@ -2,7 +2,7 @@ import {describe, it, expect} from "vitest"; import {goerliTestnetLogs, goerliTestnetDepositEvents} from "../../../utils/testnet.js"; import {parseDepositLog} from "../../../../src/eth1/utils/depositContract.js"; -describe("eth1 / util / depositContract", function () { +describe("eth1 / util / depositContract", () => { it("Should parse a raw deposit log", () => { const depositEvents = goerliTestnetLogs.map((log) => parseDepositLog(log)); expect(depositEvents).toEqual(goerliTestnetDepositEvents); diff --git a/packages/beacon-node/test/unit/eth1/utils/deposits.test.ts b/packages/beacon-node/test/unit/eth1/utils/deposits.test.ts index 316f75efc5ce..34334d1b3f8b 100644 --- a/packages/beacon-node/test/unit/eth1/utils/deposits.test.ts +++ b/packages/beacon-node/test/unit/eth1/utils/deposits.test.ts @@ -11,7 +11,7 @@ import {getDeposits, getDepositsWithProofs, DepositGetter} from "../../../../src import {DepositTree} from "../../../../src/db/repositories/depositDataRoot.js"; import {createCachedBeaconStateTest} from "../../../utils/cachedBeaconState.js"; -describe("eth1 / util / deposits", function () { +describe("eth1 / util / deposits", () => { describe("getDeposits", () => { type TestCase = { id: string; @@ -99,7 +99,6 @@ describe("eth1 / util / deposits", function () { }, ]; - /* eslint-disable @typescript-eslint/naming-convention */ const postElectraConfig = createChainForkConfig({ ALTAIR_FORK_EPOCH: 1, BELLATRIX_FORK_EPOCH: 2, @@ -112,7 +111,7 @@ describe("eth1 / util / deposits", function () { for (const testCase of testCases) { const {id, depositIndexes, eth1DepositIndex, depositCount, expectedReturnedIndexes, error, postElectra} = testCase; - it(id, async function () { + it(id, async () => { const state = postElectra ? generateState({slot: postElectraSlot, eth1DepositIndex}, postElectraConfig) : generateState({eth1DepositIndex}); @@ -140,7 +139,7 @@ describe("eth1 / util / deposits", function () { }); describe("getDepositsWithProofs", () => { - it("return empty array if no pending deposits", function () { + it("return empty array if no pending deposits", () => { const initialValues = [Buffer.alloc(32)]; const depositRootTree = ssz.phase0.DepositDataRootList.toViewDU(initialValues); const depositCount = 0; @@ -150,7 +149,7 @@ describe("eth1 / util / deposits", function () { expect(deposits).toEqual([]); }); - it("return deposits with valid proofs", function () { + it("return deposits with valid proofs", () => { const depositEvents = Array.from( {length: 2}, (_, index): phase0.DepositEvent => ({ diff --git a/packages/beacon-node/test/unit/eth1/utils/eth1Data.test.ts b/packages/beacon-node/test/unit/eth1/utils/eth1Data.test.ts index 4b5bf74772b7..dff98500b293 100644 --- a/packages/beacon-node/test/unit/eth1/utils/eth1Data.test.ts +++ b/packages/beacon-node/test/unit/eth1/utils/eth1Data.test.ts @@ -12,7 +12,7 @@ import {expectRejectedWithLodestarError} from "../../../utils/errors.js"; import {Eth1ErrorCode} from "../../../../src/eth1/errors.js"; import {DepositTree} from "../../../../src/db/repositories/depositDataRoot.js"; -describe("eth1 / util / getEth1DataForBlocks", function () { +describe("eth1 / util / getEth1DataForBlocks", () => { type TestCase = { id: string; blocks: Eth1Block[]; @@ -95,7 +95,7 @@ describe("eth1 / util / getEth1DataForBlocks", function () { for (const testCase of testCases) { const {id, blocks, deposits, depositRootTree, lastProcessedDepositBlockNumber, expectedEth1Data, error} = testCase(); - it(id, async function () { + it(id, async () => { const eth1DatasPromise = getEth1DataForBlocks( blocks, // Simulate a descending stream reading from DB @@ -117,7 +117,7 @@ describe("eth1 / util / getEth1DataForBlocks", function () { } }); -describe("eth1 / util / getDepositsByBlockNumber", function () { +describe("eth1 / util / getDepositsByBlockNumber", () => { type TestCase = { id: string; fromBlock: number; @@ -181,7 +181,7 @@ describe("eth1 / util / getDepositsByBlockNumber", function () { for (const testCase of testCases) { const {id, fromBlock, toBlock, deposits, expectedResult} = testCase(); - it(id, async function () { + it(id, async () => { const result = await getDepositsByBlockNumber( fromBlock, toBlock, // Simulate a descending stream reading from DB @@ -192,7 +192,7 @@ describe("eth1 / util / getDepositsByBlockNumber", function () { } }); -describe("eth1 / util / getDepositRootByDepositCount", function () { +describe("eth1 / util / getDepositRootByDepositCount", () => { type TestCase = { id: string; depositCounts: number[]; @@ -243,7 +243,7 @@ describe("eth1 / util / getDepositRootByDepositCount", function () { for (const testCase of testCases) { const {id, depositCounts, depositRootTree, expectedMap} = testCase(); - it(id, function () { + it(id, () => { const map = getDepositRootByDepositCount(depositCounts, depositRootTree); expect(renderDepositRootByDepositCount(map)).toEqual(renderDepositRootByDepositCount(expectedMap)); }); diff --git a/packages/beacon-node/test/unit/eth1/utils/eth1DepositEvent.test.ts b/packages/beacon-node/test/unit/eth1/utils/eth1DepositEvent.test.ts index 7538dc0acf63..ea504464778c 100644 --- a/packages/beacon-node/test/unit/eth1/utils/eth1DepositEvent.test.ts +++ b/packages/beacon-node/test/unit/eth1/utils/eth1DepositEvent.test.ts @@ -1,7 +1,7 @@ import {describe, it, expect} from "vitest"; import {assertConsecutiveDeposits} from "../../../../src/eth1/utils/eth1DepositEvent.js"; -describe("eth1 / util / assertConsecutiveDeposits", function () { +describe("eth1 / util / assertConsecutiveDeposits", () => { const testCases: { id: string; ok: boolean; diff --git a/packages/beacon-node/test/unit/eth1/utils/eth1Vote.test.ts b/packages/beacon-node/test/unit/eth1/utils/eth1Vote.test.ts index 0ad63e5e0d8f..e9a9ab5aad24 100644 --- a/packages/beacon-node/test/unit/eth1/utils/eth1Vote.test.ts +++ b/packages/beacon-node/test/unit/eth1/utils/eth1Vote.test.ts @@ -12,7 +12,7 @@ import { Eth1DataGetter, } from "../../../../src/eth1/utils/eth1Vote.js"; -describe("eth1 / util / eth1Vote", function () { +describe("eth1 / util / eth1Vote", () => { function generateEth1Vote(i: number): phase0.Eth1Data { return { blockHash: Buffer.alloc(32, i), @@ -21,7 +21,7 @@ describe("eth1 / util / eth1Vote", function () { }; } - describe("pickEth1Vote", function () { + describe("pickEth1Vote", () => { // Function array to scope votes in each test case defintion const testCases: (() => { id: string; @@ -82,7 +82,7 @@ describe("eth1 / util / eth1Vote", function () { for (const testCase of testCases) { const {id, eth1DataVotesInState, votesToConsider, expectedEth1Vote} = testCase(); - it(id, async function () { + it(id, async () => { const state = generateState({slot: 5, eth1DataVotes: eth1DataVotesInState}); const eth1Vote = pickEth1Vote(state, votesToConsider); expect(ssz.phase0.Eth1Data.toJson(eth1Vote)).toEqual(ssz.phase0.Eth1Data.toJson(expectedEth1Vote)); @@ -90,7 +90,7 @@ describe("eth1 / util / eth1Vote", function () { } }); - describe("getEth1VotesToConsider", function () { + describe("getEth1VotesToConsider", () => { // Function array to scope votes in each test case defintion const testCases: (() => { id: string; @@ -127,7 +127,7 @@ describe("eth1 / util / eth1Vote", function () { for (const testCase of testCases) { const {id, state, eth1Datas, expectedVotesToConsider} = testCase(); - it(`get votesToConsider: ${id}`, async function () { + it(`get votesToConsider: ${id}`, async () => { const eth1DataGetter: Eth1DataGetter = async ({timestampRange}) => filterBy(eth1Datas, timestampRange, (eth1Data) => eth1Data.timestamp); diff --git a/packages/beacon-node/test/unit/eth1/utils/groupDepositEventsByBlock.test.ts b/packages/beacon-node/test/unit/eth1/utils/groupDepositEventsByBlock.test.ts index 5712d1095270..a4e786b3aa68 100644 --- a/packages/beacon-node/test/unit/eth1/utils/groupDepositEventsByBlock.test.ts +++ b/packages/beacon-node/test/unit/eth1/utils/groupDepositEventsByBlock.test.ts @@ -2,7 +2,7 @@ import {describe, it, expect} from "vitest"; import {phase0} from "@lodestar/types"; import {groupDepositEventsByBlock} from "../../../../src/eth1/utils/groupDepositEventsByBlock.js"; -describe("eth1 / util / groupDepositEventsByBlock", function () { +describe("eth1 / util / groupDepositEventsByBlock", () => { it("should return deposit events by block sorted by index", () => { const depositData = { amount: 0, diff --git a/packages/beacon-node/test/unit/eth1/utils/optimizeNextBlockDiffForGenesis.test.ts b/packages/beacon-node/test/unit/eth1/utils/optimizeNextBlockDiffForGenesis.test.ts index cacfd7dc685f..39c4a4d6e773 100644 --- a/packages/beacon-node/test/unit/eth1/utils/optimizeNextBlockDiffForGenesis.test.ts +++ b/packages/beacon-node/test/unit/eth1/utils/optimizeNextBlockDiffForGenesis.test.ts @@ -2,14 +2,11 @@ import {describe, it, expect} from "vitest"; import {optimizeNextBlockDiffForGenesis} from "../../../../src/eth1/utils/optimizeNextBlockDiffForGenesis.js"; import {Eth1Block} from "../../../../src/eth1/interface.js"; -describe("eth1 / utils / optimizeNextBlockDiffForGenesis", function () { +describe("eth1 / utils / optimizeNextBlockDiffForGenesis", () => { it("should return optimized block diff to find genesis time", () => { const params = { - // eslint-disable-next-line @typescript-eslint/naming-convention MIN_GENESIS_TIME: 1578009600, - // eslint-disable-next-line @typescript-eslint/naming-convention GENESIS_DELAY: 172800, - // eslint-disable-next-line @typescript-eslint/naming-convention SECONDS_PER_ETH1_BLOCK: 14, }; const initialTimeDiff = params.GENESIS_DELAY * 2; @@ -32,9 +29,8 @@ describe("eth1 / utils / optimizeNextBlockDiffForGenesis", function () { if (lastFetchedBlock.timestamp > params.MIN_GENESIS_TIME - params.GENESIS_DELAY) { break; - } else { - diffRecord.push({number: lastFetchedBlock.blockNumber, blockDiff}); } + diffRecord.push({number: lastFetchedBlock.blockNumber, blockDiff}); } // Make sure the returned diffs converge to genesis time fast diff --git a/packages/beacon-node/test/unit/executionEngine/httpRetry.test.ts b/packages/beacon-node/test/unit/executionEngine/httpRetry.test.ts index b75dc8048283..b254fc9d8b45 100644 --- a/packages/beacon-node/test/unit/executionEngine/httpRetry.test.ts +++ b/packages/beacon-node/test/unit/executionEngine/httpRetry.test.ts @@ -32,10 +32,10 @@ describe("ExecutionEngine / http ", () => { reqJsonRpcPayload = req.body; delete (reqJsonRpcPayload as {id?: number}).id; return returnValue; - } else { - --errorResponsesBeforeSuccess; - throw Error(`Will succeed after ${errorResponsesBeforeSuccess} more attempts`); } + + --errorResponsesBeforeSuccess; + throw Error(`Will succeed after ${errorResponsesBeforeSuccess} more attempts`); }); afterCallbacks.push(async () => { @@ -56,8 +56,8 @@ describe("ExecutionEngine / http ", () => { ); }); - describe("notifyForkchoiceUpdate", function () { - it("notifyForkchoiceUpdate no retry when no pay load attributes", async function () { + describe("notifyForkchoiceUpdate", () => { + it("notifyForkchoiceUpdate no retry when no pay load attributes", async () => { errorResponsesBeforeSuccess = 2; const forkChoiceHeadData = { headBlockHash: "0xb084c10440f05f5a23a55d1d7ebcb1b3892935fb56f23cdc9a7f42c348eed174", @@ -85,7 +85,7 @@ describe("ExecutionEngine / http ", () => { expect(errorResponsesBeforeSuccess).toBe(1); }); - it("notifyForkchoiceUpdate with retry when pay load attributes", async function () { + it("notifyForkchoiceUpdate with retry when pay load attributes", async () => { errorResponsesBeforeSuccess = defaultExecutionEngineHttpOpts.retries - 1; const forkChoiceHeadData = { headBlockHash: "0xb084c10440f05f5a23a55d1d7ebcb1b3892935fb56f23cdc9a7f42c348eed174", diff --git a/packages/beacon-node/test/unit/monitoring/remoteService.ts b/packages/beacon-node/test/unit/monitoring/remoteService.ts index c5ce0e9ef0b3..d407adb9d175 100644 --- a/packages/beacon-node/test/unit/monitoring/remoteService.ts +++ b/packages/beacon-node/test/unit/monitoring/remoteService.ts @@ -22,7 +22,7 @@ export const remoteServiceError: RemoteServiceError = {status: "error", data: nu export async function startRemoteService(): Promise<{baseUrl: URL}> { const server = fastify(); - server.post(remoteServiceRoutes.success, {}, async function (request, reply) { + server.post(remoteServiceRoutes.success, {}, async (request, reply) => { if (Array.isArray(request.body)) { request.body.forEach(validateRequestData); } else { @@ -32,11 +32,9 @@ export async function startRemoteService(): Promise<{baseUrl: URL}> { return reply.status(200).send(); }); - server.post(remoteServiceRoutes.error, {}, async function (_request, reply) { - return reply.status(400).send(remoteServiceError); - }); + server.post(remoteServiceRoutes.error, {}, async (_request, reply) => reply.status(400).send(remoteServiceError)); - server.post(remoteServiceRoutes.pending, {}, function () { + server.post(remoteServiceRoutes.pending, {}, () => { // keep request pending until timeout is reached or aborted }); @@ -74,13 +72,13 @@ function validateRequestData(data: ReceivedData): void { } function validateClientStats(data: ReceivedData, schema: ClientStatsSchema): void { - schema.forEach((s) => { + for (const s of schema) { try { expect(data[s.key]).toBeInstanceOf(s.type); - } catch { + } catch (_e) { throw new Error( `Validation of property "${s.key}" failed. Expected type "${s.type}" but received "${typeof data[s.key]}".` ); } - }); + } } diff --git a/packages/beacon-node/test/unit/monitoring/service.test.ts b/packages/beacon-node/test/unit/monitoring/service.test.ts index 43936ff1756d..fed64b9bc553 100644 --- a/packages/beacon-node/test/unit/monitoring/service.test.ts +++ b/packages/beacon-node/test/unit/monitoring/service.test.ts @@ -108,7 +108,6 @@ describe("monitoring / service", () => { expect(logger.info).toHaveBeenCalledWith( "Started monitoring service", // TODO: Debug why `expect.any` causing type error - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment expect.objectContaining({interval: expect.any(Number), machine: null, remote: expect.any(String)}) ); }); @@ -170,7 +169,7 @@ describe("monitoring / service", () => { service?.close(); }); - (["beacon", "validator"] as const).forEach((client) => { + for (const client of ["beacon", "validator"] as const) { it(`should collect and send ${client} stats to remote service`, async () => { const endpoint = `${baseUrl}${remoteServiceRoutes.success}`; service = new MonitoringService(client, {endpoint, collectSystemStats: true}, {register, logger}); @@ -182,7 +181,7 @@ describe("monitoring / service", () => { // Fail test if warning was logged due to a 500 response. expect(logger.warn).not.toHaveBeenCalledWith("Failed to send client stats"); }); - }); + } it("should properly handle remote service errors", async () => { const endpoint = `${baseUrl}${remoteServiceRoutes.error}`; diff --git a/packages/beacon-node/test/unit/network/beaconBlocksMaybeBlobsByRange.test.ts b/packages/beacon-node/test/unit/network/beaconBlocksMaybeBlobsByRange.test.ts index d1dc7ba57fa9..2104235e7215 100644 --- a/packages/beacon-node/test/unit/network/beaconBlocksMaybeBlobsByRange.test.ts +++ b/packages/beacon-node/test/unit/network/beaconBlocksMaybeBlobsByRange.test.ts @@ -10,14 +10,13 @@ import {INetwork} from "../../../src/network/interface.js"; import {ZERO_HASH} from "../../../src/constants/constants.js"; describe("beaconBlocksMaybeBlobsByRange", () => { - beforeAll(async function () { + beforeAll(async () => { await initCKZG(); loadEthereumTrustedSetup(); }); const peerId = "Qma9T5YraSnpRDZqRR4krcSJabThc8nwZuJV3LercPHufi"; - /* eslint-disable @typescript-eslint/naming-convention */ const chainConfig = createChainForkConfig({ ...defaultChainConfig, ALTAIR_FORK_EPOCH: 0, diff --git a/packages/beacon-node/test/unit/network/gossip/topic.test.ts b/packages/beacon-node/test/unit/network/gossip/topic.test.ts index dbaa4002bfcc..2a61d8604439 100644 --- a/packages/beacon-node/test/unit/network/gossip/topic.test.ts +++ b/packages/beacon-node/test/unit/network/gossip/topic.test.ts @@ -4,7 +4,7 @@ import {GossipType, GossipEncoding, GossipTopicMap} from "../../../../src/networ import {parseGossipTopic, stringifyGossipTopic} from "../../../../src/network/gossip/topic.js"; import {config} from "../../../utils/config.js"; -describe("network / gossip / topic", function () { +describe("network / gossip / topic", () => { const encoding = GossipEncoding.ssz_snappy; // Enforce with Typescript that we test all GossipType diff --git a/packages/beacon-node/test/unit/network/metadata.test.ts b/packages/beacon-node/test/unit/network/metadata.test.ts index 12bd9b168425..50e4157a29cd 100644 --- a/packages/beacon-node/test/unit/network/metadata.test.ts +++ b/packages/beacon-node/test/unit/network/metadata.test.ts @@ -4,7 +4,7 @@ import {ssz} from "@lodestar/types"; import {getENRForkID} from "../../../src/network/metadata.js"; import {config} from "../../utils/config.js"; -describe("network / metadata / getENRForkID", function () { +describe("network / metadata / getENRForkID", () => { // At 0, next fork is altair const currentEpoch = 0; const enrForkID = getENRForkID(config, currentEpoch); diff --git a/packages/beacon-node/test/unit/network/peers/priorization.test.ts b/packages/beacon-node/test/unit/network/peers/priorization.test.ts index 3ec770051275..e72cc32ce28c 100644 --- a/packages/beacon-node/test/unit/network/peers/priorization.test.ts +++ b/packages/beacon-node/test/unit/network/peers/priorization.test.ts @@ -1,7 +1,8 @@ import {PeerId} from "@libp2p/interface"; -import {createSecp256k1PeerId} from "@libp2p/peer-id-factory"; import {BitArray} from "@chainsafe/ssz"; import {describe, it, expect} from "vitest"; +import {generateKeyPair} from "@libp2p/crypto/keys"; +import {peerIdFromPrivateKey} from "@libp2p/peer-id"; import {ATTESTATION_SUBNET_COUNT} from "@lodestar/params"; import { ExcessPeerDisconnectReason, @@ -14,11 +15,11 @@ import {RequestedSubnet} from "../../../../src/network/peers/utils/index.js"; type Result = ReturnType; -// eslint-disable-next-line vitest/valid-describe-callback describe("network / peers / priorization", async () => { const peers: PeerId[] = []; for (let i = 0; i < 8; i++) { - const peer = await createSecp256k1PeerId(); + const pk = await generateKeyPair("secp256k1"); + const peer = peerIdFromPrivateKey(pk); peer.toString = () => `peer-${i}`; peers.push(peer); } @@ -264,11 +265,11 @@ describe("network / peers / priorization", async () => { } }); -// eslint-disable-next-line vitest/valid-describe-callback -describe("sortPeersToPrune", async function () { +describe("sortPeersToPrune", async () => { const peers: PeerId[] = []; for (let i = 0; i < 8; i++) { - const peer = await createSecp256k1PeerId(); + const pk = await generateKeyPair("secp256k1"); + const peer = peerIdFromPrivateKey(pk); peer.toString = () => `peer-${i}`; peers.push(peer); } diff --git a/packages/beacon-node/test/unit/network/peers/score.test.ts b/packages/beacon-node/test/unit/network/peers/score.test.ts index df842f9a1310..8962b282e0ad 100644 --- a/packages/beacon-node/test/unit/network/peers/score.test.ts +++ b/packages/beacon-node/test/unit/network/peers/score.test.ts @@ -19,19 +19,18 @@ vi.mock("../../../../src/network/peers/score/index.js", async (importActual) => }; }); -describe("simple block provider score tracking", function () { +describe("simple block provider score tracking", () => { const peer = peerIdFromString("Qma9T5YraSnpRDZqRR4krcSJabThc8nwZuJV3LercPHufi"); const MIN_SCORE = -100; const actionName = "test-action"; - // eslint-disable-next-line @typescript-eslint/explicit-function-return-type function mockStore() { const scoreStore = new PeerRpcScoreStore(); const peerScores = scoreStore["scores"] as MapDef; return {scoreStore, peerScores}; } - it("Should return default score, without any previous action", function () { + it("Should return default score, without any previous action", () => { const {scoreStore} = mockStore(); const score = scoreStore.getScore(peer); expect(score).toBe(0); @@ -70,7 +69,7 @@ describe("simple block provider score tracking", function () { expect(scoreStore.getScore(peer)).toBeGreaterThan(minScore); }); - it("should not go below min score", function () { + it("should not go below min score", () => { const {scoreStore} = mockStore(); scoreStore.applyAction(peer, PeerAction.Fatal, actionName); scoreStore.applyAction(peer, PeerAction.Fatal, actionName); @@ -78,7 +77,7 @@ describe("simple block provider score tracking", function () { }); }); -describe("updateGossipsubScores", function () { +describe("updateGossipsubScores", () => { let peerRpcScoresStub: PeerRpcScoreStore; beforeEach(() => { diff --git a/packages/beacon-node/test/unit/network/processorQueues.test.ts b/packages/beacon-node/test/unit/network/processorQueues.test.ts index 378d87ab7861..07a10591c0ad 100644 --- a/packages/beacon-node/test/unit/network/processorQueues.test.ts +++ b/packages/beacon-node/test/unit/network/processorQueues.test.ts @@ -21,10 +21,10 @@ async function validateTest(job: string, tracker: string[], opts: ValidateOpts): async function getStateFromCache(retrieveSync: boolean): Promise { if (retrieveSync) { return 1; - } else { - await sleep(0); - return 2; } + + await sleep(0); + return 2; } describe("event loop with branching async", () => { diff --git a/packages/beacon-node/test/unit/network/subnets/attnetsService.test.ts b/packages/beacon-node/test/unit/network/subnets/attnetsService.test.ts index 0c7b3df98268..d279a5d759d7 100644 --- a/packages/beacon-node/test/unit/network/subnets/attnetsService.test.ts +++ b/packages/beacon-node/test/unit/network/subnets/attnetsService.test.ts @@ -26,7 +26,6 @@ describe("AttnetsService", () => { "be" ); const ALTAIR_FORK_EPOCH = 100; - // eslint-disable-next-line @typescript-eslint/naming-convention const config = createBeaconConfig({ALTAIR_FORK_EPOCH}, ZERO_HASH); // const {SECONDS_PER_SLOT} = config; let service: AttnetsService; @@ -36,7 +35,7 @@ describe("AttnetsService", () => { let clock: IClock; const logger = testLogger(); - beforeEach(function () { + beforeEach(() => { vi.useFakeTimers({now: Date.now()}); gossipStub = vi.mocked(new Eth2Gossipsub({} as any, {} as any)); vi.spyOn(gossipStub, "subscribeTopic").mockReturnValue(undefined); diff --git a/packages/beacon-node/test/unit/network/util.test.ts b/packages/beacon-node/test/unit/network/util.test.ts index 14c74930e521..70da41bd2c2a 100644 --- a/packages/beacon-node/test/unit/network/util.test.ts +++ b/packages/beacon-node/test/unit/network/util.test.ts @@ -4,7 +4,7 @@ import {ForkName} from "@lodestar/params"; import {getDiscv5Multiaddrs} from "../../../src/network/libp2p/index.js"; import {getCurrentAndNextFork} from "../../../src/network/forks.js"; -describe("getCurrentAndNextFork", function () { +describe("getCurrentAndNextFork", () => { const altairEpoch = config.forks.altair.epoch; afterEach(() => { config.forks.altair.epoch = altairEpoch; @@ -34,7 +34,7 @@ describe("getCurrentAndNextFork", function () { }); describe("getDiscv5Multiaddrs", () => { - it("should extract bootMultiaddrs from enr with tcp", async function () { + it("should extract bootMultiaddrs from enr with tcp", async () => { const enrWithTcp = [ "enr:-LK4QDiPGwNomqUqNDaM3iHYvtdX7M5qngson6Qb2xGIg1LwC8-Nic0aQwO0rVbJt5xp32sRE3S1YqvVrWO7OgVNv0kBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpA7CIeVAAAgCf__________gmlkgnY0gmlwhBKNA4qJc2VjcDI1NmsxoQKbBS4ROQ_sldJm5tMgi36qm5I5exKJFb4C8dDVS_otAoN0Y3CCIyiDdWRwgiMo", ]; @@ -45,7 +45,7 @@ describe("getDiscv5Multiaddrs", () => { ); }); - it("should not extract bootMultiaddrs from enr without tcp", async function () { + it("should not extract bootMultiaddrs from enr without tcp", async () => { const enrWithoutTcp = [ "enr:-Ku4QCFQW96tEDYPjtaueW3WIh1CB0cJnvw_ibx5qIFZGqfLLj-QajMX6XwVs2d4offuspwgH3NkIMpWtCjCytVdlywGh2F0dG5ldHOIEAIAAgABAUyEZXRoMpCi7FS9AQAAAAAiAQAAAAAAgmlkgnY0gmlwhFA4VK6Jc2VjcDI1NmsxoQNGH1sJJS86-0x9T7qQewz9Wn9zlp6bYxqqrR38JQ49yIN1ZHCCIyg", ]; diff --git a/packages/beacon-node/test/unit/sync/backfill/verify.test.ts b/packages/beacon-node/test/unit/sync/backfill/verify.test.ts index 08ffdc4c3b02..bba1f7c93f19 100644 --- a/packages/beacon-node/test/unit/sync/backfill/verify.test.ts +++ b/packages/beacon-node/test/unit/sync/backfill/verify.test.ts @@ -12,17 +12,16 @@ import {BackfillSyncErrorCode, BackfillSyncError} from "./../../../../src/sync/b // Global variable __dirname no longer available in ES6 modules. // Solutions: https://stackoverflow.com/questions/46745014/alternative-for-dirname-in-node-js-when-using-es6-modules -// eslint-disable-next-line @typescript-eslint/naming-convention const __dirname = path.dirname(fileURLToPath(import.meta.url)); -describe("backfill sync - verify block sequence", function () { +describe("backfill sync - verify block sequence", () => { //mainnet validators root const beaconConfig = createBeaconConfig( config, ssz.Root.fromJson("0x4b363db94e286120d76eb905340fdd4e54bfe9f06bf33ff6cf5ad27f511bfe95") ); - it("should verify valid chain of blocks", function () { + it("should verify valid chain of blocks", () => { const blocks = getBlocks(); expect(() => @@ -30,20 +29,22 @@ describe("backfill sync - verify block sequence", function () { ).not.toThrow(); }); - it("should fail with sequence not anchored", function () { + it("should fail with sequence not anchored", () => { const blocks = getBlocks(); const wrongAncorRoot = ssz.Root.defaultValue(); expect(() => verifyBlockSequence(beaconConfig, blocks, wrongAncorRoot)).toThrow(BackfillSyncErrorCode.NOT_ANCHORED); }); - it("should fail with sequence not linear", function () { + it("should fail with sequence not linear", () => { const blocks = getBlocks(); expect(() => { const {error} = verifyBlockSequence( beaconConfig, // remove middle block - blocks.filter((b) => b.data.message.slot !== 2).slice(0, blocks.length - 2), + blocks + .filter((b) => b.data.message.slot !== 2) + .slice(0, blocks.length - 2), blocks[blocks.length - 1].data.message.parentRoot ); if (error != null) throw new BackfillSyncError({code: error}); diff --git a/packages/beacon-node/test/unit/sync/range/chain.test.ts b/packages/beacon-node/test/unit/sync/range/chain.test.ts index 44d5cc7c173a..658f950b2c18 100644 --- a/packages/beacon-node/test/unit/sync/range/chain.test.ts +++ b/packages/beacon-node/test/unit/sync/range/chain.test.ts @@ -72,7 +72,7 @@ describe("sync / range / chain", () => { } }; - const downloadBeaconBlocksByRange: SyncChainFns["downloadBeaconBlocksByRange"] = async (peerId, request) => { + const downloadBeaconBlocksByRange: SyncChainFns["downloadBeaconBlocksByRange"] = async (_peerId, request) => { const blocks: BlockInput[] = []; for (let i = request.startSlot; i < request.startSlot + request.count; i += request.step) { if (skippedSlots?.has(i)) { @@ -124,7 +124,7 @@ describe("sync / range / chain", () => { const peers = [peer]; const processChainSegment: SyncChainFns["processChainSegment"] = async () => {}; - const downloadBeaconBlocksByRange: SyncChainFns["downloadBeaconBlocksByRange"] = async (peer, request) => { + const downloadBeaconBlocksByRange: SyncChainFns["downloadBeaconBlocksByRange"] = async (_peer, request) => { const blocks: BlockInput[] = []; for (let i = request.startSlot; i < request.startSlot + request.count; i += request.step) { blocks.push( diff --git a/packages/beacon-node/test/unit/sync/unknownBlock.test.ts b/packages/beacon-node/test/unit/sync/unknownBlock.test.ts index f6791fc29e9c..0694cb97f4ab 100644 --- a/packages/beacon-node/test/unit/sync/unknownBlock.test.ts +++ b/packages/beacon-node/test/unit/sync/unknownBlock.test.ts @@ -22,7 +22,6 @@ import {ZERO_HASH} from "../../../src/constants/constants.js"; describe("sync by UnknownBlockSync", () => { const logger = testLogger(); const slotSec = 0.3; - // eslint-disable-next-line @typescript-eslint/naming-convention const config = createChainForkConfig({...minimalConfig, SECONDS_PER_SLOT: slotSec}); beforeEach(() => { @@ -119,11 +118,13 @@ describe("sync by UnknownBlockSync", () => { ]); let reportPeerResolveFn: (value: Parameters) => void; - const reportPeerPromise = new Promise>((r) => (reportPeerResolveFn = r)); + const reportPeerPromise = new Promise>((r) => { + reportPeerResolveFn = r; + }); let sendBeaconBlocksByRootResolveFn: (value: Parameters) => void; - const sendBeaconBlocksByRootPromise = new Promise>( - (r) => (sendBeaconBlocksByRootResolveFn = r) - ); + const sendBeaconBlocksByRootPromise = new Promise>((r) => { + sendBeaconBlocksByRootResolveFn = r; + }); const network: Partial = { events: new NetworkEventBus(), @@ -157,8 +158,12 @@ describe("sync by UnknownBlockSync", () => { let blockAResolver: () => void; let blockCResolver: () => void; - const blockAProcessed = new Promise((resolve) => (blockAResolver = resolve)); - const blockCProcessed = new Promise((resolve) => (blockCResolver = resolve)); + const blockAProcessed = new Promise((resolve) => { + blockAResolver = resolve; + }); + const blockCProcessed = new Promise((resolve) => { + blockCResolver = resolve; + }); const chain: Partial = { clock: new ClockStopped(0), @@ -234,7 +239,7 @@ describe("sync by UnknownBlockSync", () => { } }); -describe("UnknownBlockSync", function () { +describe("UnknownBlockSync", () => { let network: INetwork; let chain: MockedBeaconChain; const logger = testLogger(); diff --git a/packages/beacon-node/test/unit/util/array.test.ts b/packages/beacon-node/test/unit/util/array.test.ts index d505d27c2e9f..75d3a1b0856d 100644 --- a/packages/beacon-node/test/unit/util/array.test.ts +++ b/packages/beacon-node/test/unit/util/array.test.ts @@ -3,13 +3,13 @@ import {findLastIndex, LinkedList} from "../../../src/util/array.js"; describe("findLastIndex", () => { it("should return the last index that matches a predicate", () => { - expect(findLastIndex([1, 2, 3, 4], (n) => n % 2 == 0)).toEqual(3); - expect(findLastIndex([1, 2, 3, 4, 5], (n) => n % 2 == 0)).toEqual(3); + expect(findLastIndex([1, 2, 3, 4], (n) => n % 2 === 0)).toEqual(3); + expect(findLastIndex([1, 2, 3, 4, 5], (n) => n % 2 === 0)).toEqual(3); expect(findLastIndex([1, 2, 3, 4, 5], () => true)).toEqual(4); }); it("should return -1 if there are no matches", () => { - expect(findLastIndex([1, 3, 5], (n) => n % 2 == 0)).toEqual(-1); + expect(findLastIndex([1, 3, 5], (n) => n % 2 === 0)).toEqual(-1); expect(findLastIndex([1, 2, 3, 4, 5], () => false)).toEqual(-1); }); }); diff --git a/packages/beacon-node/test/unit/util/clock.test.ts b/packages/beacon-node/test/unit/util/clock.test.ts index ff224c1b378a..87955b98182c 100644 --- a/packages/beacon-node/test/unit/util/clock.test.ts +++ b/packages/beacon-node/test/unit/util/clock.test.ts @@ -4,7 +4,7 @@ import {SLOTS_PER_EPOCH} from "@lodestar/params"; import {Clock, ClockEvent} from "../../../src/util/clock.js"; import {MAXIMUM_GOSSIP_CLOCK_DISPARITY} from "../../../src/constants/index.js"; -describe("Clock", function () { +describe("Clock", () => { let abortController: AbortController; let clock: Clock; @@ -26,7 +26,7 @@ describe("Clock", function () { }); // TODO: Debug why this test is fragile after migrating to vitest - it.skip("Should notify on new slot", function () { + it.skip("Should notify on new slot", () => { const spy = vi.fn(); clock.on(ClockEvent.slot, spy); vi.advanceTimersByTime(config.SECONDS_PER_SLOT * 1000); @@ -34,7 +34,7 @@ describe("Clock", function () { expect(spy).toBeCalledWith(clock.currentSlot); }); - it("Should notify on new epoch", function () { + it("Should notify on new epoch", () => { const spy = vi.fn(); clock.on(ClockEvent.epoch, spy); vi.advanceTimersByTime(SLOTS_PER_EPOCH * config.SECONDS_PER_SLOT * 1000); diff --git a/packages/beacon-node/test/unit/util/dependentRoot.test.ts b/packages/beacon-node/test/unit/util/dependentRoot.test.ts index e7923f111d0b..c8044f332e34 100644 --- a/packages/beacon-node/test/unit/util/dependentRoot.test.ts +++ b/packages/beacon-node/test/unit/util/dependentRoot.test.ts @@ -26,9 +26,8 @@ describe("util / getShufflingDependentRoot", () => { forkchoiceStub.getDependentRoot.mockImplementation((block, epochDiff) => { if (block === headBattHeadBlock && epochDiff === EpochDifference.previous) { return "current"; - } else { - throw new Error("should not be called"); } + throw new Error("should not be called"); }); expect(getShufflingDependentRoot(forkchoiceStub, attEpoch, blockEpoch, headBattHeadBlock)).toEqual("current"); }); @@ -39,9 +38,8 @@ describe("util / getShufflingDependentRoot", () => { forkchoiceStub.getDependentRoot.mockImplementation((block, epochDiff) => { if (block === headBattHeadBlock && epochDiff === EpochDifference.current) { return "0x000"; - } else { - throw new Error("should not be called"); } + throw new Error("should not be called"); }); expect(getShufflingDependentRoot(forkchoiceStub, attEpoch, blockEpoch, headBattHeadBlock)).toEqual("0x000"); }); diff --git a/packages/beacon-node/test/unit/util/file.test.ts b/packages/beacon-node/test/unit/util/file.test.ts index 9e519ac01681..6040e14b4263 100644 --- a/packages/beacon-node/test/unit/util/file.test.ts +++ b/packages/beacon-node/test/unit/util/file.test.ts @@ -3,10 +3,10 @@ import path from "node:path"; import {describe, it, expect, beforeAll, afterAll} from "vitest"; import {ensureDir, writeIfNotExist} from "../../../src/util/file.js"; -describe("file util", function () { +describe("file util", () => { const dirPath = path.join(".", "keys/toml/test_config.toml"); - describe("ensureDir", function () { + describe("ensureDir", () => { it("create dir if not exists", async () => { // ${dirPath} should not exist expect(fs.existsSync(dirPath)).toBe(false); @@ -17,7 +17,7 @@ describe("file util", function () { }); }); - describe("writeIfNotExist", function () { + describe("writeIfNotExist", () => { const filePath = path.join(dirPath, "test.txt"); const data = new Uint8Array([0, 1, 2]); beforeAll(async () => { diff --git a/packages/beacon-node/test/unit/util/kzg.test.ts b/packages/beacon-node/test/unit/util/kzg.test.ts index e170aed1a2de..3b1de419ae93 100644 --- a/packages/beacon-node/test/unit/util/kzg.test.ts +++ b/packages/beacon-node/test/unit/util/kzg.test.ts @@ -16,7 +16,7 @@ describe("C-KZG", () => { } }); - beforeAll(async function () { + beforeAll(async () => { await initCKZG(); loadEthereumTrustedSetup(); }); @@ -31,7 +31,6 @@ describe("C-KZG", () => { expect(ckzg.verifyBlobKzgProofBatch(blobs, commitments, proofs)).toBe(true); }); - /* eslint-disable @typescript-eslint/naming-convention */ it("BlobSidecars", async () => { const chainConfig = createChainForkConfig({ ...defaultChainConfig, @@ -64,14 +63,14 @@ describe("C-KZG", () => { // Full validation validateBlobSidecars(slot, blockRoot, kzgCommitments, blobSidecars); - blobSidecars.forEach(async (blobSidecar) => { + for (const blobSidecar of blobSidecars) { try { await validateGossipBlobSidecar(chain, blobSidecar, blobSidecar.index); - } catch (error) { + } catch (_e) { // We expect some error from here // console.log(error); } - }); + } }); }); diff --git a/packages/beacon-node/test/unit/util/wrapError.test.ts b/packages/beacon-node/test/unit/util/wrapError.test.ts index 19bff7321e3c..2a8e5ca15ceb 100644 --- a/packages/beacon-node/test/unit/util/wrapError.test.ts +++ b/packages/beacon-node/test/unit/util/wrapError.test.ts @@ -5,13 +5,15 @@ describe("util / wrapError", () => { const error = Error("test-error"); async function throwNoAwait(shouldThrow: boolean): Promise { if (shouldThrow) throw error; - else return true; + + return true; } async function throwAwait(shouldThrow: boolean): Promise { await new Promise((r) => setTimeout(r, 0)); if (shouldThrow) throw error; - else return true; + + return true; } it("Handle error and result with throwNoAwait", async () => { diff --git a/packages/beacon-node/test/utils/cache.ts b/packages/beacon-node/test/utils/cache.ts index 9d5d3566c99d..2fd15427c659 100644 --- a/packages/beacon-node/test/utils/cache.ts +++ b/packages/beacon-node/test/utils/cache.ts @@ -3,7 +3,7 @@ import {toHexString} from "@chainsafe/ssz"; export function memoOnce(fn: () => R): () => R { let value: R | null = null; - return function () { + return () => { if (value === null) { value = fn(); } diff --git a/packages/beacon-node/test/utils/clock.ts b/packages/beacon-node/test/utils/clock.ts index ea14c866c1b0..390d7dd095dd 100644 --- a/packages/beacon-node/test/utils/clock.ts +++ b/packages/beacon-node/test/utils/clock.ts @@ -4,11 +4,14 @@ import {Slot, Epoch} from "@lodestar/types"; import {IClock} from "../../src/util/clock.js"; export class ClockStatic extends EventEmitter implements IClock { + genesisTime: number; + constructor( readonly currentSlot: Slot, - public genesisTime = 0 + genesisTime = 0 ) { super(); + this.genesisTime = genesisTime; } get currentEpoch(): Epoch { diff --git a/packages/beacon-node/test/utils/config.ts b/packages/beacon-node/test/utils/config.ts index 2aad1c14c03e..f5d566560b65 100644 --- a/packages/beacon-node/test/utils/config.ts +++ b/packages/beacon-node/test/utils/config.ts @@ -6,7 +6,6 @@ import {ZERO_HASH} from "../../src/constants/index.js"; /** default config with ZERO_HASH as genesisValidatorsRoot */ export const config = createBeaconConfig(chainConfig, ZERO_HASH); -/* eslint-disable @typescript-eslint/naming-convention */ export function getConfig(fork: ForkName, forkEpoch = 0): ChainForkConfig { switch (fork) { case ForkName.phase0: diff --git a/packages/beacon-node/test/utils/errors.ts b/packages/beacon-node/test/utils/errors.ts index c3d293e83c78..1bf31a2ce9af 100644 --- a/packages/beacon-node/test/utils/errors.ts +++ b/packages/beacon-node/test/utils/errors.ts @@ -53,9 +53,11 @@ export function expectLodestarError(err1: LodestarErro export function getErrorMetadata(err: LodestarError | Error | unknown): unknown { if (err instanceof LodestarError) { return mapValues(err.getMetadata(), (value) => getErrorMetadata(value as any)); - } else if (err instanceof Error) { + } + + if (err instanceof Error) { return err.message; - } else { - return err; } + + return err; } diff --git a/packages/beacon-node/test/utils/network.ts b/packages/beacon-node/test/utils/network.ts index 56c831b269f5..71bb0bd255da 100644 --- a/packages/beacon-node/test/utils/network.ts +++ b/packages/beacon-node/test/utils/network.ts @@ -1,6 +1,6 @@ import {BitArray} from "@chainsafe/ssz"; -import {PeerId} from "@libp2p/interface"; -import {createSecp256k1PeerId} from "@libp2p/peer-id-factory"; +import {PrivateKey} from "@libp2p/interface"; +import {generateKeyPair} from "@libp2p/crypto/keys"; import {ATTESTATION_SUBNET_COUNT, SYNC_COMMITTEE_SUBNET_COUNT} from "@lodestar/params"; import {INetwork, Network, NetworkEvent} from "../../src/network/index.js"; import {Libp2p} from "../../src/network/interface.js"; @@ -8,18 +8,17 @@ import {createNodeJsLibp2p} from "../../src/network/libp2p/index.js"; import {NetworkOptions, defaultNetworkOptions} from "../../src/network/options.js"; import {PeerIdStr} from "../../src/util/peerId.js"; -export async function createNode(multiaddr: string, inPeerId?: PeerId): Promise { - const peerId = inPeerId || (await createSecp256k1PeerId()); - return createNodeJsLibp2p(peerId, {localMultiaddrs: [multiaddr]}); +export async function createNode(multiaddr: string, privateKey?: PrivateKey): Promise { + return createNodeJsLibp2p(privateKey ?? (await generateKeyPair("secp256k1")), {localMultiaddrs: [multiaddr]}); } export async function createNetworkModules( multiaddr: string, - peerId?: PeerId, + privateKey?: PrivateKey, opts?: Partial -): Promise<{opts: NetworkOptions; peerId: PeerId}> { +): Promise<{opts: NetworkOptions; privateKey: PrivateKey}> { return { - peerId: peerId ?? (await createSecp256k1PeerId()), + privateKey: privateKey ?? (await generateKeyPair("secp256k1")), opts: {...defaultNetworkOptions, ...opts, localMultiaddrs: [multiaddr]}, }; } diff --git a/packages/beacon-node/test/utils/networkWithMockDb.ts b/packages/beacon-node/test/utils/networkWithMockDb.ts index f8a4a6181d2f..b1c4293588d2 100644 --- a/packages/beacon-node/test/utils/networkWithMockDb.ts +++ b/packages/beacon-node/test/utils/networkWithMockDb.ts @@ -1,4 +1,4 @@ -import {createSecp256k1PeerId} from "@libp2p/peer-id-factory"; +import {generateKeyPair} from "@libp2p/crypto/keys"; import {ChainForkConfig, createBeaconConfig} from "@lodestar/config"; import {ssz} from "@lodestar/types"; import {BeaconChain} from "../../src/chain/chain.js"; @@ -70,7 +70,7 @@ export async function getNetworkForTest( } ); - const modules: Omit = { + const modules: Omit = { config: beaconConfig, chain, db, @@ -81,7 +81,7 @@ export async function getNetworkForTest( const network = await Network.init({ ...modules, - peerId: await createSecp256k1PeerId(), + privateKey: await generateKeyPair("secp256k1"), opts: { ...defaultNetworkOptions, maxPeers: 1, diff --git a/packages/beacon-node/test/utils/node/beacon.ts b/packages/beacon-node/test/utils/node/beacon.ts index 0163fa148102..746c2cde5fd4 100644 --- a/packages/beacon-node/test/utils/node/beacon.ts +++ b/packages/beacon-node/test/utils/node/beacon.ts @@ -1,7 +1,7 @@ import deepmerge from "deepmerge"; import tmp from "tmp"; -import {PeerId} from "@libp2p/interface"; -import {createSecp256k1PeerId} from "@libp2p/peer-id-factory"; +import {PrivateKey} from "@libp2p/interface"; +import {generateKeyPair} from "@libp2p/crypto/keys"; import {config as minimalConfig} from "@lodestar/config/default"; import {createBeaconConfig, createChainForkConfig, ChainConfig} from "@lodestar/config"; import {RecursivePartial} from "@lodestar/utils"; @@ -26,16 +26,16 @@ export async function getDevBeaconNode( options?: RecursivePartial; validatorCount?: number; logger?: LoggerNode; - peerId?: PeerId; + privateKey?: PrivateKey; peerStoreDir?: string; anchorState?: BeaconStateAllForks; wsCheckpoint?: phase0.Checkpoint; } & InteropStateOpts ): Promise { const {params, validatorCount = 8, peerStoreDir} = opts; - let {options = {}, logger, peerId} = opts; + let {options = {}, logger, privateKey} = opts; - if (!peerId) peerId = await createSecp256k1PeerId(); + if (!privateKey) privateKey = await generateKeyPair("secp256k1"); const tmpDir = tmp.dirSync({unsafeCleanup: true}); const config = createChainForkConfig({...minimalConfig, ...params}); logger = logger ?? testLogger(); @@ -93,7 +93,7 @@ export async function getDevBeaconNode( db, logger, processShutdownCallback: () => {}, - peerId, + privateKey, peerStoreDir, anchorState, wsCheckpoint: opts.wsCheckpoint, diff --git a/packages/beacon-node/test/utils/node/simTest.ts b/packages/beacon-node/test/utils/node/simTest.ts index e94c32cefb10..7b771b8534ed 100644 --- a/packages/beacon-node/test/utils/node/simTest.ts +++ b/packages/beacon-node/test/utils/node/simTest.ts @@ -112,7 +112,7 @@ function avg(arr: number[]): number { /** * Print a table grid of (Y) epoch / (X) slot_per_epoch */ -function printEpochSlotGrid(map: Map, config: BeaconConfig, title: string): void { +function printEpochSlotGrid(map: Map, _config: BeaconConfig, title: string): void { const lastSlot = Array.from(map.keys())[map.size - 1]; const lastEpoch = computeEpochAtSlot(lastSlot); const rowsByEpochBySlot = linspace(0, lastEpoch).map((epoch) => { @@ -132,7 +132,7 @@ function printEpochGrid(maps: Record>, title: string) return epoch > max ? epoch : max; }, 0); const epochGrid = linspace(0, lastEpoch).map((epoch) => - mapValues(maps, (val, key) => formatValue(maps[key].get(epoch))) + mapValues(maps, (_val, key) => formatValue(maps[key].get(epoch))) ); console.log(renderTitle(title)); console.table(epochGrid); diff --git a/packages/beacon-node/test/utils/peer.ts b/packages/beacon-node/test/utils/peer.ts index 8bd5c6c67be8..aeec92bf994e 100644 --- a/packages/beacon-node/test/utils/peer.ts +++ b/packages/beacon-node/test/utils/peer.ts @@ -1,6 +1,6 @@ import {PeerId} from "@libp2p/interface"; -import {createSecp256k1PeerId} from "@libp2p/peer-id-factory"; -import {peerIdFromBytes} from "@libp2p/peer-id"; +import {peerIdFromPrivateKey, peerIdFromPublicKey} from "@libp2p/peer-id"; +import {generateKeyPair, publicKeyFromProtobuf} from "@libp2p/crypto/keys"; import {peerIdToString} from "../../src/util/peerId.js"; /** @@ -9,11 +9,11 @@ import {peerIdToString} from "../../src/util/peerId.js"; */ export function getValidPeerId(): PeerId { const id = Buffer.from("002508021221039481269fe831799b1a0f1d521c1395b4831514859e4559c44d155eae46f03819", "hex"); - return peerIdFromBytes(id); + return peerIdFromPublicKey(publicKeyFromProtobuf(id)); } export async function getRandPeerIdStr(): Promise { - return peerIdToString(await createSecp256k1PeerId()); + return peerIdToString(peerIdFromPrivateKey(await generateKeyPair("secp256k1"))); } export const validPeerIdStr = peerIdToString(getValidPeerId()); diff --git a/packages/beacon-node/test/utils/runEl.ts b/packages/beacon-node/test/utils/runEl.ts index 9adf1a83c151..9a407f91d414 100644 --- a/packages/beacon-node/test/utils/runEl.ts +++ b/packages/beacon-node/test/utils/runEl.ts @@ -7,7 +7,6 @@ import {Eth1Provider} from "../../src/index.js"; import {ZERO_HASH} from "../../src/constants/index.js"; import {shell} from "../sim/shell.js"; -/* eslint-disable @typescript-eslint/naming-convention */ /* eslint-disable no-console */ let txRpcId = 1; @@ -84,7 +83,7 @@ async function waitForELOnline(url: string, signal: AbortSignal): Promise console.log("Waiting for few seconds for EL to fully setup, for e.g. unlock the account..."); await sleep(5000, signal); return; // Done - } catch (e) { + } catch (_e) { await sleep(1000, signal); } } @@ -180,8 +179,8 @@ async function startELProcess(args: { return tearDownCallBack; } -async function waitForELOffline(ENGINE_PORT: string): Promise { - const port = parseInt(ENGINE_PORT); +async function waitForELOffline(enginePort: string): Promise { + const port = parseInt(enginePort); for (let i = 0; i < 60; i++) { console.log("Waiting for EL offline..."); @@ -197,7 +196,7 @@ async function waitForELOffline(ENGINE_PORT: string): Promise { async function isPortInUse(port: number): Promise { return new Promise((resolve, reject) => { const server = net.createServer(); - server.once("error", function (err) { + server.once("error", (err) => { if ((err as unknown as {code: string}).code === "EADDRINUSE") { resolve(true); } else { @@ -205,7 +204,7 @@ async function isPortInUse(port: number): Promise { } }); - server.once("listening", function () { + server.once("listening", () => { // close the server if listening doesn't fail server.close(() => { resolve(false); diff --git a/packages/beacon-node/test/utils/validationData/aggregateAndProof.ts b/packages/beacon-node/test/utils/validationData/aggregateAndProof.ts index 45adfec433e4..462502719134 100644 --- a/packages/beacon-node/test/utils/validationData/aggregateAndProof.ts +++ b/packages/beacon-node/test/utils/validationData/aggregateAndProof.ts @@ -1,7 +1,6 @@ import {computeSigningRoot} from "@lodestar/state-transition"; import {DOMAIN_AGGREGATE_AND_PROOF, DOMAIN_SELECTION_PROOF} from "@lodestar/params"; import {phase0, ssz} from "@lodestar/types"; -// eslint-disable-next-line import/no-relative-packages import {getSecretKeyFromIndexCached} from "../../../../state-transition/test/perf/util.js"; import {IBeaconChain} from "../../../src/chain/index.js"; import {SeenAggregators} from "../../../src/chain/seenCache/index.js"; diff --git a/packages/beacon-node/test/utils/validationData/attestation.ts b/packages/beacon-node/test/utils/validationData/attestation.ts index 22f551cbb663..6715512ac667 100644 --- a/packages/beacon-node/test/utils/validationData/attestation.ts +++ b/packages/beacon-node/test/utils/validationData/attestation.ts @@ -6,7 +6,6 @@ import {phase0, Slot, ssz} from "@lodestar/types"; import { generateTestCachedBeaconStateOnlyValidators, getSecretKeyFromIndexCached, - // eslint-disable-next-line import/no-relative-packages } from "../../../../state-transition/test/perf/util.js"; import {IBeaconChain} from "../../../src/chain/index.js"; import {IStateRegenerator} from "../../../src/chain/regen/index.js"; diff --git a/packages/cli/docsgen/markdown.ts b/packages/cli/docsgen/markdown.ts index 5c3033e9c0df..9c7a4d0ca279 100644 --- a/packages/cli/docsgen/markdown.ts +++ b/packages/cli/docsgen/markdown.ts @@ -117,7 +117,6 @@ function renderOption(optionName: string, option: CliOptionDefinition): string | defaultValue = `"${defaultValue}"`; } if (option.type === "array") { - // eslint-disable-next-line quotes if (!defaultValue.includes(`"`)) { defaultValue = `"${defaultValue}"`; } diff --git a/packages/cli/package.json b/packages/cli/package.json index a5527a8eee87..67d0dfd332cc 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -28,8 +28,8 @@ "check-build": "node -e \"(async function() { await import('./lib/index.js') })()\" lodestar --help", "check-types": "tsc", "docs:build": "node --loader ts-node/esm ./docsgen/index.ts", - "lint": "eslint --color --ext .ts src/ test/", - "lint:fix": "yarn run lint --fix", + "lint": "biome check src/ test/", + "lint:fix": "yarn run lint --write", "test:unit": "vitest --run --dir test/unit/", "test:e2e": "vitest --run --config vitest.e2e.config.ts --dir test/e2e/", "test:sim:multifork": "LODESTAR_PRESET=minimal DOTENV_CONFIG_PATH=../../.env.test node -r dotenv/config --loader ts-node/esm test/sim/multiFork.test.ts", @@ -54,14 +54,14 @@ "@chainsafe/bls-keygen": "^0.4.0", "@chainsafe/bls-keystore": "^3.1.0", "@chainsafe/blst": "^2.0.3", - "@chainsafe/discv5": "^9.0.0", - "@chainsafe/enr": "^3.0.0", + "@chainsafe/discv5": "^10.0.1", + "@chainsafe/enr": "^4.0.1", "@chainsafe/persistent-merkle-tree": "^0.8.0", "@chainsafe/ssz": "^0.17.1", "@chainsafe/threads": "^1.11.1", - "@libp2p/crypto": "^4.1.0", - "@libp2p/peer-id": "^4.1.0", - "@libp2p/peer-id-factory": "^4.1.0", + "@libp2p/crypto": "^5.0.4", + "@libp2p/interface": "^2.1.2", + "@libp2p/peer-id": "^5.0.4", "@lodestar/api": "^1.22.0", "@lodestar/beacon-node": "^1.22.0", "@lodestar/config": "^1.22.0", diff --git a/packages/cli/src/applyPreset.ts b/packages/cli/src/applyPreset.ts index 25f78b7d32ac..612c5d648c63 100644 --- a/packages/cli/src/applyPreset.ts +++ b/packages/cli/src/applyPreset.ts @@ -1,8 +1,6 @@ // MUST import this file first before anything and not import any Lodestar code. -// eslint-disable-next-line no-restricted-imports import {hasher} from "@chainsafe/persistent-merkle-tree/lib/hasher/as-sha256.js"; -// eslint-disable-next-line no-restricted-imports import {setHasher} from "@chainsafe/persistent-merkle-tree/lib/hasher/index.js"; // without setting this first, persistent-merkle-tree will use noble instead @@ -45,7 +43,6 @@ else if (network) { if (network === "dev") { process.env.LODESTAR_PRESET = "minimal"; // "c-kzg" has hardcoded the mainnet value, do not use presets - // eslint-disable-next-line @typescript-eslint/naming-convention setActivePreset(PresetName.minimal, {FIELD_ELEMENTS_PER_BLOB: 4096}); } else if (network === "gnosis" || network === "chiado") { process.env.LODESTAR_PRESET = "gnosis"; @@ -57,7 +54,6 @@ else if (process.argv[2] === "dev") { process.env.LODESTAR_PRESET = "minimal"; process.env.LODESTAR_NETWORK = "dev"; // "c-kzg" has hardcoded the mainnet value, do not use presets - // eslint-disable-next-line @typescript-eslint/naming-convention setActivePreset(PresetName.minimal, {FIELD_ELEMENTS_PER_BLOB: 4096}); } @@ -94,6 +90,3 @@ function valueOfArg(argName: string): string | null { return null; } - -// Add empty export to make this a module -export {}; diff --git a/packages/cli/src/cmds/beacon/handler.ts b/packages/cli/src/cmds/beacon/handler.ts index d51af66e37d0..2a0238fede20 100644 --- a/packages/cli/src/cmds/beacon/handler.ts +++ b/packages/cli/src/cmds/beacon/handler.ts @@ -24,7 +24,7 @@ import {LogArgs} from "../../options/logOptions.js"; import {BeaconArgs} from "./options.js"; import {getBeaconPaths} from "./paths.js"; import {initBeaconState} from "./initBeaconState.js"; -import {initPeerIdAndEnr} from "./initPeerIdAndEnr.js"; +import {initPrivateKeyAndEnr} from "./initPeerIdAndEnr.js"; const DEFAULT_RETENTION_SSZ_OBJECTS_HOURS = 15 * 24; const HOURS_TO_MS = 3600 * 1000; @@ -34,7 +34,7 @@ const EIGHT_GB = 8 * 1024 * 1024 * 1024; * Runs a beacon node. */ export async function beaconHandler(args: BeaconArgs & GlobalArgs): Promise { - const {config, options, beaconPaths, network, version, commit, peerId, logger} = await beaconHandlerInit(args); + const {config, options, beaconPaths, network, version, commit, privateKey, logger} = await beaconHandlerInit(args); const heapSizeLimit = getHeapStatistics().heap_size_limit; if (heapSizeLimit < EIGHT_GB) { @@ -80,7 +80,7 @@ export async function beaconHandler(args: BeaconArgs & GlobalArgs): Promise { +): Promise<{privateKey: PrivateKey; enr: SignableENR}> { const {persistNetworkIdentity} = args; - const newPeerIdAndENR = async (): Promise<{peerId: PeerId; enr: SignableENR}> => { - const peerId = await createSecp256k1PeerId(); - const enr = SignableENR.createV4(createPrivateKeyFromPeerId(peerId).privateKey); - return {peerId, enr}; + const newPrivateKeyAndENR = async (): Promise<{privateKey: PrivateKey; enr: SignableENR}> => { + const privateKey = await generateKeyPair("secp256k1"); + const enr = SignableENR.createFromPrivateKey(privateKey); + return {privateKey, enr}; }; - const readPersistedPeerIdAndENR = async ( + const readPersistedPrivateKeyAndENR = async ( peerIdFile: string, enrFile: string - ): Promise<{peerId: PeerId; enr: SignableENR; newEnr: boolean}> => { - let peerId: PeerId; + ): Promise<{privateKey: PrivateKey; enr: SignableENR; newEnr: boolean}> => { + let privateKey: PrivateKey; let enr: SignableENR; // attempt to read stored peer id try { - peerId = await readPeerId(peerIdFile); - } catch (e) { + privateKey = readPrivateKey(peerIdFile); + } catch (_e) { logger.warn("Unable to read peerIdFile, creating a new peer id"); - return {...(await newPeerIdAndENR()), newEnr: true}; + return {...(await newPrivateKeyAndENR()), newEnr: true}; } // attempt to read stored enr try { - enr = SignableENR.decodeTxt(fs.readFileSync(enrFile, "utf-8"), createPrivateKeyFromPeerId(peerId).privateKey); - } catch (e) { + enr = SignableENR.decodeTxt(fs.readFileSync(enrFile, "utf-8"), privateKey.raw); + } catch (_e) { logger.warn("Unable to decode stored local ENR, creating a new ENR"); - enr = SignableENR.createV4(createPrivateKeyFromPeerId(peerId).privateKey); - return {peerId, enr, newEnr: true}; + enr = SignableENR.createFromPrivateKey(privateKey); + return {privateKey, enr, newEnr: true}; } // check stored peer id against stored enr - if (!peerId.equals(await enr.peerId())) { + if (!privateKey.equals(enr.peerId)) { logger.warn("Stored local ENR doesn't match peerIdFile, creating a new ENR"); - enr = SignableENR.createV4(createPrivateKeyFromPeerId(peerId).privateKey); - return {peerId, enr, newEnr: true}; + enr = SignableENR.createFromPrivateKey(privateKey); + return {privateKey, enr, newEnr: true}; } - return {peerId, enr, newEnr: false}; + return {privateKey, enr, newEnr: false}; }; if (persistNetworkIdentity) { const enrFile = path.join(beaconDir, "enr"); const peerIdFile = path.join(beaconDir, "peer-id.json"); - const {peerId, enr, newEnr} = await readPersistedPeerIdAndENR(peerIdFile, enrFile); + const {privateKey, enr, newEnr} = await readPersistedPrivateKeyAndENR(peerIdFile, enrFile); overwriteEnrWithCliArgs(enr, args, logger, {newEnr, bootnode}); // Re-persist peer-id and enr - writeFile600Perm(peerIdFile, exportToJSON(peerId)); + writeFile600Perm(peerIdFile, exportToJSON(privateKey)); writeFile600Perm(enrFile, enr.encodeTxt()); - return {peerId, enr}; - } else { - const {peerId, enr} = await newPeerIdAndENR(); - overwriteEnrWithCliArgs(enr, args, logger, {newEnr: true, bootnode}); - return {peerId, enr}; + return {privateKey, enr}; } + const {privateKey, enr} = await newPrivateKeyAndENR(); + overwriteEnrWithCliArgs(enr, args, logger, {newEnr: true, bootnode}); + return {privateKey, enr}; } diff --git a/packages/cli/src/cmds/bootnode/handler.ts b/packages/cli/src/cmds/bootnode/handler.ts index 77851b1fcb88..9c093eed1272 100644 --- a/packages/cli/src/cmds/bootnode/handler.ts +++ b/packages/cli/src/cmds/bootnode/handler.ts @@ -10,7 +10,7 @@ import {getBeaconConfigFromArgs} from "../../config/index.js"; import {getNetworkBootnodes, isKnownNetworkName, readBootnodes} from "../../networks/index.js"; import {onGracefulShutdown, mkdir, writeFile600Perm} from "../../util/index.js"; import {getVersionData} from "../../util/version.js"; -import {initPeerIdAndEnr} from "../beacon/initPeerIdAndEnr.js"; +import {initPrivateKeyAndEnr} from "../beacon/initPeerIdAndEnr.js"; import {parseArgs as parseMetricsArgs} from "../../options/beaconNodeOptions/metrics.js"; import {parseArgs as parseNetworkArgs} from "../../options/beaconNodeOptions/network.js"; import {getBeaconPaths} from "../beacon/paths.js"; @@ -22,7 +22,7 @@ import {BootnodeArgs} from "./options.js"; * Runs a bootnode. */ export async function bootnodeHandler(args: BootnodeArgs & GlobalArgs): Promise { - const {discv5Args, metricsArgs, bootnodeDir, network, version, commit, peerId, enr, logger} = + const {discv5Args, metricsArgs, bootnodeDir, network, version, commit, privateKey, enr, logger} = await bootnodeHandlerInit(args); const abortController = new AbortController(); @@ -34,7 +34,7 @@ export async function bootnodeHandler(args: BootnodeArgs & GlobalArgs): Promise< ip4: enr.getLocationMultiaddr("udp4")?.toString(), ip6: enr.getLocationMultiaddr("udp6")?.toString(), }); - logger.info("Identity", {peerId: peerId.toString(), nodeId: enr.nodeId}); + logger.info("Identity", {peerId: enr.peerId.toString(), nodeId: enr.nodeId}); logger.info("ENR", {enr: enr.encodeTxt()}); // bootnode setup @@ -53,7 +53,7 @@ export async function bootnodeHandler(args: BootnodeArgs & GlobalArgs): Promise< const discv5 = Discv5.create({ enr, - peerId, + privateKey, bindAddrs: { ip4: (bindAddrs.ip4 ? multiaddr(bindAddrs.ip4) : undefined) as Multiaddr, ip6: bindAddrs.ip6 ? multiaddr(bindAddrs.ip6) : undefined, @@ -68,7 +68,7 @@ export async function bootnodeHandler(args: BootnodeArgs & GlobalArgs): Promise< logger.info("Adding bootnode", { ip4: bootEnr.getLocationMultiaddr("udp4")?.toString(), ip6: bootEnr.getLocationMultiaddr("udp6")?.toString(), - peerId: (await bootEnr.peerId()).toString(), + peerId: bootEnr.peerId.toString(), nodeId: enr.nodeId, }); discv5.addEnr(bootEnr); @@ -156,7 +156,6 @@ export async function bootnodeHandler(args: BootnodeArgs & GlobalArgs): Promise< } /** Separate function to simplify unit testing of options merging */ -// eslint-disable-next-line @typescript-eslint/explicit-function-return-type export async function bootnodeHandlerInit(args: BootnodeArgs & GlobalArgs) { const {config, network} = getBeaconConfigFromArgs(args); const {version, commit} = getVersionData(); @@ -181,7 +180,7 @@ export async function bootnodeHandlerInit(args: BootnodeArgs & GlobalArgs) { ); const logger = initLogger(args, beaconPaths.dataDir, config, "bootnode.log"); - const {peerId, enr} = await initPeerIdAndEnr(args as unknown as BeaconArgs, bootnodeDir, logger, true); + const {privateKey, enr} = await initPrivateKeyAndEnr(args as unknown as BeaconArgs, bootnodeDir, logger, true); - return {discv5Args, metricsArgs, bootnodeDir, network, version, commit, peerId, enr, logger}; + return {discv5Args, metricsArgs, bootnodeDir, network, version, commit, privateKey, enr, logger}; } diff --git a/packages/cli/src/cmds/bootnode/options.ts b/packages/cli/src/cmds/bootnode/options.ts index dd597e6a22ef..f3422b4029a1 100644 --- a/packages/cli/src/cmds/bootnode/options.ts +++ b/packages/cli/src/cmds/bootnode/options.ts @@ -55,7 +55,7 @@ export const bootnodeExtraOptions: CliCommandOptions = { // Each bootnode entry could be comma separated, just deserialize it into a single array // as comma separated entries are generally most friendly in ansible kind of setups, i.e. // [ "en1", "en2,en3" ] => [ 'en1', 'en2', 'en3' ] - coerce: (args: string[]) => args.map((item) => item.split(",")).flat(1), + coerce: (args: string[]) => args.flatMap((item) => item.split(",")), group: "network", }, diff --git a/packages/cli/src/cmds/dev/options.ts b/packages/cli/src/cmds/dev/options.ts index 5286b81729c6..e442b0605cdc 100644 --- a/packages/cli/src/cmds/dev/options.ts +++ b/packages/cli/src/cmds/dev/options.ts @@ -81,12 +81,12 @@ const externalOptionsOverrides: Partial closeMetrics()); // only start server if metrics are explicitly enabled - if (args["metrics"]) { + if (args.metrics) { const port = args["metrics.port"] ?? validatorMetricsDefaultOptions.port; const address = args["metrics.address"] ?? validatorMetricsDefaultOptions.address; const metricsServer = await getHttpMetricsServer({port, address}, {register, logger}); @@ -186,7 +186,7 @@ export async function validatorHandler(args: IValidatorCliArgs & GlobalArgs): Pr // Start keymanager API backend // Only if keymanagerEnabled flag is set to true - if (args["keymanager"]) { + if (args.keymanager) { // if proposerSettingsFile provided disable the key proposerConfigWrite in keymanager const proposerConfigWriteDisabled = args.proposerSettingsFile !== undefined; if (proposerConfigWriteDisabled) { @@ -234,7 +234,7 @@ function getProposerConfigFromArgs( builder: { gasLimit: args.defaultGasLimit, selection: parseBuilderSelection( - args["builder.selection"] ?? (args["builder"] ? defaultOptions.builderAliasSelection : undefined) + args["builder.selection"] ?? (args.builder ? defaultOptions.builderAliasSelection : undefined) ), boostFactor: parseBuilderBoostFactor(args["builder.boostFactor"]), }, diff --git a/packages/cli/src/cmds/validator/keymanager/decryptKeystoreDefinitions.ts b/packages/cli/src/cmds/validator/keymanager/decryptKeystoreDefinitions.ts index 0ce0646c978a..7cfaa9768494 100644 --- a/packages/cli/src/cmds/validator/keymanager/decryptKeystoreDefinitions.ts +++ b/packages/cli/src/cmds/validator/keymanager/decryptKeystoreDefinitions.ts @@ -51,7 +51,7 @@ export async function decryptKeystoreDefinitions( opts.logger.debug("Loaded keystores via keystore cache"); return signers; - } catch { + } catch (_e) { // Some error loading the cache, ignore and invalidate cache await clearKeystoreCache(opts.cacheFilePath); } diff --git a/packages/cli/src/cmds/validator/keymanager/decryptKeystores/poolSize.ts b/packages/cli/src/cmds/validator/keymanager/decryptKeystores/poolSize.ts index 9219ae6d8537..2939dade7e31 100644 --- a/packages/cli/src/cmds/validator/keymanager/decryptKeystores/poolSize.ts +++ b/packages/cli/src/cmds/validator/keymanager/decryptKeystores/poolSize.ts @@ -6,7 +6,7 @@ try { } else { maxPoolSize = (await import("node:os")).availableParallelism(); } -} catch (e) { +} catch (_e) { maxPoolSize = 8; } diff --git a/packages/cli/src/cmds/validator/keymanager/impl.ts b/packages/cli/src/cmds/validator/keymanager/impl.ts index d965b2af5075..b4233f3162cd 100644 --- a/packages/cli/src/cmds/validator/keymanager/impl.ts +++ b/packages/cli/src/cmds/validator/keymanager/impl.ts @@ -378,7 +378,6 @@ export class KeymanagerApi implements Api { function ensureJSON(strOrJson: string | T): T { if (typeof strOrJson === "string") { return JSON.parse(strOrJson) as T; - } else { - return strOrJson; } + return strOrJson; } diff --git a/packages/cli/src/cmds/validator/keymanager/server.ts b/packages/cli/src/cmds/validator/keymanager/server.ts index c4d3256c6151..e48c708c96a8 100644 --- a/packages/cli/src/cmds/validator/keymanager/server.ts +++ b/packages/cli/src/cmds/validator/keymanager/server.ts @@ -80,6 +80,7 @@ function readFileIfExists(filepath: string): string | null { return fs.readFileSync(filepath, "utf8").trim(); } catch (e) { if ((e as {code: string}).code === "ENOENT") return null; - else throw e; + + throw e; } } diff --git a/packages/cli/src/cmds/validator/options.ts b/packages/cli/src/cmds/validator/options.ts index 87b43543b62e..3beb8197793c 100644 --- a/packages/cli/src/cmds/validator/options.ts +++ b/packages/cli/src/cmds/validator/options.ts @@ -195,7 +195,7 @@ export const validatorOptions: CliCommandOptions = { string: true, coerce: (urls: string[]): string[] => // Parse ["url1,url2"] to ["url1", "url2"] - urls.map((item) => item.split(",")).flat(1), + urls.flatMap((item) => item.split(",")), alias: ["server"], // for backwards compatibility }, @@ -352,8 +352,7 @@ export const validatorOptions: CliCommandOptions = { coerce: (pubkeys: string[]): string[] => // Parse ["0x11,0x22"] to ["0x11", "0x22"] pubkeys - .map((item) => item.split(",")) - .flat(1) + .flatMap((item) => item.split(",")) .map(ensure0xPrefix), group: "externalSigner", }, diff --git a/packages/cli/src/cmds/validator/signers/importExternalKeystores.ts b/packages/cli/src/cmds/validator/signers/importExternalKeystores.ts index 7b90d16d1d88..f86ea90ab1a8 100644 --- a/packages/cli/src/cmds/validator/signers/importExternalKeystores.ts +++ b/packages/cli/src/cmds/validator/signers/importExternalKeystores.ts @@ -28,17 +28,17 @@ export function importKeystoreDefinitionsFromExternalDir(args: { export async function readPassphraseOrPrompt(args: {importKeystoresPassword?: string}): Promise { if (args.importKeystoresPassword) { return readPassphraseFile(args.importKeystoresPassword); - } else { - const answers = await inquirer.prompt<{password: string}>([ - { - name: "password", - type: "password", - message: "Enter the keystore(s) password", - }, - ]); - - return answers.password; } + + const answers = await inquirer.prompt<{password: string}>([ + { + name: "password", + type: "password", + message: "Enter the keystore(s) password", + }, + ]); + + return answers.password; } /** diff --git a/packages/cli/src/cmds/validator/signers/index.ts b/packages/cli/src/cmds/validator/signers/index.ts index c155b52d186a..950be2db1cf5 100644 --- a/packages/cli/src/cmds/validator/signers/index.ts +++ b/packages/cli/src/cmds/validator/signers/index.ts @@ -53,13 +53,12 @@ export async function getSignersFromArgs( // Using a remote signer with TESTNETS if (args["externalSigner.pubkeys"] || args["externalSigner.fetch"]) { return getRemoteSigners(args); - } else { - return indexes.map((index) => ({type: SignerType.Local, secretKey: interopSecretKey(index)})); } + return indexes.map((index) => ({type: SignerType.Local, secretKey: interopSecretKey(index)})); } // UNSAFE, ONLY USE FOR TESTNETS - Derive keys directly from a mnemonic - else if (args.fromMnemonic) { + if (args.fromMnemonic) { if (network === defaultNetwork) { throw new YargsError("fromMnemonic must only be used in testnets"); } @@ -76,7 +75,7 @@ export async function getSignersFromArgs( } // Import JSON keystores and run - else if (args.importKeystores) { + if (args.importKeystores) { const keystoreDefinitions = importKeystoreDefinitionsFromExternalDir({ keystoresPath: args.importKeystores, password: await readPassphraseOrPrompt(args), @@ -98,52 +97,50 @@ export async function getSignersFromArgs( ignoreLockFile: args.force, onDecrypt: needle, cacheFilePath: path.join(accountPaths.cacheDir, "imported_keystores.cache"), - disableThreadPool: args["disableKeystoresThreadPool"], + disableThreadPool: args.disableKeystoresThreadPool, logger, signal, }); } // Remote keys are declared manually or will be fetched from external signer - else if (args["externalSigner.pubkeys"] || args["externalSigner.fetch"]) { + if (args["externalSigner.pubkeys"] || args["externalSigner.fetch"]) { return getRemoteSigners(args); } // Read keys from local account manager - else { - const persistedKeysBackend = new PersistedKeysBackend(accountPaths); - - // Read and decrypt local keystores, imported via keymanager api or import cmd - const keystoreDefinitions = persistedKeysBackend.readAllKeystores(); - - const needle = showProgress({ - total: keystoreDefinitions.length, - frequencyMs: KEYSTORE_IMPORT_PROGRESS_MS, - signal, - progress: ({ratePerSec, percentage, current, total}) => { - logger.info( - `${percentage.toFixed(0)}% of local keystores imported. current=${current} total=${total} rate=${( - ratePerSec * 60 - ).toFixed(2)}keys/m` - ); - }, - }); - - const keystoreSigners = await decryptKeystoreDefinitions(keystoreDefinitions, { - ignoreLockFile: args.force, - onDecrypt: needle, - cacheFilePath: path.join(accountPaths.cacheDir, "local_keystores.cache"), - disableThreadPool: args["disableKeystoresThreadPool"], - logger, - signal, - }); - - // Read local remote keys, imported via keymanager api - const signerDefinitions = persistedKeysBackend.readAllRemoteKeys(); - const remoteSigners = signerDefinitions.map(({url, pubkey}): Signer => ({type: SignerType.Remote, url, pubkey})); - - return [...keystoreSigners, ...remoteSigners]; - } + const persistedKeysBackend = new PersistedKeysBackend(accountPaths); + + // Read and decrypt local keystores, imported via keymanager api or import cmd + const keystoreDefinitions = persistedKeysBackend.readAllKeystores(); + + const needle = showProgress({ + total: keystoreDefinitions.length, + frequencyMs: KEYSTORE_IMPORT_PROGRESS_MS, + signal, + progress: ({ratePerSec, percentage, current, total}) => { + logger.info( + `${percentage.toFixed(0)}% of local keystores imported. current=${current} total=${total} rate=${( + ratePerSec * 60 + ).toFixed(2)}keys/m` + ); + }, + }); + + const keystoreSigners = await decryptKeystoreDefinitions(keystoreDefinitions, { + ignoreLockFile: args.force, + onDecrypt: needle, + cacheFilePath: path.join(accountPaths.cacheDir, "local_keystores.cache"), + disableThreadPool: args.disableKeystoresThreadPool, + logger, + signal, + }); + + // Read local remote keys, imported via keymanager api + const signerDefinitions = persistedKeysBackend.readAllRemoteKeys(); + const remoteSigners = signerDefinitions.map(({url, pubkey}): Signer => ({type: SignerType.Remote, url, pubkey})); + + return [...keystoreSigners, ...remoteSigners]; } export function getSignerPubkeyHex(signer: Signer): string { diff --git a/packages/cli/src/cmds/validator/signers/logSigners.ts b/packages/cli/src/cmds/validator/signers/logSigners.ts index 20aa50d25ff6..d245ee75883a 100644 --- a/packages/cli/src/cmds/validator/signers/logSigners.ts +++ b/packages/cli/src/cmds/validator/signers/logSigners.ts @@ -60,11 +60,11 @@ function groupRemoteSignersByUrl(remoteSigners: SignerRemote[]): {url: string; p * is connected with fetching enabled, but otherwise exit the process and suggest a different configuration. */ export function warnOrExitNoSigners(args: IValidatorCliArgs, logger: Pick): void { - if (args["keymanager"] && !args["externalSigner.fetch"]) { + if (args.keymanager && !args["externalSigner.fetch"]) { logger.warn("No local keystores or remote keys found with current args, expecting to be added via keymanager"); - } else if (!args["keymanager"] && args["externalSigner.fetch"]) { + } else if (!args.keymanager && args["externalSigner.fetch"]) { logger.warn("No remote keys found with current args, expecting to be added to external signer and fetched later"); - } else if (args["keymanager"] && args["externalSigner.fetch"]) { + } else if (args.keymanager && args["externalSigner.fetch"]) { logger.warn( "No local keystores or remote keys found with current args, expecting to be added via keymanager or fetched from external signer later" ); diff --git a/packages/cli/src/cmds/validator/slashingProtection/export.ts b/packages/cli/src/cmds/validator/slashingProtection/export.ts index c18b020f5782..f57f9d3ec0bd 100644 --- a/packages/cli/src/cmds/validator/slashingProtection/export.ts +++ b/packages/cli/src/cmds/validator/slashingProtection/export.ts @@ -43,8 +43,7 @@ export const exportCmd: CliCommand // Parse ["0x11,0x22"] to ["0x11", "0x22"] pubkeys - .map((item) => item.split(",")) - .flat(1) + .flatMap((item) => item.split(",")) .map(ensure0xPrefix), }, }, diff --git a/packages/cli/src/cmds/validator/voluntaryExit.ts b/packages/cli/src/cmds/validator/voluntaryExit.ts index 02f1591b59ed..5b4cfdf270f0 100644 --- a/packages/cli/src/cmds/validator/voluntaryExit.ts +++ b/packages/cli/src/cmds/validator/voluntaryExit.ts @@ -59,8 +59,7 @@ If no `pubkeys` are provided, it will exit all validators that have been importe coerce: (pubkeys: string[]): string[] => // Parse ["0x11,0x22"] to ["0x11", "0x22"] pubkeys - .map((item) => item.split(",")) - .flat(1) + .flatMap((item) => item.split(",")) .map(ensure0xPrefix), }, @@ -151,7 +150,7 @@ async function processVoluntaryExit( const voluntaryExit: phase0.VoluntaryExit = {epoch: exitEpoch, validatorIndex: index}; const signingRoot = computeSigningRoot(ssz.phase0.VoluntaryExit, voluntaryExit, domain); - let signature; + let signature: Signature; switch (signer.type) { case SignerType.Local: signature = signer.secretKey.sign(signingRoot); @@ -192,18 +191,15 @@ function selectSignersToExit(args: VoluntaryExitArgs, signers: Signer[]): Signer const signer = signersByPubkey.get(pubkey); if (!signer) { throw new YargsError(`Unknown pubkey ${pubkey}`); - } else { - selectedSigners.push({pubkey, signer}); } + selectedSigners.push({pubkey, signer}); } return selectedSigners; - } else { - return signersWithPubkey; } + return signersWithPubkey; } -// eslint-disable-next-line @typescript-eslint/explicit-function-return-type async function resolveValidatorIndexes(client: ApiClient, signersToExit: SignerPubkey[]) { const pubkeys = signersToExit.map(({pubkey}) => pubkey); diff --git a/packages/cli/src/config/peerId.ts b/packages/cli/src/config/peerId.ts index d4906c716ba7..91390696c2f4 100644 --- a/packages/cli/src/config/peerId.ts +++ b/packages/cli/src/config/peerId.ts @@ -1,7 +1,11 @@ -import type {PeerId} from "@libp2p/interface"; -import {peerIdFromBytes} from "@libp2p/peer-id"; -import {createFromPrivKey, createFromPubKey} from "@libp2p/peer-id-factory"; -import {unmarshalPrivateKey, unmarshalPublicKey} from "@libp2p/crypto/keys"; +import type {PrivateKey} from "@libp2p/interface"; +import {peerIdFromPrivateKey, peerIdFromString} from "@libp2p/peer-id"; +import { + privateKeyFromProtobuf, + privateKeyToProtobuf, + publicKeyFromProtobuf, + publicKeyToProtobuf, +} from "@libp2p/crypto/keys"; import {fromString as uint8ArrayFromString} from "uint8arrays/from-string"; import {toString as uint8ArrayToString} from "uint8arrays/to-string"; import {writeFile600Perm, readFile} from "../util/index.js"; @@ -9,45 +13,38 @@ import {writeFile600Perm, readFile} from "../util/index.js"; // Peer id to / from JSON taken from peer-id-factory // See https://github.com/libp2p/js-libp2p-peer-id/pull/9 for more details -async function createFromParts(multihash: Uint8Array, privKey?: Uint8Array, pubKey?: Uint8Array): Promise { - if (privKey != null) { - const key = await unmarshalPrivateKey(privKey); +// after libp2p 2.0, PeerId no longer contains a private key +// but we retain a semi-backwards-compatible on-disk format +// Note: all properties are required +export type PeerIdJSON = {id: string; pubKey: string; privKey: string}; - return createFromPrivKey(key); - } else if (pubKey != null) { - const key = unmarshalPublicKey(pubKey); - - return createFromPubKey(key); - } - - return peerIdFromBytes(multihash); -} - -export type PeerIdJSON = {id: string; pubKey?: string; privKey?: string}; - -export function exportToJSON(peerId: PeerId, excludePrivateKey?: boolean): PeerIdJSON { +export function exportToJSON(privateKey: PrivateKey): PeerIdJSON { + const publicKey = privateKey.publicKey; + const peerId = peerIdFromPrivateKey(privateKey); return { - id: uint8ArrayToString(peerId.toBytes(), "base58btc"), - pubKey: peerId.publicKey != null ? uint8ArrayToString(peerId.publicKey, "base64pad") : undefined, - privKey: - excludePrivateKey === true || peerId.privateKey == null - ? undefined - : uint8ArrayToString(peerId.privateKey, "base64pad"), + id: peerId.toString(), + pubKey: uint8ArrayToString(publicKeyToProtobuf(publicKey), "base64pad"), + privKey: uint8ArrayToString(privateKeyToProtobuf(privateKey), "base64pad"), }; } -export async function createFromJSON(obj: PeerIdJSON): Promise { - return createFromParts( - uint8ArrayFromString(obj.id, "base58btc"), - obj.privKey != null ? uint8ArrayFromString(obj.privKey, "base64pad") : undefined, - obj.pubKey != null ? uint8ArrayFromString(obj.pubKey, "base64pad") : undefined - ); +export function createFromJSON(obj: PeerIdJSON): PrivateKey { + const privateKey = privateKeyFromProtobuf(uint8ArrayFromString(obj.privKey, "base64pad")); + const publicKey = publicKeyFromProtobuf(uint8ArrayFromString(obj.pubKey, "base64pad")); + const peerId = peerIdFromString(obj.id); + if (!publicKey.equals(privateKey.publicKey)) { + throw new Error("Public key does not match private key"); + } + if (!peerId.equals(peerIdFromPrivateKey(privateKey))) { + throw new Error("Peer ID does not match private key"); + } + return privateKey; } -export function writePeerId(filepath: string, peerId: PeerId): void { - writeFile600Perm(filepath, exportToJSON(peerId)); +export function writePrivateKey(filepath: string, privateKey: PrivateKey): void { + writeFile600Perm(filepath, exportToJSON(privateKey)); } -export async function readPeerId(filepath: string): Promise { +export function readPrivateKey(filepath: string): PrivateKey { return createFromJSON(readFile(filepath)); } diff --git a/packages/cli/src/index.ts b/packages/cli/src/index.ts index 5cdccbacfeec..0d509af17ab0 100644 --- a/packages/cli/src/index.ts +++ b/packages/cli/src/index.ts @@ -14,7 +14,6 @@ void lodestar // Show command help message when no command is provided if (msg.includes("Not enough non-option arguments")) { yarg.showHelp(); - // eslint-disable-next-line no-console console.log("\n"); } } @@ -22,7 +21,6 @@ void lodestar const errorMessage = err !== undefined ? (err instanceof YargsError ? err.message : err.stack) : msg || "Unknown error"; - // eslint-disable-next-line no-console console.error(` ✖ ${errorMessage}\n`); process.exit(1); }) diff --git a/packages/cli/src/networks/dev.ts b/packages/cli/src/networks/dev.ts index ff8afc127dcc..6ce87273b3cb 100644 --- a/packages/cli/src/networks/dev.ts +++ b/packages/cli/src/networks/dev.ts @@ -1,8 +1,9 @@ import {gnosisChainConfig} from "@lodestar/config/networks"; import {minimalChainConfig, mainnetChainConfig} from "@lodestar/config/configs"; import {ACTIVE_PRESET, PresetName} from "@lodestar/params"; +import {ChainConfig} from "@lodestar/config"; -let chainConfig; +let chainConfig: ChainConfig; switch (ACTIVE_PRESET) { case PresetName.mainnet: chainConfig = mainnetChainConfig; diff --git a/packages/cli/src/networks/index.ts b/packages/cli/src/networks/index.ts index 0831b78cd2f6..e2fc9dd621b6 100644 --- a/packages/cli/src/networks/index.ts +++ b/packages/cli/src/networks/index.ts @@ -109,7 +109,6 @@ export async function getNetworkBootnodes(network: NetworkName): Promise = { // Enable all if (namespaces.includes(enabledAll)) return allNamespaces; // Parse ["debug,lodestar"] to ["debug", "lodestar"] - return namespaces.map((val) => val.split(",")).flat(1); + return namespaces.flatMap((val) => val.split(",")); }, }, diff --git a/packages/cli/src/options/beaconNodeOptions/builder.ts b/packages/cli/src/options/beaconNodeOptions/builder.ts index 2c89cbad89d2..d0e4089dd81c 100644 --- a/packages/cli/src/options/beaconNodeOptions/builder.ts +++ b/packages/cli/src/options/beaconNodeOptions/builder.ts @@ -18,7 +18,7 @@ export function parseArgs(args: ExecutionBuilderArgs): IBeaconNodeOptions["execu } return { - enabled: args["builder"], + enabled: args.builder, url: args["builder.url"] ?? defaultExecutionBuilderHttpOpts.url, timeout: args["builder.timeout"], faultInspectionWindow: args["builder.faultInspectionWindow"], diff --git a/packages/cli/src/options/beaconNodeOptions/chain.ts b/packages/cli/src/options/beaconNodeOptions/chain.ts index aae97b6db68f..78ffd47da8f4 100644 --- a/packages/cli/src/options/beaconNodeOptions/chain.ts +++ b/packages/cli/src/options/beaconNodeOptions/chain.ts @@ -36,13 +36,13 @@ export type ChainArgs = { export function parseArgs(args: ChainArgs): IBeaconNodeOptions["chain"] { return { - suggestedFeeRecipient: args["suggestedFeeRecipient"], + suggestedFeeRecipient: args.suggestedFeeRecipient, blsVerifyAllMultiThread: args["chain.blsVerifyAllMultiThread"], blsVerifyAllMainThread: args["chain.blsVerifyAllMainThread"], disableBlsBatchVerify: args["chain.disableBlsBatchVerify"], persistProducedBlocks: args["chain.persistProducedBlocks"], persistInvalidSszObjects: args["chain.persistInvalidSszObjects"], - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-explicit-any + // biome-ignore lint/suspicious/noExplicitAny: persistInvalidSszObjectsDir: undefined as any, proposerBoost: args["chain.proposerBoost"], proposerBoostReorg: args["chain.proposerBoostReorg"], @@ -55,8 +55,8 @@ export function parseArgs(args: ChainArgs): IBeaconNodeOptions["chain"] { trustedSetup: args["chain.trustedSetup"], safeSlotsToImportOptimistically: args["safe-slots-to-import-optimistically"], archiveStateEpochFrequency: args["chain.archiveStateEpochFrequency"], - emitPayloadAttributes: args["emitPayloadAttributes"], - broadcastValidationStrictness: args["broadcastValidationStrictness"], + emitPayloadAttributes: args.emitPayloadAttributes, + broadcastValidationStrictness: args.broadcastValidationStrictness, minSameMessageSignatureSetsToBatch: args["chain.minSameMessageSignatureSetsToBatch"] ?? defaultOptions.chain.minSameMessageSignatureSetsToBatch, maxShufflingCacheEpochs: args["chain.maxShufflingCacheEpochs"] ?? defaultOptions.chain.maxShufflingCacheEpochs, diff --git a/packages/cli/src/options/beaconNodeOptions/eth1.ts b/packages/cli/src/options/beaconNodeOptions/eth1.ts index 46654cca6b2e..f12a1704dec7 100644 --- a/packages/cli/src/options/beaconNodeOptions/eth1.ts +++ b/packages/cli/src/options/beaconNodeOptions/eth1.ts @@ -25,14 +25,12 @@ export function parseArgs(args: Eth1Args & Partial): IBeaco // jwt auth mechanism. if (providerUrls === undefined && args["execution.urls"]) { providerUrls = args["execution.urls"]; - jwtSecretHex = args["jwtSecret"] - ? extractJwtHexSecret(fs.readFileSync(args["jwtSecret"], "utf-8").trim()) - : undefined; - jwtId = args["jwtId"]; + jwtSecretHex = args.jwtSecret ? extractJwtHexSecret(fs.readFileSync(args.jwtSecret, "utf-8").trim()) : undefined; + jwtId = args.jwtId; } return { - enabled: args["eth1"], + enabled: args.eth1, providerUrls, jwtSecretHex, jwtId, @@ -59,7 +57,7 @@ export const options: CliCommandOptions = { string: true, coerce: (urls: string[]): string[] => // Parse ["url1,url2"] to ["url1", "url2"] - urls.map((item) => item.split(",")).flat(1), + urls.flatMap((item) => item.split(",")), group: "eth1", }, diff --git a/packages/cli/src/options/beaconNodeOptions/execution.ts b/packages/cli/src/options/beaconNodeOptions/execution.ts index 85b81a5e708b..2d32ee2ae786 100644 --- a/packages/cli/src/options/beaconNodeOptions/execution.ts +++ b/packages/cli/src/options/beaconNodeOptions/execution.ts @@ -30,10 +30,8 @@ export function parseArgs(args: ExecutionEngineArgs): IBeaconNodeOptions["execut * jwtSecret is parsed as hex instead of bytes because the merge with defaults * in beaconOptions messes up the bytes array as as index => value object */ - jwtSecretHex: args["jwtSecret"] - ? extractJwtHexSecret(fs.readFileSync(args["jwtSecret"], "utf-8").trim()) - : undefined, - jwtId: args["jwtId"], + jwtSecretHex: args.jwtSecret ? extractJwtHexSecret(fs.readFileSync(args.jwtSecret, "utf-8").trim()) : undefined, + jwtId: args.jwtId, }; } @@ -45,7 +43,7 @@ export const options: CliCommandOptions = { string: true, coerce: (urls: string[]): string[] => // Parse ["url1,url2"] to ["url1", "url2"] - urls.map((item) => item.split(",")).flat(1), + urls.flatMap((item) => item.split(",")), group: "execution", }, diff --git a/packages/cli/src/options/beaconNodeOptions/metrics.ts b/packages/cli/src/options/beaconNodeOptions/metrics.ts index ba12a7546eae..ded63b7dc24d 100644 --- a/packages/cli/src/options/beaconNodeOptions/metrics.ts +++ b/packages/cli/src/options/beaconNodeOptions/metrics.ts @@ -9,7 +9,7 @@ export type MetricsArgs = { export function parseArgs(args: MetricsArgs): IBeaconNodeOptions["metrics"] { return { - enabled: args["metrics"], + enabled: args.metrics, port: args["metrics.port"], address: args["metrics.address"], }; diff --git a/packages/cli/src/options/beaconNodeOptions/network.ts b/packages/cli/src/options/beaconNodeOptions/network.ts index bfe9c7710e86..cfd109bdc50a 100644 --- a/packages/cli/src/options/beaconNodeOptions/network.ts +++ b/packages/cli/src/options/beaconNodeOptions/network.ts @@ -57,18 +57,17 @@ function validateMultiaddrArg>(args } } -// eslint-disable-next-line @typescript-eslint/explicit-function-return-type export function parseListenArgs(args: NetworkArgs) { // If listenAddress is explicitly set, use it // If listenAddress6 is not set, use defaultListenAddress const listenAddress = args.listenAddress ?? (args.listenAddress6 ? undefined : defaultListenAddress); - const port = listenAddress ? args.port ?? defaultP2pPort : undefined; - const discoveryPort = listenAddress ? args.discoveryPort ?? args.port ?? defaultP2pPort : undefined; + const port = listenAddress ? (args.port ?? defaultP2pPort) : undefined; + const discoveryPort = listenAddress ? (args.discoveryPort ?? args.port ?? defaultP2pPort) : undefined; // Only use listenAddress6 if it is explicitly set const listenAddress6 = args.listenAddress6; - const port6 = listenAddress6 ? args.port6 ?? defaultP2pPort6 : undefined; - const discoveryPort6 = listenAddress6 ? args.discoveryPort6 ?? args.port6 ?? defaultP2pPort6 : undefined; + const port6 = listenAddress6 ? (args.port6 ?? defaultP2pPort6) : undefined; + const discoveryPort6 = listenAddress6 ? (args.discoveryPort6 ?? args.port6 ?? defaultP2pPort6) : undefined; return {listenAddress, port, discoveryPort, listenAddress6, port6, discoveryPort6}; } @@ -101,21 +100,21 @@ export function parseArgs(args: NetworkArgs): IBeaconNodeOptions["network"] { const bindMu6 = listenAddress6 ? `${muArgs.listenAddress6}${muArgs.discoveryPort6}` : undefined; const localMu6 = listenAddress6 ? `${muArgs.listenAddress6}${muArgs.port6}` : undefined; - const targetPeers = args["targetPeers"]; + const targetPeers = args.targetPeers; const maxPeers = args["network.maxPeers"] ?? (targetPeers !== undefined ? Math.floor(targetPeers * 1.1) : undefined); if (targetPeers != null && maxPeers != null && targetPeers > maxPeers) { throw new YargsError("network.maxPeers must be greater than or equal to targetPeers"); } // Set discv5 opts to null to disable only if explicitly disabled - const enableDiscv5 = args["discv5"] ?? true; + const enableDiscv5 = args.discv5 ?? true; // TODO: Okay to set to empty array? - const bootEnrs = args["bootnodes"] ?? []; + const bootEnrs = args.bootnodes ?? []; // throw if user-provided enrs are invalid for (const enrStr of bootEnrs) { try { ENR.decodeTxt(enrStr); - } catch (e) { + } catch (_e) { throw new YargsError(`Provided ENR in bootnodes is invalid:\n ${enrStr}`); } } @@ -129,17 +128,17 @@ export function parseArgs(args: NetworkArgs): IBeaconNodeOptions["network"] { ip6: bindMu6, }, bootEnrs, - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-explicit-any + // biome-ignore lint/suspicious/noExplicitAny: enr: undefined as any, } : null, maxPeers: maxPeers ?? defaultOptions.network.maxPeers, targetPeers: targetPeers ?? defaultOptions.network.targetPeers, localMultiaddrs: [localMu, localMu6].filter(Boolean) as string[], - subscribeAllSubnets: args["subscribeAllSubnets"], + subscribeAllSubnets: args.subscribeAllSubnets, slotsToSubscribeBeforeAggregatorDuty: - args["slotsToSubscribeBeforeAggregatorDuty"] ?? defaultOptions.network.slotsToSubscribeBeforeAggregatorDuty, - disablePeerScoring: args["disablePeerScoring"], + args.slotsToSubscribeBeforeAggregatorDuty ?? defaultOptions.network.slotsToSubscribeBeforeAggregatorDuty, + disablePeerScoring: args.disablePeerScoring, connectToDiscv5Bootnodes: args["network.connectToDiscv5Bootnodes"], discv5FirstQueryDelayMs: args["network.discv5FirstQueryDelayMs"], dontSendGossipAttestationsToForkchoice: args["network.dontSendGossipAttestationsToForkchoice"], @@ -149,7 +148,7 @@ export function parseArgs(args: NetworkArgs): IBeaconNodeOptions["network"] { gossipsubDHigh: args["network.gossipsubDHigh"], gossipsubAwaitHandler: args["network.gossipsubAwaitHandler"], disableFloodPublish: args["network.disableFloodPublish"], - mdns: args["mdns"], + mdns: args.mdns, rateLimitMultiplier: args["network.rateLimitMultiplier"], maxGossipTopicConcurrency: args["network.maxGossipTopicConcurrency"], useWorker: args["network.useWorker"], @@ -212,12 +211,12 @@ export const options: CliCommandOptions = { bootnodes: { type: "array", description: "Bootnodes for discv5 discovery", - defaultDescription: JSON.stringify((defaultOptions.network.discv5 || {}).bootEnrs || []), + defaultDescription: JSON.stringify(defaultOptions.network.discv5?.bootEnrs || []), group: "network", // Each bootnode entry could be comma separated, just deserialize it into a single array // as comma separated entries are generally most friendly in ansible kind of setups, i.e. // [ "en1", "en2,en3" ] => [ 'en1', 'en2', 'en3' ] - coerce: (args: string[]) => args.map((item) => item.split(",")).flat(1), + coerce: (args: string[]) => args.flatMap((item) => item.split(",")), }, targetPeers: { diff --git a/packages/cli/src/options/logOptions.ts b/packages/cli/src/options/logOptions.ts index b45057a4532f..09eb5b1d56cb 100644 --- a/packages/cli/src/options/logOptions.ts +++ b/packages/cli/src/options/logOptions.ts @@ -65,6 +65,6 @@ export const logOptions: CliCommandOptions = { description: "Set log level for a specific module by name: 'chain=debug' or 'network=debug,chain=debug'", type: "array", string: true, - coerce: (args: string[]) => args.map((item) => item.split(",")).flat(1), + coerce: (args: string[]) => args.flatMap((item) => item.split(",")), }, }; diff --git a/packages/cli/src/options/paramsOptions.ts b/packages/cli/src/options/paramsOptions.ts index b35a15e3c9b6..bd89ffa77d9e 100644 --- a/packages/cli/src/options/paramsOptions.ts +++ b/packages/cli/src/options/paramsOptions.ts @@ -25,14 +25,14 @@ export function parseBeaconParamsArgs(args: Record): IB } const paramsOptionsByName = ObjectKeys(chainConfigTypes).reduce( - (options: Record, key): Record => ({ - ...options, - [getArgKey(key)]: { + (options: Record, key): Record => { + options[getArgKey(key)] = { hidden: true, type: "string", group: "params", - }, - }), + }; + return options; + }, {} ); diff --git a/packages/cli/src/util/file.ts b/packages/cli/src/util/file.ts index 99e93a96dc59..a18768d456b9 100644 --- a/packages/cli/src/util/file.ts +++ b/packages/cli/src/util/file.ts @@ -13,7 +13,6 @@ export const yamlSchema = FAILSAFE_SCHEMA.extend({ new Type("tag:yaml.org,2002:str", { kind: "scalar", construct: function construct(data) { - // eslint-disable-next-line @typescript-eslint/no-unsafe-return return data !== null ? data : ""; }, }), @@ -105,9 +104,8 @@ export function readFileIfExists(filepath: string, acceptedFormats?: string[] } catch (e) { if ((e as {code: string}).code === "ENOENT") { return null; - } else { - throw e; } + throw e; } } @@ -142,9 +140,8 @@ export async function downloadOrLoadFile(pathOrUrl: string): Promise if (isUrl(pathOrUrl)) { const res = await got.get(pathOrUrl, {encoding: "binary"}); return res.rawBody; - } else { - return fs.promises.readFile(pathOrUrl); } + return fs.promises.readFile(pathOrUrl); } /** diff --git a/packages/cli/src/util/format.ts b/packages/cli/src/util/format.ts index a86ca0662a9f..e8361649824a 100644 --- a/packages/cli/src/util/format.ts +++ b/packages/cli/src/util/format.ts @@ -36,8 +36,8 @@ export function parseRange(range: string): number[] { const [from, to] = range.split("..").map((n) => parseInt(n)); - if (isNaN(from)) throw Error(`Invalid range from isNaN '${range}'`); - if (isNaN(to)) throw Error(`Invalid range to isNaN '${range}'`); + if (Number.isNaN(from)) throw Error(`Invalid range from isNaN '${range}'`); + if (Number.isNaN(to)) throw Error(`Invalid range to isNaN '${range}'`); if (from > to) throw Error(`Invalid range from > to '${range}'`); const arr: number[] = []; diff --git a/packages/cli/src/util/fs.ts b/packages/cli/src/util/fs.ts index 37464c877b85..17501bea78c9 100644 --- a/packages/cli/src/util/fs.ts +++ b/packages/cli/src/util/fs.ts @@ -21,7 +21,8 @@ export function unlinkSyncMaybe(filepath: string): boolean { } catch (e) { const {code} = e as ErrorFs; if (code === "ENOENT") return false; - else throw e; + + throw e; } } @@ -37,7 +38,8 @@ export function rmdirSyncMaybe(dirpath: string): boolean { // about error codes https://nodejs.org/api/fs.html#fspromisesrmdirpath-options // ENOENT error on Windows and an ENOTDIR if (code === "ENOENT" || code === "ENOTDIR") return false; - else throw e; + + throw e; } } diff --git a/packages/cli/src/util/gitData/gitDataPath.ts b/packages/cli/src/util/gitData/gitDataPath.ts index e243ca433f2d..1ad3104aafc6 100644 --- a/packages/cli/src/util/gitData/gitDataPath.ts +++ b/packages/cli/src/util/gitData/gitDataPath.ts @@ -4,7 +4,6 @@ import {fileURLToPath} from "node:url"; // Global variable __dirname no longer available in ES6 modules. // Solutions: https://stackoverflow.com/questions/46745014/alternative-for-dirname-in-node-js-when-using-es6-modules -// eslint-disable-next-line @typescript-eslint/naming-convention const __dirname = path.dirname(fileURLToPath(import.meta.url)); // Persist git data and distribute through NPM so CLI consumers can know exactly diff --git a/packages/cli/src/util/gitData/index.ts b/packages/cli/src/util/gitData/index.ts index 96c5e4bbaef2..0720d39d9e30 100644 --- a/packages/cli/src/util/gitData/index.ts +++ b/packages/cli/src/util/gitData/index.ts @@ -11,7 +11,7 @@ export function readAndGetGitData(): GitData { let persistedGitData: Partial; try { persistedGitData = readGitDataFile(); - } catch (e) { + } catch (_e) { persistedGitData = {}; } @@ -23,13 +23,13 @@ export function readAndGetGitData(): GitData { branch: currentGitData.branch && currentGitData.branch.length > 0 ? currentGitData.branch - : persistedGitData.branch ?? "", + : (persistedGitData.branch ?? ""), commit: currentGitData.commit && currentGitData.commit.length > 0 ? currentGitData.commit - : persistedGitData.commit ?? "", + : (persistedGitData.commit ?? ""), }; - } catch (e) { + } catch (_e) { return { branch: "", commit: "", @@ -49,7 +49,7 @@ export function getGitData(): GitData { function getBranch(): string { try { return shellSilent("git rev-parse --abbrev-ref HEAD"); - } catch (e) { + } catch (_e) { return ""; } } @@ -58,7 +58,7 @@ function getBranch(): string { function getCommit(): string { try { return shellSilent("git rev-parse --verify HEAD"); - } catch (e) { + } catch (_e) { return ""; } } diff --git a/packages/cli/src/util/jwt.ts b/packages/cli/src/util/jwt.ts index e77e9e692cd6..b79b0a0dea7f 100644 --- a/packages/cli/src/util/jwt.ts +++ b/packages/cli/src/util/jwt.ts @@ -2,7 +2,7 @@ export function extractJwtHexSecret(jwtSecretContents: string): string { const hexPattern = new RegExp(/^(0x|0X)?(?[a-fA-F0-9]+)$/, "g"); const jwtSecretHexMatch = hexPattern.exec(jwtSecretContents); const jwtSecret = jwtSecretHexMatch?.groups?.jwtSecret; - if (!jwtSecret || jwtSecret.length != 64) { + if (!jwtSecret || jwtSecret.length !== 64) { throw Error(`Need a valid 256 bit hex encoded secret ${jwtSecret} ${jwtSecretContents}`); } // Return the secret in proper hex format diff --git a/packages/cli/src/util/logger.ts b/packages/cli/src/util/logger.ts index e08029f5f1df..7a394c9ce25f 100644 --- a/packages/cli/src/util/logger.ts +++ b/packages/cli/src/util/logger.ts @@ -89,14 +89,16 @@ export function cleanOldLogFiles(args: LogArgs, paths: {defaultLogFilepath: stri .filter((logFileName) => shouldDeleteLogFile(prefix, extension, logFileName, args.logFileDailyRotate)) .map((logFileName) => path.join(folder, logFileName)); // delete files - toDelete.forEach((filename) => fs.unlinkSync(filename)); + for (const filename of toDelete) { + fs.unlinkSync(filename); + } } export function shouldDeleteLogFile(prefix: string, extension: string, logFileName: string, maxFiles: number): boolean { const maxDifferenceMs = maxFiles * 24 * 60 * 60 * 1000; const match = logFileName.match(new RegExp(`${prefix}-([0-9]{4}-[0-9]{2}-[0-9]{2}).${extension}`)); // if match[1] exists, it should be the date pattern of YYYY-MM-DD - if (match && match[1] && Date.now() - new Date(match[1]).getTime() > maxDifferenceMs) { + if (match?.[1] && Date.now() - new Date(match[1]).getTime() > maxDifferenceMs) { return true; } return false; diff --git a/packages/cli/src/util/object.ts b/packages/cli/src/util/object.ts index d37f41ea6655..7f2e8a49d6c8 100644 --- a/packages/cli/src/util/object.ts +++ b/packages/cli/src/util/object.ts @@ -3,10 +3,10 @@ import {RecursivePartial} from "@lodestar/utils"; /** * Removes (mutates) all properties with a value === undefined, recursively */ -// eslint-disable-next-line @typescript-eslint/no-explicit-any + +// biome-ignore lint/suspicious/noExplicitAny: export function removeUndefinedRecursive(obj: T): RecursivePartial { for (const key of Object.keys(obj)) { - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment const value = obj[key]; if (value && typeof value === "object") removeUndefinedRecursive(value); else if (value === undefined) delete obj[key]; diff --git a/packages/cli/src/util/process.ts b/packages/cli/src/util/process.ts index cd040bdffb55..e274d782b8ba 100644 --- a/packages/cli/src/util/process.ts +++ b/packages/cli/src/util/process.ts @@ -8,7 +8,6 @@ const exitSignals = ["SIGTERM", "SIGINT"] as NodeJS.Signals[]; */ export function onGracefulShutdown( cleanUpFunction: () => Promise, - // eslint-disable-next-line no-console logFn: (msg: string) => void = console.log ): void { for (const signal of exitSignals) { diff --git a/packages/cli/src/util/proposerConfig.ts b/packages/cli/src/util/proposerConfig.ts index 509dc8213df1..2c12ce8f8524 100644 --- a/packages/cli/src/util/proposerConfig.ts +++ b/packages/cli/src/util/proposerConfig.ts @@ -1,5 +1,3 @@ -/* eslint-disable @typescript-eslint/naming-convention */ - import fs from "node:fs"; import path from "node:path"; import {ValidatorProposerConfig} from "@lodestar/validator"; diff --git a/packages/cli/src/util/types.ts b/packages/cli/src/util/types.ts index ced3bf34b1f6..bf194170f3e2 100644 --- a/packages/cli/src/util/types.ts +++ b/packages/cli/src/util/types.ts @@ -1,7 +1,8 @@ /** * Typed `Object.keys(o: T)` function, returning `(keyof T)[]` */ -// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/naming-convention + +// biome-ignore lint/suspicious/noExplicitAny: export function ObjectKeys(o: T): (keyof T)[] { return Object.keys(o); } diff --git a/packages/cli/src/util/version.ts b/packages/cli/src/util/version.ts index 4752856e5b1d..624412107603 100644 --- a/packages/cli/src/util/version.ts +++ b/packages/cli/src/util/version.ts @@ -6,7 +6,6 @@ import {readAndGetGitData} from "./gitData/index.js"; // Global variable __dirname no longer available in ES6 modules. // Solutions: https://stackoverflow.com/questions/46745014/alternative-for-dirname-in-node-js-when-using-es6-modules -// eslint-disable-next-line @typescript-eslint/naming-convention const __dirname = path.dirname(fileURLToPath(import.meta.url)); type VersionJson = { diff --git a/packages/cli/test/e2e/blsToExecutionchange.test.ts b/packages/cli/test/e2e/blsToExecutionchange.test.ts index 51720e424c7e..57f32421d313 100644 --- a/packages/cli/test/e2e/blsToExecutionchange.test.ts +++ b/packages/cli/test/e2e/blsToExecutionchange.test.ts @@ -8,7 +8,7 @@ import {interopSecretKey} from "@lodestar/state-transition"; import {execCliCommand, spawnCliCommand, stopChildProcess} from "@lodestar/test-utils"; import {testFilesDir} from "../utils.js"; -describe("bLSToExecutionChange cmd", function () { +describe("bLSToExecutionChange cmd", () => { vi.setConfig({testTimeout: 60_000}); it("Perform bLSToExecutionChange", async () => { diff --git a/packages/cli/test/e2e/importFromFsDirect.test.ts b/packages/cli/test/e2e/importFromFsDirect.test.ts index 644635bc0ffe..6f612e84afe6 100644 --- a/packages/cli/test/e2e/importFromFsDirect.test.ts +++ b/packages/cli/test/e2e/importFromFsDirect.test.ts @@ -7,24 +7,17 @@ import {testFilesDir} from "../utils.js"; import {cachedPubkeysHex, cachedSeckeysHex} from "../utils/cachedKeys.js"; import {expectKeys, startValidatorWithKeyManager} from "../utils/validator.js"; -describe("import from fs same cmd as validate", function () { +describe("import from fs same cmd as validate", () => { vi.setConfig({testTimeout: 30_000}); const dataDir = path.join(testFilesDir, "import-and-validate-test"); const importFromDir = path.join(dataDir, "eth2.0_deposit_out"); const passphraseFilepath = path.join(importFromDir, "password.text"); - beforeAll(() => { + beforeAll(async () => { rimraf.sync(dataDir); rimraf.sync(importFromDir); - }); - - const passphrase = "AAAAAAAA0000000000"; - const keyCount = 2; - const pubkeys = cachedPubkeysHex.slice(0, keyCount); - const secretKeys = cachedSeckeysHex.slice(0, keyCount); - beforeAll(async () => { // Produce and encrypt keystores const keystoresStr = await getKeystoresStr(passphrase, secretKeys); @@ -35,6 +28,11 @@ describe("import from fs same cmd as validate", function () { } }); + const passphrase = "AAAAAAAA0000000000"; + const keyCount = 2; + const pubkeys = cachedPubkeysHex.slice(0, keyCount); + const secretKeys = cachedSeckeysHex.slice(0, keyCount); + // Check that there are not keys loaded without adding extra args `--importKeystores` it("run 'validator' there are no keys loaded", async () => { const {keymanagerClient, stopValidator} = await startValidatorWithKeyManager([], { diff --git a/packages/cli/test/e2e/importFromFsPreStep.test.ts b/packages/cli/test/e2e/importFromFsPreStep.test.ts index 7eebf2d4946e..437180ef07e5 100644 --- a/packages/cli/test/e2e/importFromFsPreStep.test.ts +++ b/packages/cli/test/e2e/importFromFsPreStep.test.ts @@ -8,7 +8,7 @@ import {testFilesDir} from "../utils.js"; import {cachedPubkeysHex, cachedSeckeysHex} from "../utils/cachedKeys.js"; import {expectKeys, startValidatorWithKeyManager} from "../utils/validator.js"; -describe("import from fs then validate", function () { +describe("import from fs then validate", () => { vi.setConfig({testTimeout: 30_000}); const dataDir = path.join(testFilesDir, "import-then-validate-test"); @@ -47,7 +47,7 @@ describe("import from fs then validate", function () { } }); - it("run 'validator list' and check pubkeys are imported", async function () { + it("run 'validator list' and check pubkeys are imported", async () => { fs.mkdirSync(path.join(dataDir, "keystores"), {recursive: true}); fs.mkdirSync(path.join(dataDir, "secrets"), {recursive: true}); @@ -58,7 +58,7 @@ describe("import from fs then validate", function () { } }); - it("run 'validator' check keys are loaded", async function () { + it("run 'validator' check keys are loaded", async () => { const {keymanagerClient, stopValidator} = await startValidatorWithKeyManager([], {dataDir}); onTestFinished(async () => { await stopValidator(); diff --git a/packages/cli/test/e2e/importKeystoresFromApi.test.ts b/packages/cli/test/e2e/importKeystoresFromApi.test.ts index b7abe1e8d293..7f71e2977a92 100644 --- a/packages/cli/test/e2e/importKeystoresFromApi.test.ts +++ b/packages/cli/test/e2e/importKeystoresFromApi.test.ts @@ -12,7 +12,7 @@ import {cachedPubkeysHex, cachedSeckeysHex} from "../utils/cachedKeys.js"; import {expectDeepEquals} from "../utils/runUtils.js"; import {expectKeys, startValidatorWithKeyManager} from "../utils/validator.js"; -describe("import keystores from api", function () { +describe("import keystores from api", () => { vi.setConfig({testTimeout: 30_000}); const dataDir = path.join(testFilesDir, "import-keystores-test"); @@ -30,7 +30,6 @@ describe("import keystores from api", function () { const genesisValidatorsRoot = "0x0000000000000000000000000000000000000000000000000000000000000000"; const slashingProtection: Interchange = { - /* eslint-disable @typescript-eslint/naming-convention */ metadata: { interchange_format_version: "5", genesis_validators_root: genesisValidatorsRoot, @@ -119,7 +118,7 @@ describe("import keystores from api", function () { }); }); - it("run 'validator' check keys are loaded + delete", async function () { + it("run 'validator' check keys are loaded + delete", async () => { const {keymanagerClient, stopValidator} = await startValidatorWithKeyManager([], {dataDir}); onTestFinished(async () => { await stopValidator(); @@ -139,7 +138,7 @@ describe("import keystores from api", function () { await expectKeys(keymanagerClient, [], "Wrong listKeys after deleting"); }); - it("different process check no keys are loaded", async function () { + it("different process check no keys are loaded", async () => { const {keymanagerClient, stopValidator} = await startValidatorWithKeyManager([], {dataDir}); onTestFinished(async () => { await stopValidator(); @@ -149,7 +148,7 @@ describe("import keystores from api", function () { await expectKeys(keymanagerClient, [], "Wrong listKeys"); }); - it("reject calls without bearerToken", async function () { + it("reject calls without bearerToken", async () => { const {stopValidator} = await startValidatorWithKeyManager([], {dataDir}); onTestFinished(async () => { await stopValidator(); diff --git a/packages/cli/test/e2e/importRemoteKeysFromApi.test.ts b/packages/cli/test/e2e/importRemoteKeysFromApi.test.ts index 0d7e4aa58da3..b66611cbf4f4 100644 --- a/packages/cli/test/e2e/importRemoteKeysFromApi.test.ts +++ b/packages/cli/test/e2e/importRemoteKeysFromApi.test.ts @@ -20,7 +20,7 @@ async function expectKeys(keymanagerClient: ApiClient, expectedPubkeys: string[] ); } -describe("import remoteKeys from api", function () { +describe("import remoteKeys from api", () => { vi.setConfig({testTimeout: 30_000}); const dataDir = path.join(testFilesDir, "import-remoteKeys-test"); @@ -65,7 +65,7 @@ describe("import remoteKeys from api", function () { ); }); - it("run 'validator' check keys are loaded + delete", async function () { + it("run 'validator' check keys are loaded + delete", async () => { const {keymanagerClient, stopValidator} = await startValidatorWithKeyManager([], {dataDir}); onTestFinished(async () => { await stopValidator(); @@ -86,7 +86,7 @@ describe("import remoteKeys from api", function () { await expectKeys(keymanagerClient, [], "Wrong listRemoteKeys after deleting"); }); - it("reject calls without bearerToken", async function () { + it("reject calls without bearerToken", async () => { const {stopValidator} = await startValidatorWithKeyManager([], {dataDir}); onTestFinished(async () => { await stopValidator(); diff --git a/packages/cli/test/e2e/propserConfigfromKeymanager.test.ts b/packages/cli/test/e2e/propserConfigfromKeymanager.test.ts index ffeb40460f40..2f25c82999a7 100644 --- a/packages/cli/test/e2e/propserConfigfromKeymanager.test.ts +++ b/packages/cli/test/e2e/propserConfigfromKeymanager.test.ts @@ -9,7 +9,7 @@ import {cachedPubkeysHex, cachedSeckeysHex} from "../utils/cachedKeys.js"; import {expectDeepEquals} from "../utils/runUtils.js"; import {startValidatorWithKeyManager} from "../utils/validator.js"; -describe("import keystores from api, test DefaultProposerConfig", function () { +describe("import keystores from api, test DefaultProposerConfig", () => { vi.setConfig({testTimeout: 30_000}); const dataDir = path.join(testFilesDir, "proposer-config-test"); @@ -39,7 +39,6 @@ describe("import keystores from api, test DefaultProposerConfig", function () { const genesisValidatorsRoot = "0x0000000000000000000000000000000000000000000000000000000000000000"; const slashingProtection: Interchange = { - /* eslint-disable @typescript-eslint/naming-convention */ metadata: { interchange_format_version: "5", genesis_validators_root: genesisValidatorsRoot, diff --git a/packages/cli/test/e2e/runDevCmd.test.ts b/packages/cli/test/e2e/runDevCmd.test.ts index 68dcca156d88..3beb68393815 100644 --- a/packages/cli/test/e2e/runDevCmd.test.ts +++ b/packages/cli/test/e2e/runDevCmd.test.ts @@ -4,7 +4,7 @@ import {config} from "@lodestar/config/default"; import {retry} from "@lodestar/utils"; import {spawnCliCommand, stopChildProcess} from "@lodestar/test-utils"; -describe("Run dev command", function () { +describe("Run dev command", () => { vi.setConfig({testTimeout: 30_000}); it("Run dev command with no --dataDir until beacon api is listening", async () => { diff --git a/packages/cli/test/e2e/validatorList.test.ts b/packages/cli/test/e2e/validatorList.test.ts index b6fe4da5faeb..7f86fb8ef89b 100644 --- a/packages/cli/test/e2e/validatorList.test.ts +++ b/packages/cli/test/e2e/validatorList.test.ts @@ -9,7 +9,7 @@ import {runCliCommand} from "@lodestar/test-utils"; import {testFilesDir} from "../utils.js"; import {getLodestarCli} from "../../src/cli.js"; -describe("cmds / validator", function () { +describe("cmds / validator", () => { vi.setConfig({testTimeout: 30_000}); const lodestar = getLodestarCli(); @@ -54,7 +54,7 @@ describe("cmds / validator", function () { expect(console.log).toHaveBeenCalledWith(`Imported keystore ${pkHex} ${keystoreFilepath}`); }); - it("should list validators", async function () { + it("should list validators", async () => { fs.mkdirSync(path.join(dataDir, "keystores"), {recursive: true}); fs.mkdirSync(path.join(dataDir, "secrets"), {recursive: true}); diff --git a/packages/cli/test/e2e/voluntaryExit.test.ts b/packages/cli/test/e2e/voluntaryExit.test.ts index 49499e891731..0abddcab7652 100644 --- a/packages/cli/test/e2e/voluntaryExit.test.ts +++ b/packages/cli/test/e2e/voluntaryExit.test.ts @@ -7,7 +7,7 @@ import {interopSecretKey} from "@lodestar/state-transition"; import {spawnCliCommand, execCliCommand, stopChildProcess} from "@lodestar/test-utils"; import {testFilesDir} from "../utils.js"; -describe("voluntaryExit cmd", function () { +describe("voluntaryExit cmd", () => { vi.setConfig({testTimeout: 60_000}); it("Perform a voluntary exit", async () => { @@ -78,10 +78,8 @@ describe("voluntaryExit cmd", function () { const validator = (await client.beacon.getStateValidator({stateId: "head", validatorId: pubkey})).value(); if (validator.status !== "active_exiting") { throw Error("Validator not exiting"); - } else { - // eslint-disable-next-line no-console - console.log(`Confirmed validator ${pubkey} = ${validator.status}`); } + console.log(`Confirmed validator ${pubkey} = ${validator.status}`); }, {retryDelay: 1000, retries: 20} ); diff --git a/packages/cli/test/e2e/voluntaryExitFromApi.test.ts b/packages/cli/test/e2e/voluntaryExitFromApi.test.ts index 664091d5c520..97ac06d5fc5c 100644 --- a/packages/cli/test/e2e/voluntaryExitFromApi.test.ts +++ b/packages/cli/test/e2e/voluntaryExitFromApi.test.ts @@ -8,7 +8,7 @@ import {spawnCliCommand, stopChildProcess} from "@lodestar/test-utils"; import {retry} from "@lodestar/utils"; import {testFilesDir} from "../utils.js"; -describe("voluntary exit from api", function () { +describe("voluntary exit from api", () => { vi.setConfig({testTimeout: 60_000}); it("Perform a voluntary exit", async () => { @@ -85,10 +85,8 @@ describe("voluntary exit from api", function () { const validator = (await beaconClient.getStateValidator({stateId: "head", validatorId: pubkeyToExit})).value(); if (validator.status !== "active_exiting") { throw Error("Validator not exiting"); - } else { - // eslint-disable-next-line no-console - console.log(`Confirmed validator ${pubkeyToExit} = ${validator.status}`); } + console.log(`Confirmed validator ${pubkeyToExit} = ${validator.status}`); }, {retryDelay: 1000, retries: 20} ); diff --git a/packages/cli/test/e2e/voluntaryExitRemoteSigner.test.ts b/packages/cli/test/e2e/voluntaryExitRemoteSigner.test.ts index a9cf2f48a168..769380f2053f 100644 --- a/packages/cli/test/e2e/voluntaryExitRemoteSigner.test.ts +++ b/packages/cli/test/e2e/voluntaryExitRemoteSigner.test.ts @@ -14,7 +14,7 @@ import { } from "@lodestar/test-utils"; import {testFilesDir} from "../utils.js"; -describe("voluntaryExit using remote signer", function () { +describe("voluntaryExit using remote signer", () => { vi.setConfig({testTimeout: 30_000}); let externalSigner: StartedExternalSigner; @@ -100,10 +100,8 @@ describe("voluntaryExit using remote signer", function () { const validator = (await client.beacon.getStateValidator({stateId: "head", validatorId: pubkey})).value(); if (validator.status !== "active_exiting") { throw Error("Validator not exiting"); - } else { - // eslint-disable-next-line no-console - console.log(`Confirmed validator ${pubkey} = ${validator.status}`); } + console.log(`Confirmed validator ${pubkey} = ${validator.status}`); }, {retryDelay: 1000, retries: 20} ); diff --git a/packages/cli/test/scripts/e2e_test_env.ts b/packages/cli/test/scripts/e2e_test_env.ts index 24d0142827a8..fcecfac5e1c7 100644 --- a/packages/cli/test/scripts/e2e_test_env.ts +++ b/packages/cli/test/scripts/e2e_test_env.ts @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/naming-convention */ import path from "node:path"; import {BeaconClient, ExecutionClient} from "../utils/crucible/interfaces.js"; import {Simulation} from "../utils/crucible/simulation.js"; diff --git a/packages/cli/test/sim/backupEthProvider.test.ts b/packages/cli/test/sim/backupEthProvider.test.ts index 1310119c9c3e..4ccc131a58bc 100644 --- a/packages/cli/test/sim/backupEthProvider.test.ts +++ b/packages/cli/test/sim/backupEthProvider.test.ts @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/naming-convention */ import path from "node:path"; import {activePreset} from "@lodestar/params"; import {Simulation} from "../utils/crucible/simulation.js"; diff --git a/packages/cli/test/sim/deneb.test.ts b/packages/cli/test/sim/deneb.test.ts index b9c30a5ff523..865540ae7635 100644 --- a/packages/cli/test/sim/deneb.test.ts +++ b/packages/cli/test/sim/deneb.test.ts @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/naming-convention */ import path from "node:path"; import {Simulation} from "../utils/crucible/simulation.js"; import {BeaconClient, ExecutionClient, ValidatorClient} from "../utils/crucible/interfaces.js"; diff --git a/packages/cli/test/sim/endpoints.test.ts b/packages/cli/test/sim/endpoints.test.ts index 6a119fc219d7..308ac6a0053c 100644 --- a/packages/cli/test/sim/endpoints.test.ts +++ b/packages/cli/test/sim/endpoints.test.ts @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/naming-convention */ import path from "node:path"; import assert from "node:assert"; import {toHexString} from "@chainsafe/ssz"; diff --git a/packages/cli/test/sim/mixedClient.test.ts b/packages/cli/test/sim/mixedClient.test.ts index bfb2a5a99b1b..45029a1b26b4 100644 --- a/packages/cli/test/sim/mixedClient.test.ts +++ b/packages/cli/test/sim/mixedClient.test.ts @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/naming-convention */ import path from "node:path"; import {Simulation} from "../utils/crucible/simulation.js"; import {nodeAssertion} from "../utils/crucible/assertions/nodeAssertion.js"; diff --git a/packages/cli/test/sim/multiFork.test.ts b/packages/cli/test/sim/multiFork.test.ts index 47ad59a165b6..047d9196239d 100644 --- a/packages/cli/test/sim/multiFork.test.ts +++ b/packages/cli/test/sim/multiFork.test.ts @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/naming-convention */ import path from "node:path"; import {Match, BeaconClient, ExecutionClient, ValidatorClient} from "../utils/crucible/interfaces.js"; import {Simulation} from "../utils/crucible/simulation.js"; diff --git a/packages/cli/test/unit/cmds/beacon.test.ts b/packages/cli/test/unit/cmds/beacon.test.ts index fc1f50ad1251..74cde026b1ad 100644 --- a/packages/cli/test/unit/cmds/beacon.test.ts +++ b/packages/cli/test/unit/cmds/beacon.test.ts @@ -1,15 +1,16 @@ import path from "node:path"; import fs from "node:fs"; import {describe, it, expect} from "vitest"; -import {createFromJSON, createSecp256k1PeerId} from "@libp2p/peer-id-factory"; import {multiaddr} from "@multiformats/multiaddr"; -import {createPrivateKeyFromPeerId, ENR, SignableENR} from "@chainsafe/enr"; +import {ENR, SignableENR} from "@chainsafe/enr"; +import {generateKeyPair} from "@libp2p/crypto/keys"; +import {peerIdFromPrivateKey} from "@libp2p/peer-id"; import {chainConfig} from "@lodestar/config/default"; import {chainConfigToJson} from "@lodestar/config"; import {LogLevel} from "@lodestar/utils"; -import {exportToJSON} from "../../../src/config/peerId.js"; +import {createFromJSON, exportToJSON} from "../../../src/config/peerId.js"; import {beaconHandlerInit} from "../../../src/cmds/beacon/handler.js"; -import {initPeerIdAndEnr, isLocalMultiAddr} from "../../../src/cmds/beacon/initPeerIdAndEnr.js"; +import {initPrivateKeyAndEnr, isLocalMultiAddr} from "../../../src/cmds/beacon/initPeerIdAndEnr.js"; import {BeaconArgs} from "../../../src/cmds/beacon/options.js"; import {GlobalArgs} from "../../../src/options/globalOptions.js"; import {testFilesDir, testLogger} from "../../utils.js"; @@ -55,26 +56,26 @@ describe("cmds / beacon / args handler", () => { }); it("Create different PeerId every run", async () => { - const {peerId: peerId1} = await runBeaconHandlerInit({}); - const {peerId: peerId2} = await runBeaconHandlerInit({}); + const {privateKey: pk1} = await runBeaconHandlerInit({}); + const {privateKey: pk2} = await runBeaconHandlerInit({}); - expect(peerId1.toString()).not.toBe(peerId2.toString()); + expect(pk1.equals(pk2)).toBe(false); }); it("Re-use existing peer", async () => { - const prevPeerId = await createSecp256k1PeerId(); + const prevPk = await generateKeyPair("secp256k1"); const peerIdFile = path.join(testFilesDir, "peer-id.json"); - fs.writeFileSync(peerIdFile, JSON.stringify(exportToJSON(prevPeerId))); - const enr = SignableENR.createV4(createPrivateKeyFromPeerId(prevPeerId).privateKey); + fs.writeFileSync(peerIdFile, JSON.stringify(exportToJSON(prevPk))); + const enr = SignableENR.createFromPrivateKey(prevPk); const enrFilePath = path.join(testFilesDir, "enr"); fs.writeFileSync(enrFilePath, enr.encodeTxt()); - const {peerId} = await runBeaconHandlerInit({ + const {privateKey} = await runBeaconHandlerInit({ persistNetworkIdentity: true, }); - expect(peerId.toString()).toBe(prevPeerId.toString()); + expect(privateKey.equals(prevPk)).toBe(true); }); it("Set known deposit contract", async () => { @@ -117,48 +118,48 @@ describe("Test isLocalMultiAddr", () => { describe("initPeerIdAndEnr", () => { it("should not reuse peer id, persistNetworkIdentity=false", async () => { - const {peerId: peerId1} = await initPeerIdAndEnr( + const {privateKey: pk1} = await initPrivateKeyAndEnr( {persistNetworkIdentity: false} as BeaconArgs, testFilesDir, testLogger() ); - const {peerId: peerId2} = await initPeerIdAndEnr( + const {privateKey: pk2} = await initPrivateKeyAndEnr( {persistNetworkIdentity: false} as BeaconArgs, testFilesDir, testLogger() ); - expect(peerId1.toString()).not.toBe(peerId2.toString()); + expect(pk1.equals(pk2)).toBe(false); }); it("should reuse peer id, persistNetworkIdentity=true", async () => { - const {peerId: peerId1} = await initPeerIdAndEnr( + const {privateKey: pk1} = await initPrivateKeyAndEnr( {persistNetworkIdentity: true} as BeaconArgs, testFilesDir, testLogger() ); - const {peerId: peerId2} = await initPeerIdAndEnr( + const {privateKey: pk2} = await initPrivateKeyAndEnr( {persistNetworkIdentity: true} as BeaconArgs, testFilesDir, testLogger() ); - expect(peerId1.toString()).toBe(peerId2.toString()); + expect(pk1.equals(pk2)).toBe(true); }); it("should overwrite invalid peer id", async () => { const peerIdFile = path.join(testFilesDir, "peer-id.json"); - const peerId1Str = "wrong peer id file content"; - fs.writeFileSync(peerIdFile, peerId1Str); - const {peerId: peerId2} = await initPeerIdAndEnr( + const pk1Str = "wrong peer id file content"; + fs.writeFileSync(peerIdFile, pk1Str); + const {privateKey: pk2} = await initPrivateKeyAndEnr( {persistNetworkIdentity: true} as BeaconArgs, testFilesDir, testLogger() ); - const filePeerId = await createFromJSON(JSON.parse(fs.readFileSync(peerIdFile, "utf-8"))); + const filePk = createFromJSON(JSON.parse(fs.readFileSync(peerIdFile, "utf-8"))); - expect(peerId1Str).not.toBe(peerId2.toString()); - expect(filePeerId.toString()).toBe(peerId2.toString()); + expect(pk1Str).not.toBe(peerIdFromPrivateKey(pk2).toString()); + expect(filePk.equals(pk2)).toBe(true); }); it("should overwrite invalid enr", async () => { @@ -166,7 +167,7 @@ describe("initPeerIdAndEnr", () => { const invalidEnr = "wrong enr file content"; fs.writeFileSync(enrFilePath, invalidEnr); - await initPeerIdAndEnr({persistNetworkIdentity: true} as BeaconArgs, testFilesDir, testLogger()); + await initPrivateKeyAndEnr({persistNetworkIdentity: true} as BeaconArgs, testFilesDir, testLogger()); const validEnr = fs.readFileSync(enrFilePath, "utf-8"); @@ -174,19 +175,18 @@ describe("initPeerIdAndEnr", () => { }); it("should overwrite enr that doesn't match peer id", async () => { - const otherPeerId = await createSecp256k1PeerId(); - const otherEnr = SignableENR.createFromPeerId(otherPeerId); + const otherPk = await generateKeyPair("secp256k1"); + const otherEnr = SignableENR.createFromPrivateKey(otherPk); const enrFilePath = path.join(testFilesDir, "enr"); const otherEnrStr = otherEnr.encodeTxt(); fs.writeFileSync(enrFilePath, otherEnrStr); - const {enr} = await initPeerIdAndEnr({persistNetworkIdentity: true} as BeaconArgs, testFilesDir, testLogger()); + const {enr} = await initPrivateKeyAndEnr({persistNetworkIdentity: true} as BeaconArgs, testFilesDir, testLogger()); expect(enr.nodeId).not.toBe(otherEnr); }); }); -// eslint-disable-next-line @typescript-eslint/explicit-function-return-type async function runBeaconHandlerInit(args: Partial) { return beaconHandlerInit({ logLevel: LogLevel.info, diff --git a/packages/cli/test/unit/cmds/initPeerIdAndEnr.test.ts b/packages/cli/test/unit/cmds/initPeerIdAndEnr.test.ts index a207e0c0f59d..3dd9b48c298d 100644 --- a/packages/cli/test/unit/cmds/initPeerIdAndEnr.test.ts +++ b/packages/cli/test/unit/cmds/initPeerIdAndEnr.test.ts @@ -1,7 +1,8 @@ import fs from "node:fs"; import {describe, it, expect, beforeEach, afterEach} from "vitest"; import tmp from "tmp"; -import {initPeerIdAndEnr} from "../../../src/cmds/beacon/initPeerIdAndEnr.js"; +import {peerIdFromPrivateKey} from "@libp2p/peer-id"; +import {initPrivateKeyAndEnr} from "../../../src/cmds/beacon/initPeerIdAndEnr.js"; import {BeaconArgs} from "../../../src/cmds/beacon/options.js"; import {testLogger} from "../../utils.js"; @@ -17,35 +18,35 @@ describe("initPeerIdAndEnr", () => { }); it("first time should create a new enr and peer id", async () => { - const {enr, peerId} = await initPeerIdAndEnr( + const {enr, privateKey} = await initPrivateKeyAndEnr( {persistNetworkIdentity: true} as unknown as BeaconArgs, tmpDir.name, testLogger(), true ); // "enr peer id doesn't equal the returned peer id" - expect((await enr.peerId()).toString()).toBe(peerId.toString()); + expect(enr.peerId.toString()).toBe(peerIdFromPrivateKey(privateKey).toString()); expect(enr.seq).toBe(BigInt(1)); expect(enr.tcp).toBeUndefined(); expect(enr.tcp6).toBeUndefined(); }); it("second time should use ths existing enr and peer id", async () => { - const run1 = await initPeerIdAndEnr( + const run1 = await initPrivateKeyAndEnr( {persistNetworkIdentity: true} as unknown as BeaconArgs, tmpDir.name, testLogger(), true ); - const run2 = await initPeerIdAndEnr( + const run2 = await initPrivateKeyAndEnr( {persistNetworkIdentity: true} as unknown as BeaconArgs, tmpDir.name, testLogger(), true ); - expect(run1.peerId.toString()).toBe(run2.peerId.toString()); + expect(run1.privateKey.equals(run2.privateKey)).toBe(true); expect(run1.enr.encodeTxt()).toBe(run2.enr.encodeTxt()); }); }); diff --git a/packages/cli/test/unit/config/beaconParams.test.ts b/packages/cli/test/unit/config/beaconParams.test.ts index a7ce463200d0..2a78d498bf89 100644 --- a/packages/cli/test/unit/config/beaconParams.test.ts +++ b/packages/cli/test/unit/config/beaconParams.test.ts @@ -16,7 +16,6 @@ describe("config / beaconParams", () => { const testCases: { id: string; kwargs: Parameters[0]; - // eslint-disable-next-line @typescript-eslint/naming-convention GENESIS_FORK_VERSION: string; }[] = [ { @@ -24,7 +23,6 @@ describe("config / beaconParams", () => { kwargs: { additionalParamsCli: {}, }, - // eslint-disable-next-line @typescript-eslint/naming-convention GENESIS_FORK_VERSION: GENESIS_FORK_VERSION_MAINNET, }, { @@ -33,7 +31,6 @@ describe("config / beaconParams", () => { network: networkName, additionalParamsCli: {}, }, - // eslint-disable-next-line @typescript-eslint/naming-convention GENESIS_FORK_VERSION: GENESIS_FORK_VERSION_HOLESKY, }, { @@ -43,7 +40,6 @@ describe("config / beaconParams", () => { paramsFile: paramsFilepath, additionalParamsCli: {}, }, - // eslint-disable-next-line @typescript-eslint/naming-convention GENESIS_FORK_VERSION: GENESIS_FORK_VERSION_FILE, }, { @@ -51,16 +47,13 @@ describe("config / beaconParams", () => { kwargs: { network: networkName, paramsFile: paramsFilepath, - // eslint-disable-next-line @typescript-eslint/naming-convention additionalParamsCli: {GENESIS_FORK_VERSION: GENESIS_FORK_VERSION_CLI}, }, - // eslint-disable-next-line @typescript-eslint/naming-convention GENESIS_FORK_VERSION: GENESIS_FORK_VERSION_CLI, }, ]; beforeAll(() => { - // eslint-disable-next-line @typescript-eslint/naming-convention fs.writeFileSync(paramsFilepath, yaml.dump({GENESIS_FORK_VERSION: GENESIS_FORK_VERSION_FILE})); }); @@ -68,7 +61,6 @@ describe("config / beaconParams", () => { if (fs.existsSync(paramsFilepath)) fs.unlinkSync(paramsFilepath); }); - // eslint-disable-next-line @typescript-eslint/naming-convention it.each(testCases)("$id", ({kwargs, GENESIS_FORK_VERSION}) => { const params = getBeaconParams(kwargs); expect(toHexString(params.GENESIS_FORK_VERSION)).toBe(GENESIS_FORK_VERSION); diff --git a/packages/cli/test/unit/config/peerId.test.ts b/packages/cli/test/unit/config/peerId.test.ts index c0cdc8cff1a9..120a5e931749 100644 --- a/packages/cli/test/unit/config/peerId.test.ts +++ b/packages/cli/test/unit/config/peerId.test.ts @@ -1,16 +1,16 @@ import {describe, it, expect} from "vitest"; -import {createSecp256k1PeerId} from "@libp2p/peer-id-factory"; +import {generateKeyPair} from "@libp2p/crypto/keys"; import {getTestdirPath} from "../../utils.js"; -import {writePeerId, readPeerId} from "../../../src/config/index.js"; +import {writePrivateKey, readPrivateKey} from "../../../src/config/index.js"; describe("config / peerId", () => { const peerIdFilepath = getTestdirPath("./test-peer-id.json"); it("create, write and read PeerId", async () => { - const peerId = await createSecp256k1PeerId(); - writePeerId(peerIdFilepath, peerId); - const peerIdRead = await readPeerId(peerIdFilepath); + const privateKey = await generateKeyPair("secp256k1"); + writePrivateKey(peerIdFilepath, privateKey); + const pkRead = readPrivateKey(peerIdFilepath); - expect(peerIdRead.toString()).toBe(peerId.toString()); + expect(pkRead.toString()).toBe(privateKey.toString()); }); }); diff --git a/packages/cli/test/unit/db.test.ts b/packages/cli/test/unit/db.test.ts index 1e19e514e9e5..b39c9492c9cb 100644 --- a/packages/cli/test/unit/db.test.ts +++ b/packages/cli/test/unit/db.test.ts @@ -1,7 +1,5 @@ import {describe, it} from "vitest"; -// eslint-disable-next-line import/no-relative-packages import {Bucket as BeaconBucket} from "../../../beacon-node/src/db/buckets.js"; -// eslint-disable-next-line import/no-relative-packages import {Bucket as ValidatorBucket} from "../../../validator/src/buckets.js"; describe("no db bucket overlap", () => { diff --git a/packages/cli/test/unit/options/paramsOptions.test.ts b/packages/cli/test/unit/options/paramsOptions.test.ts index a08c70008612..d6563203e652 100644 --- a/packages/cli/test/unit/options/paramsOptions.test.ts +++ b/packages/cli/test/unit/options/paramsOptions.test.ts @@ -11,9 +11,7 @@ describe("options / paramsOptions", () => { }; const expectedBeaconParams: Partial = { - // eslint-disable-next-line @typescript-eslint/naming-convention GENESIS_FORK_VERSION: "0x00000001", - // eslint-disable-next-line @typescript-eslint/naming-convention DEPOSIT_CONTRACT_ADDRESS: "0x1234567890123456789012345678901234567890", }; diff --git a/packages/cli/test/unit/util/format.test.ts b/packages/cli/test/unit/util/format.test.ts index c06259cc1842..194cc1dcbde7 100644 --- a/packages/cli/test/unit/util/format.test.ts +++ b/packages/cli/test/unit/util/format.test.ts @@ -17,8 +17,7 @@ describe("util / format / parseRange", () => { describe("util / format / isValidatePubkeyHex", () => { const testCases: Record = { - "../../malicious_link/0x933ad9491b62059dd065b560d256d8957a8c402cc6e8d8ee7290ae11e8f7329267a8811c397529dac52ae1342ba58c95": - false, + "../../malicious_link/0x933ad9491b62059dd065b560d256d8957a8c402cc6e8d8ee7290ae11e8f7329267a8811c397529dac52ae1342ba58c95": false, "0x933ad9491b62059dd065b560d256d8957a8c402cc6e8d8ee7290ae11e8f7329267a8811c397529dac52ae1342ba58c95": true, "0x933ad9491b62059dd065b560d256d8957a8c402cc6e8d8ee7290ae11e8f7329267a8811c397529dac52ae1342ba58c9": false, "0x933ad9491b62059dd065b560d256d8957a8c402cc6e8d8ee7290ae11e8f7329267a8811c397529dac52ae1342ba58c95f": false, diff --git a/packages/cli/test/unit/util/gitData.test.ts b/packages/cli/test/unit/util/gitData.test.ts index 206dd070b545..9e15fc2f4956 100644 --- a/packages/cli/test/unit/util/gitData.test.ts +++ b/packages/cli/test/unit/util/gitData.test.ts @@ -8,10 +8,9 @@ import {getGitData} from "../../../src/util/index.js"; // Global variable __dirname no longer available in ES6 modules. // Solutions: https://stackoverflow.com/questions/46745014/alternative-for-dirname-in-node-js-when-using-es6-modules -// eslint-disable-next-line @typescript-eslint/naming-convention const __dirname = path.dirname(fileURLToPath(import.meta.url)); -describe("util / gitData", function () { +describe("util / gitData", () => { // .gitData file is created at build time with the command // ``` // npm run write-git-data diff --git a/packages/cli/test/unit/util/logger.test.ts b/packages/cli/test/unit/util/logger.test.ts index bddc86f2a483..fa17218bfd1c 100644 --- a/packages/cli/test/unit/util/logger.test.ts +++ b/packages/cli/test/unit/util/logger.test.ts @@ -1,7 +1,7 @@ import {describe, it, expect, vi, beforeEach, afterEach} from "vitest"; import {shouldDeleteLogFile} from "../../../src/util/logger.js"; -describe("shouldDeleteLogFile", function () { +describe("shouldDeleteLogFile", () => { const prefix = "beacon"; const extension = "log"; diff --git a/packages/cli/test/unit/validator/keys.test.ts b/packages/cli/test/unit/validator/keys.test.ts index c977c2242c33..6902d17b3883 100644 --- a/packages/cli/test/unit/validator/keys.test.ts +++ b/packages/cli/test/unit/validator/keys.test.ts @@ -10,7 +10,7 @@ describe("validator / signers / importKeystoreDefinitionsFromExternalDir", () => if (tmpDir) fs.rmSync(tmpDir, {recursive: true}); }); - it("should filter out deposit data files", function () { + it("should filter out deposit data files", () => { tmpDir = fs.mkdtempSync("cli-keystores-import-test"); // Populate dir diff --git a/packages/cli/test/unit/validator/parseProposerConfig.test.ts b/packages/cli/test/unit/validator/parseProposerConfig.test.ts index 66220ca3329a..83c8c63ef877 100644 --- a/packages/cli/test/unit/validator/parseProposerConfig.test.ts +++ b/packages/cli/test/unit/validator/parseProposerConfig.test.ts @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/naming-convention */ import path from "node:path"; import {fileURLToPath} from "node:url"; import {describe, it, expect} from "vitest"; @@ -27,6 +26,7 @@ const testValue = { builder: { gasLimit: 35000000, selection: routes.validator.BuilderSelection.BuilderAlways, + // biome-ignore lint/correctness/noPrecisionLoss: boostFactor: BigInt(18446744073709551616), }, }, diff --git a/packages/cli/test/utils/crucible/assertions/defaults/attestationCountAssertion.ts b/packages/cli/test/utils/crucible/assertions/defaults/attestationCountAssertion.ts index 5d0f7a268f88..922ce80ae329 100644 --- a/packages/cli/test/utils/crucible/assertions/defaults/attestationCountAssertion.ts +++ b/packages/cli/test/utils/crucible/assertions/defaults/attestationCountAssertion.ts @@ -32,7 +32,7 @@ export const attestationsCountAssertion: Assertion<"attestationsCount", number, async assert({clock, store, epoch, node, dependantStores}) { const errors: AssertionResult[] = []; - const inclusionDelayStore = dependantStores["inclusionDelay"]; + const inclusionDelayStore = dependantStores.inclusionDelay; const startSlot = epoch === 0 ? 1 : clock.getFirstSlotOfEpoch(epoch); const endSlot = clock.getLastSlotOfEpoch(epoch); diff --git a/packages/cli/test/utils/crucible/assertions/nodeAssertion.ts b/packages/cli/test/utils/crucible/assertions/nodeAssertion.ts index 9659cc34e7bf..04c9b393d245 100644 --- a/packages/cli/test/utils/crucible/assertions/nodeAssertion.ts +++ b/packages/cli/test/utils/crucible/assertions/nodeAssertion.ts @@ -17,7 +17,7 @@ export const nodeAssertion: Assertion<"node", {health: number; keyManagerKeys: s let keyManagerKeys: string[]; // There is an authentication issue with the lighthouse keymanager client - if (node.validator.client == ValidatorClient.Lighthouse || getAllKeys(node.validator.keys).length === 0) { + if (node.validator.client === ValidatorClient.Lighthouse || getAllKeys(node.validator.keys).length === 0) { keyManagerKeys = []; } else { const keys = (await node.validator.keyManager.listKeys()).value(); @@ -30,7 +30,7 @@ export const nodeAssertion: Assertion<"node", {health: number; keyManagerKeys: s const errors: AssertionResult[] = []; // There is an authentication issue with the lighthouse keymanager client - if (node.validator?.client == ValidatorClient.Lighthouse) return errors; + if (node.validator?.client === ValidatorClient.Lighthouse) return errors; const {health, keyManagerKeys} = store[slot]; diff --git a/packages/cli/test/utils/crucible/clients/beacon/lighthouse.ts b/packages/cli/test/utils/crucible/clients/beacon/lighthouse.ts index 89802149024a..515418f7e558 100644 --- a/packages/cli/test/utils/crucible/clients/beacon/lighthouse.ts +++ b/packages/cli/test/utils/crucible/clients/beacon/lighthouse.ts @@ -109,7 +109,6 @@ export const generateLighthouseBeaconNode: BeaconNodeGenerator = (o "--verbosity", "5", ...(mining ? ["--mine", "--miner.etherbase", EL_GENESIS_ACCOUNT] : []), - ...(mode == ExecutionStartMode.PreMerge ? ["--nodiscover"] : []), + ...(mode === ExecutionStartMode.PreMerge ? ["--nodiscover"] : []), ...clientOptions, ], env: {}, diff --git a/packages/cli/test/utils/crucible/clients/validator/lodestar.ts b/packages/cli/test/utils/crucible/clients/validator/lodestar.ts index e95c39972eb0..a2b928c0a2d5 100644 --- a/packages/cli/test/utils/crucible/clients/validator/lodestar.ts +++ b/packages/cli/test/utils/crucible/clients/validator/lodestar.ts @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/naming-convention */ import {writeFile} from "node:fs/promises"; import path from "node:path"; import got from "got"; diff --git a/packages/cli/test/utils/crucible/constants.ts b/packages/cli/test/utils/crucible/constants.ts index baccab141a5e..b887b4ea4c8a 100644 --- a/packages/cli/test/utils/crucible/constants.ts +++ b/packages/cli/test/utils/crucible/constants.ts @@ -1,6 +1,5 @@ // Global variable __dirname no longer available in ES6 modules. // Solutions: https://stackoverflow.com/questions/46745014/alternative-for-dirname-in-node-js-when-using-es6-modules -// eslint-disable-next-line @typescript-eslint/naming-convention export const __dirname = path.dirname(fileURLToPath(import.meta.url)); import path from "node:path"; diff --git a/packages/cli/test/utils/crucible/epochClock.ts b/packages/cli/test/utils/crucible/epochClock.ts index fc71d4accadc..0973a3da0cc3 100644 --- a/packages/cli/test/utils/crucible/epochClock.ts +++ b/packages/cli/test/utils/crucible/epochClock.ts @@ -80,7 +80,6 @@ export class EpochClock { } async waitForStartOfSlot(slot: number, silent = false): Promise { - // eslint-disable-next-line no-console if (!silent) console.log("Waiting for start of slot", {target: slot, current: this.currentSlot}); const slotTime = this.getSlotTime(slot) * MS_IN_SEC - Date.now(); await sleep(slotTime, this.signal); diff --git a/packages/cli/test/utils/crucible/externalSignerServer.ts b/packages/cli/test/utils/crucible/externalSignerServer.ts index bd8576d214c2..4282f1761db9 100644 --- a/packages/cli/test/utils/crucible/externalSignerServer.ts +++ b/packages/cli/test/utils/crucible/externalSignerServer.ts @@ -29,7 +29,6 @@ export class ExternalSignerServer { return [...this.secretKeyMap.keys()]; }); - /* eslint-disable @typescript-eslint/naming-convention */ this.server.post<{ Params: { /** BLS public key as a hex string. */ diff --git a/packages/cli/test/utils/crucible/interfaces.ts b/packages/cli/test/utils/crucible/interfaces.ts index db4b1f3b8901..84b5043ba983 100644 --- a/packages/cli/test/utils/crucible/interfaces.ts +++ b/packages/cli/test/utils/crucible/interfaces.ts @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/naming-convention */ import {ChildProcess} from "node:child_process"; import {Web3} from "web3"; import {SecretKey} from "@chainsafe/blst"; diff --git a/packages/cli/test/utils/crucible/runner/dockerRunner.ts b/packages/cli/test/utils/crucible/runner/dockerRunner.ts index cfa52c9b9ebf..bc5b97811cf4 100644 --- a/packages/cli/test/utils/crucible/runner/dockerRunner.ts +++ b/packages/cli/test/utils/crucible/runner/dockerRunner.ts @@ -22,7 +22,7 @@ export class DockerRunner implements RunnerEnv { await execChildProcess(`docker network create --subnet ${dockerNetworkIpRange}.0/24 ${dockerNetworkName}`, { logger: this.logger, }); - } catch { + } catch (_e) { // During multiple sim tests files the network might already exist } } @@ -35,7 +35,7 @@ export class DockerRunner implements RunnerEnv { logger: this.logger, }); return; - } catch { + } catch (_e) { await sleep(5000); } } diff --git a/packages/cli/test/utils/crucible/simulationTracker.ts b/packages/cli/test/utils/crucible/simulationTracker.ts index e374d3b6c328..778a7ad2a771 100644 --- a/packages/cli/test/utils/crucible/simulationTracker.ts +++ b/packages/cli/test/utils/crucible/simulationTracker.ts @@ -68,7 +68,7 @@ async function pathExists(filePath: string): Promise { try { await fs.access(filePath); return true; - } catch { + } catch (_e) { return false; } } diff --git a/packages/cli/test/utils/crucible/tableReporter.ts b/packages/cli/test/utils/crucible/tableReporter.ts index d11fc9ca3fbc..d40be13ad6e8 100644 --- a/packages/cli/test/utils/crucible/tableReporter.ts +++ b/packages/cli/test/utils/crucible/tableReporter.ts @@ -33,9 +33,8 @@ export class TableReporter extends SimulationReporter // Print slots once, may be called twice for missed block timer if (slot <= this.lastPrintedSlot) { return; - } else { - this.lastPrintedSlot = slot; } + this.lastPrintedSlot = slot; if (slot <= 0) { return; @@ -59,12 +58,10 @@ export class TableReporter extends SimulationReporter const participation: {head: number; source: number; target: number}[] = []; for (const node of nodes) { - participation.push( - stores["attestationParticipation"][node.beacon.id][slot] ?? {head: 0, source: 0, target: 0} - ); + participation.push(stores.attestationParticipation[node.beacon.id][slot] ?? {head: 0, source: 0, target: 0}); const syncCommitteeParticipation: number[] = []; for (let slot = startSlot; slot <= endSlot; slot++) { - syncCommitteeParticipation.push(stores["syncCommitteeParticipation"][node.beacon.id][slot] ?? 0); + syncCommitteeParticipation.push(stores.syncCommitteeParticipation[node.beacon.id][slot] ?? 0); } nodesSyncParticipationAvg.push(avg(syncCommitteeParticipation)); } @@ -88,19 +85,19 @@ export class TableReporter extends SimulationReporter const peersCount: number[] = []; for (const node of nodes) { - const finalized = stores["finalized"][node.beacon.id][slot]; + const finalized = stores.finalized[node.beacon.id][slot]; if (!isNullish(finalized)) finalizedSlots.push(finalized); - const inclusionDelay = stores["inclusionDelay"][node.beacon.id][slot]; + const inclusionDelay = stores.inclusionDelay[node.beacon.id][slot]; if (!isNullish(inclusionDelay)) inclusionDelays.push(inclusionDelay); - const attestationsCount = stores["attestationsCount"][node.beacon.id][slot]; + const attestationsCount = stores.attestationsCount[node.beacon.id][slot]; if (!isNullish(attestationsCount)) attestationCounts.push(attestationsCount); - const head = stores["head"][node.beacon.id][slot]; + const head = stores.head[node.beacon.id][slot]; if (!isNullish(head)) heads.push(head); - const connectedPeerCount = stores["connectedPeerCount"][node.beacon.id][slot]; + const connectedPeerCount = stores.connectedPeerCount[node.beacon.id][slot]; if (!isNullish(connectedPeerCount)) peersCount.push(connectedPeerCount); } diff --git a/packages/cli/test/utils/crucible/utils/index.ts b/packages/cli/test/utils/crucible/utils/index.ts index 0b6ae1bba1e5..0e016778cdce 100644 --- a/packages/cli/test/utils/crucible/utils/index.ts +++ b/packages/cli/test/utils/crucible/utils/index.ts @@ -73,7 +73,6 @@ export function defineSimTestConfig( additionalSlots: opts.additionalSlotsForTTD ?? 2, }); - /* eslint-disable @typescript-eslint/naming-convention */ const forkConfig = createChainForkConfig({ ...opts, GENESIS_DELAY: genesisDelaySeconds, @@ -157,7 +156,7 @@ export const arrayGroupBy = ( ): Record => array.reduce( (acc, value, index, array) => { - (acc[predicate(value, index, array)] ||= []).push(value); + acc[predicate(value, index, array)]?.push(value); return acc; }, {} as {[key: string]: T[]} diff --git a/packages/cli/test/utils/crucible/utils/keys.ts b/packages/cli/test/utils/crucible/utils/keys.ts index 27983c04cd38..8915e85b529e 100644 --- a/packages/cli/test/utils/crucible/utils/keys.ts +++ b/packages/cli/test/utils/crucible/utils/keys.ts @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/naming-convention */ import {readFile, writeFile} from "node:fs/promises"; import path from "node:path"; import yaml from "js-yaml"; diff --git a/packages/cli/test/utils/crucible/utils/network.ts b/packages/cli/test/utils/crucible/utils/network.ts index e3555fc149b9..a9a70b5561b4 100644 --- a/packages/cli/test/utils/crucible/utils/network.ts +++ b/packages/cli/test/utils/crucible/utils/network.ts @@ -74,14 +74,12 @@ export async function waitForNodeSync( } export async function waitForNodeSyncStatus(env: Simulation, node: NodePair): Promise { - // eslint-disable-next-line no-constant-condition while (true) { const result = (await node.beacon.api.node.getSyncingStatus()).value(); if (!result.isSyncing) { break; - } else { - await sleep(1000, env.options.controller.signal); } + await sleep(1000, env.options.controller.signal); } } diff --git a/packages/cli/test/utils/crucible/utils/paths.ts b/packages/cli/test/utils/crucible/utils/paths.ts index 9f0628e34656..4ff149d6f308 100644 --- a/packages/cli/test/utils/crucible/utils/paths.ts +++ b/packages/cli/test/utils/crucible/utils/paths.ts @@ -79,10 +79,15 @@ export const getNodeMountedPaths = => { return Object.entries(paths) - .map(([key, value]) => [ + .flatMap(([key, value]) => [ [key, value], [`${key}Mounted`, mount ? (value as string).replace(paths.rootDir, mountPath) : value], ]) - .flat() - .reduce((o, [key, value]) => ({...o, [key]: value as string}), {}) as MountedPaths; + .reduce( + (o, [key, value]) => { + o[key] = value as string; + return o; + }, + {} as Record + ) as MountedPaths; }; diff --git a/packages/cli/test/utils/crucible/utils/syncing.ts b/packages/cli/test/utils/crucible/utils/syncing.ts index 4a8913105335..b720c6bf6ccc 100644 --- a/packages/cli/test/utils/crucible/utils/syncing.ts +++ b/packages/cli/test/utils/crucible/utils/syncing.ts @@ -148,7 +148,9 @@ export async function assertUnknownBlockSync(env: Simulation): Promise { } catch (error) { if (!(error as Error).message.includes("BLOCK_ERROR_PARENT_UNKNOWN")) { env.tracker.record({ - message: `Publishing unknown block should return "BLOCK_ERROR_PARENT_UNKNOWN" got "${(error as Error).message}"`, + message: `Publishing unknown block should return "BLOCK_ERROR_PARENT_UNKNOWN" got "${ + (error as Error).message + }"`, slot: env.clock.currentSlot, assertionId: "unknownBlockParent", }); @@ -178,13 +180,11 @@ export async function waitForNodeSync( } export async function waitForNodeSyncStatus(env: Simulation, node: NodePair): Promise { - // eslint-disable-next-line no-constant-condition while (true) { const result = (await node.beacon.api.node.getSyncingStatus()).value(); if (!result.isSyncing) { break; - } else { - await sleep(1000, env.options.controller.signal); } + await sleep(1000, env.options.controller.signal); } } diff --git a/packages/cli/test/utils/mockBeaconApiServer.ts b/packages/cli/test/utils/mockBeaconApiServer.ts index 80ce282e102c..e7e80338686f 100644 --- a/packages/cli/test/utils/mockBeaconApiServer.ts +++ b/packages/cli/test/utils/mockBeaconApiServer.ts @@ -5,7 +5,6 @@ import {ChainForkConfig} from "@lodestar/config"; import {config} from "@lodestar/config/default"; import {ssz} from "@lodestar/types"; import {fromHex, toHex} from "@lodestar/utils"; -// eslint-disable-next-line import/no-relative-packages import {testLogger} from "../../../beacon-node/test/utils/logger.js"; const ZERO_HASH_HEX = toHex(Buffer.alloc(32, 0)); diff --git a/packages/config/package.json b/packages/config/package.json index f257db65cf6e..434000db2a0f 100644 --- a/packages/config/package.json +++ b/packages/config/package.json @@ -47,8 +47,8 @@ "build:watch": "yarn run build --watch", "check-build": "node -e \"(async function() { await import('./lib/index.js') })()\"", "check-types": "tsc", - "lint": "eslint --color --ext .ts src/", - "lint:fix": "yarn run lint --fix", + "lint": "biome check src/", + "lint:fix": "yarn run lint --write", "test": "yarn test:unit", "test:unit": "yarn vitest --run --dir test/unit/", "check-readme": "typescript-docs-verifier" diff --git a/packages/config/src/chainConfig/configs/mainnet.ts b/packages/config/src/chainConfig/configs/mainnet.ts index e5792a87ac70..5da5f8d2acb0 100644 --- a/packages/config/src/chainConfig/configs/mainnet.ts +++ b/packages/config/src/chainConfig/configs/mainnet.ts @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/naming-convention */ import {fromHex as b} from "@lodestar/utils"; import {PresetName} from "@lodestar/params"; import {ChainConfig} from "../types.js"; diff --git a/packages/config/src/chainConfig/configs/minimal.ts b/packages/config/src/chainConfig/configs/minimal.ts index 53229d283511..f1a52e956f4d 100644 --- a/packages/config/src/chainConfig/configs/minimal.ts +++ b/packages/config/src/chainConfig/configs/minimal.ts @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/naming-convention */ import {fromHex as b} from "@lodestar/utils"; import {PresetName} from "@lodestar/params"; import {ChainConfig} from "../types.js"; diff --git a/packages/config/src/chainConfig/default.ts b/packages/config/src/chainConfig/default.ts index d778c9b82447..ef2b9743a1d2 100644 --- a/packages/config/src/chainConfig/default.ts +++ b/packages/config/src/chainConfig/default.ts @@ -10,9 +10,10 @@ switch (ACTIVE_PRESET) { defaultChainConfig = minimal; break; case PresetName.mainnet: - default: defaultChainConfig = mainnet; break; + default: + defaultChainConfig = mainnet; } export {defaultChainConfig}; diff --git a/packages/config/src/chainConfig/networks/chiado.ts b/packages/config/src/chainConfig/networks/chiado.ts index d96bd7510c65..096942af672c 100644 --- a/packages/config/src/chainConfig/networks/chiado.ts +++ b/packages/config/src/chainConfig/networks/chiado.ts @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/naming-convention */ import {fromHex as b} from "@lodestar/utils"; import {ChainConfig} from "../types.js"; import {gnosisChainConfig as gnosis} from "./gnosis.js"; diff --git a/packages/config/src/chainConfig/networks/ephemery.ts b/packages/config/src/chainConfig/networks/ephemery.ts index 6fefc1800bfc..d1c17c36f0ab 100644 --- a/packages/config/src/chainConfig/networks/ephemery.ts +++ b/packages/config/src/chainConfig/networks/ephemery.ts @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/naming-convention */ import {fromHex as b} from "@lodestar/utils"; import {ChainConfig} from "../types.js"; import {chainConfig as mainnet} from "../configs/mainnet.js"; diff --git a/packages/config/src/chainConfig/networks/gnosis.ts b/packages/config/src/chainConfig/networks/gnosis.ts index 2f58ffd4d045..a25162ae5028 100644 --- a/packages/config/src/chainConfig/networks/gnosis.ts +++ b/packages/config/src/chainConfig/networks/gnosis.ts @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/naming-convention */ import {fromHex as b} from "@lodestar/utils"; import {PresetName} from "@lodestar/params"; import {ChainConfig} from "../types.js"; diff --git a/packages/config/src/chainConfig/networks/holesky.ts b/packages/config/src/chainConfig/networks/holesky.ts index 16c462a9468e..46c32606931f 100644 --- a/packages/config/src/chainConfig/networks/holesky.ts +++ b/packages/config/src/chainConfig/networks/holesky.ts @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/naming-convention */ import {fromHex as b} from "@lodestar/utils"; import {ChainConfig} from "../types.js"; import {chainConfig as mainnet} from "../configs/mainnet.js"; diff --git a/packages/config/src/chainConfig/networks/mainnet.ts b/packages/config/src/chainConfig/networks/mainnet.ts index c137c578fc0e..13225b463da9 100644 --- a/packages/config/src/chainConfig/networks/mainnet.ts +++ b/packages/config/src/chainConfig/networks/mainnet.ts @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/naming-convention */ import {fromHex as b} from "@lodestar/utils"; import {ChainConfig} from "../types.js"; import {chainConfig as mainnet} from "../configs/mainnet.js"; diff --git a/packages/config/src/chainConfig/networks/sepolia.ts b/packages/config/src/chainConfig/networks/sepolia.ts index 39e72a24f3f6..e7e5dc76f691 100644 --- a/packages/config/src/chainConfig/networks/sepolia.ts +++ b/packages/config/src/chainConfig/networks/sepolia.ts @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/naming-convention */ import {fromHex as b} from "@lodestar/utils"; import {ChainConfig} from "../types.js"; import {chainConfig as mainnet} from "../configs/mainnet.js"; diff --git a/packages/config/src/chainConfig/types.ts b/packages/config/src/chainConfig/types.ts index 05fff02f2eaf..5c06b205c2f6 100644 --- a/packages/config/src/chainConfig/types.ts +++ b/packages/config/src/chainConfig/types.ts @@ -1,7 +1,5 @@ import {PresetName} from "@lodestar/params"; -/* eslint-disable @typescript-eslint/naming-convention */ - /** * Run-time chain configuration */ diff --git a/packages/config/test/unit/index.test.ts b/packages/config/test/unit/index.test.ts index a6fca7ad643a..bde31f6b1477 100644 --- a/packages/config/test/unit/index.test.ts +++ b/packages/config/test/unit/index.test.ts @@ -31,7 +31,6 @@ describe("forks", () => { }); it("correctly handle pre-genesis", () => { - // eslint-disable-next-line @typescript-eslint/naming-convention const postMergeTestnet = createForkConfig({...chainConfig, ALTAIR_FORK_EPOCH: 0, BELLATRIX_FORK_EPOCH: 0}); expect(postMergeTestnet.getForkName(-1)).toBe(ForkName.bellatrix); }); diff --git a/packages/db/package.json b/packages/db/package.json index 0e3a2c847d4b..2a10d36766bf 100644 --- a/packages/db/package.json +++ b/packages/db/package.json @@ -28,8 +28,8 @@ "build:release": "yarn clean && yarn run build", "check-build": "node -e \"(async function() { await import('./lib/index.js') })()\"", "check-types": "tsc", - "lint": "eslint --color --ext .ts src/ test/", - "lint:fix": "yarn run lint --fix", + "lint": "biome check src/ test/", + "lint:fix": "yarn run lint --write", "test": "yarn test:unit", "test:unit": "vitest --run --dir test/unit/", "check-readme": "typescript-docs-verifier" diff --git a/packages/db/src/abstractRepository.ts b/packages/db/src/abstractRepository.ts index e0462d162ddc..5d5b0763ba26 100644 --- a/packages/db/src/abstractRepository.ts +++ b/packages/db/src/abstractRepository.ts @@ -142,7 +142,7 @@ export abstract class Repository { async batchRemove(values: T[]): Promise { // handle single value in batchDelete - await this.batchDelete(Array.from({length: values.length}, (ignored, i) => this.getId(values[i]))); + await this.batchDelete(Array.from({length: values.length}, (_ignored, i) => this.getId(values[i]))); } async keys(opts?: FilterOptions): Promise { diff --git a/packages/db/src/controller/level.ts b/packages/db/src/controller/level.ts index 084b577b6a01..82fbf631f7ae 100644 --- a/packages/db/src/controller/level.ts +++ b/packages/db/src/controller/level.ts @@ -78,11 +78,11 @@ export class LevelDbController implements DatabaseController { if (res?.startsWith("Usage: gdu ")) { return "gdu"; } - } catch { + } catch (_e) { /* eslint-disable no-console */ console.error("Cannot find gdu command, falling back to du"); } diff --git a/packages/flare/package.json b/packages/flare/package.json index 3a11e9b49ebf..a08e5fe0edc1 100644 --- a/packages/flare/package.json +++ b/packages/flare/package.json @@ -41,8 +41,8 @@ "build:watch": "yarn run build --watch", "check-build": "node -e \"(async function() { await import('./lib/index.js') })()\" flare --help", "check-types": "tsc", - "lint": "eslint --color --ext .ts src/", - "lint:fix": "yarn run lint --fix", + "lint": "biome check src/", + "lint:fix": "yarn run lint --write", "test": "yarn test:unit", "test:unit": "vitest --run --dir test/unit/", "check-readme": "typescript-docs-verifier" diff --git a/packages/flare/src/cmds/selfSlashAttester.ts b/packages/flare/src/cmds/selfSlashAttester.ts index 6ccc9d80a98f..174535ba2e7d 100644 --- a/packages/flare/src/cmds/selfSlashAttester.ts +++ b/packages/flare/src/cmds/selfSlashAttester.ts @@ -52,7 +52,7 @@ export async function selfSlashAttesterHandler(args: SelfSlashArgs): Promise 0: ${batchSize}`); if (batchSize > MAX_VALIDATORS_PER_COMMITTEE) throw Error("batchSize must be < MAX_VALIDATORS_PER_COMMITTEE"); diff --git a/packages/flare/src/cmds/selfSlashProposer.ts b/packages/flare/src/cmds/selfSlashProposer.ts index 14a270239268..dd9580232e71 100644 --- a/packages/flare/src/cmds/selfSlashProposer.ts +++ b/packages/flare/src/cmds/selfSlashProposer.ts @@ -52,7 +52,7 @@ export async function selfSlashProposerHandler(args: SelfSlashArgs): Promise 0: ${batchSize}`); // TODO: Ask the user to confirm the range and slash action diff --git a/packages/flare/src/index.ts b/packages/flare/src/index.ts index bc10fff9181c..5f3b85b459c1 100644 --- a/packages/flare/src/index.ts +++ b/packages/flare/src/index.ts @@ -12,7 +12,6 @@ void flare // Show command help message when no command is provided if (msg.includes("Not enough non-option arguments")) { yarg.showHelp(); - // eslint-disable-next-line no-console console.log("\n"); } } @@ -20,7 +19,6 @@ void flare const errorMessage = err !== undefined ? (err instanceof YargsError ? err.message : err.stack) : msg || "Unknown error"; - // eslint-disable-next-line no-console console.error(` ✖ ${errorMessage}\n`); process.exit(1); }) diff --git a/packages/flare/src/util/format.ts b/packages/flare/src/util/format.ts index 0da0fa509be6..989472932ca6 100644 --- a/packages/flare/src/util/format.ts +++ b/packages/flare/src/util/format.ts @@ -8,8 +8,8 @@ export function parseRange(range: string): number[] { const [from, to] = range.split("..").map((n) => parseInt(n)); - if (isNaN(from)) throw Error(`Invalid range from isNaN '${range}'`); - if (isNaN(to)) throw Error(`Invalid range to isNaN '${range}'`); + if (Number.isNaN(from)) throw Error(`Invalid range from isNaN '${range}'`); + if (Number.isNaN(to)) throw Error(`Invalid range to isNaN '${range}'`); if (from > to) throw Error(`Invalid range from > to '${range}'`); const arr: number[] = []; diff --git a/packages/fork-choice/package.json b/packages/fork-choice/package.json index 728036b365d3..2197ad90a9fd 100644 --- a/packages/fork-choice/package.json +++ b/packages/fork-choice/package.json @@ -29,8 +29,8 @@ "build:release": "yarn clean && yarn run build", "check-build": "node -e \"(async function() { await import('./lib/index.js') })()\"", "check-types": "tsc", - "lint": "eslint --color --ext .ts src/ test/", - "lint:fix": "yarn run lint --fix", + "lint": "biome check src/ test/", + "lint:fix": "yarn run lint --write", "test": "yarn test:unit", "test:unit": "vitest --run --dir test/unit/", "check-readme": "typescript-docs-verifier" diff --git a/packages/fork-choice/src/forkChoice/errors.ts b/packages/fork-choice/src/forkChoice/errors.ts index ea0c6305ba42..43d209106eed 100644 --- a/packages/fork-choice/src/forkChoice/errors.ts +++ b/packages/fork-choice/src/forkChoice/errors.ts @@ -95,8 +95,4 @@ export type ForkChoiceErrorType = | {code: ForkChoiceErrorCode.UNABLE_TO_SET_JUSTIFIED_CHECKPOINT; error: Error} | {code: ForkChoiceErrorCode.AFTER_BLOCK_FAILED; error: Error}; -export class ForkChoiceError extends LodestarError { - constructor(type: ForkChoiceErrorType) { - super(type); - } -} +export class ForkChoiceError extends LodestarError {} diff --git a/packages/fork-choice/src/forkChoice/forkChoice.ts b/packages/fork-choice/src/forkChoice/forkChoice.ts index 6ae3f52e7d3a..dcc76441865e 100644 --- a/packages/fork-choice/src/forkChoice/forkChoice.ts +++ b/packages/fork-choice/src/forkChoice/forkChoice.ts @@ -1,4 +1,4 @@ -import {Logger, fromHex, toRootHex} from "@lodestar/utils"; +import {Logger, MapDef, fromHex, toRootHex} from "@lodestar/utils"; import {SLOTS_PER_HISTORICAL_ROOT, SLOTS_PER_EPOCH, INTERVALS_PER_SLOT} from "@lodestar/params"; import {bellatrix, Slot, ValidatorIndex, phase0, ssz, RootHex, Epoch, Root, BeaconBlock} from "@lodestar/types"; import { @@ -34,7 +34,6 @@ import {ForkChoiceError, ForkChoiceErrorCode, InvalidBlockCode, InvalidAttestati import { IForkChoice, LatestMessage, - QueuedAttestation, PowBlockHex, EpochDifference, AncestorResult, @@ -91,7 +90,15 @@ export class ForkChoice implements IForkChoice { * Attestations that arrived at the current slot and must be queued for later processing. * NOT currently tracked in the protoArray */ - private readonly queuedAttestations = new Set(); + private readonly queuedAttestations: MapDef>> = new MapDef( + () => new MapDef(() => new Set()) + ); + + /** + * It's inconsistent to count number of queued attestations at different intervals of slot. + * Instead of that, we count number of queued attestations at the previous slot. + */ + private queuedAttestationsPreviousSlot = 0; // Note: as of Jun 2022 Lodestar metrics show that 100% of the times updateHead() is called, synced = false. // Because we are processing attestations from gossip, recomputing scores is always necessary @@ -130,7 +137,7 @@ export class ForkChoice implements IForkChoice { getMetrics(): ForkChoiceMetrics { return { votes: this.votes.length, - queuedAttestations: this.queuedAttestations.size, + queuedAttestations: this.queuedAttestationsPreviousSlot, validatedAttestationDatas: this.validatedAttestationDatas.size, balancesLength: this.balances.length, nodes: this.protoArray.nodes.length, @@ -198,6 +205,7 @@ export class ForkChoice implements IForkChoice { return {head, isHeadTimely, notReorgedReason}; } case UpdateHeadOpt.GetCanonicialHead: + return {head: canonicialHeadBlock}; default: return {head: canonicialHeadBlock}; } @@ -413,7 +421,8 @@ export class ForkChoice implements IForkChoice { }); } - return (this.head = headNode); + this.head = headNode; + return this.head; } /** @@ -714,12 +723,13 @@ export class ForkChoice implements IForkChoice { // Attestations can only affect the fork choice of subsequent slots. // Delay consideration in the fork choice until their slot is in the past. // ``` - this.queuedAttestations.add({ - slot: slot, - attestingIndices: attestation.attestingIndices, - blockRoot: blockRootHex, - targetEpoch, - }); + const byRoot = this.queuedAttestations.getOrDefault(slot); + const validatorIndices = byRoot.getOrDefault(blockRootHex); + for (const validatorIndex of attestation.attestingIndices) { + if (!this.fcStore.equivocatingIndices.has(validatorIndex)) { + validatorIndices.add(validatorIndex); + } + } } } @@ -749,6 +759,11 @@ export class ForkChoice implements IForkChoice { /** * Call `onTick` for all slots between `fcStore.getCurrentSlot()` and the provided `currentSlot`. + * This should only be called once per slot because: + * - calling this multiple times in the same slot does not update `votes` + * - new attestations in the current slot must stay in the queue + * - new attestations in the old slots are applied to the `votes` already + * - also side effect of this function is `validatedAttestationDatas` reseted */ updateTime(currentSlot: Slot): void { if (this.fcStore.currentSlot >= currentSlot) return; @@ -758,6 +773,7 @@ export class ForkChoice implements IForkChoice { this.onTick(previousSlot + 1); } + this.queuedAttestationsPreviousSlot = 0; // Process any attestations that might now be eligible. this.processAttestationQueue(); this.validatedAttestationDatas = new Set(); @@ -1232,7 +1248,9 @@ export class ForkChoice implements IForkChoice { currentEpoch: epochNow, }, }); - } else if (!forceImport && targetEpoch + 1 < epochNow) { + } + + if (!forceImport && targetEpoch + 1 < epochNow) { throw new ForkChoiceError({ code: ForkChoiceErrorCode.INVALID_ATTESTATION, err: { @@ -1350,15 +1368,23 @@ export class ForkChoice implements IForkChoice { */ private processAttestationQueue(): void { const currentSlot = this.fcStore.currentSlot; - for (const attestation of this.queuedAttestations.values()) { - // Delay consideration in the fork choice until their slot is in the past. - if (attestation.slot < currentSlot) { - this.queuedAttestations.delete(attestation); - const {blockRoot, targetEpoch} = attestation; - const blockRootHex = blockRoot; - for (const validatorIndex of attestation.attestingIndices) { - this.addLatestMessage(validatorIndex, targetEpoch, blockRootHex); + for (const [slot, byRoot] of this.queuedAttestations.entries()) { + const targetEpoch = computeEpochAtSlot(slot); + if (slot < currentSlot) { + this.queuedAttestations.delete(slot); + for (const [blockRoot, validatorIndices] of byRoot.entries()) { + const blockRootHex = blockRoot; + for (const validatorIndex of validatorIndices) { + // equivocatingIndices was checked in onAttestation + this.addLatestMessage(validatorIndex, targetEpoch, blockRootHex); + } + + if (slot === currentSlot - 1) { + this.queuedAttestationsPreviousSlot += validatorIndices.size; + } } + } else { + break; } } } @@ -1509,7 +1535,9 @@ export function assertValidTerminalPowBlock( throw Error( `Invalid terminal POW block: total difficulty not reached expected >= ${config.TERMINAL_TOTAL_DIFFICULTY}, actual = ${powBlock.totalDifficulty}` ); - } else if (!isParentTotalDifficultyValid) { + } + + if (!isParentTotalDifficultyValid) { throw Error( `Invalid terminal POW block parent: expected < ${config.TERMINAL_TOTAL_DIFFICULTY}, actual = ${powBlockParent.totalDifficulty}` ); diff --git a/packages/fork-choice/src/forkChoice/interface.ts b/packages/fork-choice/src/forkChoice/interface.ts index 0b6d56a88bf2..9ac8cdfac81b 100644 --- a/packages/fork-choice/src/forkChoice/interface.ts +++ b/packages/fork-choice/src/forkChoice/interface.ts @@ -250,14 +250,3 @@ export type LatestMessage = { epoch: Epoch; root: RootHex; }; - -/** - * Used for queuing attestations from the current slot. Only contains the minimum necessary - * information about the attestation. - */ -export type QueuedAttestation = { - slot: Slot; - attestingIndices: ValidatorIndex[]; - blockRoot: RootHex; - targetEpoch: Epoch; -}; diff --git a/packages/fork-choice/src/forkChoice/store.ts b/packages/fork-choice/src/forkChoice/store.ts index d16e021529db..2cd4da512870 100644 --- a/packages/fork-choice/src/forkChoice/store.ts +++ b/packages/fork-choice/src/forkChoice/store.ts @@ -55,18 +55,22 @@ export class ForkChoiceStore implements IForkChoiceStore { private _finalizedCheckpoint: CheckpointWithHex; unrealizedFinalizedCheckpoint: CheckpointWithHex; equivocatingIndices = new Set(); + justifiedBalancesGetter: JustifiedBalancesGetter; + currentSlot: Slot; constructor( - public currentSlot: Slot, + currentSlot: Slot, justifiedCheckpoint: phase0.Checkpoint, finalizedCheckpoint: phase0.Checkpoint, justifiedBalances: EffectiveBalanceIncrements, - public justifiedBalancesGetter: JustifiedBalancesGetter, + justifiedBalancesGetter: JustifiedBalancesGetter, private readonly events?: { onJustified: (cp: CheckpointWithHex) => void; onFinalized: (cp: CheckpointWithHex) => void; } ) { + this.justifiedBalancesGetter = justifiedBalancesGetter; + this.currentSlot = currentSlot; const justified = { checkpoint: toCheckpointWithHex(justifiedCheckpoint), balances: justifiedBalances, diff --git a/packages/fork-choice/src/protoArray/computeDeltas.ts b/packages/fork-choice/src/protoArray/computeDeltas.ts index 8301c1e77a75..c921e12f751e 100644 --- a/packages/fork-choice/src/protoArray/computeDeltas.ts +++ b/packages/fork-choice/src/protoArray/computeDeltas.ts @@ -3,6 +3,9 @@ import {EffectiveBalanceIncrements} from "@lodestar/state-transition"; import {VoteTracker} from "./interface.js"; import {ProtoArrayError, ProtoArrayErrorCode} from "./errors.js"; +// reuse arrays to avoid memory reallocation and gc +const deltas = new Array(); + /** * Returns a list of `deltas`, where there is one delta for each of the indices in `indices` * @@ -19,14 +22,12 @@ export function computeDeltas( newBalances: EffectiveBalanceIncrements, equivocatingIndices: Set ): number[] { - const deltas = new Array(numProtoNodes); - for (let i = 0; i < numProtoNodes; i++) { - deltas[i] = 0; - } + deltas.length = numProtoNodes; + deltas.fill(0); // avoid creating new variables in the loop to potentially reduce GC pressure - let oldBalance, newBalance: number; - let currentIndex, nextIndex: number | null; + let oldBalance: number, newBalance: number; + let currentIndex: number | null, nextIndex: number | null; for (let vIndex = 0; vIndex < votes.length; vIndex++) { const vote = votes[vIndex]; @@ -47,7 +48,7 @@ export function computeDeltas( // It is possible that there was a vote for an unknown validator if we change our justified // state to a new state with a higher epoch that is on a different fork because that fork may have // on-boarded fewer validators than the prior fork. - newBalance = newBalances[vIndex] ?? 0; + newBalance = newBalances === oldBalances ? oldBalance : (newBalances[vIndex] ?? 0); if (equivocatingIndices.size > 0 && equivocatingIndices.has(vIndex)) { // this function could be called multiple times but we only want to process slashing validator for 1 time diff --git a/packages/fork-choice/src/protoArray/errors.ts b/packages/fork-choice/src/protoArray/errors.ts index 2e044de154e1..650fd1c0b244 100644 --- a/packages/fork-choice/src/protoArray/errors.ts +++ b/packages/fork-choice/src/protoArray/errors.ts @@ -56,8 +56,4 @@ export type ProtoArrayErrorType = | {code: ProtoArrayErrorCode.INVALID_JUSTIFIED_EXECUTION_STATUS; root: RootHex} | ({code: ProtoArrayErrorCode.INVALID_LVH_EXECUTION_RESPONSE} & LVHExecError); -export class ProtoArrayError extends LodestarError { - constructor(type: ProtoArrayErrorType) { - super(type); - } -} +export class ProtoArrayError extends LodestarError {} diff --git a/packages/fork-choice/src/protoArray/protoArray.ts b/packages/fork-choice/src/protoArray/protoArray.ts index 0b793d2be099..82a8b2620880 100644 --- a/packages/fork-choice/src/protoArray/protoArray.ts +++ b/packages/fork-choice/src/protoArray/protoArray.ts @@ -304,9 +304,9 @@ export class ProtoArray { * EL is lazy (or buggy) with its LVH response. */ throw Error(`Unable to find latestValidExecHash=${latestValidExecHash} in the forkchoice`); - } else { - this.propagateInValidExecutionStatusByIndex(invalidateFromParentIndex, latestValidHashIndex, currentSlot); } + + this.propagateInValidExecutionStatusByIndex(invalidateFromParentIndex, latestValidHashIndex, currentSlot); } } @@ -431,7 +431,9 @@ export class ProtoArray { code: ProtoArrayErrorCode.INVALID_LVH_EXECUTION_RESPONSE, ...this.lvhError, }); - } else if (validNode.executionStatus === ExecutionStatus.Syncing) { + } + + if (validNode.executionStatus === ExecutionStatus.Syncing) { validNode.executionStatus = ExecutionStatus.Valid; } return validNode; @@ -808,10 +810,9 @@ export class ProtoArray { descendantRoot: blockRoot, ancestorSlot, }); - } else { - // Root is older or equal than queried slot, thus a skip slot. Return most recent root prior to slot. - return blockRoot; } + // Root is older or equal than queried slot, thus a skip slot. Return most recent root prior to slot. + return blockRoot; } /** @@ -964,7 +965,6 @@ export class ProtoArray { * Returns a common ancestor for nodeA or nodeB or null if there's none */ getCommonAncestor(nodeA: ProtoNode, nodeB: ProtoNode): ProtoNode | null { - // eslint-disable-next-line no-constant-condition while (true) { // If nodeA is higher than nodeB walk up nodeA tree if (nodeA.slot > nodeB.slot) { diff --git a/packages/fork-choice/test/unit/forkChoice/forkChoice.test.ts b/packages/fork-choice/test/unit/forkChoice/forkChoice.test.ts index 40988a0e4a71..f47849136bff 100644 --- a/packages/fork-choice/test/unit/forkChoice/forkChoice.test.ts +++ b/packages/fork-choice/test/unit/forkChoice/forkChoice.test.ts @@ -14,11 +14,9 @@ import { EpochDifference, DataAvailabilityStatus, } from "../../../src/index.js"; +import {getBlockRoot, getStateRoot} from "../../utils/index.js"; -const rootStateBytePrefix = 0xaa; -const rootBlockBytePrefix = 0xbb; - -describe("Forkchoice", function () { +describe("Forkchoice", () => { const genesisSlot = 0; const genesisEpoch = 0; const genesisRoot = "0x0000000000000000000000000000000000000000000000000000000000000000"; @@ -118,7 +116,7 @@ describe("Forkchoice", function () { } }; - it("getAllAncestorBlocks", function () { + it("getAllAncestorBlocks", () => { // Add block that is a finalized descendant. const block = getBlock(genesisSlot + 1); protoArr.onBlock(block, block.slot); @@ -175,20 +173,6 @@ describe("Forkchoice", function () { // TODO: more unit tests for other apis }); -export function getStateRoot(slot: number): RootHex { - const root = Buffer.alloc(32, 0x00); - root[0] = rootStateBytePrefix; - root[31] = slot; - return toHex(root); -} - -export function getBlockRoot(slot: number): RootHex { - const root = Buffer.alloc(32, 0x00); - root[0] = rootBlockBytePrefix; - root[31] = slot; - return toHex(root); -} - function range(from: number, toInclusive: number): number[] { const arr: number[] = []; for (let i = from; i <= toInclusive; i++) { diff --git a/packages/fork-choice/test/unit/forkChoice/getProposerHead.test.ts b/packages/fork-choice/test/unit/forkChoice/getProposerHead.test.ts index f603a4069b83..187834e6d63a 100644 --- a/packages/fork-choice/test/unit/forkChoice/getProposerHead.test.ts +++ b/packages/fork-choice/test/unit/forkChoice/getProposerHead.test.ts @@ -13,11 +13,11 @@ import { DataAvailabilityStatus, } from "../../../src/index.js"; import {NotReorgedReason} from "../../../src/forkChoice/interface.js"; -import {getBlockRoot, getStateRoot} from "./forkChoice.test.js"; +import {getBlockRoot, getStateRoot} from "../../utils/index.js"; type ProtoBlockWithWeight = ProtoBlock & {weight: number}; // weight of the block itself -describe("Forkchoice / GetProposerHead", function () { +describe("Forkchoice / GetProposerHead", () => { const genesisSlot = 0; const genesisEpoch = 0; const genesisRoot = "0x0000000000000000000000000000000000000000000000000000000000000000"; diff --git a/packages/fork-choice/test/unit/forkChoice/utils.test.ts b/packages/fork-choice/test/unit/forkChoice/utils.test.ts index 3f315d079842..44b0eb8b719b 100644 --- a/packages/fork-choice/test/unit/forkChoice/utils.test.ts +++ b/packages/fork-choice/test/unit/forkChoice/utils.test.ts @@ -3,12 +3,11 @@ import {createChainForkConfig} from "@lodestar/config"; import {ssz} from "@lodestar/types"; import {assertValidTerminalPowBlock, ExecutionStatus} from "../../../src/index.js"; -describe("assertValidTerminalPowBlock", function () { - // eslint-disable-next-line @typescript-eslint/naming-convention +describe("assertValidTerminalPowBlock", () => { const config = createChainForkConfig({TERMINAL_TOTAL_DIFFICULTY: BigInt(10)}); const block = ssz.bellatrix.BeaconBlock.defaultValue(); const executionStatus = ExecutionStatus.Valid; - it("should accept ttd >= genesis block as terminal without powBlockParent", function () { + it("should accept ttd >= genesis block as terminal without powBlockParent", () => { const powBlock = { blockHash: "0x" + "ab".repeat(32), // genesis powBlock will have zero parent hash @@ -20,7 +19,7 @@ describe("assertValidTerminalPowBlock", function () { ).not.toThrow(); }); - it("should require powBlockParent if powBlock not genesis", function () { + it("should require powBlockParent if powBlock not genesis", () => { const powBlock = { blockHash: "0x" + "ab".repeat(32), // genesis powBlock will have non zero parent hash @@ -32,7 +31,7 @@ describe("assertValidTerminalPowBlock", function () { ).toThrow(); }); - it("should require powBlock >= ttd", function () { + it("should require powBlock >= ttd", () => { const powBlock = { blockHash: "0x" + "ab".repeat(32), // genesis powBlock will have non zero parent hash @@ -44,7 +43,7 @@ describe("assertValidTerminalPowBlock", function () { ).toThrow(); }); - it("should require powBlockParent < ttd", function () { + it("should require powBlockParent < ttd", () => { const powBlock = { blockHash: "0x" + "ab".repeat(32), // genesis powBlock will have non zero parent hash @@ -56,7 +55,7 @@ describe("assertValidTerminalPowBlock", function () { ).toThrow(); }); - it("should accept powBlockParent < ttd and powBlock >= ttd", function () { + it("should accept powBlockParent < ttd and powBlock >= ttd", () => { const powBlock = { blockHash: "0x" + "ab".repeat(32), // genesis powBlock will have non zero parent hash diff --git a/packages/fork-choice/test/unit/protoArray/getCommonAncestor.test.ts b/packages/fork-choice/test/unit/protoArray/getCommonAncestor.test.ts index fdf1a1f3bae4..b9b7f9c37b43 100644 --- a/packages/fork-choice/test/unit/protoArray/getCommonAncestor.test.ts +++ b/packages/fork-choice/test/unit/protoArray/getCommonAncestor.test.ts @@ -77,9 +77,13 @@ describe("getCommonAncestor", () => { for (const {nodeA, nodeB, ancestor} of testCases) { it(`${nodeA} & ${nodeB} -> ${ancestor}`, () => { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + // biome-ignore lint/style/noNonNullAssertion: const ancestorNode = fc.getCommonAncestor(fc.getNode(nodeA)!, fc.getNode(nodeB)!); - expect(ancestorNode && ancestorNode.blockRoot).toBe(ancestor); + if (ancestor) { + expect(ancestorNode?.blockRoot).toBe(ancestor); + } else { + expect(ancestorNode).toBeNull(); + } }); } diff --git a/packages/fork-choice/test/utils/index.ts b/packages/fork-choice/test/utils/index.ts new file mode 100644 index 000000000000..8354a8c31d56 --- /dev/null +++ b/packages/fork-choice/test/utils/index.ts @@ -0,0 +1,19 @@ +import {RootHex} from "@lodestar/types"; +import {toHex} from "@lodestar/utils"; + +const rootStateBytePrefix = 0xaa; +const rootBlockBytePrefix = 0xbb; + +export function getStateRoot(slot: number): RootHex { + const root = Buffer.alloc(32, 0x00); + root[0] = rootStateBytePrefix; + root[31] = slot; + return toHex(root); +} + +export function getBlockRoot(slot: number): RootHex { + const root = Buffer.alloc(32, 0x00); + root[0] = rootBlockBytePrefix; + root[31] = slot; + return toHex(root); +} diff --git a/packages/light-client/package.json b/packages/light-client/package.json index 2eda3a45d455..a503d6bc510e 100644 --- a/packages/light-client/package.json +++ b/packages/light-client/package.json @@ -62,8 +62,8 @@ "check-bundle": "node -e \"(async function() { await import('./dist/lightclient.min.mjs') })()\"", "build:release": "yarn clean && yarn run build && yarn run build:bundle", "check-types": "tsc", - "lint": "eslint --color --ext .ts src/ test/", - "lint:fix": "yarn run lint --fix", + "lint": "biome check src/ test/", + "lint:fix": "yarn run lint --write", "test": "yarn test:unit", "test:unit": "vitest --run --dir test/unit/", "test:browsers": "yarn test:browsers:chrome && yarn test:browsers:firefox && yarn test:browsers:electron", diff --git a/packages/light-client/src/events.ts b/packages/light-client/src/events.ts index 5b561718e89e..7c01843d8ad0 100644 --- a/packages/light-client/src/events.ts +++ b/packages/light-client/src/events.ts @@ -15,7 +15,7 @@ export type LightclientEmitterEvents = { export type LightclientEmitter = MittEmitter; -// eslint-disable-next-line @typescript-eslint/no-explicit-any +// biome-ignore lint/suspicious/noExplicitAny: export type MittEmitter void>> = { on(type: K, handler: T[K]): void; off(type: K, handler: T[K]): void; diff --git a/packages/light-client/src/index.ts b/packages/light-client/src/index.ts index 5ec0dd73b469..098ea18adc31 100644 --- a/packages/light-client/src/index.ts +++ b/packages/light-client/src/index.ts @@ -224,7 +224,6 @@ export class Lightclient { } private async runLoop(): Promise { - // eslint-disable-next-line no-constant-condition while (true) { const currentPeriod = computeSyncPeriodAtSlot(this.currentSlot); // Check if we have a sync committee for the current clock period diff --git a/packages/light-client/src/spec/isBetterUpdate.ts b/packages/light-client/src/spec/isBetterUpdate.ts index 260d54434fba..00220cd6b5dd 100644 --- a/packages/light-client/src/spec/isBetterUpdate.ts +++ b/packages/light-client/src/spec/isBetterUpdate.ts @@ -28,49 +28,49 @@ export function isBetterUpdate(newUpdate: LightClientUpdateSummary, oldUpdate: L const oldNumActiveParticipants = oldUpdate.activeParticipants; const newHasSupermajority = newNumActiveParticipants * 3 >= SYNC_COMMITTEE_SIZE * 2; const oldHasSupermajority = oldNumActiveParticipants * 3 >= SYNC_COMMITTEE_SIZE * 2; - if (newHasSupermajority != oldHasSupermajority) { + if (newHasSupermajority !== oldHasSupermajority) { return newHasSupermajority; } - if (!newHasSupermajority && newNumActiveParticipants != oldNumActiveParticipants) { + if (!newHasSupermajority && newNumActiveParticipants !== oldNumActiveParticipants) { return newNumActiveParticipants > oldNumActiveParticipants; } // Compare presence of relevant sync committee const newHasRelevantSyncCommittee = newUpdate.isSyncCommitteeUpdate && - computeSyncPeriodAtSlot(newUpdate.attestedHeaderSlot) == computeSyncPeriodAtSlot(newUpdate.signatureSlot); + computeSyncPeriodAtSlot(newUpdate.attestedHeaderSlot) === computeSyncPeriodAtSlot(newUpdate.signatureSlot); const oldHasRelevantSyncCommittee = oldUpdate.isSyncCommitteeUpdate && - computeSyncPeriodAtSlot(oldUpdate.attestedHeaderSlot) == computeSyncPeriodAtSlot(oldUpdate.signatureSlot); - if (newHasRelevantSyncCommittee != oldHasRelevantSyncCommittee) { + computeSyncPeriodAtSlot(oldUpdate.attestedHeaderSlot) === computeSyncPeriodAtSlot(oldUpdate.signatureSlot); + if (newHasRelevantSyncCommittee !== oldHasRelevantSyncCommittee) { return newHasRelevantSyncCommittee; } // Compare indication of any finality const newHasFinality = newUpdate.isFinalityUpdate; const oldHasFinality = oldUpdate.isFinalityUpdate; - if (newHasFinality != oldHasFinality) { + if (newHasFinality !== oldHasFinality) { return newHasFinality; } // Compare sync committee finality if (newHasFinality) { const newHasSyncCommitteeFinality = - computeSyncPeriodAtSlot(newUpdate.finalizedHeaderSlot) == computeSyncPeriodAtSlot(newUpdate.attestedHeaderSlot); + computeSyncPeriodAtSlot(newUpdate.finalizedHeaderSlot) === computeSyncPeriodAtSlot(newUpdate.attestedHeaderSlot); const oldHasSyncCommitteeFinality = - computeSyncPeriodAtSlot(oldUpdate.finalizedHeaderSlot) == computeSyncPeriodAtSlot(oldUpdate.attestedHeaderSlot); - if (newHasSyncCommitteeFinality != oldHasSyncCommitteeFinality) { + computeSyncPeriodAtSlot(oldUpdate.finalizedHeaderSlot) === computeSyncPeriodAtSlot(oldUpdate.attestedHeaderSlot); + if (newHasSyncCommitteeFinality !== oldHasSyncCommitteeFinality) { return newHasSyncCommitteeFinality; } } // Tiebreaker 1: Sync committee participation beyond supermajority - if (newNumActiveParticipants != oldNumActiveParticipants) { + if (newNumActiveParticipants !== oldNumActiveParticipants) { return newNumActiveParticipants > oldNumActiveParticipants; } // Tiebreaker 2: Prefer older data (fewer changes to best) - if (newUpdate.attestedHeaderSlot != oldUpdate.attestedHeaderSlot) { + if (newUpdate.attestedHeaderSlot !== oldUpdate.attestedHeaderSlot) { return newUpdate.attestedHeaderSlot < oldUpdate.attestedHeaderSlot; } return newUpdate.signatureSlot < oldUpdate.signatureSlot; diff --git a/packages/light-client/src/spec/utils.ts b/packages/light-client/src/spec/utils.ts index 408412464606..36bc7098fcc5 100644 --- a/packages/light-client/src/spec/utils.ts +++ b/packages/light-client/src/spec/utils.ts @@ -96,17 +96,19 @@ export function upgradeLightClientHeader( const startUpgradeFromFork = Object.values(ForkName)[ForkSeq[headerFork] + 1]; switch (startUpgradeFromFork) { + // biome-ignore lint/suspicious/useDefaultSwitchClauseLast: We want default to evaluate at first to throw error early default: throw Error( `Invalid startUpgradeFromFork=${startUpgradeFromFork} for headerFork=${headerFork} in upgradeLightClientHeader to targetFork=${targetFork}` ); case ForkName.altair: + // biome-ignore lint/suspicious/noFallthroughSwitchClause: We need fall-through behavior here case ForkName.bellatrix: // Break if no further upgradation is required else fall through if (ForkSeq[targetFork] <= ForkSeq.bellatrix) break; - // eslint-disable-next-line no-fallthrough + // biome-ignore lint/suspicious/noFallthroughSwitchClause: We need fall-through behavior here case ForkName.capella: (upgradedHeader as LightClientHeader).execution = ssz.capella.LightClientHeader.fields.execution.defaultValue(); @@ -116,7 +118,7 @@ export function upgradeLightClientHeader( // Break if no further upgradation is required else fall through if (ForkSeq[targetFork] <= ForkSeq.capella) break; - // eslint-disable-next-line no-fallthrough + // biome-ignore lint/suspicious/noFallthroughSwitchClause: We need fall-through behavior here case ForkName.deneb: (upgradedHeader as LightClientHeader).execution.blobGasUsed = ssz.deneb.LightClientHeader.fields.execution.fields.blobGasUsed.defaultValue(); @@ -126,7 +128,6 @@ export function upgradeLightClientHeader( // Break if no further upgradation is required else fall through if (ForkSeq[targetFork] <= ForkSeq.deneb) break; - // eslint-disable-next-line no-fallthrough case ForkName.electra: // No changes to LightClientHeader in Electra diff --git a/packages/light-client/src/utils/clock.ts b/packages/light-client/src/utils/clock.ts index 44b74b1b601b..efe210b620d8 100644 --- a/packages/light-client/src/utils/clock.ts +++ b/packages/light-client/src/utils/clock.ts @@ -39,7 +39,7 @@ export function timeUntilNextEpoch(config: Pick const msFromGenesis = Date.now() - genesisTime * 1000; if (msFromGenesis >= 0) { return milliSecondsPerEpoch - (msFromGenesis % milliSecondsPerEpoch); - } else { - return Math.abs(msFromGenesis % milliSecondsPerEpoch); } + + return Math.abs(msFromGenesis % milliSecondsPerEpoch); } diff --git a/packages/light-client/src/utils/logger.ts b/packages/light-client/src/utils/logger.ts index afdbf7da7d3d..1f13b98bd6c6 100644 --- a/packages/light-client/src/utils/logger.ts +++ b/packages/light-client/src/utils/logger.ts @@ -1,4 +1,4 @@ -// eslint-disable-next-line @typescript-eslint/no-explicit-any +// biome-ignore lint/suspicious/noExplicitAny: export type LogHandler = (message: string, context?: any, error?: Error) => void; export type ILcLogger = { diff --git a/packages/light-client/test/unit/isValidLightClientHeader.test.ts b/packages/light-client/test/unit/isValidLightClientHeader.test.ts index db27a8266103..2bbbd1250961 100644 --- a/packages/light-client/test/unit/isValidLightClientHeader.test.ts +++ b/packages/light-client/test/unit/isValidLightClientHeader.test.ts @@ -4,8 +4,7 @@ import {LightClientHeader, ssz} from "@lodestar/types"; import {createBeaconConfig, createChainForkConfig, defaultChainConfig} from "@lodestar/config"; import {isValidLightClientHeader} from "../../src/spec/utils.js"; -describe("isValidLightClientHeader", function () { - /* eslint-disable @typescript-eslint/naming-convention */ +describe("isValidLightClientHeader", () => { const chainConfig = createChainForkConfig({ ...defaultChainConfig, ALTAIR_FORK_EPOCH: 0, @@ -88,10 +87,10 @@ describe("isValidLightClientHeader", function () { ["capella upgraded to deneb LC header", capellaUpgradedDenebHeader], ]; - testCases.forEach(([name, header]: [string, LightClientHeader]) => { - it(name, function () { + for (const [name, header] of testCases) { + it(name, () => { const isValid = isValidLightClientHeader(config, header); expect(isValid).toBe(true); }); - }); + } }); diff --git a/packages/light-client/test/unit/sync.node.test.ts b/packages/light-client/test/unit/sync.node.test.ts index bcd1d0f25d0b..52afd05760d7 100644 --- a/packages/light-client/test/unit/sync.node.test.ts +++ b/packages/light-client/test/unit/sync.node.test.ts @@ -45,7 +45,6 @@ describe("sync", () => { const targetSlot = firstHeadSlot + slotsIntoPeriod; // Genesis data such that targetSlot is at the current clock slot - // eslint-disable-next-line @typescript-eslint/naming-convention const chainConfig: ChainConfig = {...chainConfigDef, SECONDS_PER_SLOT, ALTAIR_FORK_EPOCH}; const genesisTime = Math.floor(Date.now() / 1000) - chainConfig.SECONDS_PER_SLOT * targetSlot; const genesisValidatorsRoot = Buffer.alloc(32, 0xaa); diff --git a/packages/light-client/test/unit/syncInMemory.test.ts b/packages/light-client/test/unit/syncInMemory.test.ts index 770827e86655..6118a1b4e61a 100644 --- a/packages/light-client/test/unit/syncInMemory.test.ts +++ b/packages/light-client/test/unit/syncInMemory.test.ts @@ -22,7 +22,7 @@ function getSyncCommittee( return syncCommitteeKeys; } -describe("syncInMemory", function () { +describe("syncInMemory", () => { // In browser test this process is taking more time than default 2000ms vi.setConfig({testTimeout: 10000}); @@ -39,9 +39,7 @@ describe("syncInMemory", function () { expect(sk.toPublicKey().toHex()).toBe( "0xaa1a1c26055a329817a5759d877a2795f9499b97d6056edde0eea39512f24e8bc874b4471f0501127abb1ea0d9f68ac1" ); - }); - beforeAll(() => { // Create a state that has as nextSyncCommittee the committee 2 const finalizedBlockSlot = SLOTS_PER_EPOCH * EPOCHS_PER_SYNC_COMMITTEE_PERIOD + 1; const headerBlockSlot = finalizedBlockSlot + 1; diff --git a/packages/light-client/test/unit/validation.test.ts b/packages/light-client/test/unit/validation.test.ts index 61442fb4bf8c..6ed3b714a690 100644 --- a/packages/light-client/test/unit/validation.test.ts +++ b/packages/light-client/test/unit/validation.test.ts @@ -15,7 +15,7 @@ import {assertValidLightClientUpdate} from "../../src/validation.js"; import {LightClientSnapshotFast, SyncCommitteeFast} from "../../src/types.js"; import {defaultBeaconBlockHeader, getSyncAggregateSigningRoot, signAndAggregate} from "../utils/utils.js"; -describe("validation", function () { +describe("validation", () => { // In browser test this process is taking more time than default 2000ms // specially on the CI vi.setConfig({testTimeout: 15000}); @@ -26,7 +26,7 @@ describe("validation", function () { let update: altair.LightClientUpdate; let snapshot: LightClientSnapshotFast; - beforeAll(function () { + beforeAll(() => { // Update slot must > snapshot slot // attestedHeaderSlot must == updateHeaderSlot + 1 const snapshotHeaderSlot = 1; diff --git a/packages/logger/package.json b/packages/logger/package.json index 196fb306a8b0..3d6ee5a0d874 100644 --- a/packages/logger/package.json +++ b/packages/logger/package.json @@ -53,8 +53,8 @@ "build:release": "yarn clean && yarn build", "check-build": "node -e \"(async function() { await import('./lib/index.js') })()\"", "check-types": "tsc", - "lint": "eslint --color --ext .ts src/ test/", - "lint:fix": "yarn run lint --fix", + "lint": "biome check src/ test/", + "lint:fix": "yarn run lint --write", "test": "yarn test:unit && yarn test:e2e", "test:unit": "vitest --run --dir test/unit/", "test:browsers": "yarn test:browsers:chrome && yarn test:browsers:firefox && yarn test:browsers:electron", diff --git a/packages/logger/src/browser.ts b/packages/logger/src/browser.ts index fc91fcfcd2a3..7f4972111459 100644 --- a/packages/logger/src/browser.ts +++ b/packages/logger/src/browser.ts @@ -57,7 +57,7 @@ class BrowserConsole extends Transport { constructor(opts: winston.transport.TransportStreamOptions | undefined) { super(opts); - this.level = opts?.level && this.levels.hasOwnProperty(opts.level) ? opts.level : "info"; + this.level = opts?.level && Object.prototype.hasOwnProperty.call(this.levels, opts.level) ? opts.level : "info"; } log(info: WinstonLogInfo, callback: () => void): void { @@ -70,9 +70,7 @@ class BrowserConsole extends Transport { const message = info[MESSAGE]; if (val <= this.levels[this.level as LogLevel]) { - // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-expect-error - // eslint-disable-next-line @typescript-eslint/no-unsafe-call, no-console console[mappedMethod](message); } diff --git a/packages/logger/src/env.ts b/packages/logger/src/env.ts index 201d91c69069..e81ae9613e15 100644 --- a/packages/logger/src/env.ts +++ b/packages/logger/src/env.ts @@ -6,20 +6,18 @@ import {LogFormat, TimestampFormat} from "./interface.js"; export function getEnvLogLevel(): LogLevel | null { if (process == null) return null; - if (process.env["LOG_LEVEL"]) return process.env["LOG_LEVEL"] as LogLevel; - if (process.env["DEBUG"]) return LogLevel.debug; - if (process.env["VERBOSE"]) return LogLevel.verbose; + if (process.env.LOG_LEVEL) return process.env.LOG_LEVEL as LogLevel; + if (process.env.DEBUG) return LogLevel.debug; + if (process.env.VERBOSE) return LogLevel.verbose; return null; } export function getEnvLogger(opts?: Partial): Logger { const level = opts?.level ?? getEnvLogLevel(); - const format = (opts?.format ?? process.env["LOG_FORMAT"]) as LogFormat; + const format = (opts?.format ?? process.env.LOG_FORMAT) as LogFormat; const timestampFormat = opts?.timestampFormat ?? - ((process.env["LOG_TIMESTAMP_FORMAT"] - ? {format: process.env["LOG_TIMESTAMP_FORMAT"]} - : undefined) as TimestampFormat); + ((process.env.LOG_TIMESTAMP_FORMAT ? {format: process.env.LOG_TIMESTAMP_FORMAT} : undefined) as TimestampFormat); if (level != null) { return getBrowserLogger({...opts, level, format, timestampFormat}); diff --git a/packages/logger/src/interface.ts b/packages/logger/src/interface.ts index 8f270b0dc4ee..e3ba8483a458 100644 --- a/packages/logger/src/interface.ts +++ b/packages/logger/src/interface.ts @@ -1,4 +1,3 @@ -// eslint-disable-next-line import/no-extraneous-dependencies import {LEVEL, MESSAGE} from "triple-beam"; import {LogLevel, Logger, LogHandler, LogData} from "@lodestar/utils"; @@ -15,7 +14,6 @@ export const logLevelNum: {[K in LogLevel]: number} = { [LogLevel.trace]: 5, }; -// eslint-disable-next-line @typescript-eslint/naming-convention export const LogLevels = Object.values(LogLevel); export type LogFormat = "human" | "json"; diff --git a/packages/logger/src/node.ts b/packages/logger/src/node.ts index 60ca87e0367c..fcd9c535dd9e 100644 --- a/packages/logger/src/node.ts +++ b/packages/logger/src/node.ts @@ -128,7 +128,7 @@ export class WinstonLoggerNode extends WinstonLogger implements LoggerNode { } static fromOpts(opts: LoggerNodeOpts, transports: winston.transport[]): WinstonLoggerNode { - return new WinstonLoggerNode(this.createWinstonInstance(opts, transports), opts); + return new WinstonLoggerNode(WinstonLoggerNode.createWinstonInstance(opts, transports), opts); } static fromNewTransports(opts: LoggerNodeOpts): WinstonLoggerNode { diff --git a/packages/logger/src/utils/consoleTransport.ts b/packages/logger/src/utils/consoleTransport.ts index 41a1084b4b83..6bfd62b2ecd8 100644 --- a/packages/logger/src/utils/consoleTransport.ts +++ b/packages/logger/src/utils/consoleTransport.ts @@ -26,6 +26,7 @@ export class ConsoleDynamicLevel extends transports.Console { return this.levelByModule.delete(module); } + // biome-ignore lint/correctness/noUndeclaredVariables: BufferEncoding is not been identified by the biomejs _write(info: WinstonLogInfo, enc: BufferEncoding, callback: (error?: Error | null | undefined) => void): void { const moduleLevel = this.levelByModule.get(info.module) ?? this.defaultLevel; diff --git a/packages/logger/src/utils/format.ts b/packages/logger/src/utils/format.ts index 651dc56ce687..4e657c0040af 100644 --- a/packages/logger/src/utils/format.ts +++ b/packages/logger/src/utils/format.ts @@ -21,8 +21,8 @@ export function getFormat(opts: LoggerOptions): Format { switch (opts.format) { case "json": return jsonLogFormat(opts); - case "human": + return humanReadableLogFormat(opts); default: return humanReadableLogFormat(opts); } @@ -49,6 +49,7 @@ function formatTimestamp(opts: LoggerOptions): Format { }; case TimestampFormatCode.DateRegular: + return format.timestamp({format: "MMM-DD HH:mm:ss.SSS"}); default: return format.timestamp({format: "MMM-DD HH:mm:ss.SSS"}); } @@ -70,7 +71,8 @@ function jsonLogFormat(opts: LoggerOptions): Format { /** * Winston template function print a human readable string given a log object */ -// eslint-disable-next-line @typescript-eslint/no-explicit-any + +// biome-ignore lint/suspicious/noExplicitAny: function humanReadableTemplateFn(_info: {[key: string]: any; level: string; message: string}): string { const info = _info as WinstonInfoArg; diff --git a/packages/logger/src/utils/json.ts b/packages/logger/src/utils/json.ts index 7408de582dd1..bab060cc8187 100644 --- a/packages/logger/src/utils/json.ts +++ b/packages/logger/src/utils/json.ts @@ -44,10 +44,9 @@ export function logCtxToJson(arg: unknown, depth = 0, fromError = false): LogDat if (arg instanceof LodestarError) { if (fromError) { return "[LodestarErrorCircular]"; - } else { - // Allow one extra depth level for LodestarError - metadata = logCtxToJson(arg.getMetadata(), depth - 1, true) as Record; } + // Allow one extra depth level for LodestarError + metadata = logCtxToJson(arg.getMetadata(), depth - 1, true) as Record; } else { metadata = {message: arg.message}; } @@ -105,10 +104,9 @@ export function logCtxToString(arg: unknown, depth = 0, fromError = false): stri if (arg instanceof LodestarError) { if (fromError) { return "[LodestarErrorCircular]"; - } else { - // Allow one extra depth level for LodestarError - metadata = logCtxToString(arg.getMetadata(), depth - 1, true); } + // Allow one extra depth level for LodestarError + metadata = logCtxToString(arg.getMetadata(), depth - 1, true); } else { metadata = arg.message; } @@ -127,6 +125,7 @@ export function logCtxToString(arg: unknown, depth = 0, fromError = false): stri case "string": case "undefined": case "boolean": + return String(arg); default: return String(arg); } diff --git a/packages/logger/src/winston.ts b/packages/logger/src/winston.ts index 4e6fbbecd6b2..b886894e6aba 100644 --- a/packages/logger/src/winston.ts +++ b/packages/logger/src/winston.ts @@ -42,7 +42,7 @@ export class WinstonLogger implements Logger { constructor(protected readonly winston: Winston) {} static fromOpts(options: Partial = {}, transports?: winston.transport[]): WinstonLogger { - return new WinstonLogger(this.createWinstonInstance(options, transports)); + return new WinstonLogger(WinstonLogger.createWinstonInstance(options, transports)); } static createWinstonInstance(options: Partial = {}, transports?: winston.transport[]): Winston { diff --git a/packages/logger/test/e2e/logger/workerLogger.js b/packages/logger/test/e2e/logger/workerLogger.js index 9608336c433f..83d1c857631f 100644 --- a/packages/logger/test/e2e/logger/workerLogger.js +++ b/packages/logger/test/e2e/logger/workerLogger.js @@ -9,7 +9,6 @@ if (!parentPort) throw Error("parentPort must be defined"); const file = fs.createWriteStream(workerData.logFilepath, {flags: "a"}); parentPort.on("message", (data) => { - // eslint-disable-next-line no-console console.log(data); file.write(data); }); diff --git a/packages/logger/test/e2e/logger/workerLogs.test.ts b/packages/logger/test/e2e/logger/workerLogs.test.ts index 3c81cbf92c57..01ede8f6e4ec 100644 --- a/packages/logger/test/e2e/logger/workerLogs.test.ts +++ b/packages/logger/test/e2e/logger/workerLogs.test.ts @@ -7,10 +7,9 @@ import {LoggerWorker, getLoggerWorker} from "./workerLoggerHandler.js"; // Global variable __dirname no longer available in ES6 modules. // Solutions: https://stackoverflow.com/questions/46745014/alternative-for-dirname-in-node-js-when-using-es6-modules -// eslint-disable-next-line @typescript-eslint/naming-convention const __dirname = path.dirname(fileURLToPath(import.meta.url)); -describe("worker logs", function () { +describe("worker logs", () => { vi.setConfig({testTimeout: 60_000}); const logFilepath = path.join(__dirname, "../../../test-logs/test_worker_logs.log"); diff --git a/packages/logger/test/unit/node.node.test.ts b/packages/logger/test/unit/node.node.test.ts index 12782fa49af8..b7c882a1e3bd 100644 --- a/packages/logger/test/unit/node.node.test.ts +++ b/packages/logger/test/unit/node.node.test.ts @@ -6,7 +6,7 @@ import {formatsTestCases} from "../fixtures/loggerFormats.js"; // Node.js maps `process.stdout` to `console._stdout`. // spy does not work on `process.stdout` directly. -// eslint-disable-next-line @typescript-eslint/naming-convention +// biome-ignore lint/style/useNamingConvention: Need property name _stdout for testing type TestConsole = typeof console & {_stdout: {write: Mock}}; describe("node logger", () => { diff --git a/packages/logger/test/unit/utils/json.test.ts b/packages/logger/test/unit/utils/json.test.ts index 912f15fa958b..7ca5604edf00 100644 --- a/packages/logger/test/unit/utils/json.test.ts +++ b/packages/logger/test/unit/utils/json.test.ts @@ -24,8 +24,10 @@ describe("Json helper", () => { {id: "symbol", arg: Symbol("foo"), json: "Symbol(foo)"}, // Functions + // biome-ignore lint/complexity/useArrowFunction: We need a function for the this test {id: "function", arg: function () {}, json: "function() {\n }"}, {id: "arrow function", arg: () => {}, json: "() => {\n }"}, + // biome-ignore lint/complexity/useArrowFunction: We need a function for the this test {id: "async function", arg: async function () {}, json: "async function() {\n }"}, {id: "async arrow function", arg: async () => {}, json: "async () => {\n }"}, @@ -113,7 +115,6 @@ describe("Json helper", () => { // Circular references () => { const circularReference: any = {}; - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access circularReference.myself = circularReference; return { id: "circular reference", @@ -161,8 +162,7 @@ describe("Json helper", () => { // Objects {id: "object of basic types", json: {a: 1, b: "a", c: root}, output: `a=1, b=a, c=${rootHex}`}, - // eslint-disable-next-line quotes - {id: "object of objects", json: {a: {b: 1}}, output: `a=[object]`}, + {id: "object of objects", json: {a: {b: 1}}, output: "a=[object]"}, { id: "error metadata", json: { @@ -175,7 +175,6 @@ describe("Json helper", () => { // Circular references () => { const circularReference: any = {}; - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access circularReference.myself = circularReference; return { id: "circular reference", diff --git a/packages/logger/test/unit/winston.node.test.ts b/packages/logger/test/unit/winston.node.test.ts index 8ef49da4e02d..e4cfca2b041a 100644 --- a/packages/logger/test/unit/winston.node.test.ts +++ b/packages/logger/test/unit/winston.node.test.ts @@ -8,7 +8,7 @@ import {readFileWhenExists} from "../utils/files.js"; // Node.js maps `process.stdout` to `console._stdout`. // spy does not work on `process.stdout` directly. -// eslint-disable-next-line @typescript-eslint/naming-convention +// biome-ignore lint/style/useNamingConvention: Need property name _stdout for testing type TestConsole = typeof console & {_stdout: {write: Mock}}; describe("winston logger", () => { diff --git a/packages/params/package.json b/packages/params/package.json index c281f97a41ec..33b8415170f1 100644 --- a/packages/params/package.json +++ b/packages/params/package.json @@ -50,8 +50,8 @@ "build:watch": "yarn run build --watch", "check-build": "node -e \"(async function() { await import('./lib/index.js') })()\"", "check-types": "tsc", - "lint": "eslint --color --ext .ts src/ test/", - "lint:fix": "yarn run lint --fix", + "lint": "biome check src/ test/", + "lint:fix": "yarn run lint --write", "test": "yarn test:unit", "test:unit": "vitest --run --dir test/unit/", "test:browsers": "yarn test:browsers:chrome && yarn test:browsers:firefox && yarn test:browsers:electron", diff --git a/packages/params/src/json.ts b/packages/params/src/json.ts index 8d475e680f4d..9fe49a920424 100644 --- a/packages/params/src/json.ts +++ b/packages/params/src/json.ts @@ -50,7 +50,7 @@ function deserializePresetValue(valueStr: unknown, keyName: string): number { const value = parseInt(valueStr, 10); - if (isNaN(value)) { + if (Number.isNaN(value)) { throw Error(`Invalid ${keyName} value ${valueStr} expected number`); } diff --git a/packages/params/src/presets/gnosis.ts b/packages/params/src/presets/gnosis.ts index 412c38a6eb82..5a4a2eac4113 100644 --- a/packages/params/src/presets/gnosis.ts +++ b/packages/params/src/presets/gnosis.ts @@ -4,7 +4,6 @@ import {mainnetPreset} from "./mainnet.js"; // Gnosis preset // https://github.com/gnosischain/specs/tree/master/consensus/preset/gnosis -/* eslint-disable @typescript-eslint/naming-convention */ export const gnosisPreset: BeaconPreset = { ...mainnetPreset, diff --git a/packages/params/src/presets/mainnet.ts b/packages/params/src/presets/mainnet.ts index ca599e990df4..a7225739037f 100644 --- a/packages/params/src/presets/mainnet.ts +++ b/packages/params/src/presets/mainnet.ts @@ -3,7 +3,6 @@ import {BeaconPreset} from "../types.js"; // Mainnet preset // https://github.com/ethereum/consensus-specs/tree/dev/presets/mainnet -/* eslint-disable @typescript-eslint/naming-convention */ export const mainnetPreset: BeaconPreset = { // Misc // --------------------------------------------------------------- diff --git a/packages/params/src/presets/minimal.ts b/packages/params/src/presets/minimal.ts index 5dc8fc10d803..d7ab2c27f342 100644 --- a/packages/params/src/presets/minimal.ts +++ b/packages/params/src/presets/minimal.ts @@ -3,7 +3,6 @@ import {BeaconPreset} from "../types.js"; // Minimal preset // https://github.com/ethereum/consensus-specs/tree/dev/presets/minimal -/* eslint-disable @typescript-eslint/naming-convention */ export const minimalPreset: BeaconPreset = { // Misc // --------------------------------------------------------------- diff --git a/packages/params/src/types.ts b/packages/params/src/types.ts index e867b4a3cf71..2fd88da9fde3 100644 --- a/packages/params/src/types.ts +++ b/packages/params/src/types.ts @@ -1,5 +1,3 @@ -/* eslint-disable @typescript-eslint/naming-convention */ - /** * Compile-time chain configuration */ diff --git a/packages/params/test/e2e/ensure-config-is-synced.test.ts b/packages/params/test/e2e/ensure-config-is-synced.test.ts index 38168fa02bae..2322b2e1ff10 100644 --- a/packages/params/test/e2e/ensure-config-is-synced.test.ts +++ b/packages/params/test/e2e/ensure-config-is-synced.test.ts @@ -10,15 +10,15 @@ import {loadConfigYaml} from "../yaml.js"; /** https://github.com/ethereum/consensus-specs/releases */ const specConfigCommit = "v1.5.0-alpha.3"; -describe("Ensure config is synced", function () { +describe("Ensure config is synced", () => { vi.setConfig({testTimeout: 60 * 1000}); - it("mainnet", async function () { + it("mainnet", async () => { const remotePreset = await downloadRemoteConfig("mainnet", specConfigCommit); assertCorrectPreset({...mainnetPreset}, remotePreset); }); - it("minimal", async function () { + it("minimal", async () => { const remotePreset = await downloadRemoteConfig("minimal", specConfigCommit); assertCorrectPreset({...minimalPreset}, remotePreset); }); @@ -44,7 +44,6 @@ async function downloadRemoteConfig(preset: "mainnet" | "minimal", commit: strin ); // Merge all the fetched yamls for the different forks - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment const beaconPresetRaw: Record = Object.assign( ...(downloadedParams as unknown as [input: Record]) ); diff --git a/packages/params/test/e2e/overridePreset.test.ts b/packages/params/test/e2e/overridePreset.test.ts index 24995cbaa042..df7afbbf84da 100644 --- a/packages/params/test/e2e/overridePreset.test.ts +++ b/packages/params/test/e2e/overridePreset.test.ts @@ -13,10 +13,9 @@ const exec = util.promisify(child.exec); // Global variable __dirname no longer available in ES6 modules. // Solutions: https://stackoverflow.com/questions/46745014/alternative-for-dirname-in-node-js-when-using-es6-modules -// eslint-disable-next-line @typescript-eslint/naming-convention const __dirname = path.dirname(fileURLToPath(import.meta.url)); -describe("Override preset", function () { +describe("Override preset", () => { // Allow time for ts-node to compile Typescript source vi.setConfig({testTimeout: 30_000}); diff --git a/packages/params/test/e2e/overridePresetError.ts b/packages/params/test/e2e/overridePresetError.ts index d5a665bece1f..869f521d33b5 100644 --- a/packages/params/test/e2e/overridePresetError.ts +++ b/packages/params/test/e2e/overridePresetError.ts @@ -5,5 +5,4 @@ import "../../lib/index.js"; import {setActivePreset, PresetName} from "../../lib/setPreset.js"; // This line should throw -// eslint-disable-next-line @typescript-eslint/naming-convention setActivePreset(PresetName.minimal, {SLOTS_PER_EPOCH: 2}); diff --git a/packages/params/test/e2e/overridePresetOk.ts b/packages/params/test/e2e/overridePresetOk.ts index 7373ecee7fff..8887155b5400 100644 --- a/packages/params/test/e2e/overridePresetOk.ts +++ b/packages/params/test/e2e/overridePresetOk.ts @@ -6,7 +6,6 @@ import assert from "node:assert"; // 1. Import from @lodestar/params/setPreset only import {setActivePreset, PresetName} from "../../src/setPreset.js"; -// eslint-disable-next-line @typescript-eslint/naming-convention setActivePreset(PresetName.minimal, {SLOTS_PER_EPOCH: 2}); // 2. Import from any other @lodestar/params paths diff --git a/packages/params/test/e2e/setPreset.test.ts b/packages/params/test/e2e/setPreset.test.ts index 844239d56bab..2108a4f23342 100644 --- a/packages/params/test/e2e/setPreset.test.ts +++ b/packages/params/test/e2e/setPreset.test.ts @@ -13,10 +13,9 @@ const exec = util.promisify(child.exec); // Global variable __dirname no longer available in ES6 modules. // Solutions: https://stackoverflow.com/questions/46745014/alternative-for-dirname-in-node-js-when-using-es6-modules -// eslint-disable-next-line @typescript-eslint/naming-convention const __dirname = path.dirname(fileURLToPath(import.meta.url)); -describe("setPreset", function () { +describe("setPreset", () => { // Allow time for ts-node to compile Typescript source vi.setConfig({testTimeout: 30_000}); diff --git a/packages/params/test/yaml.ts b/packages/params/test/yaml.ts index 162d48bc4084..f56016a4dbc0 100644 --- a/packages/params/test/yaml.ts +++ b/packages/params/test/yaml.ts @@ -8,10 +8,7 @@ export const schema = FAILSAFE_SCHEMA.extend({ implicit: [ new Type("tag:yaml.org,2002:str", { kind: "scalar", - construct: function (data) { - // eslint-disable-next-line @typescript-eslint/no-unsafe-return - return data !== null ? data : ""; - }, + construct: (data) => (data !== null ? data : ""), }), ], }); diff --git a/packages/prover/package.json b/packages/prover/package.json index 6a31b5b1baa0..9bfe7f21e480 100644 --- a/packages/prover/package.json +++ b/packages/prover/package.json @@ -48,8 +48,8 @@ "build:release": "yarn clean && yarn run build", "check-build": "node -e \"(async function() { await import('./lib/index.js') })()\"", "check-types": "tsc", - "lint": "eslint --color --ext .ts src/ test/", - "lint:fix": "yarn run lint --fix", + "lint": "biome check src/ test/", + "lint:fix": "yarn run lint --write", "test": "yarn test:unit && yarn test:e2e", "test:unit": "vitest --run --dir test/unit/", "test:browsers": "yarn test:browsers:chrome && yarn test:browsers:firefox && yarn test:browsers:electron", diff --git a/packages/prover/scripts/generate_fixtures.ts b/packages/prover/scripts/generate_fixtures.ts index 70ab31fed5c1..b5d1d18d89f1 100644 --- a/packages/prover/scripts/generate_fixtures.ts +++ b/packages/prover/scripts/generate_fixtures.ts @@ -2,9 +2,7 @@ import {writeFile, mkdir} from "node:fs/promises"; import path from "node:path"; import url from "node:url"; -// eslint-disable-next-line import/no-extraneous-dependencies import axios from "axios"; -// eslint-disable-next-line @typescript-eslint/naming-convention const __dirname = url.fileURLToPath(new URL(".", import.meta.url)); type JSONRequest = {method: string; params: unknown[]}; @@ -95,17 +93,14 @@ async function generateFixture(label: string, generator: Generator, network: NET } const beacon = { - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any - executionPayload: ((await rawBeacon(network, `eth/v2/beacon/blocks/${slot}`)) as any).data.message.body + executionPayload: ((await rawBeacon(network, `eth/v2/beacon/blocks/${slot}`)) as any).data.message.body .execution_payload, - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any - headers: ((await rawBeacon(network, `eth/v1/beacon/headers/${slot}`)) as any).data, + headers: ((await rawBeacon(network, `eth/v1/beacon/headers/${slot}`)) as any).data, }; const payloadBlock = await getBlockByHash( network, - // eslint-disable-next-line @typescript-eslint/naming-convention - (beacon.executionPayload as {block_hash: string}).block_hash, + (beacon.executionPayload as {block_hash: string}).block_hash, true ); diff --git a/packages/prover/src/cli/applyPreset.ts b/packages/prover/src/cli/applyPreset.ts index 158e05243ec7..f0c3d83c7751 100644 --- a/packages/prover/src/cli/applyPreset.ts +++ b/packages/prover/src/cli/applyPreset.ts @@ -1,8 +1,6 @@ // MUST import this file first before anything and not import any Lodestar code. -// eslint-disable-next-line no-restricted-imports, import/no-extraneous-dependencies import {hasher} from "@chainsafe/persistent-merkle-tree/lib/hasher/as-sha256.js"; -// eslint-disable-next-line no-restricted-imports, import/no-extraneous-dependencies import {setHasher} from "@chainsafe/persistent-merkle-tree/lib/hasher/index.js"; // without setting this first, persistent-merkle-tree will use noble instead @@ -45,7 +43,6 @@ else if (network) { if (network === "dev") { process.env.LODESTAR_PRESET = "minimal"; // "c-kzg" has hardcoded the mainnet value, do not use presets - // eslint-disable-next-line @typescript-eslint/naming-convention setActivePreset(PresetName.minimal, {FIELD_ELEMENTS_PER_BLOB: 4096}); } else if (network === "gnosis" || network === "chiado") { process.env.LODESTAR_PRESET = "gnosis"; @@ -85,6 +82,3 @@ function valueOfArg(argName: string): string | null { return null; } - -// Add empty export to make this a module -export {}; diff --git a/packages/prover/src/cli/cmds/start/options.ts b/packages/prover/src/cli/cmds/start/options.ts index f63ee974be44..5366efd96f6e 100644 --- a/packages/prover/src/cli/cmds/start/options.ts +++ b/packages/prover/src/cli/cmds/start/options.ts @@ -57,7 +57,7 @@ export const startOptions: CliCommandOptions = { string: true, coerce: (urls: string[]): string[] => // Parse ["url1,url2"] to ["url1", "url2"] - urls.map((item) => item.split(",")).flat(), + urls.flatMap((item) => item.split(",")), demandOption: true, group: "beacon", }, diff --git a/packages/prover/src/cli/index.ts b/packages/prover/src/cli/index.ts index 845831b32cb0..5bd071642c96 100644 --- a/packages/prover/src/cli/index.ts +++ b/packages/prover/src/cli/index.ts @@ -14,7 +14,7 @@ void prover // Show command help message when no command is provided if (msg.includes("Not enough non-option arguments")) { yarg.showHelp(); - // eslint-disable-next-line no-console + // biome-ignore lint/suspicious/noConsoleLog: This code will run only in browser so console will be available. console.log("\n"); } } @@ -22,7 +22,6 @@ void prover const errorMessage = err !== undefined ? (err instanceof YargsError ? err.message : err.stack) : msg || "Unknown error"; - // eslint-disable-next-line no-console console.error(` ✖ ${errorMessage}\n`); process.exit(1); }) diff --git a/packages/prover/src/interfaces.ts b/packages/prover/src/interfaces.ts index 36222c1476d3..9a67b47ea3b3 100644 --- a/packages/prover/src/interfaces.ts +++ b/packages/prover/src/interfaces.ts @@ -27,7 +27,7 @@ export type ELRequestHandler = ( payload: JsonRpcRequestOrBatch ) => Promise | undefined>; -// eslint-disable-next-line @typescript-eslint/no-explicit-any +// biome-ignore lint/suspicious/noExplicitAny: export type ELRequestHandlerAny = ELRequestHandler; /** diff --git a/packages/prover/src/proof_provider/payload_store.ts b/packages/prover/src/proof_provider/payload_store.ts index 343ec63719f9..c891cb994da1 100644 --- a/packages/prover/src/proof_provider/payload_store.ts +++ b/packages/prover/src/proof_provider/payload_store.ts @@ -39,7 +39,7 @@ export class PayloadStore { const maxBlockNumberForFinalized = this.finalizedRoots.max; if (maxBlockNumberForFinalized === undefined) { - return; + return undefined; } const finalizedMaxRoot = this.finalizedRoots.get(maxBlockNumberForFinalized); diff --git a/packages/prover/src/types.ts b/packages/prover/src/types.ts index 781ba1f7b207..d404cd96d4d8 100644 --- a/packages/prover/src/types.ts +++ b/packages/prover/src/types.ts @@ -45,17 +45,17 @@ export interface JsonRpcResponseWithErrorPayload { } // Make the very flexible el response type to match different libraries easily -// eslint-disable-next-line @typescript-eslint/no-explicit-any +// biome-ignore lint/suspicious/noExplicitAny: export type JsonRpcResponse = | JsonRpcResponseWithResultPayload | JsonRpcResponseWithErrorPayload; -// eslint-disable-next-line @typescript-eslint/no-explicit-any +// biome-ignore lint/suspicious/noExplicitAny: export type JsonRpcBatchResponse = JsonRpcResponse[]; // Response can be a single response or an array of responses in case of batch request // Make the very flexible el response type to match different libraries easily -// eslint-disable-next-line @typescript-eslint/no-explicit-any +// biome-ignore lint/suspicious/noExplicitAny: export type JsonRpcResponseOrBatch = JsonRpcResponse | JsonRpcBatchResponse; export type HexString = string; @@ -145,7 +145,6 @@ export interface ELAccessListResponse { export type ELStorageProof = Pick; -/* eslint-disable @typescript-eslint/naming-convention */ export type ELApi = { eth_getBalance: (address: string, block?: number | string) => string; eth_createAccessList: (transaction: ELTransaction, block?: ELBlockNumberOrTag) => ELAccessListResponse; diff --git a/packages/prover/src/utils/conversion.ts b/packages/prover/src/utils/conversion.ts index c809de5c4555..77c3141f828a 100644 --- a/packages/prover/src/utils/conversion.ts +++ b/packages/prover/src/utils/conversion.ts @@ -58,7 +58,6 @@ export function headerDataFromELBlock(blockInfo: ELBlock): HeaderData { }; } -// eslint-disable-next-line @typescript-eslint/explicit-function-return-type export function txDataFromELBlock(txInfo: ELTransaction) { return { ...txInfo, diff --git a/packages/prover/src/utils/evm.ts b/packages/prover/src/utils/evm.ts index 19f43d9584c8..40950647b8f3 100644 --- a/packages/prover/src/utils/evm.ts +++ b/packages/prover/src/utils/evm.ts @@ -20,7 +20,7 @@ export async function createVM({proofProvider}: {proofProvider: ProofProvider}): const blockchain = await Blockchain.create({common}); // Connect blockchain object with existing proof provider for block history - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any + // biome-ignore lint/suspicious/noExplicitAny: (blockchain as any).getBlock = async (blockId: number) => { const payload = await proofProvider.getExecutionPayload(blockId); return { diff --git a/packages/prover/src/utils/file.ts b/packages/prover/src/utils/file.ts index d236d2d5dc95..acc62033010f 100644 --- a/packages/prover/src/utils/file.ts +++ b/packages/prover/src/utils/file.ts @@ -15,7 +15,6 @@ const yamlSchema = FAILSAFE_SCHEMA.extend({ new Type("tag:yaml.org,2002:str", { kind: "scalar", construct: function construct(data) { - // eslint-disable-next-line @typescript-eslint/no-unsafe-return return data !== null ? data : ""; }, }), diff --git a/packages/prover/src/utils/gitData/gitDataPath.ts b/packages/prover/src/utils/gitData/gitDataPath.ts index e243ca433f2d..1ad3104aafc6 100644 --- a/packages/prover/src/utils/gitData/gitDataPath.ts +++ b/packages/prover/src/utils/gitData/gitDataPath.ts @@ -4,7 +4,6 @@ import {fileURLToPath} from "node:url"; // Global variable __dirname no longer available in ES6 modules. // Solutions: https://stackoverflow.com/questions/46745014/alternative-for-dirname-in-node-js-when-using-es6-modules -// eslint-disable-next-line @typescript-eslint/naming-convention const __dirname = path.dirname(fileURLToPath(import.meta.url)); // Persist git data and distribute through NPM so CLI consumers can know exactly diff --git a/packages/prover/src/utils/gitData/index.ts b/packages/prover/src/utils/gitData/index.ts index 96c5e4bbaef2..0720d39d9e30 100644 --- a/packages/prover/src/utils/gitData/index.ts +++ b/packages/prover/src/utils/gitData/index.ts @@ -11,7 +11,7 @@ export function readAndGetGitData(): GitData { let persistedGitData: Partial; try { persistedGitData = readGitDataFile(); - } catch (e) { + } catch (_e) { persistedGitData = {}; } @@ -23,13 +23,13 @@ export function readAndGetGitData(): GitData { branch: currentGitData.branch && currentGitData.branch.length > 0 ? currentGitData.branch - : persistedGitData.branch ?? "", + : (persistedGitData.branch ?? ""), commit: currentGitData.commit && currentGitData.commit.length > 0 ? currentGitData.commit - : persistedGitData.commit ?? "", + : (persistedGitData.commit ?? ""), }; - } catch (e) { + } catch (_e) { return { branch: "", commit: "", @@ -49,7 +49,7 @@ export function getGitData(): GitData { function getBranch(): string { try { return shellSilent("git rev-parse --abbrev-ref HEAD"); - } catch (e) { + } catch (_e) { return ""; } } @@ -58,7 +58,7 @@ function getBranch(): string { function getCommit(): string { try { return shellSilent("git rev-parse --verify HEAD"); - } catch (e) { + } catch (_e) { return ""; } } diff --git a/packages/prover/src/utils/process.ts b/packages/prover/src/utils/process.ts index 26768ffce1fb..75bb79516609 100644 --- a/packages/prover/src/utils/process.ts +++ b/packages/prover/src/utils/process.ts @@ -13,7 +13,7 @@ import {getResponseForRequest, isBatchRequest, isRequest} from "./json_rpc.js"; import {isNullish} from "./validation.js"; import {ELRpcProvider} from "./rpc_provider.js"; -/* eslint-disable @typescript-eslint/naming-convention, @typescript-eslint/no-explicit-any */ +// biome-ignore lint/suspicious/noExplicitAny: export const verifiableMethodHandlers: Record> = { eth_getBalance: eth_getBalance, eth_getTransactionCount: eth_getTransactionCount, @@ -106,7 +106,6 @@ export async function processAndVerifyRequest({ if (responses.length === 1) { return responses[0]; - } else { - return responses; } + return responses; } diff --git a/packages/prover/src/utils/version.ts b/packages/prover/src/utils/version.ts index 4752856e5b1d..624412107603 100644 --- a/packages/prover/src/utils/version.ts +++ b/packages/prover/src/utils/version.ts @@ -6,7 +6,6 @@ import {readAndGetGitData} from "./gitData/index.js"; // Global variable __dirname no longer available in ES6 modules. // Solutions: https://stackoverflow.com/questions/46745014/alternative-for-dirname-in-node-js-when-using-es6-modules -// eslint-disable-next-line @typescript-eslint/naming-convention const __dirname = path.dirname(fileURLToPath(import.meta.url)); type VersionJson = { diff --git a/packages/prover/src/verified_requests/eth_call.ts b/packages/prover/src/verified_requests/eth_call.ts index b28bd222c568..eea7ba146c3f 100644 --- a/packages/prover/src/verified_requests/eth_call.ts +++ b/packages/prover/src/verified_requests/eth_call.ts @@ -8,7 +8,6 @@ import { getVerificationFailedMessage, } from "../utils/json_rpc.js"; -// eslint-disable-next-line @typescript-eslint/naming-convention export const eth_call: ELVerifiedRequestHandler = async ({ rpc, payload, diff --git a/packages/prover/src/verified_requests/eth_estimateGas.ts b/packages/prover/src/verified_requests/eth_estimateGas.ts index fee446aadb5b..4ac4c3ccb6bc 100644 --- a/packages/prover/src/verified_requests/eth_estimateGas.ts +++ b/packages/prover/src/verified_requests/eth_estimateGas.ts @@ -8,7 +8,6 @@ import { getVerificationFailedMessage, } from "../utils/json_rpc.js"; -// eslint-disable-next-line @typescript-eslint/naming-convention export const eth_estimateGas: ELVerifiedRequestHandler< ELApiParams["eth_estimateGas"], ELApiReturn["eth_estimateGas"] diff --git a/packages/prover/src/verified_requests/eth_getBalance.ts b/packages/prover/src/verified_requests/eth_getBalance.ts index b5b7e63dcb64..0c03b23be788 100644 --- a/packages/prover/src/verified_requests/eth_getBalance.ts +++ b/packages/prover/src/verified_requests/eth_getBalance.ts @@ -6,7 +6,6 @@ import { getVerificationFailedMessage, } from "../utils/json_rpc.js"; -// eslint-disable-next-line @typescript-eslint/naming-convention export const eth_getBalance: ELVerifiedRequestHandler<[address: string, block?: number | string], string> = async ({ rpc, payload, diff --git a/packages/prover/src/verified_requests/eth_getBlockByHash.ts b/packages/prover/src/verified_requests/eth_getBlockByHash.ts index cb5fa1711c0f..00a110c01e9a 100644 --- a/packages/prover/src/verified_requests/eth_getBlockByHash.ts +++ b/packages/prover/src/verified_requests/eth_getBlockByHash.ts @@ -7,7 +7,6 @@ import { getVerificationFailedMessage, } from "../utils/json_rpc.js"; -// eslint-disable-next-line @typescript-eslint/naming-convention export const eth_getBlockByHash: ELVerifiedRequestHandler<[block: string, hydrated: boolean], ELBlock> = async ({ rpc, payload, diff --git a/packages/prover/src/verified_requests/eth_getBlockByNumber.ts b/packages/prover/src/verified_requests/eth_getBlockByNumber.ts index a08703881cc0..23e0fa2ca863 100644 --- a/packages/prover/src/verified_requests/eth_getBlockByNumber.ts +++ b/packages/prover/src/verified_requests/eth_getBlockByNumber.ts @@ -7,7 +7,6 @@ import { getVerificationFailedMessage, } from "../utils/json_rpc.js"; -// eslint-disable-next-line @typescript-eslint/naming-convention export const eth_getBlockByNumber: ELVerifiedRequestHandler< [block: string | number, hydrated: boolean], ELBlock diff --git a/packages/prover/src/verified_requests/eth_getCode.ts b/packages/prover/src/verified_requests/eth_getCode.ts index 9cb3362c4e50..f94ae8c1c8bd 100644 --- a/packages/prover/src/verified_requests/eth_getCode.ts +++ b/packages/prover/src/verified_requests/eth_getCode.ts @@ -6,7 +6,6 @@ import { getVerificationFailedMessage, } from "../utils/json_rpc.js"; -// eslint-disable-next-line @typescript-eslint/naming-convention export const eth_getCode: ELVerifiedRequestHandler<[address: string, block?: number | string], string> = async ({ rpc, payload, diff --git a/packages/prover/src/verified_requests/eth_getTransactionCount.ts b/packages/prover/src/verified_requests/eth_getTransactionCount.ts index 4cafd9b2b271..aeef67e96e74 100644 --- a/packages/prover/src/verified_requests/eth_getTransactionCount.ts +++ b/packages/prover/src/verified_requests/eth_getTransactionCount.ts @@ -6,7 +6,6 @@ import { getVerificationFailedMessage, } from "../utils/json_rpc.js"; -// eslint-disable-next-line @typescript-eslint/naming-convention export const eth_getTransactionCount: ELVerifiedRequestHandler< [address: string, block?: number | string], string @@ -15,7 +14,6 @@ export const eth_getTransactionCount: ELVerifiedRequestHandler< params: [address, block], } = payload; const result = await verifyAccount({proofProvider, logger, rpc, address, block}); - if (result.valid) { return getResponseForRequest(payload, result.data.nonce); } diff --git a/packages/prover/src/web3_provider_inspector.ts b/packages/prover/src/web3_provider_inspector.ts index c81847b64d61..154a860d0922 100644 --- a/packages/prover/src/web3_provider_inspector.ts +++ b/packages/prover/src/web3_provider_inspector.ts @@ -68,7 +68,7 @@ export class Web3ProviderInspector { return; } - const index = this.providerTypes.findIndex((p) => p.name == indexOrName); + const index = this.providerTypes.findIndex((p) => p.name === indexOrName); if (index < 0) { throw Error(`Provider type '${indexOrName}' is not registered.`); } diff --git a/packages/prover/test/e2e/cli/cmds/start.test.ts b/packages/prover/test/e2e/cli/cmds/start.test.ts index 8ac71e1a1797..75773ac02d36 100644 --- a/packages/prover/test/e2e/cli/cmds/start.test.ts +++ b/packages/prover/test/e2e/cli/cmds/start.test.ts @@ -29,7 +29,7 @@ describe("prover/proxy", () => { const paramsFilePath = path.join("/tmp", "e2e-test-env", "params.json"); const web3: Web3 = new Web3(proxyUrl); - beforeAll(async function () { + beforeAll(async () => { await waitForCapellaFork(); await mkdir(path.dirname(paramsFilePath), {recursive: true}); await writeFile(paramsFilePath, JSON.stringify(chainConfigToJson(config as ChainConfig))); diff --git a/packages/prover/test/e2e/web3_batch_request.test.ts b/packages/prover/test/e2e/web3_batch_request.test.ts index e232208a15b3..6dae04a9c36d 100644 --- a/packages/prover/test/e2e/web3_batch_request.test.ts +++ b/packages/prover/test/e2e/web3_batch_request.test.ts @@ -5,7 +5,7 @@ import {createVerifiedExecutionProvider} from "../../src/web3_provider.js"; import {rpcUrl, beaconUrl, config, waitForCapellaFork, minCapellaTimeMs} from "../utils/e2e_env.js"; import {getVerificationFailedMessage} from "../../src/utils/json_rpc.js"; -describe("web3_batch_requests", function () { +describe("web3_batch_requests", () => { vi.setConfig({hookTimeout: minCapellaTimeMs}); let web3: Web3; diff --git a/packages/prover/test/e2e/web3_provider.test.ts b/packages/prover/test/e2e/web3_provider.test.ts index 3d670d7ed412..edb3bb09e2fb 100644 --- a/packages/prover/test/e2e/web3_provider.test.ts +++ b/packages/prover/test/e2e/web3_provider.test.ts @@ -5,7 +5,7 @@ import {LCTransport} from "../../src/interfaces.js"; import {createVerifiedExecutionProvider} from "../../src/web3_provider.js"; import {waitForCapellaFork, minCapellaTimeMs, rpcUrl, beaconUrl, config} from "../utils/e2e_env.js"; -describe("web3_provider", function () { +describe("web3_provider", () => { vi.setConfig({hookTimeout: minCapellaTimeMs}); beforeAll(async () => { diff --git a/packages/prover/test/fixtures/mainnet/eth_call.json b/packages/prover/test/fixtures/mainnet/eth_call.json index 92e9ee557bc2..a3fe44880626 100644 --- a/packages/prover/test/fixtures/mainnet/eth_call.json +++ b/packages/prover/test/fixtures/mainnet/eth_call.json @@ -5226,4 +5226,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/packages/prover/test/fixtures/mainnet/eth_estimateGas_contract_call.json b/packages/prover/test/fixtures/mainnet/eth_estimateGas_contract_call.json index eaae6bc7190d..a8be70662e2b 100644 --- a/packages/prover/test/fixtures/mainnet/eth_estimateGas_contract_call.json +++ b/packages/prover/test/fixtures/mainnet/eth_estimateGas_contract_call.json @@ -5226,4 +5226,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/packages/prover/test/fixtures/mainnet/eth_estimateGas_simple_transfer.json b/packages/prover/test/fixtures/mainnet/eth_estimateGas_simple_transfer.json index f9b654b1a6fa..606e520a441c 100644 --- a/packages/prover/test/fixtures/mainnet/eth_estimateGas_simple_transfer.json +++ b/packages/prover/test/fixtures/mainnet/eth_estimateGas_simple_transfer.json @@ -5227,4 +5227,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/packages/prover/test/fixtures/sepolia/eth_getBalance_contract.json b/packages/prover/test/fixtures/sepolia/eth_getBalance_contract.json index f6e2a31b2b87..660889c259d7 100644 --- a/packages/prover/test/fixtures/sepolia/eth_getBalance_contract.json +++ b/packages/prover/test/fixtures/sepolia/eth_getBalance_contract.json @@ -2704,4 +2704,4 @@ } } ] -} \ No newline at end of file +} diff --git a/packages/prover/test/fixtures/sepolia/eth_getBalance_eoa.json b/packages/prover/test/fixtures/sepolia/eth_getBalance_eoa.json index 03627b534159..a2489403db5b 100644 --- a/packages/prover/test/fixtures/sepolia/eth_getBalance_eoa.json +++ b/packages/prover/test/fixtures/sepolia/eth_getBalance_eoa.json @@ -2703,4 +2703,4 @@ } } ] -} \ No newline at end of file +} diff --git a/packages/prover/test/fixtures/sepolia/eth_getBlock_with_contractCreation.json b/packages/prover/test/fixtures/sepolia/eth_getBlock_with_contractCreation.json index 6b0471a182cf..c61d0e58e35e 100644 --- a/packages/prover/test/fixtures/sepolia/eth_getBlock_with_contractCreation.json +++ b/packages/prover/test/fixtures/sepolia/eth_getBlock_with_contractCreation.json @@ -5,10 +5,7 @@ "id": 809166, "jsonrpc": "2.0", "method": "eth_getBlockByHash", - "params": [ - "0x3a0225b38d5927a37cc95fd48254e83c4e9b70115918a103d9fd7e36464030d4", - true - ] + "params": ["0x3a0225b38d5927a37cc95fd48254e83c4e9b70115918a103d9fd7e36464030d4", true] }, "response": { "jsonrpc": "2.0", @@ -571,4 +568,4 @@ } }, "dependentRequests": [] -} \ No newline at end of file +} diff --git a/packages/prover/test/fixtures/sepolia/eth_getBlock_with_no_accessList.json b/packages/prover/test/fixtures/sepolia/eth_getBlock_with_no_accessList.json index 59bb888450d1..c6c1f9c8d675 100644 --- a/packages/prover/test/fixtures/sepolia/eth_getBlock_with_no_accessList.json +++ b/packages/prover/test/fixtures/sepolia/eth_getBlock_with_no_accessList.json @@ -5,10 +5,7 @@ "id": 809162, "jsonrpc": "2.0", "method": "eth_getBlockByHash", - "params": [ - "0x75b10426177f0f4bd8683999e2c7c597007c6e7c4551d6336c0f880b12c6f3bf", - true - ] + "params": ["0x75b10426177f0f4bd8683999e2c7c597007c6e7c4551d6336c0f880b12c6f3bf", true] }, "response": { "jsonrpc": "2.0", @@ -2381,4 +2378,4 @@ } }, "dependentRequests": [] -} \ No newline at end of file +} diff --git a/packages/prover/test/fixtures/sepolia/eth_getCode.json b/packages/prover/test/fixtures/sepolia/eth_getCode.json index 1787e8cfd2ce..a15c15698420 100644 --- a/packages/prover/test/fixtures/sepolia/eth_getCode.json +++ b/packages/prover/test/fixtures/sepolia/eth_getCode.json @@ -2704,4 +2704,4 @@ } } ] -} \ No newline at end of file +} diff --git a/packages/prover/test/fixtures/sepolia/eth_getTransactionCount.json b/packages/prover/test/fixtures/sepolia/eth_getTransactionCount.json index ff45a5e8a776..486c44698c16 100644 --- a/packages/prover/test/fixtures/sepolia/eth_getTransactionCount.json +++ b/packages/prover/test/fixtures/sepolia/eth_getTransactionCount.json @@ -2703,4 +2703,4 @@ } } ] -} \ No newline at end of file +} diff --git a/packages/prover/test/mocks/request_handler.ts b/packages/prover/test/mocks/request_handler.ts index bbe4f24057de..edde1e59a3fe 100644 --- a/packages/prover/test/mocks/request_handler.ts +++ b/packages/prover/test/mocks/request_handler.ts @@ -116,7 +116,6 @@ export function generateReqHandlerOptionsMock( getExecutionPayload: vi.fn().mockResolvedValue(executionPayload), config: { ...config, - // eslint-disable-next-line @typescript-eslint/naming-convention PRESET_BASE: data.network as unknown as PresetName, }, network: data.network, diff --git a/packages/prover/test/tsconfig.json b/packages/prover/test/tsconfig.json index 7e6bad81b22f..f4241fc1fbcd 100644 --- a/packages/prover/test/tsconfig.json +++ b/packages/prover/test/tsconfig.json @@ -3,4 +3,4 @@ "compilerOptions": { "noEmit": false } -} \ No newline at end of file +} diff --git a/packages/prover/test/unit/proof_provider/payload_store.test.ts b/packages/prover/test/unit/proof_provider/payload_store.test.ts index b482bb579e77..6bc1e4265205 100644 --- a/packages/prover/test/unit/proof_provider/payload_store.test.ts +++ b/packages/prover/test/unit/proof_provider/payload_store.test.ts @@ -53,7 +53,7 @@ const buildBlockResponse = ({ return apiResponse; }; -describe("proof_provider/payload_store", function () { +describe("proof_provider/payload_store", () => { let api: ApiClient & {beacon: MockedObject}; let logger: Logger; let store: PayloadStore; diff --git a/packages/prover/test/unit/verified_requests/eth_getBlockByHash.test.ts b/packages/prover/test/unit/verified_requests/eth_getBlockByHash.test.ts index fca484657c01..3175bdd6d60c 100644 --- a/packages/prover/test/unit/verified_requests/eth_getBlockByHash.test.ts +++ b/packages/prover/test/unit/verified_requests/eth_getBlockByHash.test.ts @@ -3,8 +3,12 @@ import {createForkConfig} from "@lodestar/config"; import {NetworkName, networksChainConfig} from "@lodestar/config/networks"; import {VERIFICATION_FAILED_RESPONSE_CODE} from "../../../src/constants.js"; import {eth_getBlockByHash} from "../../../src/verified_requests/eth_getBlockByHash.js"; -import ethGetBlockWithContractCreation from "../../fixtures/sepolia/eth_getBlock_with_contractCreation.json" assert {type: "json"}; -import ethGetBlockWithNoAccessList from "../../fixtures/sepolia/eth_getBlock_with_no_accessList.json" assert {type: "json"}; +import ethGetBlockWithContractCreation from "../../fixtures/sepolia/eth_getBlock_with_contractCreation.json" assert { + type: "json", +}; +import ethGetBlockWithNoAccessList from "../../fixtures/sepolia/eth_getBlock_with_no_accessList.json" assert { + type: "json", +}; import {TestFixture, cloneTestFixture, generateReqHandlerOptionsMock} from "../../mocks/request_handler.js"; import {ELBlock} from "../../../src/types.js"; import {getVerificationFailedMessage} from "../../../src/utils/json_rpc.js"; diff --git a/packages/prover/test/unit/verified_requests/eth_getBlockByNumber.test.ts b/packages/prover/test/unit/verified_requests/eth_getBlockByNumber.test.ts index 81f644a46024..cc1389128ec0 100644 --- a/packages/prover/test/unit/verified_requests/eth_getBlockByNumber.test.ts +++ b/packages/prover/test/unit/verified_requests/eth_getBlockByNumber.test.ts @@ -4,8 +4,12 @@ import {NetworkName, networksChainConfig} from "@lodestar/config/networks"; import {VERIFICATION_FAILED_RESPONSE_CODE} from "../../../src/constants.js"; import {ELBlock} from "../../../src/types.js"; import {eth_getBlockByNumber} from "../../../src/verified_requests/eth_getBlockByNumber.js"; -import ethGetBlockWithContractCreation from "../../fixtures/sepolia/eth_getBlock_with_contractCreation.json" assert {type: "json"}; -import ethGetBlockWithNoAccessList from "../../fixtures/sepolia/eth_getBlock_with_no_accessList.json" assert {type: "json"}; +import ethGetBlockWithContractCreation from "../../fixtures/sepolia/eth_getBlock_with_contractCreation.json" assert { + type: "json", +}; +import ethGetBlockWithNoAccessList from "../../fixtures/sepolia/eth_getBlock_with_no_accessList.json" assert { + type: "json", +}; import {TestFixture, cloneTestFixture, generateReqHandlerOptionsMock} from "../../mocks/request_handler.js"; import {getVerificationFailedMessage} from "../../../src/utils/json_rpc.js"; @@ -88,7 +92,6 @@ describe("verified_requests / eth_getBlockByNumber", () => { // Temper the execution payload const testCase = cloneTestFixture(t, { beacon: { - // eslint-disable-next-line @typescript-eslint/naming-convention executionPayload: {parent_hash: "0xbdbd90ab601a073c3d128111eafb12fa7ece4af239abdc8be60184a08c6d7ef4"}, }, }); diff --git a/packages/prover/test/utils/e2e_env.ts b/packages/prover/test/utils/e2e_env.ts index b63d276daa5f..17af3739569a 100644 --- a/packages/prover/test/utils/e2e_env.ts +++ b/packages/prover/test/utils/e2e_env.ts @@ -1,6 +1,5 @@ import {waitForEndpoint} from "@lodestar/test-utils"; -/* eslint-disable @typescript-eslint/naming-convention */ export const rpcUrl = "http://0.0.0.0:8001"; export const beaconUrl = "http://0.0.0.0:5001"; export const proxyPort = 8888; diff --git a/packages/reqresp/package.json b/packages/reqresp/package.json index 44dcb8048f99..d6d4fbd2b5c2 100644 --- a/packages/reqresp/package.json +++ b/packages/reqresp/package.json @@ -45,15 +45,15 @@ "build:release": "yarn clean && yarn run build", "check-build": "node -e \"(async function() { await import('./lib/index.js') })()\"", "check-types": "tsc", - "lint": "eslint --color --ext .ts src/ test/", - "lint:fix": "yarn run lint --fix", + "lint": "biome check src/ test/", + "lint:fix": "yarn run lint --write", "test": "yarn test:unit", "test:unit": "vitest --run --dir test/unit/", "check-readme": "typescript-docs-verifier" }, "dependencies": { "@chainsafe/fast-crc32c": "^4.1.1", - "@libp2p/interface": "^1.3.0", + "@libp2p/interface": "^2.1.2", "@lodestar/config": "^1.22.0", "@lodestar/params": "^1.22.0", "@lodestar/utils": "^1.22.0", @@ -67,10 +67,10 @@ "devDependencies": { "@lodestar/logger": "^1.22.0", "@lodestar/types": "^1.22.0", - "libp2p": "1.4.3" + "libp2p": "2.1.7" }, "peerDependencies": { - "libp2p": "~1.4.3" + "libp2p": "~2.1.7" }, "keywords": [ "ethereum", diff --git a/packages/reqresp/src/encoders/responseDecode.ts b/packages/reqresp/src/encoders/responseDecode.ts index 93ebff674ec6..0dde5bcdc95e 100644 --- a/packages/reqresp/src/encoders/responseDecode.ts +++ b/packages/reqresp/src/encoders/responseDecode.ts @@ -110,7 +110,7 @@ export async function readResultHeader(bufferedSource: BufferedSource): Promise< */ export async function readErrorMessage(bufferedSource: BufferedSource): Promise { // Read at least 256 or wait for the stream to end - let length; + let length: number | undefined; for await (const buffer of bufferedSource) { // Wait for next chunk with bytes or for the stream to end // Note: The entire is expected to be in the same chunk @@ -121,13 +121,13 @@ export async function readErrorMessage(bufferedSource: BufferedSource): Promise< length = buffer.length; } + // biome-ignore lint/complexity/useLiteralKeys: It is a private attribute const bytes = bufferedSource["buffer"].slice(0, length); try { return decodeErrorMessage(bytes); - } catch { + } catch (_e) { // Error message is optional and may not be included in the response stream - // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call return Buffer.prototype.toString.call(bytes, "hex"); } } diff --git a/packages/reqresp/src/encodingStrategies/sszSnappy/decode.ts b/packages/reqresp/src/encodingStrategies/sszSnappy/decode.ts index 1bf9fc815e28..9ebe52876cfe 100644 --- a/packages/reqresp/src/encodingStrategies/sszSnappy/decode.ts +++ b/packages/reqresp/src/encodingStrategies/sszSnappy/decode.ts @@ -35,7 +35,7 @@ export async function readSszSnappyHeader(bufferedSource: BufferedSource, type: let sszDataLength: number; try { sszDataLength = varintDecode(buffer.subarray()); - } catch (e) { + } catch (_e) { throw new SszSnappyError({code: SszSnappyErrorCode.INVALID_VARINT_BYTES_COUNT, bytes: Infinity}); } diff --git a/packages/reqresp/src/encodingStrategies/sszSnappy/errors.ts b/packages/reqresp/src/encodingStrategies/sszSnappy/errors.ts index 12113ceb42fb..f9d6c4a8e9b5 100644 --- a/packages/reqresp/src/encodingStrategies/sszSnappy/errors.ts +++ b/packages/reqresp/src/encodingStrategies/sszSnappy/errors.ts @@ -28,8 +28,4 @@ type SszSnappyErrorType = | {code: SszSnappyErrorCode.TOO_MANY_BYTES; sszDataLength: number} | {code: SszSnappyErrorCode.SOURCE_ABORTED}; -export class SszSnappyError extends LodestarError { - constructor(type: SszSnappyErrorType) { - super(type); - } -} +export class SszSnappyError extends LodestarError {} diff --git a/packages/reqresp/src/encodingStrategies/sszSnappy/snappyFrames/uncompress.ts b/packages/reqresp/src/encodingStrategies/sszSnappy/snappyFrames/uncompress.ts index e97260989082..8530bc7aeb88 100644 --- a/packages/reqresp/src/encodingStrategies/sszSnappy/snappyFrames/uncompress.ts +++ b/packages/reqresp/src/encodingStrategies/sszSnappy/snappyFrames/uncompress.ts @@ -35,7 +35,6 @@ export class SnappyFramesUncompress { } if (type === ChunkType.IDENTIFIER) { - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call if (!Buffer.prototype.equals.call(data, IDENTIFIER)) { throw "malformed input: bad identifier"; } @@ -52,9 +51,8 @@ export class SnappyFramesUncompress { } if (result.length === 0) { return null; - } else { - return result; } + return result; } reset(): void { diff --git a/packages/reqresp/src/metrics.ts b/packages/reqresp/src/metrics.ts index 4af18a782322..faf4b7cf65ae 100644 --- a/packages/reqresp/src/metrics.ts +++ b/packages/reqresp/src/metrics.ts @@ -5,7 +5,6 @@ export type Metrics = ReturnType; /** * A collection of metrics used throughout the Gossipsub behaviour. */ -// eslint-disable-next-line @typescript-eslint/explicit-function-return-type export function getMetrics(register: MetricsRegister) { // Using function style instead of class to prevent having to re-declare all MetricsPrometheus types. diff --git a/packages/reqresp/src/rate_limiter/ReqRespRateLimiter.ts b/packages/reqresp/src/rate_limiter/ReqRespRateLimiter.ts index 66dfbd9f1cc7..7bb87cbd1fb2 100644 --- a/packages/reqresp/src/rate_limiter/ReqRespRateLimiter.ts +++ b/packages/reqresp/src/rate_limiter/ReqRespRateLimiter.ts @@ -68,9 +68,9 @@ export class ReqRespRateLimiter { if ((byPeer && !byPeer.allows(peerIdStr, requestCount)) || (total && !total.allows(null, requestCount))) { this.opts?.onRateLimit?.(peerId, protocolID); return false; - } else { - return true; } + + return true; } prune(peerId: PeerId): void { diff --git a/packages/reqresp/src/request/index.ts b/packages/reqresp/src/request/index.ts index 4920a32eb221..9a374db3b8be 100644 --- a/packages/reqresp/src/request/index.ts +++ b/packages/reqresp/src/request/index.ts @@ -98,7 +98,6 @@ export async function* sendRequest( async (timeoutAndParentSignal) => { const protocolIds = Array.from(protocolsMap.keys()); const conn = await libp2p.dialProtocol(peerId, protocolIds, {signal: timeoutAndParentSignal}); - // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions if (!conn) throw Error("dialProtocol timeout"); return conn; }, @@ -107,9 +106,8 @@ export async function* sendRequest( ).catch((e: Error) => { if (e instanceof TimeoutError) { throw new RequestError({code: RequestErrorCode.DIAL_TIMEOUT}); - } else { - throw new RequestError({code: RequestErrorCode.DIAL_ERROR, error: e}); } + throw new RequestError({code: RequestErrorCode.DIAL_ERROR, error: e}); }); // TODO: Does the TTFB timer start on opening stream or after receiving request @@ -134,9 +132,8 @@ export async function* sendRequest( if (e instanceof TimeoutError) { throw new RequestError({code: RequestErrorCode.REQUEST_TIMEOUT}); - } else { - throw new RequestError({code: RequestErrorCode.REQUEST_ERROR, error: e as Error}); } + throw new RequestError({code: RequestErrorCode.REQUEST_ERROR, error: e as Error}); } ); @@ -210,8 +207,7 @@ export async function* sendRequest( if (e instanceof ResponseError) { throw new RequestError(responseStatusErrorToRequestError(e)); - } else { - throw e; } + throw e; } } diff --git a/packages/reqresp/src/response/index.ts b/packages/reqresp/src/response/index.ts index 27758caa3f24..d9f0e1b1806a 100644 --- a/packages/reqresp/src/response/index.ts +++ b/packages/reqresp/src/response/index.ts @@ -76,10 +76,9 @@ export async function handleRequest({ signal ).catch((e: unknown) => { if (e instanceof TimeoutError) { - throw e; // Let outter catch {} re-type the error as SERVER_ERROR - } else { - throw new ResponseError(RespStatus.INVALID_REQUEST, (e as Error).message); + throw e; // Let outter catch (_e) {} re-type the error as SERVER_ERROR } + throw new ResponseError(RespStatus.INVALID_REQUEST, (e as Error).message); }); logger.debug("Req received", logCtx); @@ -134,8 +133,7 @@ export async function handleRequest({ if (responseError !== null) { logger.verbose("Resp error", logCtx, responseError); throw responseError; - } else { - // NOTE: Only log once per request to verbose, intermediate steps to debug - logger.verbose("Resp done", logCtx); } + // NOTE: Only log once per request to verbose, intermediate steps to debug + logger.verbose("Resp done", logCtx); } diff --git a/packages/reqresp/src/utils/abortableSource.ts b/packages/reqresp/src/utils/abortableSource.ts index 17ea836bcac3..127339bbd597 100644 --- a/packages/reqresp/src/utils/abortableSource.ts +++ b/packages/reqresp/src/utils/abortableSource.ts @@ -53,9 +53,9 @@ export function abortableSource( if (result.done) { return; - } else { - yield result.value; } + + yield result.value; } } catch (err) { // End the iterator if it is a generator diff --git a/packages/reqresp/src/utils/bufferedSource.ts b/packages/reqresp/src/utils/bufferedSource.ts index ac31a62ba29c..e5daca1d2f67 100644 --- a/packages/reqresp/src/utils/bufferedSource.ts +++ b/packages/reqresp/src/utils/bufferedSource.ts @@ -18,7 +18,6 @@ export class BufferedSource { } [Symbol.asyncIterator](): AsyncIterator { - // eslint-disable-next-line @typescript-eslint/no-this-alias const that = this; let firstNext = true; @@ -32,16 +31,15 @@ export class BufferedSource { return {done: false, value: that.buffer}; } - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment const {done, value: chunk} = await that.source.next(); if (done === true) { that.isDone = true; return {done: true, value: undefined}; - } else { - // Concat new chunk and return a reference to its BufferList instance - that.buffer.append(chunk); - return {done: false, value: that.buffer}; } + + // Concat new chunk and return a reference to its BufferList instance + that.buffer.append(chunk); + return {done: false, value: that.buffer}; }, }; } diff --git a/packages/reqresp/test/fixtures/encodingStrategies.ts b/packages/reqresp/test/fixtures/encodingStrategies.ts index c7705bb9493b..7bf183d8714c 100644 --- a/packages/reqresp/test/fixtures/encodingStrategies.ts +++ b/packages/reqresp/test/fixtures/encodingStrategies.ts @@ -15,7 +15,6 @@ import { // Global variable __dirname no longer available in ES6 modules. // Solutions: https://stackoverflow.com/questions/46745014/alternative-for-dirname-in-node-js-when-using-es6-modules -// eslint-disable-next-line @typescript-eslint/naming-convention const __dirname = path.dirname(fileURLToPath(import.meta.url)); type SszSnappyTestBlockData = { diff --git a/packages/reqresp/test/fixtures/messages.ts b/packages/reqresp/test/fixtures/messages.ts index 5558e7c3e13a..a243a05b221b 100644 --- a/packages/reqresp/test/fixtures/messages.ts +++ b/packages/reqresp/test/fixtures/messages.ts @@ -14,7 +14,6 @@ type MessageFixture = { }; const phase0Metadata = ssz.phase0.Metadata.fromJson({ - // eslint-disable-next-line @typescript-eslint/naming-convention seq_number: "9", attnets: "0x0000000000000000", }); @@ -37,7 +36,6 @@ export const sszSnappyPhase0Metadata: MessageFixture = { }; const altairMetadata = ssz.altair.Metadata.fromJson({ - // eslint-disable-next-line @typescript-eslint/naming-convention seq_number: "8", attnets: "0x0000000000000000", syncnets: "0x00", @@ -178,7 +176,6 @@ if (slotBlockAltair - slotBlockPhase0 < SLOTS_PER_EPOCH) { throw Error("phase0 block slot must be an epoch apart from altair block slot"); } const ALTAIR_FORK_EPOCH = Math.floor(slotBlockAltair / SLOTS_PER_EPOCH); -// eslint-disable-next-line @typescript-eslint/naming-convention export const beaconConfig = createBeaconConfig({...chainConfig, ALTAIR_FORK_EPOCH}, ZERO_HASH); export const getEmptyHandler = () => async function* emptyHandler(): AsyncGenerator {}; diff --git a/packages/reqresp/test/fixtures/protocols.ts b/packages/reqresp/test/fixtures/protocols.ts index f20d891781ef..19e8936fc376 100644 --- a/packages/reqresp/test/fixtures/protocols.ts +++ b/packages/reqresp/test/fixtures/protocols.ts @@ -5,7 +5,6 @@ import {ContextBytesType, DialOnlyProtocol, Encoding, ProtocolHandler, Protocol} import {getEmptyHandler} from "./messages.js"; import {beaconConfig} from "./messages.js"; -// eslint-disable-next-line @typescript-eslint/naming-convention const NumToStrReq = new ContainerType( { value: new UintNumberType(4), @@ -15,7 +14,6 @@ const NumToStrReq = new ContainerType( export type NumToStrReqType = ValueOf; -// eslint-disable-next-line @typescript-eslint/naming-convention const NumToStrResp = new ContainerType( { value: new ListBasicType(new UintNumberType(1), 4), diff --git a/packages/reqresp/test/unit/encodingStrategies/sszSnappy/snappyFrames/uncompress.test.ts b/packages/reqresp/test/unit/encodingStrategies/sszSnappy/snappyFrames/uncompress.test.ts index b47621082a65..dc01a1952142 100644 --- a/packages/reqresp/test/unit/encodingStrategies/sszSnappy/snappyFrames/uncompress.test.ts +++ b/packages/reqresp/test/unit/encodingStrategies/sszSnappy/snappyFrames/uncompress.test.ts @@ -4,7 +4,7 @@ import {pipe} from "it-pipe"; import {SnappyFramesUncompress} from "../../../../../src/encodingStrategies/sszSnappy/snappyFrames/uncompress.js"; import {encodeSnappy} from "../../../../../src/encodingStrategies/sszSnappy/snappyFrames/compress.js"; -describe("encodingStrategies / sszSnappy / snappy frames / uncompress", function () { +describe("encodingStrategies / sszSnappy / snappy frames / uncompress", () => { it("should work with short input", () => new Promise((done) => { const testData = "Small test data"; @@ -12,7 +12,7 @@ describe("encodingStrategies / sszSnappy / snappy frames / uncompress", function const decompress = new SnappyFramesUncompress(); - void pipe(compressIterable, async function (source) { + void pipe(compressIterable, async (source) => { for await (const data of source) { const result = decompress.uncompress(new Uint8ArrayList(data)); if (result) { @@ -30,7 +30,7 @@ describe("encodingStrategies / sszSnappy / snappy frames / uncompress", function let result = Buffer.alloc(0); const decompress = new SnappyFramesUncompress(); - void pipe(compressIterable, async function (source) { + void pipe(compressIterable, async (source) => { for await (const data of source) { // testData will come compressed as two or more chunks result = Buffer.concat([ @@ -45,13 +45,13 @@ describe("encodingStrategies / sszSnappy / snappy frames / uncompress", function }); })); - it("should detect malformed input", function () { + it("should detect malformed input", () => { const decompress = new SnappyFramesUncompress(); expect(() => decompress.uncompress(new Uint8ArrayList(Buffer.alloc(32, 5)))).toThrow(); }); - it("should return null if not enough data", function () { + it("should return null if not enough data", () => { const decompress = new SnappyFramesUncompress(); expect(decompress.uncompress(new Uint8ArrayList(Buffer.alloc(3, 1)))).toBe(null); diff --git a/packages/reqresp/test/utils/errors.ts b/packages/reqresp/test/utils/errors.ts index 16c098f2f57c..e4697a6d97d5 100644 --- a/packages/reqresp/test/utils/errors.ts +++ b/packages/reqresp/test/utils/errors.ts @@ -53,9 +53,10 @@ export function expectLodestarError(err1: LodestarErro export function getErrorMetadata(err: LodestarError | Error | unknown): unknown { if (err instanceof LodestarError) { return mapValues(err.getMetadata(), (value) => getErrorMetadata(value as any)); - } else if (err instanceof Error) { + } + + if (err instanceof Error) { return err.message; - } else { - return err; } + return err; } diff --git a/packages/reqresp/test/utils/peer.ts b/packages/reqresp/test/utils/peer.ts index 43edaefbafdd..cbc21eca370f 100644 --- a/packages/reqresp/test/utils/peer.ts +++ b/packages/reqresp/test/utils/peer.ts @@ -1,5 +1,6 @@ import {PeerId} from "@libp2p/interface"; -import {peerIdFromBytes} from "@libp2p/peer-id"; +import {peerIdFromPublicKey} from "@libp2p/peer-id"; +import {publicKeyFromProtobuf} from "@libp2p/crypto/keys"; /** * Returns a valid PeerId with opts `bits: 256, keyType: "secp256k1"` @@ -7,5 +8,5 @@ import {peerIdFromBytes} from "@libp2p/peer-id"; */ export function getValidPeerId(): PeerId { const id = Buffer.from("002508021221039481269fe831799b1a0f1d521c1395b4831514859e4559c44d155eae46f03819", "hex"); - return peerIdFromBytes(id); + return peerIdFromPublicKey(publicKeyFromProtobuf(id)); } diff --git a/packages/spec-test-util/package.json b/packages/spec-test-util/package.json index b4aabf0140e8..501d13024159 100644 --- a/packages/spec-test-util/package.json +++ b/packages/spec-test-util/package.json @@ -44,8 +44,8 @@ "build:watch": "yarn run build --watch", "check-build": "node -e \"(async function() { await import('./lib/downloadTests.js') })()\"", "check-types": "tsc", - "lint": "eslint --color --ext .ts src/ test/", - "lint:fix": "yarn run lint --fix", + "lint": "biome check src/ test/", + "lint:fix": "yarn run lint --write", "test": "yarn test:unit && yarn test:e2e", "test:unit": "vitest --run --passWithNoTests --dir test/unit/", "test:e2e": "vitest --run --config vitest.e2e.config.ts --dir test/e2e/", diff --git a/packages/spec-test-util/src/downloadTests.ts b/packages/spec-test-util/src/downloadTests.ts index e13478934927..bca6a8ac52c9 100644 --- a/packages/spec-test-util/src/downloadTests.ts +++ b/packages/spec-test-util/src/downloadTests.ts @@ -51,9 +51,8 @@ export async function downloadGenericSpecTests( if (existingVersion === specVersion) { return log(`version ${specVersion} already downloaded`); - } else { - log(`Downloading new version ${specVersion}`); } + log(`Downloading new version ${specVersion}`); if (fs.existsSync(outputDir)) { log(`Cleaning existing version ${existingVersion} at ${outputDir}`); diff --git a/packages/spec-test-util/src/single.ts b/packages/spec-test-util/src/single.ts index 47bf8d0a0742..888c87e3ffa8 100644 --- a/packages/spec-test-util/src/single.ts +++ b/packages/spec-test-util/src/single.ts @@ -68,6 +68,7 @@ export interface SpecTestOptions { * Optionally pass function to transform loaded values * (values from input files) */ + inputProcessing?: {[K: string]: (value: any) => any}; shouldError?: (testCase: TestCase) => boolean; @@ -86,7 +87,7 @@ const defaultOptions: SpecTestOptions = { getExpected: (testCase) => testCase, shouldError: () => false, shouldSkip: () => false, - expectFunc: (testCase, expected, actual) => expect(actual).to.be.deep.equal(expected), + expectFunc: (_testCase, expected, actual) => expect(actual).to.be.deep.equal(expected), timeout: 10 * 60 * 1000, }; @@ -101,7 +102,7 @@ export function describeDirectorySpecTest throw new Error(`${testCaseDirectoryPath} is not directory`); } - describe(name, function () { + describe(name, () => { if (options.timeout !== undefined) { vi.setConfig({testTimeout: options.timeout ?? 10 * 60 * 1000}); } @@ -114,7 +115,7 @@ export function describeDirectorySpecTest // Use full path here, not just `testSubDirname` to allow usage of `vitest -t` const testName = `${name}/${testSubDirname}`; - it(testName, async function (context) { + it(testName, async (context) => { // some tests require to load meta.yaml first in order to know respective ssz types. const metaFilePath = path.join(testSubDirPath, "meta.yaml"); const meta: TestCase["meta"] = fs.existsSync(metaFilePath) @@ -123,7 +124,7 @@ export function describeDirectorySpecTest let testCase = loadInputFiles(testSubDirPath, options, meta); if (options.mapToTestCase) testCase = options.mapToTestCase(testCase); - if (options.shouldSkip && options.shouldSkip(testCase, testName, 0)) { + if (options.shouldSkip?.(testCase, testName, 0)) { context.skip(); return; } @@ -131,7 +132,7 @@ export function describeDirectorySpecTest if (options.shouldError?.(testCase)) { try { await testFunction(testCase, name); - } catch (e) { + } catch (_e) { return; } } else { @@ -156,7 +157,8 @@ function loadInputFiles( meta?: TestCase["meta"] ): TestCase { const testCase: any = {}; - fs.readdirSync(directory) + const files = fs + .readdirSync(directory) .map((name) => path.join(directory, name)) .filter((file) => { if (isDirectory(file)) { @@ -169,33 +171,37 @@ function loadInputFiles( options.inputTypes[name] = inputType; const extension = inputType.type as string; return file.endsWith(extension); - }) - .forEach((file) => { - const inputName = path.basename(file).replace(".ssz_snappy", "").replace(".ssz", "").replace(".yaml", ""); - const inputType = getInputType(file); - testCase[inputName] = deserializeInputFile(file, inputName, inputType, options, meta); - switch (inputType) { - case InputType.SSZ: - testCase[`${inputName}_raw`] = fs.readFileSync(file); - break; - case InputType.SSZ_SNAPPY: - testCase[`${inputName}_raw`] = uncompress(fs.readFileSync(file)); - break; - } - if (!options.inputProcessing) throw Error("inputProcessing is not defined"); - if (options.inputProcessing[inputName] !== undefined) { - testCase[inputName] = options.inputProcessing[inputName](testCase[inputName]); - } }); + for (const file of files) { + const inputName = path.basename(file).replace(".ssz_snappy", "").replace(".ssz", "").replace(".yaml", ""); + const inputType = getInputType(file); + testCase[inputName] = deserializeInputFile(file, inputName, inputType, options, meta); + switch (inputType) { + case InputType.SSZ: + testCase[`${inputName}_raw`] = fs.readFileSync(file); + break; + case InputType.SSZ_SNAPPY: + testCase[`${inputName}_raw`] = uncompress(fs.readFileSync(file)); + break; + } + if (!options.inputProcessing) throw Error("inputProcessing is not defined"); + if (options.inputProcessing[inputName] !== undefined) { + testCase[inputName] = options.inputProcessing[inputName](testCase[inputName]); + } + } return testCase as TestCase; } function getInputType(filename: string): InputType { if (filename.endsWith(InputType.YAML)) { return InputType.YAML; - } else if (filename.endsWith(InputType.SSZ_SNAPPY)) { + } + + if (filename.endsWith(InputType.SSZ_SNAPPY)) { return InputType.SSZ_SNAPPY; - } else if (filename.endsWith(InputType.SSZ)) { + } + + if (filename.endsWith(InputType.SSZ)) { return InputType.SSZ; } throw new Error(`Could not get InputType from ${filename}`); @@ -210,7 +216,9 @@ function deserializeInputFile( ): any { if (inputType === InputType.YAML) { return loadYaml(fs.readFileSync(file, "utf8")); - } else if (inputType === InputType.SSZ || inputType === InputType.SSZ_SNAPPY) { + } + + if (inputType === InputType.SSZ || inputType === InputType.SSZ_SNAPPY) { const sszTypes = options.getSszTypes ? options.getSszTypes(meta) : options.sszTypes; if (!sszTypes) throw Error("sszTypes is not defined"); let data = fs.readFileSync(file); @@ -238,9 +246,8 @@ function deserializeInputFile( throw Error("BeaconState type has no deserializeToViewDU method"); } return sszType.deserializeToViewDU(data); - } else { - return sszType.deserialize(data); } + return sszType.deserialize(data); } } diff --git a/packages/spec-test-util/test/e2e/single/index.test.ts b/packages/spec-test-util/test/e2e/single/index.test.ts index 849b0cead30d..2dbefbb9cd22 100644 --- a/packages/spec-test-util/test/e2e/single/index.test.ts +++ b/packages/spec-test-util/test/e2e/single/index.test.ts @@ -8,11 +8,8 @@ import {describeDirectorySpecTest, InputType, loadYamlFile} from "../../../src/s // Global variable __dirname no longer available in ES6 modules. // Solutions: https://stackoverflow.com/questions/46745014/alternative-for-dirname-in-node-js-when-using-es6-modules -// eslint-disable-next-line @typescript-eslint/naming-convention const __dirname = path.dirname(fileURLToPath(import.meta.url)); -/* eslint-disable @typescript-eslint/naming-convention */ - export type SimpleStruct = { test: boolean; number: number; diff --git a/packages/state-transition/package.json b/packages/state-transition/package.json index 6816e5679cf5..a01d835bae95 100644 --- a/packages/state-transition/package.json +++ b/packages/state-transition/package.json @@ -50,8 +50,8 @@ "build:release": "yarn clean && yarn build", "check-build": "node -e \"(async function() { await import('./lib/index.js') })()\"", "check-types": "tsc", - "lint": "eslint --color --ext .ts src/ test/", - "lint:fix": "yarn run lint --fix", + "lint": "biome check src/ test/", + "lint:fix": "yarn run lint --write", "test": "yarn test:unit", "test:unit": "vitest --run --dir test/unit/", "check-readme": "typescript-docs-verifier" @@ -63,6 +63,7 @@ "@chainsafe/persistent-merkle-tree": "^0.8.0", "@chainsafe/persistent-ts": "^0.19.1", "@chainsafe/ssz": "^0.17.1", + "@chainsafe/swap-or-not-shuffle": "^0.0.2", "@lodestar/config": "^1.22.0", "@lodestar/params": "^1.22.0", "@lodestar/types": "^1.22.0", diff --git a/packages/state-transition/src/block/isValidIndexedAttestation.ts b/packages/state-transition/src/block/isValidIndexedAttestation.ts index 33d92a208260..8c7502ceedb5 100644 --- a/packages/state-transition/src/block/isValidIndexedAttestation.ts +++ b/packages/state-transition/src/block/isValidIndexedAttestation.ts @@ -18,9 +18,8 @@ export function isValidIndexedAttestation( if (verifySignature) { return verifySignatureSet(getIndexedAttestationSignatureSet(state, indexedAttestation)); - } else { - return true; } + return true; } export function isValidIndexedAttestationBigint( @@ -34,9 +33,8 @@ export function isValidIndexedAttestationBigint( if (verifySignature) { return verifySignatureSet(getIndexedAttestationBigintSignatureSet(state, indexedAttestation)); - } else { - return true; } + return true; } /** diff --git a/packages/state-transition/src/block/processAttestationPhase0.ts b/packages/state-transition/src/block/processAttestationPhase0.ts index ba6bc9089693..e2b32bbbbee8 100644 --- a/packages/state-transition/src/block/processAttestationPhase0.ts +++ b/packages/state-transition/src/block/processAttestationPhase0.ts @@ -91,13 +91,13 @@ export function validateAttestation(fork: ForkSeq, state: CachedBeaconStateAllFo if (committeeIndices.length === 0) { throw Error("Attestation should have at least one committee bit set"); - } else { - const lastCommitteeIndex = committeeIndices[committeeIndices.length - 1]; - if (lastCommitteeIndex >= committeeCount) { - throw new Error( - `Attestation committee index exceeds committee count: lastCommitteeIndex=${lastCommitteeIndex} numCommittees=${committeeCount}` - ); - } + } + + const lastCommitteeIndex = committeeIndices[committeeIndices.length - 1]; + if (lastCommitteeIndex >= committeeCount) { + throw new Error( + `Attestation committee index exceeds committee count: lastCommitteeIndex=${lastCommitteeIndex} numCommittees=${committeeCount}` + ); } // Get total number of attestation participant of every committee specified @@ -133,9 +133,8 @@ export function isTimelyTarget(fork: ForkSeq, inclusionDistance: Slot): boolean // post deneb attestation is valid till end of next epoch for target if (fork >= ForkSeq.deneb) { return true; - } else { - return inclusionDistance <= SLOTS_PER_EPOCH; } + return inclusionDistance <= SLOTS_PER_EPOCH; } export function checkpointToStr(checkpoint: phase0.Checkpoint): string { diff --git a/packages/state-transition/src/block/processDeposit.ts b/packages/state-transition/src/block/processDeposit.ts index ee75dff0dfd1..fd671dc5f6f6 100644 --- a/packages/state-transition/src/block/processDeposit.ts +++ b/packages/state-transition/src/block/processDeposit.ts @@ -173,7 +173,7 @@ function isValidDepositSignature( const signature = Signature.fromBytes(depositSignature, true); return verify(signingRoot, publicKey, signature); - } catch (e) { + } catch (_e) { return false; // Catch all BLS errors: failed key validation, failed signature validation, invalid signature } } diff --git a/packages/state-transition/src/block/processEth1Data.ts b/packages/state-transition/src/block/processEth1Data.ts index 3d1927744328..92ab147aa772 100644 --- a/packages/state-transition/src/block/processEth1Data.ts +++ b/packages/state-transition/src/block/processEth1Data.ts @@ -58,9 +58,8 @@ export function becomesNewEth1Data( // The +1 is to account for the `eth1Data` supplied to the function. if ((sameVotesCount + 1) * 2 > SLOTS_PER_ETH1_VOTING_PERIOD) { return true; - } else { - return false; } + return false; } function isEqualEth1DataView( diff --git a/packages/state-transition/src/block/processSyncCommittee.ts b/packages/state-transition/src/block/processSyncCommittee.ts index 70c918ed60bf..5f81a984b677 100644 --- a/packages/state-transition/src/block/processSyncCommittee.ts +++ b/packages/state-transition/src/block/processSyncCommittee.ts @@ -96,9 +96,8 @@ export function getSyncCommitteeSignatureSet( // https://github.com/ethereum/eth2.0-specs/blob/30f2a076377264677e27324a8c3c78c590ae5e20/specs/altair/bls.md#eth2_fast_aggregate_verify if (byteArrayEquals(signature, G2_POINT_AT_INFINITY)) { return null; - } else { - throw Error("Empty sync committee signature is not infinity"); } + throw Error("Empty sync committee signature is not infinity"); } const domain = state.config.getDomain(state.slot, DOMAIN_SYNC_COMMITTEE, previousSlot); diff --git a/packages/state-transition/src/cache/epochCache.ts b/packages/state-transition/src/cache/epochCache.ts index 5e901e33d992..66ce12b82d18 100644 --- a/packages/state-transition/src/cache/epochCache.ts +++ b/packages/state-transition/src/cache/epochCache.ts @@ -877,6 +877,10 @@ export class EpochCache { return this.proposers; } + getBeaconProposersPrevEpoch(): ValidatorIndex[] | null { + return this.proposersPrevEpoch; + } + /** * We allow requesting proposal duties 1 epoch in the future as in normal network conditions it's possible to predict * the correct shuffling with high probability. While knowing the proposers in advance is not useful for consensus, @@ -917,7 +921,7 @@ export class EpochCache { getBeaconProposersNextEpoch(): ValidatorIndex[] { if (!this.proposersNextEpoch.computed) { const indexes = computeProposers( - this.config.getForkSeqAtEpoch(this.epoch + 1), + this.config.getForkSeqAtEpoch(this.nextEpoch), this.proposersNextEpoch.seed, this.getShufflingAtEpoch(this.nextEpoch), this.effectiveBalanceIncrements @@ -953,20 +957,19 @@ export class EpochCache { const validatorIndices = this.getBeaconCommittee(data.slot, data.index); return aggregationBits.intersectValues(validatorIndices); - } else { - const {aggregationBits, committeeBits, data} = attestation as electra.Attestation; + } + const {aggregationBits, committeeBits, data} = attestation as electra.Attestation; - // There is a naming conflict on the term `committeeIndices` - // In Lodestar it usually means a list of validator indices of participants in a committee - // In the spec it means a list of committee indices according to committeeBits - // This `committeeIndices` refers to the latter - // TODO Electra: resolve the naming conflicts - const committeeIndices = committeeBits.getTrueBitIndexes(); + // There is a naming conflict on the term `committeeIndices` + // In Lodestar it usually means a list of validator indices of participants in a committee + // In the spec it means a list of committee indices according to committeeBits + // This `committeeIndices` refers to the latter + // TODO Electra: resolve the naming conflicts + const committeeIndices = committeeBits.getTrueBitIndexes(); - const validatorIndices = this.getBeaconCommittees(data.slot, committeeIndices); + const validatorIndices = this.getBeaconCommittees(data.slot, committeeIndices); - return aggregationBits.intersectValues(validatorIndices); - } + return aggregationBits.intersectValues(validatorIndices); } getCommitteeAssignments( @@ -1026,9 +1029,8 @@ export class EpochCache { getValidatorIndex(pubkey: Uint8Array): ValidatorIndex | null { if (this.isPostElectra()) { return this.pubkey2index.get(pubkey) ?? this.unfinalizedPubkey2index.get(toMemoryEfficientHexStr(pubkey)) ?? null; - } else { - return this.pubkey2index.get(pubkey); } + return this.pubkey2index.get(pubkey); } /** @@ -1068,12 +1070,11 @@ export class EpochCache { // Repeated insert. metrics?.finalizedPubkeyDuplicateInsert.inc(); return; - } else { - // attempt to insert the same pubkey with different index, should never happen. - throw Error( - `inserted existing pubkey into finalizedPubkey2index cache with a different index, index=${index} priorIndex=${existingIndex}` - ); } + // attempt to insert the same pubkey with different index, should never happen. + throw Error( + `inserted existing pubkey into finalizedPubkey2index cache with a different index, index=${index} priorIndex=${existingIndex}` + ); } this.pubkey2index.set(pubkey, index); diff --git a/packages/state-transition/src/cache/stateCache.ts b/packages/state-transition/src/cache/stateCache.ts index 5412675352e9..3eeeb285b660 100644 --- a/packages/state-transition/src/cache/stateCache.ts +++ b/packages/state-transition/src/cache/stateCache.ts @@ -254,9 +254,11 @@ export function isCachedBeaconState( // This cache is populated during epoch transition, and should be preserved for performance. // If the cache is missing too often, means that our clone strategy is not working well. export function isStateValidatorsNodesPopulated(state: CachedBeaconStateAllForks): boolean { + // biome-ignore lint/complexity/useLiteralKeys: It is a private attribute return state.validators["nodesPopulated"] === true; } export function isStateBalancesNodesPopulated(state: CachedBeaconStateAllForks): boolean { + // biome-ignore lint/complexity/useLiteralKeys: It is a private attribute return state.balances["nodesPopulated"] === true; } diff --git a/packages/state-transition/src/epoch/processPendingBalanceDeposits.ts b/packages/state-transition/src/epoch/processPendingBalanceDeposits.ts index bef3ec0b2724..1cd9e17efbad 100644 --- a/packages/state-transition/src/epoch/processPendingBalanceDeposits.ts +++ b/packages/state-transition/src/epoch/processPendingBalanceDeposits.ts @@ -41,14 +41,13 @@ export function processPendingBalanceDeposits(state: CachedBeaconStateElectra, c if (processedAmount + amount > availableForProcessing) { // Deposit does not fit in the churn, no more deposit processing in this epoch. break; - } else { - // Deposit fits in the churn, process it. Increase balance and consume churn. - increaseBalance(state, depositIndex, Number(amount)); - if (cachedBalances) { - cachedBalances[depositIndex] += Number(amount); - } - processedAmount = processedAmount + amount; } + // Deposit fits in the churn, process it. Increase balance and consume churn. + increaseBalance(state, depositIndex, Number(amount)); + if (cachedBalances) { + cachedBalances[depositIndex] += Number(amount); + } + processedAmount = processedAmount + amount; } // Regardless of how the deposit was handled, we move on in the queue. nextDepositIndex++; diff --git a/packages/state-transition/src/metrics.ts b/packages/state-transition/src/metrics.ts index a5e5463231fa..ac558a1be139 100644 --- a/packages/state-transition/src/metrics.ts +++ b/packages/state-transition/src/metrics.ts @@ -74,9 +74,11 @@ export function onPostStateMetrics(postState: CachedBeaconStateAllForks, metrics // This cache is populated during epoch transition, and should be preserved for performance. // If the cache is missing too often, means that our clone strategy is not working well. function isValidatorsNodesPopulated(state: CachedBeaconStateAllForks): boolean { + // biome-ignore lint/complexity/useLiteralKeys: It is a private attribute return state.validators["nodesPopulated"] === true; } function isBalancesNodesPopulated(state: CachedBeaconStateAllForks): boolean { + // biome-ignore lint/complexity/useLiteralKeys: It is a private attribute return state.balances["nodesPopulated"] === true; } diff --git a/packages/state-transition/src/signatureSets/attesterSlashings.ts b/packages/state-transition/src/signatureSets/attesterSlashings.ts index 8088c2522282..36f31d97e083 100644 --- a/packages/state-transition/src/signatureSets/attesterSlashings.ts +++ b/packages/state-transition/src/signatureSets/attesterSlashings.ts @@ -8,9 +8,9 @@ export function getAttesterSlashingsSignatureSets( state: CachedBeaconStateAllForks, signedBlock: SignedBeaconBlock ): ISignatureSet[] { - return signedBlock.message.body.attesterSlashings - .map((attesterSlashing) => getAttesterSlashingSignatureSets(state, attesterSlashing)) - .flat(1); + return signedBlock.message.body.attesterSlashings.flatMap((attesterSlashing) => + getAttesterSlashingSignatureSets(state, attesterSlashing) + ); } /** Get signature sets from a single AttesterSlashing object */ diff --git a/packages/state-transition/src/signatureSets/proposerSlashings.ts b/packages/state-transition/src/signatureSets/proposerSlashings.ts index 8a004225111d..b0c1aa465bd5 100644 --- a/packages/state-transition/src/signatureSets/proposerSlashings.ts +++ b/packages/state-transition/src/signatureSets/proposerSlashings.ts @@ -35,7 +35,7 @@ export function getProposerSlashingsSignatureSets( state: CachedBeaconStateAllForks, signedBlock: SignedBeaconBlock ): ISignatureSet[] { - return signedBlock.message.body.proposerSlashings - .map((proposerSlashing) => getProposerSlashingSignatureSets(state, proposerSlashing)) - .flat(1); + return signedBlock.message.body.proposerSlashings.flatMap((proposerSlashing) => + getProposerSlashingSignatureSets(state, proposerSlashing) + ); } diff --git a/packages/state-transition/src/slot/upgradeStateToAltair.ts b/packages/state-transition/src/slot/upgradeStateToAltair.ts index cfe43e097939..22ab8b13882c 100644 --- a/packages/state-transition/src/slot/upgradeStateToAltair.ts +++ b/packages/state-transition/src/slot/upgradeStateToAltair.ts @@ -92,6 +92,7 @@ export function upgradeStateToAltair(statePhase0: CachedBeaconStatePhase0): Cach // // TODO: This could only drop the caches of index 15,16. However this would couple this code tightly with SSZ ViewDU // internals. If the cache is not cleared, consuming the ViewDU instance could break in strange ways. + // biome-ignore lint/complexity/useLiteralKeys: It is a protected attribute stateAltair["clearCache"](); // TODO: describe issue. Compute progressive target balances diff --git a/packages/state-transition/src/slot/upgradeStateToCapella.ts b/packages/state-transition/src/slot/upgradeStateToCapella.ts index ce27a17bf9b0..30a0701e58e8 100644 --- a/packages/state-transition/src/slot/upgradeStateToCapella.ts +++ b/packages/state-transition/src/slot/upgradeStateToCapella.ts @@ -64,6 +64,7 @@ export function upgradeStateToCapella(stateBellatrix: CachedBeaconStateBellatrix // Commit new added fields ViewDU to the root node stateCapella.commit(); // Clear cache to ensure the cache of bellatrix fields is not used by new capella fields + // biome-ignore lint/complexity/useLiteralKeys: It is a protected attribute stateCapella["clearCache"](); return stateCapella; diff --git a/packages/state-transition/src/slot/upgradeStateToDeneb.ts b/packages/state-transition/src/slot/upgradeStateToDeneb.ts index 53be75f72ad8..2344a8d4e08e 100644 --- a/packages/state-transition/src/slot/upgradeStateToDeneb.ts +++ b/packages/state-transition/src/slot/upgradeStateToDeneb.ts @@ -34,6 +34,7 @@ export function upgradeStateToDeneb(stateCapella: CachedBeaconStateCapella): Cac stateDeneb.commit(); // Clear cache to ensure the cache of capella fields is not used by new deneb fields + // biome-ignore lint/complexity/useLiteralKeys: It is a protected attribute stateDeneb["clearCache"](); return stateDeneb; diff --git a/packages/state-transition/src/slot/upgradeStateToElectra.ts b/packages/state-transition/src/slot/upgradeStateToElectra.ts index 0bd36a909b46..b7cdde86a479 100644 --- a/packages/state-transition/src/slot/upgradeStateToElectra.ts +++ b/packages/state-transition/src/slot/upgradeStateToElectra.ts @@ -112,6 +112,7 @@ export function upgradeStateToElectra(stateDeneb: CachedBeaconStateDeneb): Cache // Commit new added fields ViewDU to the root node stateElectra.commit(); // Clear cache to ensure the cache of deneb fields is not used by new ELECTRA fields + // biome-ignore lint/complexity/useLiteralKeys: It is a protected attribute stateElectra["clearCache"](); return stateElectra; @@ -154,6 +155,7 @@ export function upgradeStateToElectraOriginal(stateDeneb: CachedBeaconStateDeneb // Commit new added fields ViewDU to the root node stateElectra.commit(); // Clear cache to ensure the cache of deneb fields is not used by new ELECTRA fields + // biome-ignore lint/complexity/useLiteralKeys: It is a protected attribute stateElectra["clearCache"](); return stateElectra; diff --git a/packages/state-transition/src/util/balance.ts b/packages/state-transition/src/util/balance.ts index e9b7a06e4130..c6b196846ec9 100644 --- a/packages/state-transition/src/util/balance.ts +++ b/packages/state-transition/src/util/balance.ts @@ -2,7 +2,7 @@ import {EFFECTIVE_BALANCE_INCREMENT} from "@lodestar/params"; import {Gwei, ValidatorIndex} from "@lodestar/types"; import {bigIntMax} from "@lodestar/utils"; import {EffectiveBalanceIncrements} from "../cache/effectiveBalanceIncrements.js"; -import {BeaconStateAllForks} from ".."; +import {BeaconStateAllForks} from "../index.js"; import {CachedBeaconStateAllForks} from "../types.js"; /** diff --git a/packages/state-transition/src/util/blindedBlock.ts b/packages/state-transition/src/util/blindedBlock.ts index 2e4e4d590817..1793ff37255e 100644 --- a/packages/state-transition/src/util/blindedBlock.ts +++ b/packages/state-transition/src/util/blindedBlock.ts @@ -25,9 +25,13 @@ export function blindedOrFullBlockHashTreeRoot( ): Root { return isBlindedBeaconBlock(blindedOrFull) ? // Blinded - config.getExecutionForkTypes(blindedOrFull.slot).BlindedBeaconBlock.hashTreeRoot(blindedOrFull) + config + .getExecutionForkTypes(blindedOrFull.slot) + .BlindedBeaconBlock.hashTreeRoot(blindedOrFull) : // Full - config.getForkTypes(blindedOrFull.slot).BeaconBlock.hashTreeRoot(blindedOrFull); + config + .getForkTypes(blindedOrFull.slot) + .BeaconBlock.hashTreeRoot(blindedOrFull); } export function blindedOrFullBlockToHeader( @@ -36,9 +40,13 @@ export function blindedOrFullBlockToHeader( ): BeaconBlockHeader { const bodyRoot = isBlindedBeaconBlock(blindedOrFull) ? // Blinded - config.getExecutionForkTypes(blindedOrFull.slot).BlindedBeaconBlockBody.hashTreeRoot(blindedOrFull.body) + config + .getExecutionForkTypes(blindedOrFull.slot) + .BlindedBeaconBlockBody.hashTreeRoot(blindedOrFull.body) : // Full - config.getForkTypes(blindedOrFull.slot).BeaconBlockBody.hashTreeRoot(blindedOrFull.body); + config + .getForkTypes(blindedOrFull.slot) + .BeaconBlockBody.hashTreeRoot(blindedOrFull.body); return { slot: blindedOrFull.slot, @@ -94,12 +102,11 @@ export function parseExecutionPayloadAndBlobsBundle(data: ExecutionPayload | Exe } { if (isExecutionPayloadAndBlobsBundle(data)) { return data; - } else { - return { - executionPayload: data, - blobsBundle: null, - }; } + return { + executionPayload: data, + blobsBundle: null, + }; } export function reconstructFullBlockOrContents( @@ -120,7 +127,6 @@ export function reconstructFullBlockOrContents( } return {signedBlock, ...contents} as SignedBeaconBlockOrContents; - } else { - return signedBlock as SignedBeaconBlockOrContents; } + return signedBlock as SignedBeaconBlockOrContents; } diff --git a/packages/state-transition/src/util/computeAnchorCheckpoint.ts b/packages/state-transition/src/util/computeAnchorCheckpoint.ts index e2efc18952c2..e37ffc2c632d 100644 --- a/packages/state-transition/src/util/computeAnchorCheckpoint.ts +++ b/packages/state-transition/src/util/computeAnchorCheckpoint.ts @@ -9,8 +9,8 @@ export function computeAnchorCheckpoint( config: ChainForkConfig, anchorState: BeaconStateAllForks ): {checkpoint: phase0.Checkpoint; blockHeader: phase0.BeaconBlockHeader} { - let blockHeader; - let root; + let blockHeader: phase0.BeaconBlockHeader; + let root: Uint8Array; const blockTypes = config.getForkTypes(anchorState.latestBlockHeader.slot); if (anchorState.latestBlockHeader.slot === GENESIS_SLOT) { diff --git a/packages/state-transition/src/util/deposit.ts b/packages/state-transition/src/util/deposit.ts index e8ef93c515d2..4370a13c783c 100644 --- a/packages/state-transition/src/util/deposit.ts +++ b/packages/state-transition/src/util/deposit.ts @@ -15,10 +15,8 @@ export function getEth1DepositCount(state: CachedBeaconStateAllForks, eth1Data?: if (state.eth1DepositIndex < eth1DataIndexLimit) { return Math.min(MAX_DEPOSITS, eth1DataIndexLimit - state.eth1DepositIndex); - } else { - return 0; } - } else { - return Math.min(MAX_DEPOSITS, eth1DataToUse.depositCount - state.eth1DepositIndex); + return 0; } + return Math.min(MAX_DEPOSITS, eth1DataToUse.depositCount - state.eth1DepositIndex); } diff --git a/packages/state-transition/src/util/epochShuffling.ts b/packages/state-transition/src/util/epochShuffling.ts index c26c62fd2079..6f63a2f4f5f8 100644 --- a/packages/state-transition/src/util/epochShuffling.ts +++ b/packages/state-transition/src/util/epochShuffling.ts @@ -1,3 +1,4 @@ +import {asyncUnshuffleList, unshuffleList} from "@chainsafe/swap-or-not-shuffle"; import {Epoch, RootHex, ssz, ValidatorIndex} from "@lodestar/types"; import {GaugeExtra, intDiv, Logger, NoLabels, toRootHex} from "@lodestar/utils"; import { @@ -6,11 +7,11 @@ import { MAX_COMMITTEES_PER_SLOT, SLOTS_PER_EPOCH, TARGET_COMMITTEE_SIZE, + SHUFFLE_ROUND_COUNT, } from "@lodestar/params"; import {BeaconConfig} from "@lodestar/config"; import {BeaconStateAllForks} from "../types.js"; import {getSeed} from "./seed.js"; -import {unshuffleList} from "./shuffle.js"; import {computeStartSlotAtEpoch} from "./epoch.js"; import {getBlockRootAtSlot} from "./blockRoot.js"; import {computeAnchorCheckpoint} from "./computeAnchorCheckpoint.js"; @@ -102,24 +103,15 @@ export function computeCommitteeCount(activeValidatorCount: number): number { return Math.max(1, Math.min(MAX_COMMITTEES_PER_SLOT, committeesPerSlot)); } -export function computeEpochShuffling( - state: BeaconStateAllForks, - activeIndices: Uint32Array, - epoch: Epoch -): EpochShuffling { - const activeValidatorCount = activeIndices.length; - - const shuffling = activeIndices.slice(); - const seed = getSeed(state, epoch, DOMAIN_BEACON_ATTESTER); - unshuffleList(shuffling, seed); - +function buildCommitteesFromShuffling(shuffling: Uint32Array): Uint32Array[][] { + const activeValidatorCount = shuffling.length; const committeesPerSlot = computeCommitteeCount(activeValidatorCount); - const committeeCount = committeesPerSlot * SLOTS_PER_EPOCH; - const committees: Uint32Array[][] = []; + const committees = new Array(SLOTS_PER_EPOCH); for (let slot = 0; slot < SLOTS_PER_EPOCH; slot++) { - const slotCommittees: Uint32Array[] = []; + const slotCommittees = new Array(committeesPerSlot); + for (let committeeIndex = 0; committeeIndex < committeesPerSlot; committeeIndex++) { const index = slot * committeesPerSlot + committeeIndex; const startOffset = Math.floor((activeValidatorCount * index) / committeeCount); @@ -127,17 +119,48 @@ export function computeEpochShuffling( if (!(startOffset <= endOffset)) { throw new Error(`Invalid offsets: start ${startOffset} must be less than or equal end ${endOffset}`); } - slotCommittees.push(shuffling.subarray(startOffset, endOffset)); + slotCommittees[committeeIndex] = shuffling.subarray(startOffset, endOffset); } - committees.push(slotCommittees); + + committees[slot] = slotCommittees; } + return committees; +} + +export function computeEpochShuffling( + // TODO: (@matthewkeil) remove state/epoch and pass in seed to clean this up + state: BeaconStateAllForks, + activeIndices: Uint32Array, + epoch: Epoch +): EpochShuffling { + const seed = getSeed(state, epoch, DOMAIN_BEACON_ATTESTER); + const shuffling = unshuffleList(activeIndices, seed, SHUFFLE_ROUND_COUNT); + const committees = buildCommitteesFromShuffling(shuffling); + return { + epoch, + activeIndices, + shuffling, + committees, + committeesPerSlot: committees[0].length, + }; +} + +export async function computeEpochShufflingAsync( + // TODO: (@matthewkeil) remove state/epoch and pass in seed to clean this up + state: BeaconStateAllForks, + activeIndices: Uint32Array, + epoch: Epoch +): Promise { + const seed = getSeed(state, epoch, DOMAIN_BEACON_ATTESTER); + const shuffling = await asyncUnshuffleList(activeIndices, seed, SHUFFLE_ROUND_COUNT); + const committees = buildCommitteesFromShuffling(shuffling); return { epoch, activeIndices, shuffling, committees, - committeesPerSlot, + committeesPerSlot: committees[0].length, }; } diff --git a/packages/state-transition/src/util/execution.ts b/packages/state-transition/src/util/execution.ts index b9243ebe7874..deed64bd6c51 100644 --- a/packages/state-transition/src/util/execution.ts +++ b/packages/state-transition/src/util/execution.ts @@ -71,13 +71,13 @@ export function isMergeTransitionComplete(state: BeaconStateExecutions): boolean // TODO: Performance ssz.bellatrix.ExecutionPayloadHeader.defaultValue() ); - } else { - return !ssz.capella.ExecutionPayloadHeader.equals( - state.latestExecutionPayloadHeader, - // TODO: Performance - ssz.capella.ExecutionPayloadHeader.defaultValue() - ); } + + return !ssz.capella.ExecutionPayloadHeader.equals( + state.latestExecutionPayloadHeader, + // TODO: Performance + ssz.capella.ExecutionPayloadHeader.defaultValue() + ); } /** Type guard for bellatrix.BeaconState */ @@ -112,11 +112,13 @@ export function getFullOrBlindedPayloadFromBody( ): ExecutionPayload | ExecutionPayloadHeader { if (isBlindedBeaconBlockBody(body)) { return body.executionPayloadHeader; - } else if ((body as bellatrix.BeaconBlockBody).executionPayload !== undefined) { + } + + if ((body as bellatrix.BeaconBlockBody).executionPayload !== undefined) { return (body as bellatrix.BeaconBlockBody).executionPayload; - } else { - throw Error("Not full or blinded beacon block"); } + + throw Error("Not full or blinded beacon block"); } export function isCapellaPayload( diff --git a/packages/state-transition/src/util/index.ts b/packages/state-transition/src/util/index.ts index 5f8d9e5cdcfc..b88a20719b85 100644 --- a/packages/state-transition/src/util/index.ts +++ b/packages/state-transition/src/util/index.ts @@ -17,7 +17,6 @@ export * from "./genesis.js"; export * from "./interop.js"; export * from "./rootCache.js"; export * from "./seed.js"; -export * from "./shuffle.js"; export * from "./shufflingDecisionRoot.js"; export * from "./signatureSets.js"; export * from "./signingRoot.js"; diff --git a/packages/state-transition/src/util/loadState/loadValidator.ts b/packages/state-transition/src/util/loadState/loadValidator.ts index dcf5051c9c6d..406c848ef089 100644 --- a/packages/state-transition/src/util/loadState/loadValidator.ts +++ b/packages/state-transition/src/util/loadState/loadValidator.ts @@ -17,9 +17,8 @@ export function loadValidator( newValidatorValue[field] = seedValidator[field]; } return ssz.phase0.Validator.toViewDU(newValidatorValue); - } else { - return ssz.phase0.Validator.deserializeToViewDU(newValidatorBytes); } + return ssz.phase0.Validator.deserializeToViewDU(newValidatorBytes); } /** diff --git a/packages/state-transition/src/util/seed.ts b/packages/state-transition/src/util/seed.ts index a5a0028d6c17..4131d4d9481f 100644 --- a/packages/state-transition/src/util/seed.ts +++ b/packages/state-transition/src/util/seed.ts @@ -155,7 +155,7 @@ export function computeShuffledIndex(index: number, indexCount: number, seed: By const position = Math.max(permuted, flip); const source = digest(Buffer.concat([_seed, intToBytes(i, 1), intToBytes(Math.floor(position / 256), 4)])); const byte = source[Math.floor((position % 256) / 8)]; - const bit = (byte >> position % 8) % 2; + const bit = (byte >> (position % 8)) % 2; permuted = bit ? flip : permuted; } return permuted; diff --git a/packages/state-transition/src/util/shuffle.ts b/packages/state-transition/src/util/shuffle.ts deleted file mode 100644 index 39137bca69d0..000000000000 --- a/packages/state-transition/src/util/shuffle.ts +++ /dev/null @@ -1,222 +0,0 @@ -import {digest} from "@chainsafe/as-sha256"; -import {SHUFFLE_ROUND_COUNT} from "@lodestar/params"; -import {Bytes32} from "@lodestar/types"; -import {assert, bytesToBigInt} from "@lodestar/utils"; - -// ArrayLike but with settable indices -type Shuffleable = { - readonly length: number; - [index: number]: number; -}; - -// ShuffleList shuffles a list, using the given seed for randomness. Mutates the input list. -export function shuffleList(input: Shuffleable, seed: Bytes32): void { - innerShuffleList(input, seed, true); -} - -// UnshuffleList undoes a list shuffling using the seed of the shuffling. Mutates the input list. -export function unshuffleList(input: Shuffleable, seed: Bytes32): void { - innerShuffleList(input, seed, false); -} - -const _SHUFFLE_H_SEED_SIZE = 32; -const _SHUFFLE_H_ROUND_SIZE = 1; -const _SHUFFLE_H_POSITION_WINDOW_SIZE = 4; -const _SHUFFLE_H_PIVOT_VIEW_SIZE = _SHUFFLE_H_SEED_SIZE + _SHUFFLE_H_ROUND_SIZE; -const _SHUFFLE_H_TOTAL_SIZE = _SHUFFLE_H_SEED_SIZE + _SHUFFLE_H_ROUND_SIZE + _SHUFFLE_H_POSITION_WINDOW_SIZE; - -/* - -def shuffle(list_size, seed): - indices = list(range(list_size)) - for round in range(90): - hash_bytes = b''.join([ - hash(seed + round.to_bytes(1, 'little') + (i).to_bytes(4, 'little')) - for i in range((list_size + 255) // 256) - ]) - pivot = int.from_bytes(hash(seed + round.to_bytes(1, 'little')), 'little') % list_size - - powers_of_two = [1, 2, 4, 8, 16, 32, 64, 128] - - for i, index in enumerate(indices): - flip = (pivot - index) % list_size - hash_pos = index if index > flip else flip - byte = hash_bytes[hash_pos // 8] - if byte & powers_of_two[hash_pos % 8]: - indices[i] = flip - return indices - -Heavily-optimized version of the set-shuffling algorithm proposed by Vitalik to shuffle all items in a list together. - -Original here: - https://github.com/ethereum/consensus-specs/pull/576 - -Main differences, implemented by @protolambda: - - User can supply input slice to shuffle, simple provide [0,1,2,3,4, ...] to get a list of cleanly shuffled indices. - - Input slice is shuffled (hence no return value), no new array is allocated - - Allocations as minimal as possible: only a very minimal buffer for hashing - (this should be allocated on the stack, compiler will find it with escape analysis). - This is not bigger than what's used for shuffling a single index! - As opposed to larger allocations (size O(n) instead of O(1)) made in the original. - - Replaced pseudocode/python workarounds with bit-logic. - - User can provide their own hash-function (as long as it outputs a 32 len byte slice) - -This Typescript version is an adaption of the Python version, in turn an adaption of the original Go version. -Python: https://github.com/protolambda/eth2fastspec/blob/14e04e9db77ef7c8b7788ffdaa7e142d7318dd7e/eth2fastspec.py#L63 -Go: https://github.com/protolambda/eth2-shuffle -All three implemented by @protolambda, but meant for public use, like the original spec version. -*/ - -function setPositionUint32(value: number, buf: Buffer): void { - // Little endian, optimized version - buf[_SHUFFLE_H_PIVOT_VIEW_SIZE] = (value >> 0) & 0xff; - buf[_SHUFFLE_H_PIVOT_VIEW_SIZE + 1] = (value >> 8) & 0xff; - buf[_SHUFFLE_H_PIVOT_VIEW_SIZE + 2] = (value >> 16) & 0xff; - buf[_SHUFFLE_H_PIVOT_VIEW_SIZE + 3] = (value >> 24) & 0xff; -} - -// Shuffles or unshuffles, depending on the `dir` (true for shuffling, false for unshuffling -function innerShuffleList(input: Shuffleable, seed: Bytes32, dir: boolean): void { - if (input.length <= 1) { - // nothing to (un)shuffle - return; - } - if (SHUFFLE_ROUND_COUNT == 0) { - // no shuffling - return; - } - // uint32 is sufficient, and necessary in JS, - // as we do a lot of bit math on it, which cannot be done as fast on more bits. - const listSize = input.length >>> 0; - // check if list size fits in uint32 - assert.equal(listSize, input.length, "input length does not fit uint32"); - // check that the seed is 32 bytes - assert.lte(seed.length, _SHUFFLE_H_SEED_SIZE, `seed length is not lte ${_SHUFFLE_H_SEED_SIZE} bytes`); - - const buf = Buffer.alloc(_SHUFFLE_H_TOTAL_SIZE); - let r = 0; - if (!dir) { - // Start at last round. - // Iterating through the rounds in reverse, un-swaps everything, effectively un-shuffling the list. - r = SHUFFLE_ROUND_COUNT - 1; - } - - // Seed is always the first 32 bytes of the hash input, we never have to change this part of the buffer. - buf.set(seed, 0); - - // initial values here are not used: overwritten first within the inner for loop. - let source = seed; // just setting it to a Bytes32 - let byteV = 0; - - // eslint-disable-next-line no-constant-condition - while (true) { - // spec: pivot = bytes_to_int(hash(seed + int_to_bytes1(round))[0:8]) % list_size - // This is the "int_to_bytes1(round)", appended to the seed. - buf[_SHUFFLE_H_SEED_SIZE] = r; - // Seed is already in place, now just hash the correct part of the buffer, and take a uint64 from it, - // and modulo it to get a pivot within range. - const h = digest(buf.subarray(0, _SHUFFLE_H_PIVOT_VIEW_SIZE)); - const pivot = Number(bytesToBigInt(h.subarray(0, 8)) % BigInt(listSize)) >>> 0; - - // Split up the for-loop in two: - // 1. Handle the part from 0 (incl) to pivot (incl). This is mirrored around (pivot / 2) - // 2. Handle the part from pivot (excl) to N (excl). This is mirrored around ((pivot / 2) + (size/2)) - // The pivot defines a split in the array, with each of the splits mirroring their data within the split. - // Print out some example even/odd sized index lists, with some even/odd pivots, - // and you can deduce how the mirroring works exactly. - // Note that the mirror is strict enough to not consider swapping the index @mirror with itself. - let mirror = (pivot + 1) >> 1; - // Since we are iterating through the "positions" in order, we can just repeat the hash every 256th position. - // No need to pre-compute every possible hash for efficiency like in the example code. - // We only need it consecutively (we are going through each in reverse order however, but same thing) - // - // spec: source = hash(seed + int_to_bytes1(round) + int_to_bytes4(position // 256)) - // - seed is still in 0:32 (excl., 32 bytes) - // - round number is still in 32 - // - mix in the position for randomness, except the last byte of it, - // which will be used later to select a bit from the resulting hash. - // We start from the pivot position, and work back to the mirror position (of the part left to the pivot). - // This makes us process each pear exactly once (instead of unnecessarily twice, like in the spec) - setPositionUint32(pivot >> 8, buf); // already using first pivot byte below. - source = digest(buf); - byteV = source[(pivot & 0xff) >> 3]; - - for (let i = 0, j; i < mirror; i++) { - j = pivot - i; - // -- step() fn start - // The pair is i,j. With j being the bigger of the two, hence the "position" identifier of the pair. - // Every 256th bit (aligned to j). - if ((j & 0xff) == 0xff) { - // just overwrite the last part of the buffer, reuse the start (seed, round) - setPositionUint32(j >> 8, buf); - source = digest(buf); - } - - // Same trick with byte retrieval. Only every 8th. - if ((j & 0x7) == 0x7) { - byteV = source[(j & 0xff) >> 3]; - } - - const bitV = (byteV >> (j & 0x7)) & 0x1; - - if (bitV == 1) { - // swap the pair items - const tmp = input[j]; - input[j] = input[i]; - input[i] = tmp; - } - // -- step() fn end - } - - // Now repeat, but for the part after the pivot. - mirror = (pivot + listSize + 1) >> 1; - const end = listSize - 1; - // Again, seed and round input is in place, just update the position. - // We start at the end, and work back to the mirror point. - // This makes us process each pear exactly once (instead of unnecessarily twice, like in the spec) - setPositionUint32(end >> 8, buf); - source = digest(buf); - byteV = source[(end & 0xff) >> 3]; - for (let i = pivot + 1, j; i < mirror; i++) { - j = end - i + pivot + 1; - // -- step() fn start - // The pair is i,j. With j being the bigger of the two, hence the "position" identifier of the pair. - // Every 256th bit (aligned to j). - if ((j & 0xff) == 0xff) { - // just overwrite the last part of the buffer, reuse the start (seed, round) - setPositionUint32(j >> 8, buf); - source = digest(buf); - } - - // Same trick with byte retrieval. Only every 8th. - if ((j & 0x7) == 0x7) { - byteV = source[(j & 0xff) >> 3]; - } - - const bitV = (byteV >> (j & 0x7)) & 0x1; - - if (bitV == 1) { - // swap the pair items - const tmp = input[j]; - input[j] = input[i]; - input[i] = tmp; - } - // -- step() fn end - } - - // go forwards? - if (dir) { - // -> shuffle - r += 1; - if (r == SHUFFLE_ROUND_COUNT) { - break; - } - } else { - if (r == 0) { - break; - } - // -> un-shuffle - r -= 1; - } - } -} diff --git a/packages/state-transition/src/util/shufflingDecisionRoot.ts b/packages/state-transition/src/util/shufflingDecisionRoot.ts index 10af814e9af3..5a6c500d3987 100644 --- a/packages/state-transition/src/util/shufflingDecisionRoot.ts +++ b/packages/state-transition/src/util/shufflingDecisionRoot.ts @@ -12,11 +12,10 @@ import {computeStartSlotAtEpoch} from "./epoch.js"; */ export function proposerShufflingDecisionRoot(state: CachedBeaconStateAllForks): Root | null { const decisionSlot = proposerShufflingDecisionSlot(state); - if (state.slot == decisionSlot) { + if (state.slot === decisionSlot) { return null; - } else { - return getBlockRootAtSlot(state, decisionSlot); } + return getBlockRootAtSlot(state, decisionSlot); } /** @@ -37,11 +36,10 @@ function proposerShufflingDecisionSlot(state: CachedBeaconStateAllForks): Slot { */ export function attesterShufflingDecisionRoot(state: CachedBeaconStateAllForks, requestedEpoch: Epoch): Root | null { const decisionSlot = attesterShufflingDecisionSlot(state, requestedEpoch); - if (state.slot == decisionSlot) { + if (state.slot === decisionSlot) { return null; - } else { - return getBlockRootAtSlot(state, decisionSlot); } + return getBlockRootAtSlot(state, decisionSlot); } /** @@ -75,7 +73,6 @@ function attesterShufflingDecisionEpoch(state: CachedBeaconStateAllForks, reques if (requestedEpoch < currentEpoch) { throw Error(`EpochTooLow: current ${currentEpoch} requested ${requestedEpoch}`); - } else { - throw Error(`EpochTooHigh: current ${currentEpoch} requested ${requestedEpoch}`); } + throw Error(`EpochTooHigh: current ${currentEpoch} requested ${requestedEpoch}`); } diff --git a/packages/state-transition/src/util/validator.ts b/packages/state-transition/src/util/validator.ts index ebad21d9d25c..bf79f9264342 100644 --- a/packages/state-transition/src/util/validator.ts +++ b/packages/state-transition/src/util/validator.ts @@ -45,9 +45,8 @@ export function getActiveValidatorIndices(state: BeaconStateAllForks, epoch: Epo export function getActivationChurnLimit(config: ChainForkConfig, fork: ForkSeq, activeValidatorCount: number): number { if (fork >= ForkSeq.deneb) { return Math.min(config.MAX_PER_EPOCH_ACTIVATION_CHURN_LIMIT, getChurnLimit(config, activeValidatorCount)); - } else { - return getChurnLimit(config, activeValidatorCount); } + return getChurnLimit(config, activeValidatorCount); } export function getChurnLimit(config: ChainForkConfig, activeValidatorCount: number): number { @@ -79,9 +78,8 @@ export function getMaxEffectiveBalance(withdrawalCredentials: Uint8Array): numbe // Compounding withdrawal credential only available since Electra if (hasCompoundingWithdrawalCredential(withdrawalCredentials)) { return MAX_EFFECTIVE_BALANCE_ELECTRA; - } else { - return MIN_ACTIVATION_BALANCE; } + return MIN_ACTIVATION_BALANCE; } export function getActiveBalance(state: CachedBeaconStateElectra, validatorIndex: ValidatorIndex): number { diff --git a/packages/state-transition/src/util/weakSubjectivity.ts b/packages/state-transition/src/util/weakSubjectivity.ts index 0e606e66340f..8d7c82842496 100644 --- a/packages/state-transition/src/util/weakSubjectivity.ts +++ b/packages/state-transition/src/util/weakSubjectivity.ts @@ -80,7 +80,6 @@ export function computeWeakSubjectivityPeriodFromConstituents( const t = Math.floor(totalBalanceByIncrement / N); const T = MAX_EFFECTIVE_BALANCE / ETH_TO_GWEI; const delta = churnLimit; - // eslint-disable-next-line @typescript-eslint/naming-convention const Delta = MAX_DEPOSITS * SLOTS_PER_EPOCH; const D = SAFETY_DECAY; diff --git a/packages/state-transition/test/cache.ts b/packages/state-transition/test/cache.ts index 9ca7ea25201c..59ddfe40b7c1 100644 --- a/packages/state-transition/test/cache.ts +++ b/packages/state-transition/test/cache.ts @@ -3,7 +3,6 @@ import {fileURLToPath} from "node:url"; // Global variable __dirname no longer available in ES6 modules. // Solutions: https://stackoverflow.com/questions/46745014/alternative-for-dirname-in-node-js-when-using-es6-modules -// eslint-disable-next-line @typescript-eslint/naming-convention const __dirname = path.dirname(fileURLToPath(import.meta.url)); export const testCachePath = path.join(__dirname, "../test-cache"); diff --git a/packages/state-transition/test/perf/analyzeEpochs.ts b/packages/state-transition/test/perf/analyzeEpochs.ts index deb0861427bf..9fe04bf7c522 100644 --- a/packages/state-transition/test/perf/analyzeEpochs.ts +++ b/packages/state-transition/test/perf/analyzeEpochs.ts @@ -123,7 +123,6 @@ async function analyzeEpochs(network: NetworkName, fromEpoch?: number): Promise< const {previousEpochAttestations, currentEpochAttestations} = state as phase0.BeaconState; - // eslint-disable-next-line no-console console.log(`Processed epoch ${epoch}`); writeToCsv({ epoch, @@ -182,7 +181,6 @@ if (!network) { } analyzeEpochs(network as NetworkName, fromEpoch).catch((e: Error) => { - // eslint-disable-next-line no-console console.error(e); process.exit(1); }); diff --git a/packages/state-transition/test/perf/csv.ts b/packages/state-transition/test/perf/csv.ts index d54b277d707c..2f47fd79f05d 100644 --- a/packages/state-transition/test/perf/csv.ts +++ b/packages/state-transition/test/perf/csv.ts @@ -41,7 +41,7 @@ export function readCsv>(filepath: string): T[] for (let i = 0; i < headers.length; i++) { const str = valuesRow[i]; const num = parseInt(str); - value[headers[i] as keyof T] = (isNaN(num) ? str : num) as T[keyof T]; + value[headers[i] as keyof T] = (Number.isNaN(num) ? str : num) as T[keyof T]; } values[j] = value; } diff --git a/packages/state-transition/test/perf/dataStructures/arrayish.memory.ts b/packages/state-transition/test/perf/dataStructures/arrayish.memory.ts index 7e10f447181f..f37421ce2a89 100644 --- a/packages/state-transition/test/perf/dataStructures/arrayish.memory.ts +++ b/packages/state-transition/test/perf/dataStructures/arrayish.memory.ts @@ -110,7 +110,6 @@ for (let i = 0; i < 1e8; i++) { const heapUsedM = linearRegression(xs, heapUsed).m; const rssM = linearRegression(xs, rss).m; - // eslint-disable-next-line no-console console.log(i, {arrayBuffersM, externalM, heapTotalM, heapUsedM, rssM}); } } diff --git a/packages/state-transition/test/perf/dataStructures/arrayish.test.ts b/packages/state-transition/test/perf/dataStructures/arrayish.test.ts index 5b6af0d989b6..353f81951aa7 100644 --- a/packages/state-transition/test/perf/dataStructures/arrayish.test.ts +++ b/packages/state-transition/test/perf/dataStructures/arrayish.test.ts @@ -104,7 +104,7 @@ describe("Array", () => { let arr: number[]; - before(function () { + before(() => { arr = createArray(n); }); diff --git a/packages/state-transition/test/perf/epoch/processRegistryUpdates.test.ts b/packages/state-transition/test/perf/epoch/processRegistryUpdates.test.ts index 2d57de44f8ee..588fe9ec0213 100644 --- a/packages/state-transition/test/perf/epoch/processRegistryUpdates.test.ts +++ b/packages/state-transition/test/perf/epoch/processRegistryUpdates.test.ts @@ -78,7 +78,7 @@ type IndicesLengths = { * Create a state that causes `changeRatio` fraction (0,1) of validators to change their effective balance. */ function getRegistryUpdatesTestData( - vc: number, + _vc: number, lengths: IndicesLengths ): { state: CachedBeaconStateAllForks; diff --git a/packages/state-transition/test/perf/hashing.test.ts b/packages/state-transition/test/perf/hashing.test.ts index b7afc59717bc..26bfd935c08a 100644 --- a/packages/state-transition/test/perf/hashing.test.ts +++ b/packages/state-transition/test/perf/hashing.test.ts @@ -1,13 +1,14 @@ import {itBench} from "@dapplion/benchmark"; +import {unshuffleList} from "@chainsafe/swap-or-not-shuffle"; import {ssz} from "@lodestar/types"; -import {unshuffleList} from "../../src/index.js"; +import {SHUFFLE_ROUND_COUNT} from "@lodestar/params"; import {generatePerfTestCachedStatePhase0, numValidators} from "./util.js"; // Test cost of hashing state after some modifications describe("BeaconState hashTreeRoot", () => { const vc = numValidators; - const indicesShuffled: number[] = []; + let indicesShuffled: Uint32Array; let stateOg: ReturnType; before(function () { @@ -15,8 +16,13 @@ describe("BeaconState hashTreeRoot", () => { stateOg = generatePerfTestCachedStatePhase0(); stateOg.hashTreeRoot(); - for (let i = 0; i < vc; i++) indicesShuffled[i] = i; - unshuffleList(indicesShuffled, new Uint8Array([42, 32])); + const seed = new Uint8Array(32); + seed.set([42, 32], 0); + const preShuffle = new Uint32Array(numValidators); + for (let i = 0; i < vc; i++) { + preShuffle[i] = i; + } + indicesShuffled = unshuffleList(preShuffle, seed, SHUFFLE_ROUND_COUNT); }); const validator = ssz.phase0.Validator.defaultViewDU(); diff --git a/packages/state-transition/test/perf/misc/aggregationBits.test.ts b/packages/state-transition/test/perf/misc/aggregationBits.test.ts index 7954f6a06a71..a0578970dfe9 100644 --- a/packages/state-transition/test/perf/misc/aggregationBits.test.ts +++ b/packages/state-transition/test/perf/misc/aggregationBits.test.ts @@ -12,7 +12,7 @@ describe("aggregationBits", () => { let indexes: number[]; let bitlistTree: BitArray; - before(function () { + before(() => { const aggregationBits = BitArray.fromBoolArray(Array.from({length: len}, () => true)); bitlistTree = ssz.phase0.CommitteeBits.toViewDU(aggregationBits); indexes = Array.from({length: len}, () => 165432); diff --git a/packages/state-transition/test/perf/misc/arrayCreation.test.ts b/packages/state-transition/test/perf/misc/arrayCreation.test.ts index 8fd52ff99e27..4568948c678d 100644 --- a/packages/state-transition/test/perf/misc/arrayCreation.test.ts +++ b/packages/state-transition/test/perf/misc/arrayCreation.test.ts @@ -1,4 +1,4 @@ -describe.skip("array creation", function () { +describe.skip("array creation", () => { const testCases: {id: string; fn: (n: number) => void}[] = [ { id: "Array.from(() => 0)", @@ -36,7 +36,6 @@ describe.skip("array creation", function () { } const to = process.hrtime.bigint(); const diffMs = Number(to - from) / 1e6; - // eslint-disable-next-line no-console console.log(`${id}: ${diffMs / opsRun} ms`); }); } diff --git a/packages/state-transition/test/perf/misc/bitopts.test.ts b/packages/state-transition/test/perf/misc/bitopts.test.ts index 93df681bb3e2..38677002a969 100644 --- a/packages/state-transition/test/perf/misc/bitopts.test.ts +++ b/packages/state-transition/test/perf/misc/bitopts.test.ts @@ -14,7 +14,6 @@ describe.skip("bit opts", function () { } const to = process.hrtime.bigint(); const diffMs = Number(to - from) / 1e6; - // eslint-disable-next-line no-console console.log(`Time spent on OR in getAttestationDeltas: ${diffMs * ((orOptsPerRun * validators) / opsRun)} ms`); }); }); diff --git a/packages/state-transition/test/perf/misc/proxy.test.ts b/packages/state-transition/test/perf/misc/proxy.test.ts index 6a3536a12de5..08618a1727e2 100644 --- a/packages/state-transition/test/perf/misc/proxy.test.ts +++ b/packages/state-transition/test/perf/misc/proxy.test.ts @@ -12,9 +12,8 @@ describe("Proxy cost", () => { get(target, p) { if (p === "length") { return target.length; - } else { - return target[p as unknown as number]; } + return target[p as unknown as number]; }, }); diff --git a/packages/state-transition/test/perf/shuffle/numberMath.test.ts b/packages/state-transition/test/perf/shuffle/numberMath.test.ts deleted file mode 100644 index 08e57b090aa3..000000000000 --- a/packages/state-transition/test/perf/shuffle/numberMath.test.ts +++ /dev/null @@ -1,82 +0,0 @@ -import {itBench} from "@dapplion/benchmark"; - -describe.skip("shuffle number math ops", () => { - const forRuns = 100e5; - const j = forRuns / 2; - - const arrSize = forRuns; - const input: number[] = []; - const inputUint32Array = new Uint32Array(arrSize); - for (let i = 0; i < arrSize; i++) { - input[i] = i; - inputUint32Array[i] = i; - } - - itBench("if(i == 1)", () => { - for (let i = 0; i < forRuns; i++) { - if (i === 1) { - // - } - } - }); - - itBench("if(i)", () => { - for (let i = 0; i < forRuns; i++) { - if (i) { - // - } - } - }); - - itBench("i == j", () => { - for (let i = 0; i < forRuns; i++) { - i == j; - } - }); - - itBench("i === j", () => { - for (let i = 0; i < forRuns; i++) { - i === j; - } - }); - - itBench("bit opts", () => { - for (let i = 0; i < forRuns; i++) { - (j & 0x7) == 0x7; - } - }); - - itBench("modulo", () => { - for (let i = 0; i < forRuns; i++) { - j % 8 == 0; - } - }); - - itBench(">> 3", () => { - for (let i = 0; i < forRuns; i++) { - j >> 3; - } - }); - - itBench("/ 8", () => { - for (let i = 0; i < forRuns; i++) { - j / 8; - } - }); - - itBench("swap item in array", () => { - for (let i = 0; i < forRuns; i++) { - const tmp = input[forRuns - i]; - input[forRuns - i] = input[i]; - input[i] = tmp; - } - }); - - itBench("swap item in Uint32Array", () => { - for (let i = 0; i < forRuns; i++) { - const tmp = inputUint32Array[forRuns - i]; - inputUint32Array[forRuns - i] = inputUint32Array[i]; - inputUint32Array[i] = tmp; - } - }); -}); diff --git a/packages/state-transition/test/perf/shuffle/shuffle.test.ts b/packages/state-transition/test/perf/shuffle/shuffle.test.ts deleted file mode 100644 index ea1a9d606184..000000000000 --- a/packages/state-transition/test/perf/shuffle/shuffle.test.ts +++ /dev/null @@ -1,28 +0,0 @@ -import {itBench} from "@dapplion/benchmark"; -import {unshuffleList} from "../../../src/index.js"; - -// Lightouse Lodestar -// 512 254.04 us 1.6034 ms (x6) -// 16384 6.2046 ms 18.272 ms (x3) -// 4000000 1.5617 s 4.9690 s (x3) - -describe("shuffle list", () => { - const seed = new Uint8Array([42, 32]); - - for (const listSize of [ - 16384, 250000, - // Don't run 4_000_000 since it's very slow and not testnet has gotten there yet - // 4e6, - ]) { - itBench({ - id: `shuffle list - ${listSize} els`, - before: () => { - const input: number[] = []; - for (let i = 0; i < listSize; i++) input[i] = i; - return new Uint32Array(input); - }, - beforeEach: (input) => input, - fn: (input) => unshuffleList(input, seed), - }); - } -}); diff --git a/packages/state-transition/test/perf/util.ts b/packages/state-transition/test/perf/util.ts index c764e2d039f9..0f47c241f8f9 100644 --- a/packages/state-transition/test/perf/util.ts +++ b/packages/state-transition/test/perf/util.ts @@ -61,7 +61,6 @@ const secretKeyByModIndex = new Map(); const epoch = 23638; export const perfStateEpoch = epoch; -// eslint-disable-next-line @typescript-eslint/explicit-function-return-type export function getPubkeys(vc = numValidators) { const pubkeysMod = interopPubkeysCached(keypairsMod); const pubkeysModObj = pubkeysMod.map((pk) => PublicKey.fromBytes(pk)); @@ -85,7 +84,6 @@ export function getSecretKeyFromIndexCached(validatorIndex: number): SecretKey { return sk; } -// eslint-disable-next-line @typescript-eslint/explicit-function-return-type function getPubkeyCaches({pubkeysMod, pubkeysModObj}: ReturnType) { // Manually sync pubkeys to prevent doing BLS opts 110_000 times const pubkey2index = new PubkeyIndexMap(); @@ -196,7 +194,7 @@ export function generatePerfTestCachedStatePhase0(opts?: {goBackOneSlot: boolean ) as CachedBeaconStatePhase0; phase0CachedState23638.slot += 1; } - const resultingState = opts && opts.goBackOneSlot ? phase0CachedState23637 : phase0CachedState23638; + const resultingState = opts?.goBackOneSlot ? phase0CachedState23637 : phase0CachedState23638; return resultingState.clone(); } @@ -223,7 +221,6 @@ export function generatePerfTestCachedStateAltair(opts?: { const {pubkeys, pubkeysMod, pubkeysModObj} = getPubkeys(opts?.vc); const {pubkey2index, index2pubkey} = getPubkeyCaches({pubkeys, pubkeysMod, pubkeysModObj}); - // eslint-disable-next-line @typescript-eslint/naming-convention const altairConfig = createChainForkConfig({ALTAIR_FORK_EPOCH: 0}); const origState = generatePerformanceStateAltair(pubkeys); @@ -244,7 +241,7 @@ export function generatePerfTestCachedStateAltair(opts?: { ) as CachedBeaconStateAltair; altairCachedState23638.slot += 1; } - const resultingState = opts && opts.goBackOneSlot ? altairCachedState23637 : altairCachedState23638; + const resultingState = opts?.goBackOneSlot ? altairCachedState23637 : altairCachedState23638; return resultingState.clone(); } diff --git a/packages/state-transition/test/perf/util/signingRoot.test.ts b/packages/state-transition/test/perf/util/signingRoot.test.ts index 96684c753364..1d308c2e3e43 100644 --- a/packages/state-transition/test/perf/util/signingRoot.test.ts +++ b/packages/state-transition/test/perf/util/signingRoot.test.ts @@ -15,7 +15,7 @@ import {computeSigningRoot} from "../../../src/util/signingRoot.js"; ✔ toHexString serialized data 727592.3 ops/s 1.374396 us/op - 6916 runs 10.0 s ✔ Buffer.toString(base64) 2570800 ops/s 388.9840 ns/op - 24628 runs 10.1 s */ -describe("computeSigningRoot", function () { +describe("computeSigningRoot", () => { setBenchOpts({ minMs: 10_000, }); diff --git a/packages/state-transition/test/unit/cachedBeaconState.test.ts b/packages/state-transition/test/unit/cachedBeaconState.test.ts index 96c026340143..668f22e13a1e 100644 --- a/packages/state-transition/test/unit/cachedBeaconState.test.ts +++ b/packages/state-transition/test/unit/cachedBeaconState.test.ts @@ -52,7 +52,6 @@ describe("CachedBeaconState", () => { expect(state2.epochCtx.getValidatorIndex(pubkey2)).toBe(index2); }); - /* eslint-disable @typescript-eslint/naming-convention */ it("Clone and mutate cache post-Electra", () => { const stateView = ssz.electra.BeaconState.defaultViewDU(); const state1 = createCachedBeaconStateTest( diff --git a/packages/state-transition/test/unit/upgradeState.test.ts b/packages/state-transition/test/unit/upgradeState.test.ts index 301cb105dc98..19a7d5c186f8 100644 --- a/packages/state-transition/test/unit/upgradeState.test.ts +++ b/packages/state-transition/test/unit/upgradeState.test.ts @@ -46,7 +46,6 @@ const ZERO_HASH = Buffer.alloc(32, 0); /** default config with ZERO_HASH as genesisValidatorsRoot */ const config = createBeaconConfig(chainConfig, ZERO_HASH); -/* eslint-disable @typescript-eslint/naming-convention */ function getConfig(fork: ForkName, forkEpoch = 0): ChainForkConfig { switch (fork) { case ForkName.phase0: diff --git a/packages/state-transition/test/unit/util/aggregator.test.ts b/packages/state-transition/test/unit/util/aggregator.test.ts index 07fd3172926c..58c2b0afbf58 100644 --- a/packages/state-transition/test/unit/util/aggregator.test.ts +++ b/packages/state-transition/test/unit/util/aggregator.test.ts @@ -8,9 +8,7 @@ import { } from "@lodestar/params"; import {isAggregatorFromCommitteeLength, isSyncCommitteeAggregator} from "../../../src/util/aggregator.js"; -/* eslint-disable @typescript-eslint/naming-convention */ - -describe("isAttestationAggregator", function () { +describe("isAttestationAggregator", () => { const committeeLength = 130; beforeAll(() => { @@ -21,7 +19,7 @@ describe("isAttestationAggregator", function () { }); }); - it("should be false", function () { + it("should be false", () => { const result = isAggregatorFromCommitteeLength( committeeLength, fromHexString( @@ -31,7 +29,7 @@ describe("isAttestationAggregator", function () { expect(result).toBe(false); }); - it("should be true", function () { + it("should be true", () => { const result = isAggregatorFromCommitteeLength( committeeLength, fromHexString( @@ -42,7 +40,7 @@ describe("isAttestationAggregator", function () { }); }); -describe("isSyncCommitteeAggregator", function () { +describe("isSyncCommitteeAggregator", () => { beforeAll(() => { expect({ SYNC_COMMITTEE_SIZE, @@ -55,7 +53,7 @@ describe("isSyncCommitteeAggregator", function () { }); }); - it("should be false", function () { + it("should be false", () => { const result = isSyncCommitteeAggregator( fromHexString( "0x8191d16330837620f0ed85d0d3d52af5b56f7cec12658fa391814251d4b32977eb2e6ca055367354fd63175f8d1d2d7b0678c3c482b738f96a0df40bd06450d99c301a659b8396c227ed781abb37a1604297922219374772ab36b46b84817036" @@ -65,7 +63,7 @@ describe("isSyncCommitteeAggregator", function () { }); // NOTE: Invalid sig, bruteforced last characters to get a true result - it("should be true", function () { + it("should be true", () => { const result = isSyncCommitteeAggregator( fromHexString( "0xa8f8bb92931234ca6d8a34530526bcd6a4cfa3bf33bd0470200dc8fa3ebdc3ba24bc8c6e994d58a0f884eb24336d746c01a29693ed0354c0862c2d5de5859e3f58747045182844d267ba232058f7df1867a406f63a1eb8afec0cf3f00a115142" diff --git a/packages/state-transition/test/unit/util/deposit.test.ts b/packages/state-transition/test/unit/util/deposit.test.ts index 3cfa4abb3409..a682b4e993ed 100644 --- a/packages/state-transition/test/unit/util/deposit.test.ts +++ b/packages/state-transition/test/unit/util/deposit.test.ts @@ -29,7 +29,6 @@ describe("getEth1DepositCount", () => { const postElectraState = createCachedBeaconStateTest( stateView, createChainForkConfig({ - /* eslint-disable @typescript-eslint/naming-convention */ ALTAIR_FORK_EPOCH: 0, BELLATRIX_FORK_EPOCH: 0, CAPELLA_FORK_EPOCH: 0, @@ -63,7 +62,6 @@ describe("getEth1DepositCount", () => { const postElectraState = createCachedBeaconStateTest( stateView, createChainForkConfig({ - /* eslint-disable @typescript-eslint/naming-convention */ ALTAIR_FORK_EPOCH: 0, BELLATRIX_FORK_EPOCH: 0, CAPELLA_FORK_EPOCH: 0, diff --git a/packages/state-transition/test/unit/util/shuffle.test.ts b/packages/state-transition/test/unit/util/shuffle.test.ts deleted file mode 100644 index 9186968674ae..000000000000 --- a/packages/state-transition/test/unit/util/shuffle.test.ts +++ /dev/null @@ -1,29 +0,0 @@ -import {expect, describe, it} from "vitest"; -import {unshuffleList} from "../../../src/index.js"; - -describe("util / shuffle", () => { - const testCases: { - id: string; - input: number[]; - res: number[]; - }[] = [ - // Values from `unshuffleList()` at commit https://github.com/ChainSafe/lodestar/commit/ec065635ca7da7f3788da018bd68c4900f0427d2 - { - id: "8 elements", - input: [0, 1, 2, 3, 4, 5, 6, 7], - res: [6, 3, 4, 0, 1, 5, 7, 2], - }, - { - id: "16 elements", - input: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], - res: [8, 4, 11, 7, 10, 6, 0, 3, 15, 12, 5, 14, 1, 9, 13, 2], - }, - ]; - - const seed = new Uint8Array([42, 32]); - - it.each(testCases)("$id", ({input, res}) => { - unshuffleList(input, seed); - expect(input).toEqual(res); - }); -}); diff --git a/packages/state-transition/test/unit/util/shuffling.test.ts b/packages/state-transition/test/unit/util/shuffling.test.ts new file mode 100644 index 000000000000..f4039b472f5c --- /dev/null +++ b/packages/state-transition/test/unit/util/shuffling.test.ts @@ -0,0 +1,32 @@ +import {describe, it, expect} from "vitest"; +import {ssz} from "@lodestar/types"; +import {generateState} from "../../utils/state.js"; +import {computeEpochShuffling, computeEpochShufflingAsync} from "../../../src/util/epochShuffling.js"; +import {computeEpochAtSlot} from "../../../src/index.js"; + +describe("EpochShuffling", () => { + it("async and sync versions should be identical", async () => { + const numberOfValidators = 1000; + const activeIndices = Uint32Array.from(Array.from({length: numberOfValidators}, (_, i) => i)); + const state = generateState(); + state.slot = 12345; + state.validators = ssz.phase0.Validators.toViewDU( + Array.from({length: numberOfValidators}, () => ({ + activationEligibilityEpoch: 0, + activationEpoch: 0, + exitEpoch: Infinity, + effectiveBalance: 32, + pubkey: Buffer.alloc(48, 0xaa), + slashed: false, + withdrawableEpoch: Infinity, + withdrawalCredentials: Buffer.alloc(8, 0x01), + })) + ); + const epoch = computeEpochAtSlot(state.slot); + + const sync = computeEpochShuffling(state, activeIndices, epoch); + const async = await computeEpochShufflingAsync(state, activeIndices, epoch); + + expect(sync).toStrictEqual(async); + }); +}); diff --git a/packages/state-transition/test/unit/util/validator.test.ts b/packages/state-transition/test/unit/util/validator.test.ts index 65727126742d..203adf9d8ba3 100644 --- a/packages/state-transition/test/unit/util/validator.test.ts +++ b/packages/state-transition/test/unit/util/validator.test.ts @@ -49,7 +49,7 @@ describe("isActiveValidator", () => { describe("isSlashableValidator", () => { let validator: phase0.Validator; - beforeEach(function () { + beforeEach(() => { validator = generateValidator(); }); diff --git a/packages/state-transition/test/unit/util/weakSubjectivity.test.ts b/packages/state-transition/test/unit/util/weakSubjectivity.test.ts index 5f5c784e975a..ce9f02b5ed2f 100644 --- a/packages/state-transition/test/unit/util/weakSubjectivity.test.ts +++ b/packages/state-transition/test/unit/util/weakSubjectivity.test.ts @@ -4,7 +4,7 @@ import {computeWeakSubjectivityPeriodFromConstituents} from "../../../src/util/w import {getChurnLimit} from "../../../src/util/validator.js"; describe("weak subjectivity tests", () => { - describe("computeWeakSubjectivityPeriodFromConstituents", function () { + describe("computeWeakSubjectivityPeriodFromConstituents", () => { const balance28 = 28; const balance32 = 32; diff --git a/packages/state-transition/test/utils/beforeValue.ts b/packages/state-transition/test/utils/beforeValue.ts index f50520372e17..6eaa0846b155 100644 --- a/packages/state-transition/test/utils/beforeValue.ts +++ b/packages/state-transition/test/utils/beforeValue.ts @@ -14,23 +14,21 @@ export type LazyValue = {value: T}; export function beforeValue(fn: () => T | Promise, timeout?: number): LazyValue { let value: T = null as unknown as T; - beforeAll(async function () { + beforeAll(async () => { value = await fn(); }, timeout ?? 300_000); return new Proxy<{value: T}>( {value}, { - get: function (target, prop) { + get: (_target, prop) => { if (prop === "value") { if (value === null) { throw Error("beforeValue has not yet run the before() block"); - } else { - return value; } - } else { - return undefined; + return value; } + return undefined; }, } ); diff --git a/packages/state-transition/test/utils/beforeValueMocha.ts b/packages/state-transition/test/utils/beforeValueMocha.ts index 0d5f8f77d203..daac7c915d0c 100644 --- a/packages/state-transition/test/utils/beforeValueMocha.ts +++ b/packages/state-transition/test/utils/beforeValueMocha.ts @@ -20,16 +20,15 @@ export function beforeValue(fn: () => T | Promise, timeout?: number): Lazy return new Proxy<{value: T}>( {value}, { - get: function (target, prop) { + get: (_target, prop) => { if (prop === "value") { if (value === null) { throw Error("beforeValue has not yet run the before() block"); - } else { - return value; } - } else { - return undefined; + return value; } + + return undefined; }, } ); diff --git a/packages/state-transition/test/utils/rand.ts b/packages/state-transition/test/utils/rand.ts index 11a0efaffe10..d3dc3af278cc 100644 --- a/packages/state-transition/test/utils/rand.ts +++ b/packages/state-transition/test/utils/rand.ts @@ -3,8 +3,9 @@ * Source https://stackoverflow.com/questions/521295/seeding-the-random-number-generator-in-javascript */ export function mulberry32(a: number) { - return function () { - let t = (a += 0x6d2b79f5); + return () => { + a += 0x6d2b79f5; + let t = a; t = Math.imul(t ^ (t >>> 15), t | 1); t ^= t + Math.imul(t ^ (t >>> 7), t | 61); return ((t ^ (t >>> 14)) >>> 0) / 4294967296; diff --git a/packages/state-transition/test/utils/specTestCases.ts b/packages/state-transition/test/utils/specTestCases.ts index 6c038d202d74..ed3776d868d0 100644 --- a/packages/state-transition/test/utils/specTestCases.ts +++ b/packages/state-transition/test/utils/specTestCases.ts @@ -3,7 +3,6 @@ import {fileURLToPath} from "node:url"; // Global variable __dirname no longer available in ES6 modules. // Solutions: https://stackoverflow.com/questions/46745014/alternative-for-dirname-in-node-js-when-using-es6-modules -// eslint-disable-next-line @typescript-eslint/naming-convention const __dirname = path.dirname(fileURLToPath(import.meta.url)); export const SPEC_TEST_LOCATION = path.join(__dirname, "../../../../node_modules/@chainsafe/eth2-spec-tests"); diff --git a/packages/state-transition/test/utils/testFileCache.ts b/packages/state-transition/test/utils/testFileCache.ts index b894674f54f6..5283a6f87fa1 100644 --- a/packages/state-transition/test/utils/testFileCache.ts +++ b/packages/state-transition/test/utils/testFileCache.ts @@ -41,23 +41,23 @@ export async function getNetworkCachedState( if (fs.existsSync(filepath)) { const stateSsz = fs.readFileSync(filepath); return createCachedBeaconStateTest(config.getForkTypes(slot).BeaconState.deserializeToViewDU(stateSsz), config); - } else { - const stateSsz = await tryEach([ - () => downloadTestFile(fileId), - () => { - const client = getClient( - {baseUrl: getInfuraBeaconUrl(network), globalInit: {timeoutMs: timeout ?? 300_000}}, - {config} - ); - return client.debug.getStateV2({stateId: slot}).then((r) => { - return r.ssz(); - }); - }, - ]); - - fs.writeFileSync(filepath, stateSsz); - return createCachedBeaconStateTest(config.getForkTypes(slot).BeaconState.deserializeToViewDU(stateSsz), config); } + + const stateSsz = await tryEach([ + () => downloadTestFile(fileId), + () => { + const client = getClient( + {baseUrl: getInfuraBeaconUrl(network), globalInit: {timeoutMs: timeout ?? 300_000}}, + {config} + ); + return client.debug.getStateV2({stateId: slot}).then((r) => { + return r.ssz(); + }); + }, + ]); + + fs.writeFileSync(filepath, stateSsz); + return createCachedBeaconStateTest(config.getForkTypes(slot).BeaconState.deserializeToViewDU(stateSsz), config); } /** @@ -76,27 +76,26 @@ export async function getNetworkCachedBlock( if (fs.existsSync(filepath)) { const blockSsz = fs.readFileSync(filepath); return config.getForkTypes(slot).SignedBeaconBlock.deserialize(blockSsz); - } else { - const blockSsz = await tryEach([ - () => downloadTestFile(fileId), - async () => { - const client = getClient( - {baseUrl: getInfuraBeaconUrl(network), globalInit: {timeoutMs: timeout ?? 300_000}}, - {config} - ); - - return (await client.beacon.getBlockV2({blockId: slot})).ssz(); - }, - ]); - - fs.writeFileSync(filepath, blockSsz); - return config.getForkTypes(slot).SignedBeaconBlock.deserialize(blockSsz); } + + const blockSsz = await tryEach([ + () => downloadTestFile(fileId), + async () => { + const client = getClient( + {baseUrl: getInfuraBeaconUrl(network), globalInit: {timeoutMs: timeout ?? 300_000}}, + {config} + ); + + return (await client.beacon.getBlockV2({blockId: slot})).ssz(); + }, + ]); + + fs.writeFileSync(filepath, blockSsz); + return config.getForkTypes(slot).SignedBeaconBlock.deserialize(blockSsz); } async function downloadTestFile(fileId: string): Promise { const fileUrl = `${TEST_FILES_BASE_URL}/${fileId}`; - // eslint-disable-next-line no-console console.log(`Downloading file ${fileUrl}`); const res = await got(fileUrl, {responseType: "buffer"}).catch((e: Error) => { diff --git a/packages/test-utils/package.json b/packages/test-utils/package.json index 5bf61891a9d5..b2a589581055 100644 --- a/packages/test-utils/package.json +++ b/packages/test-utils/package.json @@ -42,8 +42,8 @@ "build:watch": "yarn run build --watch", "check-build": "node -e \"(async function() { await import('./lib/index.js') })()\"", "check-types": "tsc", - "lint": "eslint --color --ext .ts src/", - "lint:fix": "yarn run lint --fix", + "lint": "biome check src/", + "lint:fix": "yarn run lint --write", "check-readme": "typescript-docs-verifier" }, "repository": { diff --git a/packages/test-utils/src/childProcess.ts b/packages/test-utils/src/childProcess.ts index cd6983cca467..d8b86b83ee48 100644 --- a/packages/test-utils/src/childProcess.ts +++ b/packages/test-utils/src/childProcess.ts @@ -86,7 +86,7 @@ export function isPidRunning(pid: number): boolean { // Signal 0 is a special signal that checks if the process exists process.kill(pid, 0); return true; - } catch { + } catch (_e) { return false; } } @@ -304,7 +304,7 @@ export async function spawnChildProcess( }); proc.removeAllListeners("exit"); resolve(proc); - } catch (error) { + } catch (_e) { reject( new Error( `Health check timeout. logPrefix=${logPrefix} pid=${proc.pid} healthTimeout=${prettyMsToTime(healthTimeoutMs ?? 0)}` diff --git a/packages/test-utils/src/cli.ts b/packages/test-utils/src/cli.ts index 8b4a84ec467a..a7b2a248bc7e 100644 --- a/packages/test-utils/src/cli.ts +++ b/packages/test-utils/src/cli.ts @@ -12,7 +12,7 @@ import { // We need to make it easy for the user to pass the args for the CLI // yargs treat `["--preset minimal"] as a single arg, so we need to split it ["--preset", "minimal"] function parseArgs(args: string[]): string[] { - return args.map((a) => a.split(" ")).flat(); + return args.flatMap((a) => a.split(" ")); } type CommandRunOptions = { @@ -28,7 +28,7 @@ export async function runCliCommand( opts: CommandRunOptions = {timeoutMs: 1000} ): Promise { return wrapTimeout( - // eslint-disable-next-line no-async-promise-executor + // biome-ignore lint/suspicious/noAsyncPromiseExecutor: We want to resolve with parser call back not on main promise new Promise(async (resolve, reject) => { try { await cli diff --git a/packages/test-utils/src/doubles.ts b/packages/test-utils/src/doubles.ts index c61c10ea6099..171c55824996 100644 --- a/packages/test-utils/src/doubles.ts +++ b/packages/test-utils/src/doubles.ts @@ -37,7 +37,6 @@ function wrapLogWriter(...writers: [writer: object, ...keys: string[]][]): { for (const key of keys) { originals[index][key] = writer[key as keyof typeof writer]; - // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-expect-error writer[key as keyof typeof writer] = function mockedWriter(data: string) { // Our fixtures does not include the new line character @@ -51,7 +50,6 @@ function wrapLogWriter(...writers: [writer: object, ...keys: string[]][]): { restore: () => { for (const [index, [writer, ...keys]] of writers.entries()) { for (const key of keys) { - // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-expect-error writer[key as keyof typeof writer] = originals[index][key]; } diff --git a/packages/test-utils/src/externalSigner.ts b/packages/test-utils/src/externalSigner.ts index dbcb6bee1dc5..1e48e6af8d40 100644 --- a/packages/test-utils/src/externalSigner.ts +++ b/packages/test-utils/src/externalSigner.ts @@ -69,7 +69,6 @@ export async function startExternalSigner({ stream .on("data", (line) => process.stdout.write(line)) .on("err", (line) => process.stderr.write(line)) - // eslint-disable-next-line no-console .on("end", () => console.log("Stream closed")); return { diff --git a/packages/test-utils/src/http.ts b/packages/test-utils/src/http.ts index b4dd16390483..85b64c110cab 100644 --- a/packages/test-utils/src/http.ts +++ b/packages/test-utils/src/http.ts @@ -42,7 +42,6 @@ export async function matchReqSuccess(url: string, method: Method = "GET"): Prom * Wait for a given endpoint to return a given status code */ export async function waitForEndpoint(url: string, statusCode = 200): Promise { - // eslint-disable-next-line no-constant-condition while (true) { const status = await getReqStatus(url); diff --git a/packages/types/package.json b/packages/types/package.json index f3e034ec1b35..1c020b409071 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -59,8 +59,8 @@ "build:release": "yarn clean && yarn build", "check-build": "node -e \"(async function() { await import('./lib/index.js') })()\"", "check-types": "tsc", - "lint": "eslint --color --ext .ts src/ test/", - "lint:fix": "yarn run lint --fix", + "lint": "biome check src/ test/", + "lint:fix": "yarn run lint --write", "test": "yarn test:unit", "test:constants:minimal": "LODESTAR_PRESET=minimal vitest --run --dir test/constants/", "test:constants:mainnet": "LODESTAR_PRESET=mainnet vitest --run --dir test/constants/", diff --git a/packages/types/src/phase0/validator.ts b/packages/types/src/phase0/validator.ts index 3c2f72aac509..aaff2deaeb27 100644 --- a/packages/types/src/phase0/validator.ts +++ b/packages/types/src/phase0/validator.ts @@ -1,6 +1,7 @@ import {ByteViews, ContainerNodeStructType, ValueOfFields} from "@chainsafe/ssz"; import * as primitiveSsz from "../primitive/sszTypes.js"; +// biome-ignore lint/suspicious/noShadowRestrictedNames: We explicitly want `Boolean` name to be imported const {Boolean, Bytes32, UintNum64, BLSPubkey, EpochInf} = primitiveSsz; // this is to work with uint32, see https://github.com/ChainSafe/ssz/blob/ssz-v0.15.1/packages/ssz/src/type/uint.ts @@ -33,6 +34,7 @@ export class ValidatorNodeStructType extends ContainerNodeStructType type UnionSSZForksTypeOf> = CompositeType< ValueOf, CompositeView, @@ -41,11 +42,9 @@ type SSZTypesByFork = { export type SSZTypesFor = K extends void ? // It compiles fine, need to debug the error - // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-expect-error {[K2 in keyof SSZTypesByFork[F]]: UnionSSZForksTypeOf} : // It compiles fine, need to debug the error - // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-expect-error UnionSSZForksTypeOf]>; diff --git a/packages/types/src/utils/validatorStatus.ts b/packages/types/src/utils/validatorStatus.ts index e14a4b14c412..9e72c39d9df2 100644 --- a/packages/types/src/utils/validatorStatus.ts +++ b/packages/types/src/utils/validatorStatus.ts @@ -1,8 +1,10 @@ import {FAR_FUTURE_EPOCH} from "@lodestar/params"; import {Epoch, phase0} from "../types.js"; +/** + * [Validator status specification](https://hackmd.io/ofFJ5gOmQpu1jjHilHbdQQ) + */ export type ValidatorStatus = - | "active" | "pending_initialized" | "pending_queued" | "active_ongoing" @@ -22,7 +24,9 @@ export function getValidatorStatus(validator: phase0.Validator, currentEpoch: Ep if (validator.activationEpoch > currentEpoch) { if (validator.activationEligibilityEpoch === FAR_FUTURE_EPOCH) { return "pending_initialized"; - } else if (validator.activationEligibilityEpoch < FAR_FUTURE_EPOCH) { + } + + if (validator.activationEligibilityEpoch < FAR_FUTURE_EPOCH) { return "pending_queued"; } } @@ -30,7 +34,9 @@ export function getValidatorStatus(validator: phase0.Validator, currentEpoch: Ep if (validator.activationEpoch <= currentEpoch && currentEpoch < validator.exitEpoch) { if (validator.exitEpoch === FAR_FUTURE_EPOCH) { return "active_ongoing"; - } else if (validator.exitEpoch < FAR_FUTURE_EPOCH) { + } + + if (validator.exitEpoch < FAR_FUTURE_EPOCH) { return validator.slashed ? "active_slashed" : "active_exiting"; } } diff --git a/packages/types/test/unit/blinded.test.ts b/packages/types/test/unit/blinded.test.ts index 3a4b346d29bf..3d087b610b2d 100644 --- a/packages/types/test/unit/blinded.test.ts +++ b/packages/types/test/unit/blinded.test.ts @@ -2,7 +2,7 @@ import {describe, it, expect} from "vitest"; import {ForkName, isForkExecution} from "@lodestar/params"; import {ssz} from "../../src/index.js"; -describe("blinded data structures", function () { +describe("blinded data structures", () => { it("should have the same number of fields as non-blinded", () => { const blindedTypes = [ {a: "BlindedBeaconBlockBody" as const, b: "BeaconBlockBody" as const}, diff --git a/packages/types/test/unit/phase0/sszTypes.test.ts b/packages/types/test/unit/phase0/sszTypes.test.ts index 0cda0fc888f6..4bdb2031e5ea 100644 --- a/packages/types/test/unit/phase0/sszTypes.test.ts +++ b/packages/types/test/unit/phase0/sszTypes.test.ts @@ -5,7 +5,7 @@ import {ValidatorType} from "../../../src/phase0/validator.js"; const ValidatorContainer = new ContainerType(ValidatorType, {typeName: "Validator", jsonCase: "eth2"}); -describe("Validator ssz types", function () { +describe("Validator ssz types", () => { it("should serialize to the same value", () => { const seedValidator = { activationEligibilityEpoch: 10, diff --git a/packages/types/test/unit/ssz.test.ts b/packages/types/test/unit/ssz.test.ts index b5c972a8f471..41e4e0bbd23b 100644 --- a/packages/types/test/unit/ssz.test.ts +++ b/packages/types/test/unit/ssz.test.ts @@ -1,7 +1,7 @@ import {describe, it, expect} from "vitest"; import {ssz} from "../../src/index.js"; -describe("size", function () { +describe("size", () => { it("should calculate correct minSize and maxSize", () => { const minSize = ssz.phase0.BeaconState.minSize; const maxSize = ssz.phase0.BeaconState.maxSize; @@ -11,8 +11,8 @@ describe("size", function () { }); }); -describe("container serialization/deserialization field casing(s)", function () { - it("AttesterSlashing", function () { +describe("container serialization/deserialization field casing(s)", () => { + it("AttesterSlashing", () => { const test = { attestation1: ssz.phase0.IndexedAttestation.defaultValue(), attestation2: ssz.phase0.IndexedAttestation.defaultValue(), @@ -27,7 +27,7 @@ describe("container serialization/deserialization field casing(s)", function () expect(back).toEqual(json); }); - it("ProposerSlashing", function () { + it("ProposerSlashing", () => { const test = { signedHeader1: ssz.phase0.SignedBeaconBlockHeader.defaultValue(), signedHeader2: ssz.phase0.SignedBeaconBlockHeader.defaultValue(), diff --git a/packages/types/test/unit/validatorStatus.test.ts b/packages/types/test/unit/validatorStatus.test.ts index 8d04c0f98e3d..b5bd34004bdc 100644 --- a/packages/types/test/unit/validatorStatus.test.ts +++ b/packages/types/test/unit/validatorStatus.test.ts @@ -2,8 +2,8 @@ import {describe, it, expect} from "vitest"; import {getValidatorStatus} from "../../src/utils/validatorStatus.js"; import {phase0} from "../../src/types.js"; -describe("getValidatorStatus", function () { - it("should return PENDING_INITIALIZED", function () { +describe("getValidatorStatus", () => { + it("should return PENDING_INITIALIZED", () => { const validator = { activationEpoch: 1, activationEligibilityEpoch: Infinity, @@ -12,7 +12,7 @@ describe("getValidatorStatus", function () { const status = getValidatorStatus(validator, currentEpoch); expect(status).toBe("pending_initialized"); }); - it("should return PENDING_QUEUED", function () { + it("should return PENDING_QUEUED", () => { const validator = { activationEpoch: 1, activationEligibilityEpoch: 101010101101010, @@ -21,7 +21,7 @@ describe("getValidatorStatus", function () { const status = getValidatorStatus(validator, currentEpoch); expect(status).toBe("pending_queued"); }); - it("should return ACTIVE_ONGOING", function () { + it("should return ACTIVE_ONGOING", () => { const validator = { activationEpoch: 1, exitEpoch: Infinity, @@ -30,7 +30,7 @@ describe("getValidatorStatus", function () { const status = getValidatorStatus(validator, currentEpoch); expect(status).toBe("active_ongoing"); }); - it("should return ACTIVE_SLASHED", function () { + it("should return ACTIVE_SLASHED", () => { const validator = { activationEpoch: 1, exitEpoch: 101010101101010, @@ -40,7 +40,7 @@ describe("getValidatorStatus", function () { const status = getValidatorStatus(validator, currentEpoch); expect(status).toBe("active_slashed"); }); - it("should return ACTIVE_EXITING", function () { + it("should return ACTIVE_EXITING", () => { const validator = { activationEpoch: 1, exitEpoch: 101010101101010, @@ -50,7 +50,7 @@ describe("getValidatorStatus", function () { const status = getValidatorStatus(validator, currentEpoch); expect(status).toBe("active_exiting"); }); - it("should return EXITED_SLASHED", function () { + it("should return EXITED_SLASHED", () => { const validator = { exitEpoch: 1, withdrawableEpoch: 3, @@ -60,7 +60,7 @@ describe("getValidatorStatus", function () { const status = getValidatorStatus(validator, currentEpoch); expect(status).toBe("exited_slashed"); }); - it("should return EXITED_UNSLASHED", function () { + it("should return EXITED_UNSLASHED", () => { const validator = { exitEpoch: 1, withdrawableEpoch: 3, @@ -70,7 +70,7 @@ describe("getValidatorStatus", function () { const status = getValidatorStatus(validator, currentEpoch); expect(status).toBe("exited_unslashed"); }); - it("should return WITHDRAWAL_POSSIBLE", function () { + it("should return WITHDRAWAL_POSSIBLE", () => { const validator = { withdrawableEpoch: 1, effectiveBalance: 32, @@ -79,7 +79,7 @@ describe("getValidatorStatus", function () { const status = getValidatorStatus(validator, currentEpoch); expect(status).toBe("withdrawal_possible"); }); - it("should return WITHDRAWAL_DONE", function () { + it("should return WITHDRAWAL_DONE", () => { const validator = { withdrawableEpoch: 1, effectiveBalance: 0, @@ -88,7 +88,7 @@ describe("getValidatorStatus", function () { const status = getValidatorStatus(validator, currentEpoch); expect(status).toBe("withdrawal_done"); }); - it("should error", function () { + it("should error", () => { const validator = {} as phase0.Validator; const currentEpoch = 0; try { diff --git a/packages/utils/package.json b/packages/utils/package.json index 0723f5f1815c..6c8218741e30 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -28,8 +28,8 @@ "build:release": "yarn clean && yarn build", "check-build": "node -e \"(async function() { await import('./lib/index.js') })()\"", "check-types": "tsc && vitest --run --typecheck --dir test/types/", - "lint": "eslint --color --ext .ts src/ test/", - "lint:fix": "yarn run lint --fix", + "lint": "biome check src/ test/", + "lint:fix": "yarn run lint --write", "test:unit": "vitest --run --dir test/unit", "test:browsers": "yarn test:browsers:chrome && yarn test:browsers:firefox && yarn test:browsers:electron", "test:browsers:chrome": "vitest --run --browser chrome --config ./vitest.browser.config.ts --dir test/unit", diff --git a/packages/utils/src/assert.ts b/packages/utils/src/assert.ts index 91612b0e6407..7b6af1f00f97 100644 --- a/packages/utils/src/assert.ts +++ b/packages/utils/src/assert.ts @@ -16,7 +16,6 @@ export const assert = { */ equal(actual: T, expected: T, message?: string): void { if (!(actual === expected)) { - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions throw new AssertionError(`${message || "Expected values to be equal"}: ${actual} === ${expected}`); } }, diff --git a/packages/utils/src/bytes.ts b/packages/utils/src/bytes.ts index 95bb62ebd548..c290232ce8db 100644 --- a/packages/utils/src/bytes.ts +++ b/packages/utils/src/bytes.ts @@ -34,7 +34,8 @@ export function bytesToInt(value: Uint8Array, endianness: Endianness = "le"): nu export function bigIntToBytes(value: bigint, length: number, endianness: Endianness = "le"): Buffer { if (endianness === "le") { return toBufferLE(value, length); - } else if (endianness === "be") { + } + if (endianness === "be") { return toBufferBE(value, length); } throw new Error("endianness must be either 'le' or 'be'"); @@ -43,7 +44,8 @@ export function bigIntToBytes(value: bigint, length: number, endianness: Endiann export function bytesToBigInt(value: Uint8Array, endianness: Endianness = "le"): bigint { if (endianness === "le") { return toBigIntLE(value as Buffer); - } else if (endianness === "be") { + } + if (endianness === "be") { return toBigIntBE(value as Buffer); } throw new Error("endianness must be either 'le' or 'be'"); diff --git a/packages/utils/src/bytes/nodejs.ts b/packages/utils/src/bytes/nodejs.ts index 4cf8e78c67c6..efa7a585835f 100644 --- a/packages/utils/src/bytes/nodejs.ts +++ b/packages/utils/src/bytes/nodejs.ts @@ -1,11 +1,11 @@ export function toHex(buffer: Uint8Array | Parameters[0]): string { if (Buffer.isBuffer(buffer)) { return "0x" + buffer.toString("hex"); - } else if (buffer instanceof Uint8Array) { + } + if (buffer instanceof Uint8Array) { return "0x" + Buffer.from(buffer.buffer, buffer.byteOffset, buffer.length).toString("hex"); - } else { - return "0x" + Buffer.from(buffer).toString("hex"); } + return "0x" + Buffer.from(buffer).toString("hex"); } // Shared buffer to convert root to hex diff --git a/packages/utils/src/command.ts b/packages/utils/src/command.ts index 89929a6c41ef..2e62ba5a9648 100644 --- a/packages/utils/src/command.ts +++ b/packages/utils/src/command.ts @@ -6,7 +6,7 @@ export interface CliExample { description?: string; } -// eslint-disable-next-line @typescript-eslint/no-explicit-any +// biome-ignore lint/suspicious/noExplicitAny: export interface CliOptionDefinition extends Options { example?: Omit; // Ensure `type` property matches type of `T` @@ -28,7 +28,7 @@ export type CliCommandOptions = Required<{ CliOptionDefinition & (Required> | {demandOption: true}); }>; -// eslint-disable-next-line @typescript-eslint/no-explicit-any +// biome-ignore lint/suspicious/noExplicitAny: export interface CliCommand, ParentArgs = Record, R = any> { command: string; describe: string; @@ -41,7 +41,7 @@ export interface CliCommand, ParentArgs = Record< options?: CliCommandOptions; // 1st arg: any = free own sub command options // 2nd arg: subcommand parent options is = to this command options + parent options - // eslint-disable-next-line @typescript-eslint/no-explicit-any + // biome-ignore lint/suspicious/noExplicitAny: subcommands?: CliCommand[]; handler?: (args: OwnArgs & ParentArgs) => Promise; } @@ -51,7 +51,8 @@ export interface CliCommand, ParentArgs = Record< * @param yargs * @param cliCommand */ -// eslint-disable-next-line @typescript-eslint/no-explicit-any + +// biome-ignore lint/suspicious/noExplicitAny: export function registerCommandToYargs(yargs: Argv, cliCommand: CliCommand): void { yargs.command({ command: cliCommand.command, diff --git a/packages/utils/src/diff.ts b/packages/utils/src/diff.ts index 204989016b46..f7357cde19fa 100644 --- a/packages/utils/src/diff.ts +++ b/packages/utils/src/diff.ts @@ -203,17 +203,19 @@ export function getDiffs(val1: Diffable, val2: Diffable, objectPath: string): Di */ export function diff(val1: unknown, val2: unknown, outputValues = false, filename?: string): void { if (!isDiffable(val1)) { + // biome-ignore lint/suspicious/noConsoleLog: console.log("val1 is not Diffable"); return; } if (!isDiffable(val2)) { + // biome-ignore lint/suspicious/noConsoleLog: console.log("val2 is not Diffable"); return; } const diffs = getDiffs(val1, val2, ""); let output = ""; if (diffs.length) { - diffs.forEach((diff) => { + for (const diff of diffs) { let diffOutput = `value${diff.objectPath}`; if (diff.errorMessage) { diffOutput += `\n ${diff.errorMessage}`; @@ -222,10 +224,11 @@ export function diff(val1: unknown, val2: unknown, outputValues = false, filenam diffOutput += `\n - ${diff.val1.toString()}\n - ${diff.val2.toString()}\n`; } output += `${diffOutput}\n`; - }); + } if (filename) { fs.writeFileSync(filename, output); } else { + // biome-ignore lint/suspicious/noConsoleLog: console.log(output); } } diff --git a/packages/utils/src/err.ts b/packages/utils/src/err.ts index 81f6f92c0044..7c27a0a067a3 100644 --- a/packages/utils/src/err.ts +++ b/packages/utils/src/err.ts @@ -4,7 +4,6 @@ export type Err = {[symErr]: true; error: T}; export type Result = T | Err; -// eslint-disable-next-line @typescript-eslint/naming-convention export function Err(error: T): Err { return {[symErr]: true, error}; } diff --git a/packages/utils/src/logger.ts b/packages/utils/src/logger.ts index 925a357f4b98..e299e730a81a 100644 --- a/packages/utils/src/logger.ts +++ b/packages/utils/src/logger.ts @@ -12,7 +12,6 @@ export enum LogLevel { trace = "trace", } -// eslint-disable-next-line @typescript-eslint/naming-convention export const LogLevels = Object.values(LogLevel); export type LogHandler = (message: string, context?: LogData, error?: Error) => void; diff --git a/packages/utils/src/objects.ts b/packages/utils/src/objects.ts index ad09d36b0ecc..602e758e360c 100644 --- a/packages/utils/src/objects.ts +++ b/packages/utils/src/objects.ts @@ -18,7 +18,7 @@ export function toExpectedCase( customCasingMap?: Record ): string { if (expectedCase === "notransform") return value; - if (customCasingMap && customCasingMap[value]) return customCasingMap[value]; + if (customCasingMap?.[value]) return customCasingMap[value]; switch (expectedCase) { case "param": return Case.kebab(value); @@ -45,7 +45,7 @@ export function isPlainObject(o: unknown): o is object { if (isObjectObject(prot) === false) return false; // If constructor does not have an Object-specific method - if (prot.hasOwnProperty("isPrototypeOf") === false) { + if (Object.prototype.hasOwnProperty.call(prot, "isPrototypeOf") === false) { return false; } @@ -63,7 +63,7 @@ export function isEmptyObject(value: unknown): boolean { * * Inspired on lodash.mapValues, see https://lodash.com/docs/4.17.15#mapValues */ -// eslint-disable-next-line @typescript-eslint/no-explicit-any +// biome-ignore lint/suspicious/noExplicitAny: export function mapValues( obj: T, iteratee: (value: T[keyof T], key: keyof T) => R @@ -91,7 +91,7 @@ export function objectToExpectedCase | Record< const newObj: Record = {}; for (const name of Object.getOwnPropertyNames(obj)) { const newName = toExpectedCase(name, expectedCase); - if (newName !== name && obj.hasOwnProperty(newName)) { + if (newName !== name && Object.prototype.hasOwnProperty.call(obj, newName)) { throw new Error(`object already has a ${newName} property`); } diff --git a/packages/utils/src/promise.ts b/packages/utils/src/promise.ts index 2be7467bfff4..894444d46937 100644 --- a/packages/utils/src/promise.ts +++ b/packages/utils/src/promise.ts @@ -109,7 +109,6 @@ export async function resolveOrRacePromises wrapPromise(p)) as ReturnPromiseWithTuple; // We intentionally want an array of promises here - // eslint-disable-next-line @typescript-eslint/no-floating-promises promises = (promiseResults as PromiseResult[]).map((p) => p.promise) as unknown as T; try { diff --git a/packages/utils/src/retry.ts b/packages/utils/src/retry.ts index 6c5e63deca42..bc759d62e9b2 100644 --- a/packages/utils/src/retry.ts +++ b/packages/utils/src/retry.ts @@ -60,9 +60,13 @@ export async function retry(fn: (attempt: number) => A | Promise, opts?: R if (i === maxAttempts) { // Reached maximum number of attempts, there's no need to check if we should retry break; - } else if (shouldRetry && !shouldRetry(lastError)) { + } + + if (shouldRetry && !shouldRetry(lastError)) { break; - } else if (opts?.retryDelay !== undefined) { + } + + if (opts?.retryDelay !== undefined) { await sleep(opts?.retryDelay, opts?.signal); } } diff --git a/packages/utils/src/sleep.ts b/packages/utils/src/sleep.ts index c31a9daffd32..f2ff74255f48 100644 --- a/packages/utils/src/sleep.ts +++ b/packages/utils/src/sleep.ts @@ -10,7 +10,7 @@ export async function sleep(ms: number, signal?: AbortSignal): Promise { } return new Promise((resolve, reject) => { - if (signal && signal.aborted) return reject(new ErrorAborted()); + if (signal?.aborted) return reject(new ErrorAborted()); let onDone: () => void = () => {}; diff --git a/packages/utils/src/url.ts b/packages/utils/src/url.ts index f00b70edbde2..d4eba3bd67cf 100644 --- a/packages/utils/src/url.ts +++ b/packages/utils/src/url.ts @@ -1,5 +1,5 @@ export function isValidHttpUrl(urlStr: string): boolean { - let url; + let url: URL; try { url = new URL(urlStr); diff --git a/packages/utils/src/yaml/int.ts b/packages/utils/src/yaml/int.ts index 64a2c283dd49..264d1297f888 100644 --- a/packages/utils/src/yaml/int.ts +++ b/packages/utils/src/yaml/int.ts @@ -27,7 +27,7 @@ function resolveYamlInteger(data: string): boolean { if (data === null) return false; const max = data.length; - let ch, + let ch: string, index = 0, hasDigits = false; @@ -111,7 +111,7 @@ function resolveYamlInteger(data: string): boolean { function constructYamlInteger(data: string): bigint { let value: string | bigint = data, sign = 1, - ch, + ch: string, base: number | bigint; const digits: number[] = []; @@ -162,25 +162,20 @@ export const intType = new Type("tag:yaml.org,2002:int", { construct: constructYamlInteger, predicate: isInteger, instanceOf: BigInt, - // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore represent: { - // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore binary: function binary(obj: number) { return obj >= 0 ? "0b" + obj.toString(2) : "-0b" + obj.toString(2).slice(1); }, - // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore octal: function octal(obj: number) { return obj >= 0 ? "0" + obj.toString(8) : "-0" + obj.toString(8).slice(1); }, - // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore decimal: function decimal(obj: number) { return obj.toString(10); }, - // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore hexadecimal: function hexadecimal(obj: number) { return obj >= 0 ? "0x" + obj.toString(16).toUpperCase() : "-0x" + obj.toString(16).toUpperCase().slice(1); diff --git a/packages/utils/src/yaml/schema.ts b/packages/utils/src/yaml/schema.ts index b53fc14a3e86..8db0c67cd943 100644 --- a/packages/utils/src/yaml/schema.ts +++ b/packages/utils/src/yaml/schema.ts @@ -3,9 +3,7 @@ import yml, {FAILSAFE_SCHEMA, Type} from "js-yaml"; import {intType} from "./int.js"; export const schema = FAILSAFE_SCHEMA.extend({ - // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-expect-error - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access implicit: [yml.types.null as Type, yml.types.bool as Type, intType, yml.types.float as Type], explicit: [], }); diff --git a/packages/utils/test/perf/bytes.test.ts b/packages/utils/test/perf/bytes.test.ts index 649ea0b51e3e..6a1e96ab1579 100644 --- a/packages/utils/test/perf/bytes.test.ts +++ b/packages/utils/test/perf/bytes.test.ts @@ -3,7 +3,7 @@ import {toHex, toRootHex} from "../../src/bytes/nodejs.js"; import {toHex as browserToHex, toRootHex as browserToRootHex} from "../../src/bytes/browser.js"; import {toHexString} from "../../src/bytes.js"; -describe("bytes utils", function () { +describe("bytes utils", () => { const runsFactor = 1000; const blockRoot = new Uint8Array(Array.from({length: 32}, (_, i) => i)); diff --git a/packages/utils/test/unit/err.test.ts b/packages/utils/test/unit/err.test.ts index 94cebe3ed1a1..7a08ebbc4319 100644 --- a/packages/utils/test/unit/err.test.ts +++ b/packages/utils/test/unit/err.test.ts @@ -60,7 +60,7 @@ describe("Result Err", () => { try { await mapOkResultsAsync([], async () => [0]); throw Error("did not throw"); - } catch (e) { + } catch (_e) { // Ok } }); diff --git a/packages/utils/test/unit/math.test.ts b/packages/utils/test/unit/math.test.ts index 6827fea2bbb0..e324714600b1 100644 --- a/packages/utils/test/unit/math.test.ts +++ b/packages/utils/test/unit/math.test.ts @@ -1,7 +1,7 @@ import {describe, it, expect} from "vitest"; import {bigIntMin, bigIntMax, intDiv, intSqrt, bigIntSqrt} from "../../src/index.js"; -describe("util/maths", function () { +describe("util/maths", () => { describe("bigIntMin", () => { it("if a is lt should return a", () => { const a = BigInt(1); diff --git a/packages/utils/test/unit/objects.test.ts b/packages/utils/test/unit/objects.test.ts index 4699a8c6f405..a94ed9213390 100644 --- a/packages/utils/test/unit/objects.test.ts +++ b/packages/utils/test/unit/objects.test.ts @@ -17,8 +17,6 @@ describe("Objects helper", () => { }); }); -/* eslint-disable @typescript-eslint/naming-convention */ - describe("objectToExpectedCase", () => { const testCases: { id: string; diff --git a/packages/utils/test/unit/promise.node.test.ts b/packages/utils/test/unit/promise.node.test.ts index c9f6a3c2f98d..55cbad36b211 100644 --- a/packages/utils/test/unit/promise.node.test.ts +++ b/packages/utils/test/unit/promise.node.test.ts @@ -2,7 +2,7 @@ import {describe, it, expect, vi, beforeEach, afterEach} from "vitest"; import {callFnWhenAwait} from "../../src/promise.js"; // TODO: Need to debug why vi.useFakeTimers() is not working for the browsers -describe("callFnWhenAwait util", function () { +describe("callFnWhenAwait util", () => { beforeEach(() => { vi.useFakeTimers(); }); diff --git a/packages/utils/test/unit/promiserace.test.ts b/packages/utils/test/unit/promiserace.test.ts index 1f31a55014a4..4b20f19f9fba 100644 --- a/packages/utils/test/unit/promiserace.test.ts +++ b/packages/utils/test/unit/promiserace.test.ts @@ -58,9 +58,8 @@ describe("resolveOrRacePromises", () => { const testPromises = timeouts.map((timeMs) => { if (timeMs > 0) { return resolveAfter(`${timeMs}`, timeMs); - } else { - return rejectAfter(`${timeMs}`, -timeMs); } + return rejectAfter(`${timeMs}`, -timeMs); }); const testResults = (await resolveOrRacePromises(testPromises as unknown as NonEmptyArray>, { resolveTimeoutMs: cutoffMs, diff --git a/packages/utils/test/unit/retry.test.ts b/packages/utils/test/unit/retry.test.ts index 12afb7597015..bd77c499a364 100644 --- a/packages/utils/test/unit/retry.test.ts +++ b/packages/utils/test/unit/retry.test.ts @@ -28,7 +28,8 @@ describe("retry", () => { id: "Succeed at the last attempt", fn: async (attempt) => { if (attempt < retries) throw sampleError; - else return sampleResult; + + return sampleResult; }, opts: {retries}, result: sampleResult, diff --git a/packages/utils/test/unit/sleep.test.ts b/packages/utils/test/unit/sleep.test.ts index a887560836eb..ef632fd34f64 100644 --- a/packages/utils/test/unit/sleep.test.ts +++ b/packages/utils/test/unit/sleep.test.ts @@ -2,13 +2,13 @@ import {describe, it, expect} from "vitest"; import {sleep} from "../../src/sleep.js"; import {ErrorAborted} from "../../src/errors.js"; -describe("sleep", function () { - it("Should resolve timeout", async function () { +describe("sleep", () => { + it("Should resolve timeout", async () => { const controller = new AbortController(); await sleep(0, controller.signal); }); - it("Should abort timeout with signal", async function () { + it("Should abort timeout with signal", async () => { const controller = new AbortController(); setTimeout(() => controller.abort(), 10); @@ -17,7 +17,7 @@ describe("sleep", function () { await expect(sleep(sleepTime, controller.signal)).rejects.toThrow(ErrorAborted); }); - it("Should abort timeout with already aborted signal", async function () { + it("Should abort timeout with already aborted signal", async () => { const controller = new AbortController(); controller.abort(); diff --git a/packages/utils/test/unit/timeout.test.ts b/packages/utils/test/unit/timeout.test.ts index b8844355effb..7b4b1eb883be 100644 --- a/packages/utils/test/unit/timeout.test.ts +++ b/packages/utils/test/unit/timeout.test.ts @@ -2,7 +2,7 @@ import {describe, it, expect, afterEach} from "vitest"; import {withTimeout} from "../../src/timeout.js"; import {ErrorAborted, TimeoutError} from "../../src/errors.js"; -describe("withTimeout", function () { +describe("withTimeout", () => { const data = "DATA"; const shortTimeoutMs = 10; const longTimeoutMs = 5000; @@ -27,19 +27,19 @@ describe("withTimeout", function () { return returnValue; } - it("Should resolve timeout", async function () { + it("Should resolve timeout", async () => { const res = await withTimeout(() => pause(shortTimeoutMs, data), longTimeoutMs); expect(res).toBe(data); }); - it("Should resolve timeout with not triggered signal", async function () { + it("Should resolve timeout with not triggered signal", async () => { const controller = new AbortController(); const res = await withTimeout(() => pause(shortTimeoutMs, data), longTimeoutMs, controller.signal); expect(res).toBe(data); }); - it("Should abort timeout with triggered signal", async function () { + it("Should abort timeout with triggered signal", async () => { const controller = new AbortController(); setTimeout(() => controller.abort(), shortTimeoutMs); @@ -48,11 +48,11 @@ describe("withTimeout", function () { ); }); - it("Should timeout with no signal", async function () { + it("Should timeout with no signal", async () => { await expect(withTimeout(() => pause(longTimeoutMs, data), shortTimeoutMs)).rejects.toThrow(TimeoutError); }); - it("Should timeout with not triggered signal", async function () { + it("Should timeout with not triggered signal", async () => { const controller = new AbortController(); await expect(withTimeout(() => pause(longTimeoutMs, data), shortTimeoutMs, controller.signal)).rejects.toThrow( @@ -60,7 +60,7 @@ describe("withTimeout", function () { ); }); - it("Should abort timeout with already aborted signal", async function () { + it("Should abort timeout with already aborted signal", async () => { const controller = new AbortController(); controller.abort(); diff --git a/packages/validator/package.json b/packages/validator/package.json index 65ed656f010d..932eedac1dba 100644 --- a/packages/validator/package.json +++ b/packages/validator/package.json @@ -25,8 +25,8 @@ "build:watch": "yarn run build --watch", "check-build": "node -e \"(async function() { await import('./lib/index.js') })()\"", "check-types": "tsc", - "lint": "eslint --color --ext .ts src/ test/", - "lint:fix": "yarn run lint --fix", + "lint": "biome check src/ test/", + "lint:fix": "yarn run lint --write", "test:unit": "vitest --run --dir test/unit/", "test": "yarn test:unit && yarn test:e2e", "test:spec": "vitest --run --config vitest.spec.config.ts --dir test/spec/", diff --git a/packages/validator/src/buckets.ts b/packages/validator/src/buckets.ts index df30370b8810..3313f7b5ae35 100644 --- a/packages/validator/src/buckets.ts +++ b/packages/validator/src/buckets.ts @@ -17,11 +17,11 @@ export enum Bucket { export function getBucketNameByValue(enumValue: T): keyof typeof Bucket { const keys = Object.keys(Bucket).filter((x) => { - if (isNaN(parseInt(x))) { - return Bucket[x as keyof typeof Bucket] == enumValue; - } else { - return false; + if (Number.isNaN(parseInt(x))) { + return Bucket[x as keyof typeof Bucket] === enumValue; } + + return false; }) as (keyof typeof Bucket)[]; if (keys.length > 0) { return keys[0]; diff --git a/packages/validator/src/genesis.ts b/packages/validator/src/genesis.ts index 3156acee689f..7fc3e20673bc 100644 --- a/packages/validator/src/genesis.ts +++ b/packages/validator/src/genesis.ts @@ -6,7 +6,6 @@ import {ApiClient} from "@lodestar/api"; const WAITING_FOR_GENESIS_POLL_MS = 12 * 1000; export async function waitForGenesis(api: ApiClient, logger: Logger, signal?: AbortSignal): Promise { - // eslint-disable-next-line no-constant-condition while (true) { try { return (await api.beacon.getGenesis()).value(); diff --git a/packages/validator/src/metrics.ts b/packages/validator/src/metrics.ts index a437328e8d5f..ca693056fc54 100644 --- a/packages/validator/src/metrics.ts +++ b/packages/validator/src/metrics.ts @@ -25,7 +25,6 @@ export type LodestarGitData = { /** * A collection of metrics used by the validator client */ -// eslint-disable-next-line @typescript-eslint/explicit-function-return-type export function getMetrics(register: MetricsRegisterExtra, gitData: LodestarGitData) { // Using function style instead of class to prevent having to re-declare all MetricsPrometheus types. diff --git a/packages/validator/src/services/block.ts b/packages/validator/src/services/block.ts index c3acf19c1669..cb295450e96b 100644 --- a/packages/validator/src/services/block.ts +++ b/packages/validator/src/services/block.ts @@ -265,18 +265,17 @@ export class BlockProposingService { debugLogCtx, builderSelection ); - } else { - Object.assign(debugLogCtx, {api: "produceBlindedBlock"}); - const res = await this.api.validator.produceBlindedBlock({slot, randaoReveal, graffiti}); - const {version} = res.meta(); - const executionPayloadSource = ProducedBlockSource.builder; - - return parseProduceBlockResponse( - {data: res.value(), executionPayloadBlinded: true, executionPayloadSource, version}, - debugLogCtx, - builderSelection - ); } + Object.assign(debugLogCtx, {api: "produceBlindedBlock"}); + const res = await this.api.validator.produceBlindedBlock({slot, randaoReveal, graffiti}); + const {version} = res.meta(); + const executionPayloadSource = ProducedBlockSource.builder; + + return parseProduceBlockResponse( + {data: res.value(), executionPayloadBlinded: true, executionPayloadSource, version}, + debugLogCtx, + builderSelection + ); }; } @@ -311,26 +310,26 @@ function parseProduceBlockResponse( executionPayloadSource, debugLogCtx, } as FullOrBlindedBlockWithContents & DebugLogCtx; - } else { - const data = response.data; - if (isBlockContents(data)) { - return { - block: data.block, - contents: {blobs: data.blobs, kzgProofs: data.kzgProofs}, - version: response.version, - executionPayloadBlinded: false, - executionPayloadSource, - debugLogCtx, - } as FullOrBlindedBlockWithContents & DebugLogCtx; - } else { - return { - block: response.data, - contents: null, - version: response.version, - executionPayloadBlinded: false, - executionPayloadSource, - debugLogCtx, - } as FullOrBlindedBlockWithContents & DebugLogCtx; - } } + + const data = response.data; + if (isBlockContents(data)) { + return { + block: data.block, + contents: {blobs: data.blobs, kzgProofs: data.kzgProofs}, + version: response.version, + executionPayloadBlinded: false, + executionPayloadSource, + debugLogCtx, + } as FullOrBlindedBlockWithContents & DebugLogCtx; + } + + return { + block: response.data, + contents: null, + version: response.version, + executionPayloadBlinded: false, + executionPayloadSource, + debugLogCtx, + } as FullOrBlindedBlockWithContents & DebugLogCtx; } diff --git a/packages/validator/src/services/doppelgangerService.ts b/packages/validator/src/services/doppelgangerService.ts index e167ee1d5028..aa43d7bba55b 100644 --- a/packages/validator/src/services/doppelgangerService.ts +++ b/packages/validator/src/services/doppelgangerService.ts @@ -275,11 +275,12 @@ export class DoppelgangerService { function getStatus(state: DoppelgangerState | undefined): DoppelgangerStatus { if (!state) { return DoppelgangerStatus.Unknown; - } else if (state.remainingEpochs <= 0) { + } + if (state.remainingEpochs <= 0) { return DoppelgangerStatus.VerifiedSafe; - } else if (state.remainingEpochs === REMAINING_EPOCHS_IF_DOPPELGANGER) { + } + if (state.remainingEpochs === REMAINING_EPOCHS_IF_DOPPELGANGER) { return DoppelgangerStatus.DoppelgangerDetected; - } else { - return DoppelgangerStatus.Unverified; } + return DoppelgangerStatus.Unverified; } diff --git a/packages/validator/src/services/emitter.ts b/packages/validator/src/services/emitter.ts index 19f9ac1de54a..2072acba6219 100644 --- a/packages/validator/src/services/emitter.ts +++ b/packages/validator/src/services/emitter.ts @@ -1,4 +1,4 @@ -import {EventEmitter} from "events"; +import {EventEmitter} from "node:events"; import {StrictEventEmitter} from "strict-event-emitter-types"; import {Slot} from "@lodestar/types"; import {HeadEventData} from "./chainHeaderTracker.js"; diff --git a/packages/validator/src/services/indices.ts b/packages/validator/src/services/indices.ts index c3f511669bf1..ff8d1d46ab26 100644 --- a/packages/validator/src/services/indices.ts +++ b/packages/validator/src/services/indices.ts @@ -20,7 +20,6 @@ type SimpleValidatorStatus = "pending" | "active" | "exited" | "withdrawn"; const statusToSimpleStatusMapping = (status: routes.beacon.ValidatorStatus): SimpleValidatorStatus => { switch (status) { - case "active": case "active_exiting": case "active_slashed": case "active_ongoing": diff --git a/packages/validator/src/services/validatorStore.ts b/packages/validator/src/services/validatorStore.ts index c2b18bfd7e09..dfd856b18d13 100644 --- a/packages/validator/src/services/validatorStore.ts +++ b/packages/validator/src/services/validatorStore.ts @@ -247,7 +247,7 @@ export class ValidatorStore { throw Error(`Validator pubkey ${pubkeyHex} not known`); } // This should directly modify data in the map - delete validatorData["feeRecipient"]; + delete validatorData.feeRecipient; } getGraffiti(pubkeyHex: PubkeyHex): string | undefined { @@ -267,14 +267,14 @@ export class ValidatorStore { if (validatorData === undefined) { throw Error(`Validator pubkey ${pubkeyHex} not known`); } - delete validatorData["graffiti"]; + delete validatorData.graffiti; } getBuilderSelectionParams(pubkeyHex: PubkeyHex): {selection: routes.validator.BuilderSelection; boostFactor: bigint} { const selection = - (this.validators.get(pubkeyHex)?.builder || {}).selection ?? this.defaultProposerConfig.builder.selection; + this.validators.get(pubkeyHex)?.builder?.selection ?? this.defaultProposerConfig.builder.selection; - let boostFactor; + let boostFactor: bigint; switch (selection) { case routes.validator.BuilderSelection.Default: // Default value slightly favors local block to improve censorship resistance of Ethereum @@ -284,7 +284,7 @@ export class ValidatorStore { case routes.validator.BuilderSelection.MaxProfit: boostFactor = - (this.validators.get(pubkeyHex)?.builder || {}).boostFactor ?? this.defaultProposerConfig.builder.boostFactor; + this.validators.get(pubkeyHex)?.builder?.boostFactor ?? this.defaultProposerConfig.builder.boostFactor; break; case routes.validator.BuilderSelection.BuilderAlways: @@ -386,7 +386,7 @@ export class ValidatorStore { async addSigner(signer: Signer, valProposerConfig?: ValidatorProposerConfig): Promise { const pubkey = getSignerPubkeyHex(signer); - const proposerConfig = (valProposerConfig?.proposerConfig ?? {})[pubkey]; + const proposerConfig = valProposerConfig?.proposerConfig?.[pubkey]; const builderBoostFactor = proposerConfig?.builder?.boostFactor; if (builderBoostFactor !== undefined && builderBoostFactor > MAX_BUILDER_BOOST_FACTOR) { throw Error(`Invalid builderBoostFactor=${builderBoostFactor} > MAX_BUILDER_BOOST_FACTOR for pubkey=${pubkey}`); @@ -538,13 +538,13 @@ export class ValidatorStore { signature: await this.getSignature(duty.pubkey, signingRoot, signingSlot, signableMessage), committeeBits: BitArray.fromSingleBit(MAX_COMMITTEES_PER_SLOT, duty.committeeIndex), }; - } else { - return { - aggregationBits: BitArray.fromSingleBit(duty.committeeLength, duty.validatorCommitteeIndex), - data: attestationData, - signature: await this.getSignature(duty.pubkey, signingRoot, signingSlot, signableMessage), - } as phase0.Attestation; } + + return { + aggregationBits: BitArray.fromSingleBit(duty.committeeLength, duty.validatorCommitteeIndex), + data: attestationData, + signature: await this.getSignature(duty.pubkey, signingRoot, signingSlot, signableMessage), + } as phase0.Attestation; } async signAggregateAndProof( @@ -731,15 +731,14 @@ export class ValidatorStore { const builderData = validatorData?.builderData; if (builderData?.regFullKey === regFullKey) { return builderData.validatorRegistration; - } else { - const validatorRegistration = await this.signValidatorRegistration(pubkeyMaybeHex, regAttributes, slot); - // If pubkeyHex was actually registered, then update the regData - if (validatorData !== undefined) { - validatorData.builderData = {validatorRegistration, regFullKey}; - this.validators.set(pubkeyHex, validatorData); - } - return validatorRegistration; } + const validatorRegistration = await this.signValidatorRegistration(pubkeyMaybeHex, regAttributes, slot); + // If pubkeyHex was actually registered, then update the regData + if (validatorData !== undefined) { + validatorData.builderData = {validatorRegistration, regFullKey}; + this.validators.set(pubkeyHex, validatorData); + } + return validatorRegistration; } private async getSignature( @@ -803,7 +802,7 @@ export class ValidatorStore { } const isPostElectra = this.config.getForkSeq(data.slot) >= ForkSeq.electra; - if (!isPostElectra && duty.committeeIndex != data.index) { + if (!isPostElectra && duty.committeeIndex !== data.index) { throw Error( `Inconsistent duties during signing: duty.committeeIndex ${duty.committeeIndex} != att.committeeIndex ${data.index}` ); diff --git a/packages/validator/src/slashingProtection/attestation/errors.ts b/packages/validator/src/slashingProtection/attestation/errors.ts index 7d4b0978d097..34e11c190c8a 100644 --- a/packages/validator/src/slashingProtection/attestation/errors.ts +++ b/packages/validator/src/slashingProtection/attestation/errors.ts @@ -63,8 +63,4 @@ type InvalidAttestationErrorType = minTargetEpoch: Epoch; }; -export class InvalidAttestationError extends LodestarError { - constructor(type: InvalidAttestationErrorType) { - super(type); - } -} +export class InvalidAttestationError extends LodestarError {} diff --git a/packages/validator/src/slashingProtection/attestation/index.ts b/packages/validator/src/slashingProtection/attestation/index.ts index 681bdf5f0b13..f0d3a0bca172 100644 --- a/packages/validator/src/slashingProtection/attestation/index.ts +++ b/packages/validator/src/slashingProtection/attestation/index.ts @@ -39,7 +39,7 @@ export class SlashingProtectionAttestationService { async checkAndInsertAttestation(pubKey: BLSPubkey, attestation: SlashingProtectionAttestation): Promise { const safeStatus = await this.checkAttestation(pubKey, attestation); - if (safeStatus != SafeStatus.SAME_DATA) { + if (safeStatus !== SafeStatus.SAME_DATA) { await this.insertAttestation(pubKey, attestation); } @@ -63,13 +63,12 @@ export class SlashingProtectionAttestationService { // Interchange format allows for attestations without signing_root, then assume root is equal if (isEqualNonZeroRoot(sameTargetAtt.signingRoot, attestation.signingRoot)) { return SafeStatus.SAME_DATA; - } else { - throw new InvalidAttestationError({ - code: InvalidAttestationErrorCode.DOUBLE_VOTE, - attestation: attestation, - prev: sameTargetAtt, - }); } + throw new InvalidAttestationError({ + code: InvalidAttestationErrorCode.DOUBLE_VOTE, + attestation: attestation, + prev: sameTargetAtt, + }); } // Check for a surround vote diff --git a/packages/validator/src/slashingProtection/block/errors.ts b/packages/validator/src/slashingProtection/block/errors.ts index be3696bba700..e7868881627b 100644 --- a/packages/validator/src/slashingProtection/block/errors.ts +++ b/packages/validator/src/slashingProtection/block/errors.ts @@ -25,8 +25,4 @@ type InvalidBlockErrorType = minSlot: Slot; }; -export class InvalidBlockError extends LodestarError { - constructor(type: InvalidBlockErrorType) { - super(type); - } -} +export class InvalidBlockError extends LodestarError {} diff --git a/packages/validator/src/slashingProtection/block/index.ts b/packages/validator/src/slashingProtection/block/index.ts index bab380f99809..385575e82a0a 100644 --- a/packages/validator/src/slashingProtection/block/index.ts +++ b/packages/validator/src/slashingProtection/block/index.ts @@ -24,7 +24,7 @@ export class SlashingProtectionBlockService { async checkAndInsertBlockProposal(pubkey: BLSPubkey, block: SlashingProtectionBlock): Promise { const safeStatus = await this.checkBlockProposal(pubkey, block); - if (safeStatus != SafeStatus.SAME_DATA) { + if (safeStatus !== SafeStatus.SAME_DATA) { await this.insertBlockProposal(pubkey, block); } @@ -41,13 +41,13 @@ export class SlashingProtectionBlockService { // Interchange format allows for blocks without signing_root, then assume root is equal if (isEqualNonZeroRoot(sameSlotBlock.signingRoot, block.signingRoot)) { return SafeStatus.SAME_DATA; - } else { - throw new InvalidBlockError({ - code: InvalidBlockErrorCode.DOUBLE_BLOCK_PROPOSAL, - block, - block2: sameSlotBlock, - }); } + + throw new InvalidBlockError({ + code: InvalidBlockErrorCode.DOUBLE_BLOCK_PROPOSAL, + block, + block2: sameSlotBlock, + }); } // Refuse to sign any block with slot <= min(b.slot for b in data.signed_blocks if b.pubkey == proposer_pubkey), diff --git a/packages/validator/src/slashingProtection/interchange/errors.ts b/packages/validator/src/slashingProtection/interchange/errors.ts index 63771df357c2..d03215f0d930 100644 --- a/packages/validator/src/slashingProtection/interchange/errors.ts +++ b/packages/validator/src/slashingProtection/interchange/errors.ts @@ -12,8 +12,4 @@ type InterchangeErrorErrorType = | {code: InterchangeErrorErrorCode.UNSUPPORTED_VERSION; version: string} | {code: InterchangeErrorErrorCode.GENESIS_VALIDATOR_MISMATCH; root: Root; expectedRoot: Root}; -export class InterchangeError extends LodestarError { - constructor(type: InterchangeErrorErrorType) { - super(type); - } -} +export class InterchangeError extends LodestarError {} diff --git a/packages/validator/src/slashingProtection/interchange/formats/completeV4.ts b/packages/validator/src/slashingProtection/interchange/formats/completeV4.ts index b43ced6c80d3..26210390a272 100644 --- a/packages/validator/src/slashingProtection/interchange/formats/completeV4.ts +++ b/packages/validator/src/slashingProtection/interchange/formats/completeV4.ts @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/naming-convention */ import {fromHex, toPubkeyHex, toRootHex} from "@lodestar/utils"; import {InterchangeLodestar} from "../types.js"; import {fromOptionalHexString, numToString, toOptionalHexString} from "../../utils.js"; diff --git a/packages/validator/src/slashingProtection/interchange/formats/v5.ts b/packages/validator/src/slashingProtection/interchange/formats/v5.ts index 838ba76c1a57..88e2ce70fe07 100644 --- a/packages/validator/src/slashingProtection/interchange/formats/v5.ts +++ b/packages/validator/src/slashingProtection/interchange/formats/v5.ts @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/naming-convention */ import {fromHex, toPubkeyHex, toRootHex} from "@lodestar/utils"; import {InterchangeLodestar} from "../types.js"; import {fromOptionalHexString, numToString, toOptionalHexString} from "../../utils.js"; diff --git a/packages/validator/src/slashingProtection/minMaxSurround/errors.ts b/packages/validator/src/slashingProtection/minMaxSurround/errors.ts index fd094df54db3..b6cd31187f57 100644 --- a/packages/validator/src/slashingProtection/minMaxSurround/errors.ts +++ b/packages/validator/src/slashingProtection/minMaxSurround/errors.ts @@ -24,8 +24,4 @@ type SurroundAttestationErrorType = attestation2Target: number; }; -export class SurroundAttestationError extends LodestarError { - constructor(type: SurroundAttestationErrorType) { - super(type); - } -} +export class SurroundAttestationError extends LodestarError {} diff --git a/packages/validator/src/util/clock.ts b/packages/validator/src/util/clock.ts index ca29eacd41c2..4b3fc45cd803 100644 --- a/packages/validator/src/util/clock.ts +++ b/packages/validator/src/util/clock.ts @@ -119,17 +119,14 @@ export class Clock implements IClock { if (timeItem === TimeItem.Slot) { if (msFromGenesis >= 0) { return milliSecondsPerSlot - (msFromGenesis % milliSecondsPerSlot); - } else { - return Math.abs(msFromGenesis % milliSecondsPerSlot); - } - } else { - const milliSecondsPerEpoch = SLOTS_PER_EPOCH * milliSecondsPerSlot; - if (msFromGenesis >= 0) { - return milliSecondsPerEpoch - (msFromGenesis % milliSecondsPerEpoch); - } else { - return Math.abs(msFromGenesis % milliSecondsPerEpoch); } + return Math.abs(msFromGenesis % milliSecondsPerSlot); + } + const milliSecondsPerEpoch = SLOTS_PER_EPOCH * milliSecondsPerSlot; + if (msFromGenesis >= 0) { + return milliSecondsPerEpoch - (msFromGenesis % milliSecondsPerEpoch); } + return Math.abs(msFromGenesis % milliSecondsPerEpoch); } } diff --git a/packages/validator/src/util/externalSignerClient.ts b/packages/validator/src/util/externalSignerClient.ts index 1d9778375b88..54c0c16946ad 100644 --- a/packages/validator/src/util/externalSignerClient.ts +++ b/packages/validator/src/util/externalSignerClient.ts @@ -21,8 +21,6 @@ import {computeEpochAtSlot, blindedOrFullBlockToHeader} from "@lodestar/state-tr import {toHex, toRootHex} from "@lodestar/utils"; import {PubkeyHex} from "../types.js"; -/* eslint-disable @typescript-eslint/naming-convention */ - export enum SignableMessageType { AGGREGATION_SLOT = "AGGREGATION_SLOT", AGGREGATE_AND_PROOF = "AGGREGATE_AND_PROOF", @@ -243,14 +241,14 @@ function serializerSignableMessagePayload(config: BeaconConfig, payload: Signabl block_header: ssz.phase0.BeaconBlockHeader.toJson(blindedOrFullBlockToHeader(config, payload.data)), }, }; - } else { - return { - beacon_block: { - version, - block: config.getForkTypes(payload.data.slot).BeaconBlock.toJson(payload.data), - }, - }; } + + return { + beacon_block: { + version, + block: config.getForkTypes(payload.data.slot).BeaconBlock.toJson(payload.data), + }, + }; } case SignableMessageType.DEPOSIT: diff --git a/packages/validator/src/util/params.ts b/packages/validator/src/util/params.ts index 6d6705f512df..f83aa9828633 100644 --- a/packages/validator/src/util/params.ts +++ b/packages/validator/src/util/params.ts @@ -5,8 +5,6 @@ export class NotEqualParamsError extends Error {} type ConfigWithPreset = ChainConfig & BeaconPreset; -/* eslint-disable @typescript-eslint/naming-convention */ - /** * Assert localConfig values match externalSpecJson. externalSpecJson may contain more values than localConfig. * diff --git a/packages/validator/src/validator.ts b/packages/validator/src/validator.ts index 6ffebff2b3bd..1d370c35cc33 100644 --- a/packages/validator/src/validator.ts +++ b/packages/validator/src/validator.ts @@ -264,7 +264,7 @@ export class Validator { } ); - return new this({ + return new Validator({ opts, genesis, validatorStore, diff --git a/packages/validator/test/e2e/web3signer.test.ts b/packages/validator/test/e2e/web3signer.test.ts index ae22bc31446b..855b3dd9f754 100644 --- a/packages/validator/test/e2e/web3signer.test.ts +++ b/packages/validator/test/e2e/web3signer.test.ts @@ -12,7 +12,7 @@ import {Interchange, ISlashingProtection, Signer, SignerType, ValidatorStore} fr import {IndicesService} from "../../src/services/indices.js"; import {testLogger} from "../utils/logger.js"; -describe("web3signer signature test", function () { +describe("web3signer signature test", () => { vi.setConfig({testTimeout: 60_000, hookTimeout: 60_000}); const altairSlot = 2375711; @@ -82,7 +82,7 @@ describe("web3signer signature test", function () { }); } - it("signRandao", async function () { + it("signRandao", async () => { await assertSameSignature("signRandao", pubkeyBytes, epoch); }); diff --git a/packages/validator/test/spec/params.ts b/packages/validator/test/spec/params.ts index c51a881bfeb3..0f5c707ff1c5 100644 --- a/packages/validator/test/spec/params.ts +++ b/packages/validator/test/spec/params.ts @@ -3,7 +3,6 @@ import {fileURLToPath} from "node:url"; // Global variable __dirname no longer available in ES6 modules. // Solutions: https://stackoverflow.com/questions/46745014/alternative-for-dirname-in-node-js-when-using-es6-modules -// eslint-disable-next-line @typescript-eslint/naming-convention const __dirname = path.dirname(fileURLToPath(import.meta.url)); // Full link: https://github.com/eth2-clients/slashing-protection-interchange-tests/releases/download/v5.1.0/eip-3076-tests-v5.1.0.tar.gz diff --git a/packages/validator/test/unit/services/attestation.test.ts b/packages/validator/test/unit/services/attestation.test.ts index 66b722273102..1652af83c5d1 100644 --- a/packages/validator/test/unit/services/attestation.test.ts +++ b/packages/validator/test/unit/services/attestation.test.ts @@ -22,7 +22,7 @@ vi.mock("../../../src/services/emitter.js"); vi.mock("../../../src/services/chainHeaderTracker.js"); vi.mock("../../../src/services/syncingStatusTracker.js"); -describe("AttestationService", function () { +describe("AttestationService", () => { const api = getApiClientStub(); // @ts-expect-error - Mocked class don't need parameters const validatorStore = vi.mocked(new ValidatorStore()); @@ -52,7 +52,6 @@ describe("AttestationService", function () { vi.resetAllMocks(); }); - // eslint-disable-next-line @typescript-eslint/naming-convention const electraConfig: Partial = {ELECTRA_FORK_EPOCH: 0}; const testContexts: [string, AttestationServiceOpts, Partial][] = [ diff --git a/packages/validator/test/unit/services/attestationDuties.test.ts b/packages/validator/test/unit/services/attestationDuties.test.ts index a9d50eaf42c6..fafccf209777 100644 --- a/packages/validator/test/unit/services/attestationDuties.test.ts +++ b/packages/validator/test/unit/services/attestationDuties.test.ts @@ -18,7 +18,7 @@ import {ZERO_HASH_HEX} from "../../utils/types.js"; vi.mock("../../../src/services/chainHeaderTracker.js"); -describe("AttestationDutiesService", function () { +describe("AttestationDutiesService", () => { const api = getApiClientStub(); let validatorStore: ValidatorStore; @@ -33,7 +33,7 @@ describe("AttestationDutiesService", function () { const defaultValidator: routes.beacon.ValidatorResponse = { index, balance: 32e9, - status: "active", + status: "active_ongoing", validator: ssz.phase0.Validator.defaultValue(), }; @@ -61,7 +61,7 @@ describe("AttestationDutiesService", function () { controller.abort(); }); - it("Should fetch indexes and duties", async function () { + it("Should fetch indexes and duties", async () => { // Reply with some duties const slot = 1; const epoch = computeEpochAtSlot(slot); @@ -118,7 +118,7 @@ describe("AttestationDutiesService", function () { expect(api.validator.prepareBeaconCommitteeSubnet).toHaveBeenCalledOnce(); }); - it("Should remove signer from attestation duties", async function () { + it("Should remove signer from attestation duties", async () => { // Reply with some duties const slot = 1; const duty: routes.validator.AttesterDuty = { @@ -165,7 +165,7 @@ describe("AttestationDutiesService", function () { expect(Object.fromEntries(dutiesService["dutiesByIndexByEpoch"])).toEqual({}); }); - it("Should fetch duties when node is resynced", async function () { + it("Should fetch duties when node is resynced", async () => { // Node is syncing api.node.getSyncingStatus.mockResolvedValue( mockApiResponse({data: {headSlot: 0, syncDistance: 1, isSyncing: true, isOptimistic: false, elOffline: false}}) diff --git a/packages/validator/test/unit/services/block.test.ts b/packages/validator/test/unit/services/block.test.ts index 641ca620a1b5..dc89f1169d92 100644 --- a/packages/validator/test/unit/services/block.test.ts +++ b/packages/validator/test/unit/services/block.test.ts @@ -16,7 +16,7 @@ import {ZERO_HASH_HEX} from "../../utils/types.js"; vi.mock("../../../src/services/validatorStore.js"); -describe("BlockDutiesService", function () { +describe("BlockDutiesService", () => { const api = getApiClientStub(); // @ts-expect-error - Mocked class don't need parameters const validatorStore = vi.mocked(new ValidatorStore()); @@ -36,7 +36,7 @@ describe("BlockDutiesService", function () { }); afterEach(() => controller.abort()); - it("Should produce, sign, and publish a block", async function () { + it("Should produce, sign, and publish a block", async () => { // Reply with some duties const slot = 0; // genesisTime is right now, so test with slot = currentSlot api.validator.getProposerDuties.mockResolvedValue( @@ -111,7 +111,7 @@ describe("BlockDutiesService", function () { ]); }); - it("Should produce, sign, and publish a blinded block", async function () { + it("Should produce, sign, and publish a blinded block", async () => { // Reply with some duties const slot = 0; // genesisTime is right now, so test with slot = currentSlot api.validator.getProposerDuties.mockResolvedValue( diff --git a/packages/validator/test/unit/services/blockDuties.test.ts b/packages/validator/test/unit/services/blockDuties.test.ts index bc4053b704c8..51ced2cd70de 100644 --- a/packages/validator/test/unit/services/blockDuties.test.ts +++ b/packages/validator/test/unit/services/blockDuties.test.ts @@ -13,7 +13,7 @@ import {ClockMock} from "../../utils/clock.js"; import {initValidatorStore} from "../../utils/validatorStore.js"; import {ZERO_HASH_HEX} from "../../utils/types.js"; -describe("BlockDutiesService", function () { +describe("BlockDutiesService", () => { const api = getApiClientStub(); let validatorStore: ValidatorStore; let pubkeys: Uint8Array[]; // Initialize pubkeys in before() so bls is already initialized @@ -30,7 +30,7 @@ describe("BlockDutiesService", function () { }); afterEach(() => controller.abort()); - it("Should fetch and persist block duties", async function () { + it("Should fetch and persist block duties", async () => { // Reply with some duties const slot = 0; // genesisTime is right now, so test with slot = currentSlot const duties: routes.validator.ProposerDutyList = [{slot: slot, validatorIndex: 0, pubkey: pubkeys[0]}]; @@ -106,7 +106,7 @@ describe("BlockDutiesService", function () { expect(notifyBlockProductionFn.mock.calls[1]).toEqual([1, [pubkeys[1]]]); }); - it("Should remove signer from duty", async function () { + it("Should remove signer from duty", async () => { // Reply with some duties const slot = 0; // genesisTime is right now, so test with slot = currentSlot const duties: routes.validator.ProposerDutyList = [ diff --git a/packages/validator/test/unit/services/doppelganger.test.ts b/packages/validator/test/unit/services/doppelganger.test.ts index 9b669b3c9396..943f0c08a9d3 100644 --- a/packages/validator/test/unit/services/doppelganger.test.ts +++ b/packages/validator/test/unit/services/doppelganger.test.ts @@ -213,8 +213,10 @@ function getMockBeaconApi(livenessMap: LivenessMap): ApiClient { } class ClockMockMsToSlot extends ClockMock { - constructor(public currentEpoch: Epoch) { + currentEpoch: Epoch; + constructor(currentEpoch: Epoch) { super(); + this.currentEpoch = currentEpoch; } async tickEpoch(epoch: Epoch, signal: AbortSignal): Promise { diff --git a/packages/validator/test/unit/services/indicesService.test.ts b/packages/validator/test/unit/services/indicesService.test.ts index 8332bac7cfd6..d4619aa65b94 100644 --- a/packages/validator/test/unit/services/indicesService.test.ts +++ b/packages/validator/test/unit/services/indicesService.test.ts @@ -6,7 +6,7 @@ import {getApiClientStub} from "../../utils/apiStub.js"; import {testLogger} from "../../utils/logger.js"; import {IndicesService} from "../../../src/services/indices.js"; -describe("IndicesService", function () { +describe("IndicesService", () => { const logger = testLogger(); const api = getApiClientStub(); @@ -20,7 +20,7 @@ describe("IndicesService", function () { pubkeys = secretKeys.map((sk) => sk.toPublicKey().toBytes()); }); - it("Should remove pubkey", async function () { + it("Should remove pubkey", async () => { const indicesService = new IndicesService(logger, api, null); const firstValidatorIndex = 0; const secondValidatorIndex = 1; diff --git a/packages/validator/test/unit/services/syncCommitteDuties.test.ts b/packages/validator/test/unit/services/syncCommitteDuties.test.ts index dc43502d5b57..27a86d31f901 100644 --- a/packages/validator/test/unit/services/syncCommitteDuties.test.ts +++ b/packages/validator/test/unit/services/syncCommitteDuties.test.ts @@ -20,9 +20,7 @@ import {ClockMock} from "../../utils/clock.js"; import {initValidatorStore} from "../../utils/validatorStore.js"; import {syncCommitteeIndicesToSubnets} from "../../../src/services/utils.js"; -/* eslint-disable @typescript-eslint/naming-convention */ - -describe("SyncCommitteeDutiesService", function () { +describe("SyncCommitteeDutiesService", () => { const api = getApiClientStub(); let validatorStore: ValidatorStore; @@ -38,7 +36,7 @@ describe("SyncCommitteeDutiesService", function () { const defaultValidator: routes.beacon.ValidatorResponse = { index: indices[0], balance: 32e9, - status: "active", + status: "active_ongoing", validator: ssz.phase0.Validator.defaultValue(), }; @@ -69,7 +67,7 @@ describe("SyncCommitteeDutiesService", function () { controller.abort(); }); - it("Should fetch indexes and duties", async function () { + it("Should fetch indexes and duties", async () => { // Reply with some duties const slot = 1; const duty: routes.validator.SyncDuty = { @@ -129,7 +127,7 @@ describe("SyncCommitteeDutiesService", function () { /** * Reproduce https://github.com/ChainSafe/lodestar/issues/3572 */ - it("should remove redundant duties", async function () { + it("should remove redundant duties", async () => { // Reply with some duties const duty: routes.validator.SyncDuty = { pubkey: pubkeys[0], @@ -197,7 +195,7 @@ describe("SyncCommitteeDutiesService", function () { } as typeof dutiesByIndexByPeriodObj); }); - it("Should remove signer from sync committee duties", async function () { + it("Should remove signer from sync committee duties", async () => { // Reply with some duties const duty1: routes.validator.SyncDuty = { pubkey: pubkeys[0], @@ -210,7 +208,6 @@ describe("SyncCommitteeDutiesService", function () { validatorSyncCommitteeIndices: [7], }; when(api.validator.getSyncCommitteeDuties) - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment .calledWith({epoch: expect.any(Number), indices}) .thenResolve(mockApiResponse({data: [duty1, duty2], meta: {executionOptimistic: false}})); @@ -267,7 +264,7 @@ describe("SyncCommitteeDutiesService", function () { } as typeof dutiesByIndexByPeriodObjAfterRemoval); }); - it("Should fetch duties when node is resynced", async function () { + it("Should fetch duties when node is resynced", async () => { // Node is syncing api.node.getSyncingStatus.mockResolvedValue( mockApiResponse({data: {headSlot: 0, syncDistance: 1, isSyncing: true, isOptimistic: false, elOffline: false}}) diff --git a/packages/validator/test/unit/services/syncCommittee.test.ts b/packages/validator/test/unit/services/syncCommittee.test.ts index 449f826c3806..84c7f14d73b1 100644 --- a/packages/validator/test/unit/services/syncCommittee.test.ts +++ b/packages/validator/test/unit/services/syncCommittee.test.ts @@ -21,9 +21,7 @@ vi.mock("../../../src/services/emitter.js"); vi.mock("../../../src/services/chainHeaderTracker.js"); vi.mock("../../../src/services/syncingStatusTracker.js"); -/* eslint-disable @typescript-eslint/naming-convention */ - -describe("SyncCommitteeService", function () { +describe("SyncCommitteeService", () => { const api = getApiClientStub(); // @ts-expect-error - Mocked class don't need parameters const validatorStore = vi.mocked(new ValidatorStore()); diff --git a/packages/validator/test/unit/services/syncingStatusTracker.test.ts b/packages/validator/test/unit/services/syncingStatusTracker.test.ts index 59029e1b9c51..07364847e345 100644 --- a/packages/validator/test/unit/services/syncingStatusTracker.test.ts +++ b/packages/validator/test/unit/services/syncingStatusTracker.test.ts @@ -4,7 +4,7 @@ import {getMockedLogger} from "../../utils/logger.js"; import {ClockMock} from "../../utils/clock.js"; import {SyncingStatus, SyncingStatusTracker} from "../../../src/services/syncingStatusTracker.js"; -describe("SyncingStatusTracker", function () { +describe("SyncingStatusTracker", () => { const api = getApiClientStub(); const logger = getMockedLogger(); @@ -26,7 +26,7 @@ describe("SyncingStatusTracker", function () { controller.abort(); }); - it("should handle transition from syncing to synced", async function () { + it("should handle transition from syncing to synced", async () => { // Node is syncing const syncing: SyncingStatus = { headSlot: 0, @@ -80,7 +80,7 @@ describe("SyncingStatusTracker", function () { expect(callOnResynced).toHaveBeenCalledOnce(); }); - it("should handle errors when checking syncing status", async function () { + it("should handle errors when checking syncing status", async () => { // Node is offline const error = new Error("ECONNREFUSED"); api.node.getSyncingStatus.mockRejectedValue(error); @@ -92,7 +92,7 @@ describe("SyncingStatusTracker", function () { expect(callOnResynced).not.toHaveBeenCalled(); }); - it("should not call scheduled tasks if already synced", async function () { + it("should not call scheduled tasks if already synced", async () => { // Node is already synced const syncedHead1: SyncingStatus = { headSlot: 1, diff --git a/packages/validator/test/unit/slashingProtection/interchange/index.test.ts b/packages/validator/test/unit/slashingProtection/interchange/index.test.ts index af2694458368..4038c6d1d4c5 100644 --- a/packages/validator/test/unit/slashingProtection/interchange/index.test.ts +++ b/packages/validator/test/unit/slashingProtection/interchange/index.test.ts @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/naming-convention */ import {describe, it, expect} from "vitest"; import {toHexString} from "@chainsafe/ssz"; import {Root, ssz} from "@lodestar/types"; diff --git a/packages/validator/test/unit/slashingProtection/minMaxSurround/utils.ts b/packages/validator/test/unit/slashingProtection/minMaxSurround/utils.ts index e57af53d6837..6d9e4e0f559d 100644 --- a/packages/validator/test/unit/slashingProtection/minMaxSurround/utils.ts +++ b/packages/validator/test/unit/slashingProtection/minMaxSurround/utils.ts @@ -8,11 +8,11 @@ export class DistanceMapStore { this.map = new Map(); } - async get(pubkey: BLSPubkey, epoch: number): Promise { + async get(_pubkey: BLSPubkey, epoch: number): Promise { return this.map.get(epoch) ?? null; } - async setBatch(pubkey: BLSPubkey, values: DistanceEntry[]): Promise { + async setBatch(_pubkey: BLSPubkey, values: DistanceEntry[]): Promise { for (const {source, distance} of values) { this.map.set(source, distance); } diff --git a/packages/validator/test/unit/utils/batch.test.ts b/packages/validator/test/unit/utils/batch.test.ts index 821d27c1a43a..455d31e19577 100644 --- a/packages/validator/test/unit/utils/batch.test.ts +++ b/packages/validator/test/unit/utils/batch.test.ts @@ -1,7 +1,7 @@ import {describe, it, expect} from "vitest"; import {batchItems} from "../../../src/util/index.js"; -describe("util / batch", function () { +describe("util / batch", () => { const testCases: {items: string[]; expected: string[][]}[] = [ {items: [], expected: []}, {items: ["1"], expected: [["1"]]}, diff --git a/packages/validator/test/unit/utils/clock.test.ts b/packages/validator/test/unit/utils/clock.test.ts index d668d753014a..056260d9e515 100644 --- a/packages/validator/test/unit/utils/clock.test.ts +++ b/packages/validator/test/unit/utils/clock.test.ts @@ -5,7 +5,7 @@ import {BeaconConfig} from "@lodestar/config"; import {Clock, getCurrentSlotAround} from "../../../src/util/clock.js"; import {testLogger} from "../../utils/logger.js"; -describe("util / Clock", function () { +describe("util / Clock", () => { const logger = testLogger(); let controller: AbortController; @@ -80,8 +80,7 @@ describe("util / Clock", function () { expect(onEpoch).toHaveBeenNthCalledWith(2, 1, expect.any(AbortSignal)); }); - describe("getCurrentSlot", function () { - // eslint-disable-next-line @typescript-eslint/naming-convention + describe("getCurrentSlot", () => { const testConfig = {SECONDS_PER_SLOT: 12} as BeaconConfig; const genesisTime = Math.floor(new Date("2021-01-01").getTime() / 1000); @@ -97,7 +96,7 @@ describe("util / Clock", function () { {name: "should return next slot after 12.5s", delta: 12.5}, ]; - it.each(testCase)("$name", async function ({delta}) { + it.each(testCase)("$name", async ({delta}) => { const currentSlot = getCurrentSlotAround(testConfig, genesisTime); vi.advanceTimersByTime(delta * 1000); expect(getCurrentSlotAround(testConfig, genesisTime)).toBe(currentSlot + 1); diff --git a/packages/validator/test/unit/utils/interopConfigs.ts b/packages/validator/test/unit/utils/interopConfigs.ts index d263fa8c1d8f..36fff9051ce8 100644 --- a/packages/validator/test/unit/utils/interopConfigs.ts +++ b/packages/validator/test/unit/utils/interopConfigs.ts @@ -1,5 +1,3 @@ -/* eslint-disable @typescript-eslint/naming-convention */ - export const lighthouseHoleskyConfig = { CONFIG_NAME: "holesky", PRESET_BASE: "mainnet", diff --git a/packages/validator/test/unit/utils/params.test.ts b/packages/validator/test/unit/utils/params.test.ts index 79701e1f7a6e..13bab507cf13 100644 --- a/packages/validator/test/unit/utils/params.test.ts +++ b/packages/validator/test/unit/utils/params.test.ts @@ -12,8 +12,6 @@ const testCases: {name: string; items: [ChainConfig, Record]}[] {name: "nimbus", items: [networksChainConfig.holesky, nimbusHoleskyConfig]}, ]; -/* eslint-disable @typescript-eslint/naming-convention */ - describe("utils / params / assertEqualParams", () => { it("default == default", () => { const chainConfigJson = chainConfigToJson(chainConfig); diff --git a/packages/validator/test/unit/validatorStore.test.ts b/packages/validator/test/unit/validatorStore.test.ts index 3d8d88ee3e64..b029a33e163a 100644 --- a/packages/validator/test/unit/validatorStore.test.ts +++ b/packages/validator/test/unit/validatorStore.test.ts @@ -11,7 +11,7 @@ import {getApiClientStub} from "../utils/apiStub.js"; import {initValidatorStore} from "../utils/validatorStore.js"; import {ValidatorProposerConfig} from "../../src/services/validatorStore.js"; -describe("ValidatorStore", function () { +describe("ValidatorStore", () => { const api = getApiClientStub(); let validatorStore: ValidatorStore; @@ -48,7 +48,7 @@ describe("ValidatorStore", function () { vi.resetAllMocks(); }); - it("Should validate graffiti,feeRecipient etc. from valProposerConfig and ValidatorStore", async function () { + it("Should validate graffiti,feeRecipient etc. from valProposerConfig and ValidatorStore", async () => { //pubkeys[0] values expect(validatorStore.getGraffiti(toHexString(pubkeys[0]))).toBe( valProposerConfig.proposerConfig[toHexString(pubkeys[0])].graffiti diff --git a/packages/validator/test/utils/spec.ts b/packages/validator/test/utils/spec.ts index 91d6a75d1a52..ae0be94b4bfa 100644 --- a/packages/validator/test/utils/spec.ts +++ b/packages/validator/test/utils/spec.ts @@ -1,7 +1,6 @@ import fs from "node:fs"; import path from "node:path"; -/* eslint-disable @typescript-eslint/naming-convention */ export type SlashingProtectionInterchangeTest = { name: string; genesis_validators_root: string; diff --git a/scripts/assert_eslintrc_sorted.mjs b/scripts/assert_eslintrc_sorted.mjs deleted file mode 100755 index 0b298b627340..000000000000 --- a/scripts/assert_eslintrc_sorted.mjs +++ /dev/null @@ -1,22 +0,0 @@ -#!/usr/bin/env node - -import assert from "node:assert"; -import eslintrc from "../.eslintrc.js"; - -assertSorted(eslintrc.extends, ".extends"); -assertSorted(Object.keys(eslintrc.rules), ".rules"); -for (const overrides of eslintrc.overrides) { - assertSorted(Object.keys(overrides.rules), `.overrides ${overrides.files.join(",")}`); -} - -/** @param {string[]} keys @param {string} id */ -// eslint-disable-next-line @typescript-eslint/explicit-function-return-type -function assertSorted(keys, id) { - try { - assert.deepStrictEqual(keys, [...keys].sort()); - } catch (e) { - // eslint-disable-next-line no-console - console.log(`Lint error in ${id}\n\n`, e.message); - process.exit(1); - } -} diff --git a/scripts/release/utils.mjs b/scripts/release/utils.mjs index ee02015f0577..19ae6f3d306b 100644 --- a/scripts/release/utils.mjs +++ b/scripts/release/utils.mjs @@ -50,7 +50,7 @@ export function parseCmdArgs() { // optional arg, defaults to HEAD try { commit = shell(`git log -n 1 --pretty='%h' ${commitArg ?? "HEAD"}`); - } catch (e) { + } catch (_e) { throw Error(`Invalid commit ${commitArg}`); } @@ -62,7 +62,7 @@ export function parseCmdArgs() { try { if (versionObj.includePrerelease) throw Error("Includes pre-release"); if (semver.clean(versionArg) !== versionMMP) throw Error("No clean major.minor.path version"); - } catch (e) { + } catch (_e) { throw Error(`Bad argv[2] semver version '${versionArg}': ${e.message}`); } @@ -82,7 +82,7 @@ export function assertCommitExistsInBranch(commit, branch) { try { // Also, ensure the branch exists first headCommit = shell(`git rev-parse refs/heads/${branch}`); - } catch (e) { + } catch (_e) { throw Error(`Branch ${branch} does not exist: ${e.message}`); } @@ -95,7 +95,7 @@ export function assertCommitExistsInBranch(commit, branch) { try { shell(`git merge-base --is-ancestor ${commit} ${headCommit}`); - } catch (e) { + } catch (_e) { throw Error(`Commit ${commit} does not belong to branch ${branch}`); } } @@ -129,7 +129,7 @@ export async function confirm(message) { export function checkBranchExistsLocal(branch) { try { return shell(`git show-ref refs/heads/${branch}`); - } catch (e) { + } catch (_e) { return null; } } @@ -156,7 +156,7 @@ export function checkBranchExistsRemote(branch) { // Return the first part of the first line return out.split(/\s+/)[0]; - } catch (e) { + } catch (_e) { return null; } } @@ -169,7 +169,7 @@ export function checkBranchExistsRemote(branch) { export function checkTagExistsLocal(tag) { try { return shell(`git show-ref refs/tags/${tag}`); - } catch (e) { + } catch (_e) { return null; } } @@ -195,7 +195,7 @@ export function checkTagExistsRemote(tag) { // Return the first part of the first line return out.split(/\s+/)[0]; - } catch (e) { + } catch (_e) { return null; } } @@ -224,7 +224,7 @@ export function readMainPackageJson() { let jsonStr; try { jsonStr = fs.readFileSync(packageJsonPath, "utf8"); - } catch (e) { + } catch (_e) { if (e.code === "ENOENT") { throw Error(`Must run script from repo root dir, package.json not found at ${packageJsonPath}`); } else { diff --git a/scripts/vitest/setupFiles/dotenv.ts b/scripts/vitest/setupFiles/dotenv.ts index 71364c7426bc..511cefd8eed4 100644 --- a/scripts/vitest/setupFiles/dotenv.ts +++ b/scripts/vitest/setupFiles/dotenv.ts @@ -1,8 +1,6 @@ import path from "node:path"; // It's a dev dependency -// eslint-disable-next-line import/no-extraneous-dependencies import {config} from "dotenv"; -// eslint-disable-next-line @typescript-eslint/naming-convention const __dirname = new URL(".", import.meta.url).pathname; config({path: path.join(__dirname, "../../../.env.test")}); diff --git a/types/vitest/index.d.ts b/types/vitest/index.d.ts index 387edcfa5279..297ed11e1904 100644 --- a/types/vitest/index.d.ts +++ b/types/vitest/index.d.ts @@ -1,4 +1,3 @@ -// eslint-disable-next-line import/no-extraneous-dependencies, @typescript-eslint/no-unused-vars import * as vitest from "vitest"; interface CustomMatchers { @@ -42,7 +41,6 @@ interface CustomAsymmetricMatchers extends CustomMatchers { } declare module "vitest" { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - interface Assertion extends CustomMatchers {} + interface Assertion extends CustomMatchers {} interface AsymmetricMatchersContaining extends CustomAsymmetricMatchers {} } diff --git a/yarn.lock b/yarn.lock index 9c749a977827..8f0f295b382f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,11 +2,6 @@ # yarn lockfile v1 -"@aashutoshrathi/word-wrap@^1.2.3": - version "1.2.6" - resolved "https://registry.yarnpkg.com/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz#bd9154aec9983f77b3a034ecaa015c2e4201f6cf" - integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA== - "@actions/cache@^1.0.7": version "1.0.7" resolved "https://registry.npmjs.org/@actions/cache/-/cache-1.0.7.tgz" @@ -289,6 +284,60 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== +"@biomejs/biome@^1.9.3": + version "1.9.3" + resolved "https://registry.yarnpkg.com/@biomejs/biome/-/biome-1.9.3.tgz#5362fc390ac00c82e3698824490e3801d012c1b0" + integrity sha512-POjAPz0APAmX33WOQFGQrwLvlu7WLV4CFJMlB12b6ZSg+2q6fYu9kZwLCOA+x83zXfcPd1RpuWOKJW0GbBwLIQ== + optionalDependencies: + "@biomejs/cli-darwin-arm64" "1.9.3" + "@biomejs/cli-darwin-x64" "1.9.3" + "@biomejs/cli-linux-arm64" "1.9.3" + "@biomejs/cli-linux-arm64-musl" "1.9.3" + "@biomejs/cli-linux-x64" "1.9.3" + "@biomejs/cli-linux-x64-musl" "1.9.3" + "@biomejs/cli-win32-arm64" "1.9.3" + "@biomejs/cli-win32-x64" "1.9.3" + +"@biomejs/cli-darwin-arm64@1.9.3": + version "1.9.3" + resolved "https://registry.yarnpkg.com/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-1.9.3.tgz#3a981835a7a891589b356bbdb4e50157e494aa7d" + integrity sha512-QZzD2XrjJDUyIZK+aR2i5DDxCJfdwiYbUKu9GzkCUJpL78uSelAHAPy7m0GuPMVtF/Uo+OKv97W3P9nuWZangQ== + +"@biomejs/cli-darwin-x64@1.9.3": + version "1.9.3" + resolved "https://registry.yarnpkg.com/@biomejs/cli-darwin-x64/-/cli-darwin-x64-1.9.3.tgz#0e33284e5def9cbc17705b6a9acbc22b161accb1" + integrity sha512-vSCoIBJE0BN3SWDFuAY/tRavpUtNoqiceJ5PrU3xDfsLcm/U6N93JSM0M9OAiC/X7mPPfejtr6Yc9vSgWlEgVw== + +"@biomejs/cli-linux-arm64-musl@1.9.3": + version "1.9.3" + resolved "https://registry.yarnpkg.com/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-1.9.3.tgz#b68e2fe56381cbf71770b6c785215448c47595fd" + integrity sha512-VBzyhaqqqwP3bAkkBrhVq50i3Uj9+RWuj+pYmXrMDgjS5+SKYGE56BwNw4l8hR3SmYbLSbEo15GcV043CDSk+Q== + +"@biomejs/cli-linux-arm64@1.9.3": + version "1.9.3" + resolved "https://registry.yarnpkg.com/@biomejs/cli-linux-arm64/-/cli-linux-arm64-1.9.3.tgz#bb8186f000bd7366c3a1822a4a505e374905c462" + integrity sha512-vJkAimD2+sVviNTbaWOGqEBy31cW0ZB52KtpVIbkuma7PlfII3tsLhFa+cwbRAcRBkobBBhqZ06hXoZAN8NODQ== + +"@biomejs/cli-linux-x64-musl@1.9.3": + version "1.9.3" + resolved "https://registry.yarnpkg.com/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-1.9.3.tgz#01ccee0db2ca2ec9fb51fa69b2fc9e96434b5b32" + integrity sha512-TJmnOG2+NOGM72mlczEsNki9UT+XAsMFAOo8J0me/N47EJ/vkLXxf481evfHLlxMejTY6IN8SdRSiPVLv6AHlA== + +"@biomejs/cli-linux-x64@1.9.3": + version "1.9.3" + resolved "https://registry.yarnpkg.com/@biomejs/cli-linux-x64/-/cli-linux-x64-1.9.3.tgz#82d6fb824dd2c76142ab8625e202eb63a34e14f1" + integrity sha512-x220V4c+romd26Mu1ptU+EudMXVS4xmzKxPVb9mgnfYlN4Yx9vD5NZraSx/onJnd3Gh/y8iPUdU5CDZJKg9COA== + +"@biomejs/cli-win32-arm64@1.9.3": + version "1.9.3" + resolved "https://registry.yarnpkg.com/@biomejs/cli-win32-arm64/-/cli-win32-arm64-1.9.3.tgz#7fac607ade8e204eecae09e127713f000da0ccf2" + integrity sha512-lg/yZis2HdQGsycUvHWSzo9kOvnGgvtrYRgoCEwPBwwAL8/6crOp3+f47tPwI/LI1dZrhSji7PNsGKGHbwyAhw== + +"@biomejs/cli-win32-x64@1.9.3": + version "1.9.3" + resolved "https://registry.yarnpkg.com/@biomejs/cli-win32-x64/-/cli-win32-x64-1.9.3.tgz#1cbc269dcd5f29b034cb7f5982353c1cc3629318" + integrity sha512-cQMy2zanBkVLpmmxXdK6YePzmZx0s5Z7KEnwmrW54rcXK3myCNbQa09SwGZ8i/8sLw0H9F3X7K4rxVNGU8/D4Q== + "@bundled-es-modules/cookie@^2.0.0": version "2.0.0" resolved "https://registry.yarnpkg.com/@bundled-es-modules/cookie/-/cookie-2.0.0.tgz#c3b82703969a61cf6a46e959a012b2c257f6b164" @@ -407,14 +456,14 @@ "@chainsafe/blst-linux-x64-musl" "2.0.3" "@chainsafe/blst-win32-x64-msvc" "2.0.3" -"@chainsafe/discv5@^9.0.0": - version "9.0.0" - resolved "https://registry.yarnpkg.com/@chainsafe/discv5/-/discv5-9.0.0.tgz#05d4d9d671894b41f0fafa8f32c48ae3ed761bd1" - integrity sha512-7s23ziqsHG/KRgkX79qB/w8kuqPrY8aJaF2aRDy9cScJocJ6ZaOnXhEc8Ku1AcSyrvfGp+tY8R4rDABcxRY+Wg== +"@chainsafe/discv5@^10.0.1": + version "10.0.1" + resolved "https://registry.yarnpkg.com/@chainsafe/discv5/-/discv5-10.0.1.tgz#1aefe3826b19b1f66e76c737a7a49ae7c77d7664" + integrity sha512-YpvqOMOn/sQMHU97lonvRnbtLZQW1Vqjcwtofd0hOJ6ohtxn+Ne7Cos8qCOFkhRHirGG6irHej4akh/BlBscSA== dependencies: - "@chainsafe/enr" "^3.0.0" - "@libp2p/crypto" "^4.0.1" - "@libp2p/interface" "^1.1.1" + "@chainsafe/enr" "^4.0.1" + "@libp2p/crypto" "^5.0.1" + "@libp2p/interface" "^2.0.1" "@multiformats/multiaddr" "^12.1.10" bcrypto "^5.4.0" bigint-buffer "^1.1.5" @@ -423,34 +472,21 @@ rlp "^2.2.6" strict-event-emitter-types "^2.0.0" -"@chainsafe/enr@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@chainsafe/enr/-/enr-3.0.0.tgz#71c83d4381d703bbcd19245ce733eb7c779a30ed" - integrity sha512-D8M8sqnvOim0jWlTdr2IhLyVe0GSUgpk+QO6UaLY4pQVdW1myJP8REp7xdbv1193ULVEkJQFTJAZexTOtmu3jw== +"@chainsafe/enr@^4.0.1": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@chainsafe/enr/-/enr-4.0.1.tgz#9c9ad8cd84aedc1242d7e7ac99d670c0f8ee3c0d" + integrity sha512-eYGZC6Wq9UNtD5AZLO21w9DctRkEAhMZ/kIa+eggT5lVRcVSI06O7PmSXOSRW6z+Td/9MQKGEDtuyYa1esWlSg== dependencies: - "@libp2p/crypto" "^4.0.1" - "@libp2p/interface" "^1.1.1" - "@libp2p/peer-id" "^4.0.4" + "@libp2p/crypto" "^5.0.1" + "@libp2p/interface" "^2.0.1" + "@libp2p/peer-id" "^5.0.1" "@multiformats/multiaddr" "^12.1.10" bigint-buffer "^1.1.5" - ethereum-cryptography "^2.1.3" + ethereum-cryptography "^2.2.0" rlp "^2.2.6" uint8-varint "^2.0.2" uint8arrays "^5.0.1" -"@chainsafe/eslint-plugin-node@^11.2.3": - version "11.2.3" - resolved "https://registry.npmjs.org/@chainsafe/eslint-plugin-node/-/eslint-plugin-node-11.2.3.tgz" - integrity sha512-2iQv5JEaPcJuKP4pdawGd6iOVoUEDwx/PhsLqevwQXXz0WYwazW+p1fTF1bAcQNvZzLz4/wEBPtcVpQKNwY+jw== - dependencies: - eslint-plugin-es "^4.1.0" - eslint-utils "^2.0.0" - ignore "^5.1.1" - is-core-module "^2.3.0" - minimatch "^3.0.4" - resolve "^1.10.1" - semver "^6.1.0" - "@chainsafe/fast-crc32c@^4.1.1": version "4.1.1" resolved "https://registry.yarnpkg.com/@chainsafe/fast-crc32c/-/fast-crc32c-4.1.1.tgz#f551284ecf8325f676a1e26b938bcca51b9c8d93" @@ -492,54 +528,37 @@ resolved "https://registry.yarnpkg.com/@chainsafe/is-ip/-/is-ip-2.0.2.tgz#7311e7403f11d8c5cfa48111f56fcecaac37c9f6" integrity sha512-ndGqEMG1W5WkGagaqOZHpPU172AGdxr+LD15sv3WIUvT5oCFUrG1Y0CW/v2Egwj4JXEvSibaIIIqImsm98y1nA== -"@chainsafe/libp2p-gossipsub@^13.0.0": - version "13.0.0" - resolved "https://registry.yarnpkg.com/@chainsafe/libp2p-gossipsub/-/libp2p-gossipsub-13.0.0.tgz#b1dfa5c2d455d77ab8dfc97f5eb8961861bb623e" - integrity sha512-2q+v429uZjMl6N3d+j9QCMj8YO0aiYvLSN1t0aTdpMXQHCHLJaaT9PtNn845B1Li7/uZjYESmikgVt8r7keH0w== +"@chainsafe/libp2p-gossipsub@^14.1.0": + version "14.1.0" + resolved "https://registry.yarnpkg.com/@chainsafe/libp2p-gossipsub/-/libp2p-gossipsub-14.1.0.tgz#0003a214c2a88b04ab7c256c70ec439717958f09" + integrity sha512-nzFBbHOoRFa/bXUSzmJaXOgHI+EttTldhLJ33yWcM0DxnWhLKychHkCDLoJO3THa1+dnzrDJoxj3N3/V0WoPVw== dependencies: - "@libp2p/crypto" "^4.0.1" - "@libp2p/interface" "^1.1.2" - "@libp2p/interface-internal" "^1.0.7" - "@libp2p/peer-id" "^4.0.5" - "@libp2p/pubsub" "^9.0.8" + "@libp2p/crypto" "^5.0.0" + "@libp2p/interface" "^2.0.0" + "@libp2p/interface-internal" "^2.0.0" + "@libp2p/peer-id" "^5.0.0" + "@libp2p/pubsub" "^10.0.0" "@multiformats/multiaddr" "^12.1.14" denque "^2.1.0" it-length-prefixed "^9.0.4" it-pipe "^3.0.1" it-pushable "^3.2.3" multiformats "^13.0.1" - protons-runtime "5.4.0" + protons-runtime "^5.5.0" uint8arraylist "^2.4.8" uint8arrays "^5.0.1" -"@chainsafe/libp2p-identify@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@chainsafe/libp2p-identify/-/libp2p-identify-1.0.0.tgz#28191e619715a87c140d8b516ee85cb7d39e41e0" - integrity sha512-X+VWUC0xeCFIulE4BU5M8FmTxZ/OKzku+9/1UaX2EG1LcqQkCDrPi6CCODbE0SraqImG4aVHRbiCFWxKEfE8wQ== - dependencies: - "@libp2p/interface" "^1.1.2" - "@libp2p/interface-internal" "^1.0.7" - "@libp2p/peer-id" "^4.0.5" - "@libp2p/peer-record" "^7.0.7" - "@multiformats/multiaddr" "^12.1.10" - "@multiformats/multiaddr-matcher" "^1.1.0" - it-protobuf-stream "^1.1.1" - protons-runtime "^5.0.0" - uint8arraylist "^2.4.7" - uint8arrays "^5.0.0" - wherearewe "^2.0.1" - -"@chainsafe/libp2p-noise@^15.0.0": - version "15.0.0" - resolved "https://registry.yarnpkg.com/@chainsafe/libp2p-noise/-/libp2p-noise-15.0.0.tgz#c3f38a31d03d96b475f7e35b592a22f5fe9269a0" - integrity sha512-O8Y/WVU4J/qrnG72jwVhbmdXiBzv1dT9B3PMClCRmZ9z/5vVPEGRVXE/SVYeGF3bNuBTLoh+F+GaKG/9UHlMhg== +"@chainsafe/libp2p-noise@^16.0.0": + version "16.0.0" + resolved "https://registry.yarnpkg.com/@chainsafe/libp2p-noise/-/libp2p-noise-16.0.0.tgz#52bb558490065439b0026950d7d99567da5c2c96" + integrity sha512-8rqr8V1RD2/lVbfL0Bb//N8iPOFof11cUe8v8z8xJT7fUhCAbtCCSM4jbwI4HCnw0MvHLmcpmAfDCFRwcWzoeA== dependencies: "@chainsafe/as-chacha20poly1305" "^0.1.0" "@chainsafe/as-sha256" "^0.4.1" - "@libp2p/crypto" "^4.0.0" - "@libp2p/interface" "^1.0.0" - "@libp2p/peer-id" "^4.0.0" - "@noble/ciphers" "^0.4.0" + "@libp2p/crypto" "^5.0.0" + "@libp2p/interface" "^2.0.0" + "@libp2p/peer-id" "^5.0.0" + "@noble/ciphers" "^0.6.0" "@noble/curves" "^1.1.0" "@noble/hashes" "^1.3.1" it-length-prefixed "^9.0.1" @@ -547,7 +566,7 @@ it-pair "^2.0.6" it-pipe "^3.0.1" it-stream-types "^2.0.1" - protons-runtime "^5.0.0" + protons-runtime "^5.5.0" uint8arraylist "^2.4.3" uint8arrays "^5.0.0" wherearewe "^2.0.1" @@ -643,6 +662,60 @@ "@chainsafe/as-sha256" "0.5.0" "@chainsafe/persistent-merkle-tree" "0.8.0" +"@chainsafe/swap-or-not-shuffle-darwin-arm64@0.0.2": + version "0.0.2" + resolved "https://registry.yarnpkg.com/@chainsafe/swap-or-not-shuffle-darwin-arm64/-/swap-or-not-shuffle-darwin-arm64-0.0.2.tgz#9c4b02970619b9ec5274f357f3a03ff97e745957" + integrity sha512-e2tmpSgGTHFv1g3oEKP/YElDTmxZwuSwVQ+Cf0gTUA8z4YQsJar61293My6JeA7qC5razWjhvcEk13ZbTCqk0w== + +"@chainsafe/swap-or-not-shuffle-darwin-x64@0.0.2": + version "0.0.2" + resolved "https://registry.yarnpkg.com/@chainsafe/swap-or-not-shuffle-darwin-x64/-/swap-or-not-shuffle-darwin-x64-0.0.2.tgz#d2777b93455a217bf4b5b94b84e76239bc3ce860" + integrity sha512-JrK4psAQz0HzlfnsGRcHnhJSv6OHfjVNkEtERnpAjyeigwCRh09wNBzHEnIk8SOGFk29DabI4FC1wdh2Cs0DAA== + +"@chainsafe/swap-or-not-shuffle-linux-arm64-gnu@0.0.2": + version "0.0.2" + resolved "https://registry.yarnpkg.com/@chainsafe/swap-or-not-shuffle-linux-arm64-gnu/-/swap-or-not-shuffle-linux-arm64-gnu-0.0.2.tgz#a881c6e29704bbbaceb8b75fd9394832087979f3" + integrity sha512-nGTIRUXt1QRNiWQXZnA8IWiHnAw6FNkU7RkngkoDzjD8pEhrtWs8tv/pdOxRKEhw21HBvKi7z8J+a7/MtxDLTg== + +"@chainsafe/swap-or-not-shuffle-linux-arm64-musl@0.0.2": + version "0.0.2" + resolved "https://registry.yarnpkg.com/@chainsafe/swap-or-not-shuffle-linux-arm64-musl/-/swap-or-not-shuffle-linux-arm64-musl-0.0.2.tgz#118f80f7bd7e8f83fb566112a17003f228d86593" + integrity sha512-sumwkxQ0Mky+W66Jf43cHUybgHQ4FENj2iRBRw3jGWiZ79Vv/DZ1dMA6I4/LVWCsvZmFUIvMvKNthGHXefh2DQ== + +"@chainsafe/swap-or-not-shuffle-linux-x64-gnu@0.0.2": + version "0.0.2" + resolved "https://registry.yarnpkg.com/@chainsafe/swap-or-not-shuffle-linux-x64-gnu/-/swap-or-not-shuffle-linux-x64-gnu-0.0.2.tgz#2dca41ba2848f904b5c9bc831cb0428c958261f3" + integrity sha512-do9NH/43eUWxtY+k3fxFltSSfKJpyvAINA/dJ3EHVkqS/oBTwR450CVNV5HFcR5Uvgxuth3/BjVYb4APs8N/MQ== + +"@chainsafe/swap-or-not-shuffle-linux-x64-musl@0.0.2": + version "0.0.2" + resolved "https://registry.yarnpkg.com/@chainsafe/swap-or-not-shuffle-linux-x64-musl/-/swap-or-not-shuffle-linux-x64-musl-0.0.2.tgz#75025eee02e2b34f10852c1de57b8e0050584320" + integrity sha512-ClwDMZd768PIaAUQhbyZpqqip0b6Sgjt8IpP5ACYMJr2AHoiG64POZaiFu+zusT4q3s4/dvqaz86jRQaF4vFkw== + +"@chainsafe/swap-or-not-shuffle-win32-arm64-msvc@0.0.2": + version "0.0.2" + resolved "https://registry.yarnpkg.com/@chainsafe/swap-or-not-shuffle-win32-arm64-msvc/-/swap-or-not-shuffle-win32-arm64-msvc-0.0.2.tgz#f5520df2bf72e823ef225d9f13d317b91b6372e4" + integrity sha512-i9+qj0VSppy2xMChQE38rCmWmmy8SJ0uSaApc0L4KZ+t2aqquYyEUXWGgfdXMZx9MqAUvuigzv34T9qivADFag== + +"@chainsafe/swap-or-not-shuffle-win32-x64-msvc@0.0.2": + version "0.0.2" + resolved "https://registry.yarnpkg.com/@chainsafe/swap-or-not-shuffle-win32-x64-msvc/-/swap-or-not-shuffle-win32-x64-msvc-0.0.2.tgz#7413aa32a4006bf144b66087844aee71bb2a5f42" + integrity sha512-zZ9J0PWzGEgfjjAVMeTvAPdHNs5XCeQqfNQ0E/lQUYhS8Wi84y44R+7M6C/KIcS0GmvCpZXI2sQGeNjqbU5LoA== + +"@chainsafe/swap-or-not-shuffle@^0.0.2": + version "0.0.2" + resolved "https://registry.yarnpkg.com/@chainsafe/swap-or-not-shuffle/-/swap-or-not-shuffle-0.0.2.tgz#59a148b80bb8e8d4f2f38f7bd00562c7a6b99e62" + integrity sha512-Rbk3p86cX71VAq46+nRcBOHOetK2ls4QrAUf1YOWTYLHmmLvx8j9Q6gQndjtu0OeYGd7Eyj1pQCFDlS9kixk+g== + optionalDependencies: + "@chainsafe/swap-or-not-shuffle-darwin-arm64" "0.0.2" + "@chainsafe/swap-or-not-shuffle-darwin-x64" "0.0.2" + "@chainsafe/swap-or-not-shuffle-linux-arm64-gnu" "0.0.2" + "@chainsafe/swap-or-not-shuffle-linux-arm64-musl" "0.0.2" + "@chainsafe/swap-or-not-shuffle-linux-x64-gnu" "0.0.2" + "@chainsafe/swap-or-not-shuffle-linux-x64-musl" "0.0.2" + "@chainsafe/swap-or-not-shuffle-win32-arm64-msvc" "0.0.2" + "@chainsafe/swap-or-not-shuffle-win32-x64-msvc" "0.0.2" + "@chainsafe/threads@^1.11.1": version "1.11.1" resolved "https://registry.yarnpkg.com/@chainsafe/threads/-/threads-1.11.1.tgz#0b3b8c76f5875043ef6d47aeeb681dc80378f205" @@ -819,38 +892,6 @@ resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz#acad351d582d157bb145535db2a6ff53dd514b5c" integrity sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw== -"@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0": - version "4.4.0" - resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" - integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== - dependencies: - eslint-visitor-keys "^3.3.0" - -"@eslint-community/regexpp@^4.5.1", "@eslint-community/regexpp@^4.6.1": - version "4.8.1" - resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.8.1.tgz#8c4bb756cc2aa7eaf13cfa5e69c83afb3260c20c" - integrity sha512-PWiOzLIUAjN/w5K17PoF4n6sKBw0gqLHPhywmYHP4t1VFQQVYeb1yWsJwnMVEMl3tUHME7X/SJPZLmtG7XBDxQ== - -"@eslint/eslintrc@^2.1.4": - version "2.1.4" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.1.4.tgz#388a269f0f25c1b6adc317b5a2c55714894c70ad" - integrity sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ== - dependencies: - ajv "^6.12.4" - debug "^4.3.2" - espree "^9.6.0" - globals "^13.19.0" - ignore "^5.2.0" - import-fresh "^3.2.1" - js-yaml "^4.1.0" - minimatch "^3.1.2" - strip-json-comments "^3.1.1" - -"@eslint/js@8.57.0": - version "8.57.0" - resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.57.0.tgz#a5417ae8427873f1dd08b70b3574b453e67b5f7f" - integrity sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g== - "@ethereumjs/block@^4.2.2": version "4.2.2" resolved "https://registry.yarnpkg.com/@ethereumjs/block/-/block-4.2.2.tgz#fddecd34ed559f84ab8eb13098a6dee51a1360ae" @@ -1430,25 +1471,6 @@ resolved "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz" integrity sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw== -"@humanwhocodes/config-array@^0.11.14": - version "0.11.14" - resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.14.tgz#d78e481a039f7566ecc9660b4ea7fe6b1fec442b" - integrity sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg== - dependencies: - "@humanwhocodes/object-schema" "^2.0.2" - debug "^4.3.1" - minimatch "^3.0.5" - -"@humanwhocodes/module-importer@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" - integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== - -"@humanwhocodes/object-schema@^2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz#d9fae00a2d5cb40f92cfe64b47ad749fbc38f917" - integrity sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw== - "@hutson/parse-repository-url@^3.0.0": version "3.0.2" resolved "https://registry.yarnpkg.com/@hutson/parse-repository-url/-/parse-repository-url-3.0.2.tgz#98c23c950a3d9b6c8f0daed06da6c3af06981340" @@ -1652,247 +1674,277 @@ yargs "16.2.0" yargs-parser "20.2.4" -"@libp2p/bootstrap@^10.0.21": - version "10.0.21" - resolved "https://registry.yarnpkg.com/@libp2p/bootstrap/-/bootstrap-10.0.21.tgz#be8b528604dc9634002f54d978ce6d5648d6a3ff" - integrity sha512-a9OGwyRM1ucq7ECUaxB4HdNoxCj21vXHcKce9khf44V5rUngF8Qzy07DI6/OaPyxJlXlDS19IJ7igaiYKx0TJw== +"@libp2p/bootstrap@^11.0.4": + version "11.0.7" + resolved "https://registry.yarnpkg.com/@libp2p/bootstrap/-/bootstrap-11.0.7.tgz#ecb14834fff03a184a3a7fd211d2ef85b3002fc6" + integrity sha512-PRDMVXf67+ASYTco6APqPy4HF03mQ8UX+BbBZcMAMpnlPsetYfWgQg3YiBe56J+PVQLs0FPsGpfLmAg7PUguQA== dependencies: - "@libp2p/interface" "^1.3.0" - "@libp2p/peer-id" "^4.1.0" + "@libp2p/interface" "^2.1.2" + "@libp2p/interface-internal" "^2.0.7" + "@libp2p/peer-id" "^5.0.4" "@multiformats/mafmt" "^12.1.6" - "@multiformats/multiaddr" "^12.2.1" + "@multiformats/multiaddr" "^12.2.3" -"@libp2p/crypto@^4.0.0", "@libp2p/crypto@^4.0.1", "@libp2p/crypto@^4.1.0": - version "4.1.0" - resolved "https://registry.yarnpkg.com/@libp2p/crypto/-/crypto-4.1.0.tgz#722060a77ced262dc89c7e42fc19ae67506b74ac" - integrity sha512-Gu4jkSdrVk1LOeyiOAuktmtN5pbSq6b9byzch2CfclFGZgXrHg3b46I0Fy63nZBc60Wq2KID3MQMVuRkVkDwAw== +"@libp2p/crypto@^5.0.0", "@libp2p/crypto@^5.0.1", "@libp2p/crypto@^5.0.4": + version "5.0.4" + resolved "https://registry.yarnpkg.com/@libp2p/crypto/-/crypto-5.0.4.tgz#26f24025f3dd2be959360c6b58c94ccadb04ed63" + integrity sha512-v5xsngOlDu8JP3GQDvK+2YYzTELl7/aPfXPbIzKEcy7ON2hu79t1BZMuavjPsr+WWIPNg5yKst6IJfRilzwXRQ== dependencies: - "@libp2p/interface" "^1.3.0" + "@libp2p/interface" "^2.1.2" "@noble/curves" "^1.4.0" "@noble/hashes" "^1.4.0" asn1js "^3.0.5" multiformats "^13.1.0" protons-runtime "^5.4.0" uint8arraylist "^2.4.8" - uint8arrays "^5.0.3" - -"@libp2p/identify@^1.0.20": - version "1.0.20" - resolved "https://registry.yarnpkg.com/@libp2p/identify/-/identify-1.0.20.tgz#cce6c4efad77afe6c0b26b0704a902f2fdbaeab2" - integrity sha512-bhn57ZI4MIMn0p3S6YNc8Sr5ReA8We8bVU25lNAefVUO3gMeQOMZ6FdTVJKbxoSumvZ+q8ciB2IOvu4rMU7o1g== - dependencies: - "@libp2p/interface" "^1.3.0" - "@libp2p/interface-internal" "^1.1.1" - "@libp2p/peer-id" "^4.1.0" - "@libp2p/peer-record" "^7.0.15" - "@multiformats/multiaddr" "^12.2.1" - "@multiformats/multiaddr-matcher" "^1.2.0" - it-protobuf-stream "^1.1.2" + uint8arrays "^5.1.0" + +"@libp2p/identify@^3.0.4": + version "3.0.7" + resolved "https://registry.yarnpkg.com/@libp2p/identify/-/identify-3.0.7.tgz#a7541d6775cf652314bf2209b281b402e8dedc35" + integrity sha512-4Ns/0HN9lvQAox8eaJruKXakOtikduk6kPlz+KYmFMgVE5/kRBRf7h0aK/8cyU9sQPbSZLCaJ3gBWoDrfMIu2w== + dependencies: + "@libp2p/crypto" "^5.0.4" + "@libp2p/interface" "^2.1.2" + "@libp2p/interface-internal" "^2.0.7" + "@libp2p/peer-id" "^5.0.4" + "@libp2p/peer-record" "^8.0.7" + "@libp2p/utils" "^6.1.0" + "@multiformats/multiaddr" "^12.2.3" + "@multiformats/multiaddr-matcher" "^1.2.1" + it-drain "^3.0.7" + it-parallel "^3.0.7" + it-protobuf-stream "^1.1.3" protons-runtime "^5.4.0" uint8arraylist "^2.4.8" - uint8arrays "^5.0.3" + uint8arrays "^5.1.0" wherearewe "^2.0.1" -"@libp2p/interface-internal@^1.0.7", "@libp2p/interface-internal@^1.1.1": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@libp2p/interface-internal/-/interface-internal-1.1.1.tgz#ff16b4fee4a3d3e39121e26eeeab42e9257f5f49" - integrity sha512-lLPd7yysXqpb1oiPZAn57w3CQdD33C+mu6pfUuPYI5yWMgwWq8V3XE4IMG1IyHUGEYZAuGglghAH9YQNbtticw== +"@libp2p/interface-internal@^2.0.0", "@libp2p/interface-internal@^2.0.7": + version "2.0.7" + resolved "https://registry.yarnpkg.com/@libp2p/interface-internal/-/interface-internal-2.0.7.tgz#ceefa71553ce5aec9be793fcc646680f7d289806" + integrity sha512-numJBYHajL7W1BuURkQ4tlZ4sUGNGI3GWkhTmL2fS+LxYS2hUVTxcemHtUZGpcJQ17GiCqq+j4GE3bkBagOb0g== dependencies: - "@libp2p/interface" "^1.3.0" - "@libp2p/peer-collections" "^5.1.11" - "@multiformats/multiaddr" "^12.2.1" + "@libp2p/interface" "^2.1.2" + "@libp2p/peer-collections" "^6.0.7" + "@multiformats/multiaddr" "^12.2.3" + progress-events "^1.0.0" uint8arraylist "^2.4.8" -"@libp2p/interface@^1.0.0", "@libp2p/interface@^1.1.1", "@libp2p/interface@^1.1.2", "@libp2p/interface@^1.3.0": - version "1.3.0" - resolved "https://registry.yarnpkg.com/@libp2p/interface/-/interface-1.3.0.tgz#c4fcee2878aa8d37357974b6c7395cb2a645eb50" - integrity sha512-K72Km0Co1Z+pXpggWuoAvUUbvwZYvjCcywrHj2Ym3jt2anTE3hzL4rlZrrkzA0YhNTRFRiZ04dnu6WMXT5/4+A== +"@libp2p/interface@^1.7.0": + version "1.7.0" + resolved "https://registry.yarnpkg.com/@libp2p/interface/-/interface-1.7.0.tgz#b75b6032a6b0d0d5a13e551dcf4d481a8ca9a88f" + integrity sha512-/zFyaIaIGW0aihhsH7/93vQdpWInUzFocxF11RO/029Y6h0SVjs24HHbils+DqaFDTqN+L7oNlBx2rM2MnmTjA== dependencies: - "@multiformats/multiaddr" "^12.2.1" + "@multiformats/multiaddr" "^12.2.3" it-pushable "^3.2.3" it-stream-types "^2.0.1" multiformats "^13.1.0" progress-events "^1.0.0" uint8arraylist "^2.4.8" -"@libp2p/logger@^4.0.11", "@libp2p/logger@^4.0.6": - version "4.0.11" - resolved "https://registry.yarnpkg.com/@libp2p/logger/-/logger-4.0.11.tgz#671692a0cceee73a0c0bf9b5f05ea14fde05f5e5" - integrity sha512-WsZBup1Q+ec4C7i2YiCx0elFrejqJea3Fmkzy3t4fAek7Ofyh4GQonk3A4R7XsG5yq8+Hu1fpsGhIK8EVQsqZQ== +"@libp2p/interface@^2.0.0", "@libp2p/interface@^2.0.1", "@libp2p/interface@^2.1.2": + version "2.1.2" + resolved "https://registry.yarnpkg.com/@libp2p/interface/-/interface-2.1.2.tgz#7b38047a7d2d35a6a4e0f0f22fbdeeec98b85321" + integrity sha512-uD4NapC+1qGX7RmgC1aehQm3pMs1MpO1DwuhUlAo1M6CyNxfs1Ha9jhg2T+G4u4CAJM6wffZTyPGnKnrR+M8Fw== dependencies: - "@libp2p/interface" "^1.3.0" - "@multiformats/multiaddr" "^12.2.1" - debug "^4.3.4" + "@multiformats/multiaddr" "^12.2.3" + it-pushable "^3.2.3" + it-stream-types "^2.0.1" + multiformats "^13.1.0" + progress-events "^1.0.0" + uint8arraylist "^2.4.8" + +"@libp2p/logger@^4.0.6": + version "4.0.20" + resolved "https://registry.yarnpkg.com/@libp2p/logger/-/logger-4.0.20.tgz#bcb7fa83f3803d8ec37926747a18108728589c13" + integrity sha512-TTh2dhHsOTAlMPxSa9ncFPHa/0jTt+0AQxwHdlxg/OGLAgc9VRhnrhHUbJZp07Crcw4T/MOfS4KhjlxgqYgJRw== + dependencies: + "@libp2p/interface" "^1.7.0" + "@multiformats/multiaddr" "^12.2.3" interface-datastore "^8.2.11" multiformats "^13.1.0" + weald "^1.0.2" -"@libp2p/mdns@^10.0.21": - version "10.0.21" - resolved "https://registry.yarnpkg.com/@libp2p/mdns/-/mdns-10.0.21.tgz#028a388b73de703e4c762fd4937f217648c8128c" - integrity sha512-/lmjsZJvhfEXeSodqKECiRZk8mqApESc3OI6MhHxNvRBsfncY93IZM7lR6jwlmyQ2DOL5rCkm2rcr9geIsVzmQ== +"@libp2p/logger@^5.1.0": + version "5.1.0" + resolved "https://registry.yarnpkg.com/@libp2p/logger/-/logger-5.1.0.tgz#d580e2ee89e3f4224129cc12d727b45494aad6e5" + integrity sha512-hmkk1TONYRe+kKs5QTxkayIfj9qicp8hcrJ1Ac9QfTW/jdaUlnqd1uop4QcOD5GV6qNMq+v1qaMFWFYSN9RcPA== dependencies: - "@libp2p/interface" "^1.3.0" - "@libp2p/interface-internal" "^1.1.1" - "@libp2p/peer-id" "^4.1.0" - "@libp2p/utils" "^5.3.2" - "@multiformats/multiaddr" "^12.2.1" + "@libp2p/interface" "^2.1.2" + "@multiformats/multiaddr" "^12.2.3" + interface-datastore "^8.3.0" + multiformats "^13.1.0" + weald "^1.0.2" + +"@libp2p/mdns@^11.0.4": + version "11.0.7" + resolved "https://registry.yarnpkg.com/@libp2p/mdns/-/mdns-11.0.7.tgz#ab968f952085a59d3ea829727e79f631fa049376" + integrity sha512-CW0MbN2bQvSVsZmYT8Ul5a2TOiwhU3aBKyHyCuf5WA70Nu6Lc72YSc+vRT2EIw5Ihb+dbxC/mXrhY1xKdXaWCg== + dependencies: + "@libp2p/interface" "^2.1.2" + "@libp2p/interface-internal" "^2.0.7" + "@libp2p/peer-id" "^5.0.4" + "@libp2p/utils" "^6.1.0" + "@multiformats/multiaddr" "^12.2.3" "@types/multicast-dns" "^7.2.4" dns-packet "^5.6.1" multicast-dns "^7.2.5" -"@libp2p/mplex@^10.0.21": - version "10.0.21" - resolved "https://registry.yarnpkg.com/@libp2p/mplex/-/mplex-10.0.21.tgz#530de45f23dd36d5ac35e21a1c259767c5bfdab1" - integrity sha512-F7pK/xG9LNG3KhZBMb6SsiR7MI18na1x1e1qr8EvlyJcmdT0OiiHCnjDXWrmy+wh6uTD2qhRM+ea1vQEhKANXw== +"@libp2p/mplex@^11.0.4": + version "11.0.7" + resolved "https://registry.yarnpkg.com/@libp2p/mplex/-/mplex-11.0.7.tgz#18f5af4d59bbd9bdf64c9ddda30020c6b674010d" + integrity sha512-q13aTXf6+kEQk67bnlDnXBy8TAU19zxrNrxzwTTW3m9HEyPEKoA1YJuSqZuDjxfP31BbMshs3xxnlXgph5SpUw== dependencies: - "@libp2p/interface" "^1.3.0" - "@libp2p/utils" "^5.3.2" + "@libp2p/interface" "^2.1.2" + "@libp2p/utils" "^6.1.0" it-pipe "^3.0.1" it-pushable "^3.2.3" it-stream-types "^2.0.1" uint8-varint "^2.0.4" uint8arraylist "^2.4.8" - uint8arrays "^5.0.3" + uint8arrays "^5.1.0" -"@libp2p/multistream-select@^5.1.8": - version "5.1.8" - resolved "https://registry.yarnpkg.com/@libp2p/multistream-select/-/multistream-select-5.1.8.tgz#c484534496625da2a20873874b33e90d3ef2a95e" - integrity sha512-mYbYyjKhNOGIaS3kefs+koofGmiBvLukcnS+BVCZDGjYxAjhaes9PB++VyuX/D0lTZSk08P3cIBvw2sN+amOVQ== +"@libp2p/multistream-select@^6.0.5": + version "6.0.5" + resolved "https://registry.yarnpkg.com/@libp2p/multistream-select/-/multistream-select-6.0.5.tgz#919c923ac13573a44de6945695f1d1882ba35da4" + integrity sha512-iOMHcF/NzeShmnRLf9KI39bgfxptklbf6Tv9NvBbICfYO/IJB6KDI6bOif5eXXqUqZjHrQJ3jrRppOEwk2HV4g== dependencies: - "@libp2p/interface" "^1.3.0" + "@libp2p/interface" "^2.1.2" it-length-prefixed "^9.0.4" - it-length-prefixed-stream "^1.1.6" + it-length-prefixed-stream "^1.1.7" it-stream-types "^2.0.1" p-defer "^4.0.1" race-signal "^1.0.2" uint8-varint "^2.0.4" uint8arraylist "^2.4.8" - uint8arrays "^5.0.3" - -"@libp2p/peer-collections@^5.1.11": - version "5.1.11" - resolved "https://registry.yarnpkg.com/@libp2p/peer-collections/-/peer-collections-5.1.11.tgz#55589fccb4daf6a9f611f3e4126d2721d856aaca" - integrity sha512-w8ZeXfsAxBQiYgRnvpD3mxGORxwAXFsIhAOxFXl8scFhuE1j086PoTfRTuKYfp4DAyNHWkhUd+LQaXN0OG/Fgg== - dependencies: - "@libp2p/interface" "^1.3.0" - "@libp2p/peer-id" "^4.1.0" + uint8arrays "^5.1.0" -"@libp2p/peer-id-factory@^4.1.0": - version "4.1.0" - resolved "https://registry.yarnpkg.com/@libp2p/peer-id-factory/-/peer-id-factory-4.1.0.tgz#e134ff61c38d1a0fd210bf1fbdcd9116a74f2919" - integrity sha512-EMovpqtqj+5s+QpzSkVundoPQ88/GQMShB79Y6zLUkGZ73VtqWds/9e1WsrHBx6HhvmkmXFOrzcW8qfml3sE7A== +"@libp2p/peer-collections@^6.0.7": + version "6.0.7" + resolved "https://registry.yarnpkg.com/@libp2p/peer-collections/-/peer-collections-6.0.7.tgz#8347e08aebbdf4a39962bb87e5ae86cc0aadfcb4" + integrity sha512-e3o994iEUvPR58x8Y5iE6lvrkv48oJXp/A1XIxMB4D/kA4OlY5BjDpHpR4nE4+EkzhIbslbMLAfip2FStyjtHg== dependencies: - "@libp2p/crypto" "^4.1.0" - "@libp2p/interface" "^1.3.0" - "@libp2p/peer-id" "^4.1.0" - protons-runtime "^5.4.0" - uint8arraylist "^2.4.8" - uint8arrays "^5.0.3" + "@libp2p/interface" "^2.1.2" + "@libp2p/peer-id" "^5.0.4" + "@libp2p/utils" "^6.1.0" + multiformats "^13.2.2" -"@libp2p/peer-id@^4.0.0", "@libp2p/peer-id@^4.0.4", "@libp2p/peer-id@^4.0.5", "@libp2p/peer-id@^4.1.0": - version "4.1.0" - resolved "https://registry.yarnpkg.com/@libp2p/peer-id/-/peer-id-4.1.0.tgz#460e07d5b25339cf80afcb5e30c4f701423d1755" - integrity sha512-XmuqEfz3H+Cwq72V3opXg7wK2WnB08VEnG5nLILefLg+qo1KMlUP5pCP3ffyvYIvxMnsRla/xPYRDEBtL2JMpg== +"@libp2p/peer-id@^5.0.0", "@libp2p/peer-id@^5.0.1", "@libp2p/peer-id@^5.0.4": + version "5.0.4" + resolved "https://registry.yarnpkg.com/@libp2p/peer-id/-/peer-id-5.0.4.tgz#5a71f449b97098a5b12631b6be898a016a82c6bb" + integrity sha512-CHNbQ4Odlc+YDTtv6BzWdGSaJ1I3Wb6iHNV7YB59v0ivSsd0NzlR31qWpK/ByUAMT+hfzQzR1dK9s3e7zS4/zQ== dependencies: - "@libp2p/interface" "^1.3.0" + "@libp2p/crypto" "^5.0.4" + "@libp2p/interface" "^2.1.2" multiformats "^13.1.0" - uint8arrays "^5.0.3" - -"@libp2p/peer-record@^7.0.15", "@libp2p/peer-record@^7.0.7": - version "7.0.15" - resolved "https://registry.yarnpkg.com/@libp2p/peer-record/-/peer-record-7.0.15.tgz#063f302fb52ebe6c548a4533e3fa3b910efdfc84" - integrity sha512-VNDjLAuDF+CHf50+50CZQeT341kJm0GuWhuOqlzonOlJihpm5314Xe1BV3oeLgrtdp1ikLvQ099JqZN/l4KIQQ== - dependencies: - "@libp2p/crypto" "^4.1.0" - "@libp2p/interface" "^1.3.0" - "@libp2p/peer-id" "^4.1.0" - "@libp2p/utils" "^5.3.2" - "@multiformats/multiaddr" "^12.2.1" + uint8arrays "^5.1.0" + +"@libp2p/peer-record@^8.0.7": + version "8.0.7" + resolved "https://registry.yarnpkg.com/@libp2p/peer-record/-/peer-record-8.0.7.tgz#a092b2405e1130b8211f8ef15748b453096029d8" + integrity sha512-YsN8R+5O0MQwYQ0UGqERJJVRx7hAU4/nxiby91wzbgdfuL4qVPXHG4k0OAAtxVGLYa0q7KeXBpBG8qoaKhOXMQ== + dependencies: + "@libp2p/crypto" "^5.0.4" + "@libp2p/interface" "^2.1.2" + "@libp2p/peer-id" "^5.0.4" + "@libp2p/utils" "^6.1.0" + "@multiformats/multiaddr" "^12.2.3" + multiformats "^13.2.2" protons-runtime "^5.4.0" uint8-varint "^2.0.4" uint8arraylist "^2.4.8" - uint8arrays "^5.0.3" - -"@libp2p/peer-store@^10.0.16": - version "10.0.16" - resolved "https://registry.yarnpkg.com/@libp2p/peer-store/-/peer-store-10.0.16.tgz#0bde6e2185e416a137d8adb7b2c381bfe4acf535" - integrity sha512-xzitLNXnCG8eAs3KT5j0sBkK0ooChv4QDqjEzCNr+Gzwryi2fn386KlPoCGNkbeAUsIHS81TY/ldK8o8NBac7Q== - dependencies: - "@libp2p/interface" "^1.3.0" - "@libp2p/peer-collections" "^5.1.11" - "@libp2p/peer-id" "^4.1.0" - "@libp2p/peer-record" "^7.0.15" - "@multiformats/multiaddr" "^12.2.1" - interface-datastore "^8.2.11" - it-all "^3.0.4" + uint8arrays "^5.1.0" + +"@libp2p/peer-store@^11.0.7": + version "11.0.7" + resolved "https://registry.yarnpkg.com/@libp2p/peer-store/-/peer-store-11.0.7.tgz#e9a57d8a0ce1b3d0559a11b7e6633620f4297276" + integrity sha512-h8W/XVYfKTmJhhnh2Mdub23CzPv24l5g1RRwFsEKCkWAe95M/fvDMPTM2ahRUB64qfnFT5X4XNFFyJFMsVtjLA== + dependencies: + "@libp2p/crypto" "^5.0.4" + "@libp2p/interface" "^2.1.2" + "@libp2p/peer-collections" "^6.0.7" + "@libp2p/peer-id" "^5.0.4" + "@libp2p/peer-record" "^8.0.7" + "@multiformats/multiaddr" "^12.2.3" + interface-datastore "^8.3.0" + it-all "^3.0.6" mortice "^3.0.4" multiformats "^13.1.0" protons-runtime "^5.4.0" uint8arraylist "^2.4.8" - uint8arrays "^5.0.3" + uint8arrays "^5.1.0" -"@libp2p/prometheus-metrics@^3.0.21": - version "3.0.21" - resolved "https://registry.yarnpkg.com/@libp2p/prometheus-metrics/-/prometheus-metrics-3.0.21.tgz#78b3327a614aacc62886597d6c6eb67c5597b8db" - integrity sha512-sqU8pI9CG/b86YUEt3IaE3ZSbauBfKbxFRdSiYVRN8EbliGxQC9blgwUcGDfWW2qcXZEgM4m2FTDLZrujFDbzA== +"@libp2p/prometheus-metrics@^4.1.2": + version "4.2.1" + resolved "https://registry.yarnpkg.com/@libp2p/prometheus-metrics/-/prometheus-metrics-4.2.1.tgz#a563e05cac1f67a161824301cacdfd659bc3052c" + integrity sha512-Mt93FWjP1Jz5G/FsG7cf0J4Y1nYs4eQvx1RjtuEghoQcSzD8nSupeMt67YRQG87R/qrs0jdiGtYxmoCoagsIDw== dependencies: - "@libp2p/interface" "^1.3.0" - it-foreach "^2.0.6" + "@libp2p/interface" "^2.1.2" + it-foreach "^2.1.0" it-stream-types "^2.0.1" - prom-client "^15.1.1" + prom-client "^15.1.2" uint8arraylist "^2.4.8" -"@libp2p/pubsub@^9.0.8": - version "9.0.16" - resolved "https://registry.yarnpkg.com/@libp2p/pubsub/-/pubsub-9.0.16.tgz#90857f494213f7a596df15081956514728e14aa2" - integrity sha512-SCV0eZuYMyhHhBFzUBslHjvfwKfL2UMZSSr08c7MsTrqvQQSVdiCEeGKfoR70h7BUvBBQkPLcCqTFZGRoYX8dA== - dependencies: - "@libp2p/crypto" "^4.1.0" - "@libp2p/interface" "^1.3.0" - "@libp2p/interface-internal" "^1.1.1" - "@libp2p/peer-collections" "^5.1.11" - "@libp2p/peer-id" "^4.1.0" - "@libp2p/utils" "^5.3.2" +"@libp2p/pubsub@^10.0.0": + version "10.0.7" + resolved "https://registry.yarnpkg.com/@libp2p/pubsub/-/pubsub-10.0.7.tgz#1b7e0b7e96b75a8a1f557171ef4d72c17879e5c0" + integrity sha512-XYAYaASilesqxonjhiEENF/jXoT3jcftNYySkiyajrw3rZnLVkfJMRese3lkFqkIZqy7K/7aAtYEDJLeSrJDiQ== + dependencies: + "@libp2p/crypto" "^5.0.4" + "@libp2p/interface" "^2.1.2" + "@libp2p/interface-internal" "^2.0.7" + "@libp2p/peer-collections" "^6.0.7" + "@libp2p/peer-id" "^5.0.4" + "@libp2p/utils" "^6.1.0" it-length-prefixed "^9.0.4" it-pipe "^3.0.1" it-pushable "^3.2.3" multiformats "^13.1.0" p-queue "^8.0.1" uint8arraylist "^2.4.8" - uint8arrays "^5.0.3" + uint8arrays "^5.1.0" -"@libp2p/tcp@9.0.23": - version "9.0.23" - resolved "https://registry.yarnpkg.com/@libp2p/tcp/-/tcp-9.0.23.tgz#44eed016fdbe4725726d451a67af548507f5591b" - integrity sha512-ERX7b//PEmy4AwhjkjLx83ZpfwTlrbDt12TEn4+ZDqtsx1lzgCjuNVUy3joSWMu9ySIvMjnzxm7mxlkAJd8buw== +"@libp2p/tcp@10.0.4": + version "10.0.4" + resolved "https://registry.yarnpkg.com/@libp2p/tcp/-/tcp-10.0.4.tgz#9fdcd4ef5940816d366ee29e7e8150a5a4bd2f11" + integrity sha512-53WIxkKNMHJphTK/VUJvL5jPrkEitZpZqUSA8zN7e02OXwwOC/X3U03xvVFdrjGL32rW524+7I+SrvS+hVdNCw== dependencies: - "@libp2p/interface" "^1.3.0" - "@libp2p/utils" "^5.3.2" + "@libp2p/interface" "^2.1.2" + "@libp2p/utils" "^6.0.4" "@multiformats/mafmt" "^12.1.6" - "@multiformats/multiaddr" "^12.2.1" + "@multiformats/multiaddr" "^12.2.3" "@types/sinon" "^17.0.3" - stream-to-it "^1.0.0" + progress-events "^1.0.0" + stream-to-it "^1.0.1" -"@libp2p/utils@^5.3.2": - version "5.3.2" - resolved "https://registry.yarnpkg.com/@libp2p/utils/-/utils-5.3.2.tgz#044881910350fb22ed0f9db35e6f68f7e8948801" - integrity sha512-3HVixx17xT7JCEY931Gd2E2WmtY0RQirDeb6OZ1YD0T3VdWUMxH7pdf1gZpCHjQTg18ISIItZnFCGy+NyoYv6Q== +"@libp2p/utils@^6.0.4", "@libp2p/utils@^6.1.0": + version "6.1.0" + resolved "https://registry.yarnpkg.com/@libp2p/utils/-/utils-6.1.0.tgz#5ccece78a38bec2c2d759136ccc78494838c2b87" + integrity sha512-pxuUI8QgeS06bMZRpy0JnACPhrrCJS5/rVNTcnQK8lV1ag2bjwkGG/359AwjeEolzYQeLrmmqnZyawd1Y74wpw== dependencies: "@chainsafe/is-ip" "^2.0.2" - "@libp2p/interface" "^1.3.0" - "@libp2p/logger" "^4.0.11" - "@multiformats/multiaddr" "^12.2.1" - "@multiformats/multiaddr-matcher" "^1.2.0" + "@libp2p/crypto" "^5.0.4" + "@libp2p/interface" "^2.1.2" + "@libp2p/logger" "^5.1.0" + "@multiformats/multiaddr" "^12.2.3" + "@sindresorhus/fnv1a" "^3.1.0" + "@types/murmurhash3js-revisited" "^3.0.3" + any-signal "^4.1.1" delay "^6.0.0" get-iterator "^2.0.1" is-loopback-addr "^2.0.2" + it-foreach "^2.1.1" + it-pipe "^3.0.1" it-pushable "^3.2.3" it-stream-types "^2.0.1" + murmurhash3js-revisited "^3.0.0" netmask "^2.0.2" p-defer "^4.0.1" - race-event "^1.2.0" + race-event "^1.3.0" race-signal "^1.0.2" uint8arraylist "^2.4.8" + uint8arrays "^5.1.0" "@lukeed/ms@^2.0.2": version "2.0.2" @@ -1959,7 +2011,7 @@ outvariant "^1.2.1" strict-event-emitter "^0.5.1" -"@multiformats/dns@^1.0.3", "@multiformats/dns@^1.0.5": +"@multiformats/dns@^1.0.3", "@multiformats/dns@^1.0.6": version "1.0.6" resolved "https://registry.yarnpkg.com/@multiformats/dns/-/dns-1.0.6.tgz#b8c7de11459a02a5f4e609d35d3cdb95cb6ad152" integrity sha512-nt/5UqjMPtyvkG9BQYdJ4GfLK3nMqGpFZOzf4hAmIa0sJh2LlS9YKXZ4FgwBDsaHvzZqR/rUFIywIc7pkHNNuw== @@ -1979,23 +2031,22 @@ dependencies: "@multiformats/multiaddr" "^12.0.0" -"@multiformats/multiaddr-matcher@^1.1.0", "@multiformats/multiaddr-matcher@^1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@multiformats/multiaddr-matcher/-/multiaddr-matcher-1.2.0.tgz#8a2beae9eff394861668e6a2776fb1e7bf719c81" - integrity sha512-LH6yR7h3HSNKcxuvvi2UpLuowuVkYC6H9Y3jqmKuTai8XtKnXtW6NcDZFD/ooTBY+H4yX/scoJpjOalHrk5qdQ== +"@multiformats/multiaddr-matcher@^1.2.1": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@multiformats/multiaddr-matcher/-/multiaddr-matcher-1.2.4.tgz#affb3c63b5cd83b44156be19583981651373ec2e" + integrity sha512-GgpqzQFL4Mj8t7cLNHC5nuYUuSm0kTtSUyYswiyWwTSUY3XwRAMx0UiFWQg+ETk0u+/IvFaHxfnyEoH3tasvwg== dependencies: "@chainsafe/is-ip" "^2.0.1" "@multiformats/multiaddr" "^12.0.0" multiformats "^13.0.0" -"@multiformats/multiaddr@^12.0.0", "@multiformats/multiaddr@^12.1.10", "@multiformats/multiaddr@^12.1.14", "@multiformats/multiaddr@^12.1.3", "@multiformats/multiaddr@^12.2.1": - version "12.2.1" - resolved "https://registry.yarnpkg.com/@multiformats/multiaddr/-/multiaddr-12.2.1.tgz#d95d1590b17dbe39dcefbb4d832d14434d3fe075" - integrity sha512-UwjoArBbv64FlaetV4DDwh+PUMfzXUBltxQwdh+uTYnGFzVa8ZfJsn1vt1RJlJ6+Xtrm3RMekF/B+K338i2L5Q== +"@multiformats/multiaddr@^12.0.0", "@multiformats/multiaddr@^12.1.10", "@multiformats/multiaddr@^12.1.14", "@multiformats/multiaddr@^12.1.3", "@multiformats/multiaddr@^12.2.3": + version "12.3.1" + resolved "https://registry.yarnpkg.com/@multiformats/multiaddr/-/multiaddr-12.3.1.tgz#953ceb4ae3b39125b7b2c721230ea7b398cf49fe" + integrity sha512-yoGODQY4nIj41ENJClucS8FtBoe8w682bzbKldEQr9lSlfdHqAsRC+vpJAOBpiMwPps1tHua4kxrDmvprdhoDQ== dependencies: "@chainsafe/is-ip" "^2.0.1" "@chainsafe/netmask" "^2.0.0" - "@libp2p/interface" "^1.0.0" "@multiformats/dns" "^1.0.3" multiformats "^13.0.0" uint8-varint "^2.0.1" @@ -2066,12 +2117,19 @@ resolved "https://registry.yarnpkg.com/@napi-rs/snappy-win32-x64-msvc/-/snappy-win32-x64-msvc-7.2.2.tgz#4f598d3a5d50904d9f72433819f68b21eaec4f7d" integrity sha512-a43cyx1nK0daw6BZxVcvDEXxKMFLSBSDTAhsFD0VqSKcC7MGUBMaqyoWUcMiI7LBSz4bxUmxDWKfCYzpEmeb3w== -"@noble/ciphers@^0.4.0": - version "0.4.0" - resolved "https://registry.yarnpkg.com/@noble/ciphers/-/ciphers-0.4.0.tgz#e3f69e3ce935683dd8dadb636652a5cb5cd5958c" - integrity sha512-xaUaUUDWbHIFSxaQ/pIe+33VG2mfJp6N/KxKLmZr5biWdNznCAmfu24QRhX10BbVAuqOahAoyp0S4M9md6GPDw== +"@noble/ciphers@^0.6.0": + version "0.6.0" + resolved "https://registry.yarnpkg.com/@noble/ciphers/-/ciphers-0.6.0.tgz#a3d82c72ce71ba43128e7eb71757b5ecb75b1273" + integrity sha512-mIbq/R9QXk5/cTfESb1OKtyFnk7oc1Om/8onA1158K9/OZUQFDEVy55jVTato+xmp3XX6F6Qh0zz0Nc1AxAlRQ== + +"@noble/curves@1.4.2", "@noble/curves@~1.4.0": + version "1.4.2" + resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.4.2.tgz#40309198c76ed71bc6dbf7ba24e81ceb4d0d1fe9" + integrity sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw== + dependencies: + "@noble/hashes" "1.4.0" -"@noble/curves@1.3.0", "@noble/curves@^1.1.0", "@noble/curves@~1.3.0": +"@noble/curves@^1.1.0": version "1.3.0" resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.3.0.tgz#01be46da4fd195822dab821e72f71bf4aeec635e" integrity sha512-t01iSXPuN+Eqzb4eBX0S5oubSqXbK/xXa1Ne18Hj8f9pStxztHCE2gfboSp/dZRLSqfuLpRK2nDXDK+W9puocA== @@ -2090,12 +2148,12 @@ resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.1.2.tgz#e9e035b9b166ca0af657a7848eb2718f0f22f183" integrity sha512-KYRCASVTv6aeUi1tsF8/vpyR7zpfs3FUzy2Jqm+MU+LmUKhQ0y2FpfwqkCcxSg2ua4GALJd8k2R76WxwZGbQpA== -"@noble/hashes@1.3.3", "@noble/hashes@^1.0.0", "@noble/hashes@^1.3.0", "@noble/hashes@^1.3.1", "@noble/hashes@~1.3.2": +"@noble/hashes@1.3.3", "@noble/hashes@^1.0.0", "@noble/hashes@^1.3.0", "@noble/hashes@^1.3.1": version "1.3.3" resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.3.tgz#39908da56a4adc270147bb07968bf3b16cfe1699" integrity sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA== -"@noble/hashes@1.4.0", "@noble/hashes@^1.4.0": +"@noble/hashes@1.4.0", "@noble/hashes@^1.4.0", "@noble/hashes@~1.4.0": version "1.4.0" resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.4.0.tgz#45814aa329f30e4fe0ba49426f49dfccdd066426" integrity sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg== @@ -2207,7 +2265,7 @@ resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== -"@nodelib/fs.walk@^1.2.3", "@nodelib/fs.walk@^1.2.8": +"@nodelib/fs.walk@^1.2.3": version "1.2.8" resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== @@ -2662,22 +2720,17 @@ resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== -"@pkgr/core@^0.1.0": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@pkgr/core/-/core-0.1.1.tgz#1ec17e2edbec25c8306d424ecfbf13c7de1aaa31" - integrity sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA== - "@polka/url@^1.0.0-next.24": version "1.0.0-next.24" resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.24.tgz#58601079e11784d20f82d0585865bb42305c4df3" integrity sha512-2LuNTFBIO0m7kKIQvvPHN6UE63VjpmL9rnEEaOOaiSPbZK+zUOYIzBAWcED+3XYzhYsd/0mD57VdxAEqqV52CQ== "@puppeteer/browsers@1.4.6", "@puppeteer/browsers@^1.6.0", "@puppeteer/browsers@^2.1.0": - version "2.3.0" - resolved "https://registry.yarnpkg.com/@puppeteer/browsers/-/browsers-2.3.0.tgz#791ea7d80450fea24eb19fb1d70c367ad4e08cae" - integrity sha512-ioXoq9gPxkss4MYhD+SFaU9p1IHFUX0ILAWFPyjGaBdjLsYAlZw6j1iLA0N/m12uVHLFDfSYNF7EQccjinIMDA== + version "2.4.0" + resolved "https://registry.yarnpkg.com/@puppeteer/browsers/-/browsers-2.4.0.tgz#a0dd0f4e381e53f509109ae83b891db5972750f5" + integrity sha512-x8J1csfIygOwf6D6qUAZ0ASk3z63zPb7wkNeHRerCMh82qWKUrOgkuP005AJC8lDL6/evtXETGEJVcwykKT4/g== dependencies: - debug "^4.3.5" + debug "^4.3.6" extract-zip "^2.0.1" progress "^2.0.3" proxy-agent "^6.4.0" @@ -2718,85 +2771,85 @@ estree-walker "^2.0.2" picomatch "^2.3.1" -"@rollup/rollup-android-arm-eabi@4.16.1": - version "4.16.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.16.1.tgz#ad76cc870b1e2bc4476dfc02b82e20cea272a09d" - integrity sha512-92/y0TqNLRYOTXpm6Z7mnpvKAG9P7qmK7yJeRJSdzElNCUnsgbpAsGqerUboYRIQKzgfq4pWu9xVkgpWLfmNsw== - -"@rollup/rollup-android-arm64@4.16.1": - version "4.16.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.16.1.tgz#e7bd4f2b8ec5e049f98edbc68d72cb05356f81d8" - integrity sha512-ttWB6ZCfRLuDIUiE0yiu5gcqOsYjA5F7kEV1ggHMj20FwLZ8A1FMeahZJFl/pnOmcnD2QL0z4AcDuo27utGU8A== - -"@rollup/rollup-darwin-arm64@4.16.1": - version "4.16.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.16.1.tgz#8fd277b4be6cc956167710e36b4ee365f8a44050" - integrity sha512-QLDvPLetbqjHojTGFw9+nuSP3YY/iz2k1cep6crYlr97sS+ZJ0W43b8Z0zC00+lnFZj6JSNxiA4DjboNQMuh1A== - -"@rollup/rollup-darwin-x64@4.16.1": - version "4.16.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.16.1.tgz#5ab829322926fefce42db3529649a1098b420fe3" - integrity sha512-TAUK/D8khRrRIa1KwRzo8JNKk3tcqaeXWdtsiLgA8zmACWwlWLjPCJ4DULGHQrMkeBjp1Cd3Yuwx04lZgFx5Vg== - -"@rollup/rollup-linux-arm-gnueabihf@4.16.1": - version "4.16.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.16.1.tgz#0154bc34e6a88fb0147adc827512add8d3a2338c" - integrity sha512-KO+WGZjrh6zyFTD1alIFkfdtxf8B4BC+hqd3kBZHscPLvE5FR/6QKsyuCT0JlERxxYBSUKNUQ/UHyX5uwO1x2A== - -"@rollup/rollup-linux-arm-musleabihf@4.16.1": - version "4.16.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.16.1.tgz#0f3fa433a81b389042555133d38b4b886b369e58" - integrity sha512-NqxbllzIB1WoAo4ThUXVtd21iiM5IHMTTXmXySKBLVcZvkU0HIZmatlP7hLzb5yQubcmdIeWmncd2NdsjocEiw== - -"@rollup/rollup-linux-arm64-gnu@4.16.1": - version "4.16.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.16.1.tgz#c8f2d523ac4bcff382601306989b27137d536dd6" - integrity sha512-snma5NvV8y7IECQ5rq0sr0f3UUu+92NVmG/913JXJMcXo84h9ak9TA5UI9Cl2XRM9j3m37QwDBtEYnJzRkSmxA== - -"@rollup/rollup-linux-arm64-musl@4.16.1": - version "4.16.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.16.1.tgz#86b5104635131182b6b2b6997c4aa5594ce557b7" - integrity sha512-KOvqGprlD84ueivhCi2flvcUwDRD20mAsE3vxQNVEI2Di9tnPGAfEu6UcrSPZbM+jG2w1oSr43hrPo0RNg6GGg== - -"@rollup/rollup-linux-powerpc64le-gnu@4.16.1": - version "4.16.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.16.1.tgz#5de8b20105aaaeb36eb86fab0a1020d81c7bd4d5" - integrity sha512-/gsNwtiGLqYwN4vP+EIdUC6Q6LTlpupWqokqIndvZcjn9ig/5P01WyaYCU2wvfL/2Z82jp5kX8c1mDBOvCP3zg== - -"@rollup/rollup-linux-riscv64-gnu@4.16.1": - version "4.16.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.16.1.tgz#5319629dcdcb85ba201c6f0f894c9472e7d1013d" - integrity sha512-uU8zuGkQfGqfD9w6VRJZI4IuG4JIfNxxJgEmLMAmPVHREKGsxFVfgHy5c6CexQF2vOfgjB33OsET3Vdn2lln9A== - -"@rollup/rollup-linux-s390x-gnu@4.16.1": - version "4.16.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.16.1.tgz#246ac211ed0d78f7a9bc5c1d0653bde4c6cd9f63" - integrity sha512-lsjLtDgtcGFEuBP6yrXwkRN5/wKlvUZtfbKZZu0yaoNpiBL4epgnO21osAALIspVRnl4qZgyLFd8xjCYYWgwfw== - -"@rollup/rollup-linux-x64-gnu@4.16.1": - version "4.16.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.16.1.tgz#d0c03203ddeb9454fc6fdde93a39b01c176ac6d9" - integrity sha512-N2ZizKhUryqqrMfdCnjhJhZRgv61C6gK+hwVtCIKC8ts8J+go+vqENnGexwg21nHIOvLN5mBM8a7DI2vlyIOPg== - -"@rollup/rollup-linux-x64-musl@4.16.1": - version "4.16.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.16.1.tgz#20235632e2be4689d663aadaceaaf90df03b1a33" - integrity sha512-5ICeMxqg66FrOA2AbnBQ2TJVxfvZsKLxmof0ibvPLaYtbsJqnTUtJOofgWb46Gjd4uZcA4rdsp4JCxegzQPqCg== - -"@rollup/rollup-win32-arm64-msvc@4.16.1": - version "4.16.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.16.1.tgz#af113ad682fc13d1f870242c5539031f8cc27cf1" - integrity sha512-1vIP6Ce02L+qWD7uZYRiFiuAJo3m9kARatWmFSnss0gZnVj2Id7OPUU9gm49JPGasgcR3xMqiH3fqBJ8t00yVg== - -"@rollup/rollup-win32-ia32-msvc@4.16.1": - version "4.16.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.16.1.tgz#4e7b57e757c95da8e79092056d1b428617515668" - integrity sha512-Y3M92DcVsT6LoP+wrKpoUWPaazaP1fzbNkp0a0ZSj5Y//+pQVfVe/tQdsYQQy7dwXR30ZfALUIc9PCh9Izir6w== - -"@rollup/rollup-win32-x64-msvc@4.16.1": - version "4.16.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.16.1.tgz#5068a893ba292279adbe76fc487316724b15d811" - integrity sha512-x0fvpHMuF7fK5r8oZxSi8VYXkrVmRgubXpO/wcf15Lk3xZ4Jvvh5oG+u7Su1776A7XzVKZhD2eRc4t7H50gL3w== +"@rollup/rollup-android-arm-eabi@4.22.4": + version "4.22.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.22.4.tgz#8b613b9725e8f9479d142970b106b6ae878610d5" + integrity sha512-Fxamp4aEZnfPOcGA8KSNEohV8hX7zVHOemC8jVBoBUHu5zpJK/Eu3uJwt6BMgy9fkvzxDaurgj96F/NiLukF2w== + +"@rollup/rollup-android-arm64@4.22.4": + version "4.22.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.22.4.tgz#654ca1049189132ff602bfcf8df14c18da1f15fb" + integrity sha512-VXoK5UMrgECLYaMuGuVTOx5kcuap1Jm8g/M83RnCHBKOqvPPmROFJGQaZhGccnsFtfXQ3XYa4/jMCJvZnbJBdA== + +"@rollup/rollup-darwin-arm64@4.22.4": + version "4.22.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.22.4.tgz#6d241d099d1518ef0c2205d96b3fa52e0fe1954b" + integrity sha512-xMM9ORBqu81jyMKCDP+SZDhnX2QEVQzTcC6G18KlTQEzWK8r/oNZtKuZaCcHhnsa6fEeOBionoyl5JsAbE/36Q== + +"@rollup/rollup-darwin-x64@4.22.4": + version "4.22.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.22.4.tgz#42bd19d292a57ee11734c980c4650de26b457791" + integrity sha512-aJJyYKQwbHuhTUrjWjxEvGnNNBCnmpHDvrb8JFDbeSH3m2XdHcxDd3jthAzvmoI8w/kSjd2y0udT+4okADsZIw== + +"@rollup/rollup-linux-arm-gnueabihf@4.22.4": + version "4.22.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.22.4.tgz#f23555ee3d8fe941c5c5fd458cd22b65eb1c2232" + integrity sha512-j63YtCIRAzbO+gC2L9dWXRh5BFetsv0j0va0Wi9epXDgU/XUi5dJKo4USTttVyK7fGw2nPWK0PbAvyliz50SCQ== + +"@rollup/rollup-linux-arm-musleabihf@4.22.4": + version "4.22.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.22.4.tgz#f3bbd1ae2420f5539d40ac1fde2b38da67779baa" + integrity sha512-dJnWUgwWBX1YBRsuKKMOlXCzh2Wu1mlHzv20TpqEsfdZLb3WoJW2kIEsGwLkroYf24IrPAvOT/ZQ2OYMV6vlrg== + +"@rollup/rollup-linux-arm64-gnu@4.22.4": + version "4.22.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.22.4.tgz#7abe900120113e08a1f90afb84c7c28774054d15" + integrity sha512-AdPRoNi3NKVLolCN/Sp4F4N1d98c4SBnHMKoLuiG6RXgoZ4sllseuGioszumnPGmPM2O7qaAX/IJdeDU8f26Aw== + +"@rollup/rollup-linux-arm64-musl@4.22.4": + version "4.22.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.22.4.tgz#9e655285c8175cd44f57d6a1e8e5dedfbba1d820" + integrity sha512-Gl0AxBtDg8uoAn5CCqQDMqAx22Wx22pjDOjBdmG0VIWX3qUBHzYmOKh8KXHL4UpogfJ14G4wk16EQogF+v8hmA== + +"@rollup/rollup-linux-powerpc64le-gnu@4.22.4": + version "4.22.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.22.4.tgz#9a79ae6c9e9d8fe83d49e2712ecf4302db5bef5e" + integrity sha512-3aVCK9xfWW1oGQpTsYJJPF6bfpWfhbRnhdlyhak2ZiyFLDaayz0EP5j9V1RVLAAxlmWKTDfS9wyRyY3hvhPoOg== + +"@rollup/rollup-linux-riscv64-gnu@4.22.4": + version "4.22.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.22.4.tgz#67ac70eca4ace8e2942fabca95164e8874ab8128" + integrity sha512-ePYIir6VYnhgv2C5Xe9u+ico4t8sZWXschR6fMgoPUK31yQu7hTEJb7bCqivHECwIClJfKgE7zYsh1qTP3WHUA== + +"@rollup/rollup-linux-s390x-gnu@4.22.4": + version "4.22.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.22.4.tgz#9f883a7440f51a22ed7f99e1d070bd84ea5005fc" + integrity sha512-GqFJ9wLlbB9daxhVlrTe61vJtEY99/xB3C8e4ULVsVfflcpmR6c8UZXjtkMA6FhNONhj2eA5Tk9uAVw5orEs4Q== + +"@rollup/rollup-linux-x64-gnu@4.22.4": + version "4.22.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.22.4.tgz#70116ae6c577fe367f58559e2cffb5641a1dd9d0" + integrity sha512-87v0ol2sH9GE3cLQLNEy0K/R0pz1nvg76o8M5nhMR0+Q+BBGLnb35P0fVz4CQxHYXaAOhE8HhlkaZfsdUOlHwg== + +"@rollup/rollup-linux-x64-musl@4.22.4": + version "4.22.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.22.4.tgz#f473f88219feb07b0b98b53a7923be716d1d182f" + integrity sha512-UV6FZMUgePDZrFjrNGIWzDo/vABebuXBhJEqrHxrGiU6HikPy0Z3LfdtciIttEUQfuDdCn8fqh7wiFJjCNwO+g== + +"@rollup/rollup-win32-arm64-msvc@4.22.4": + version "4.22.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.22.4.tgz#4349482d17f5d1c58604d1c8900540d676f420e0" + integrity sha512-BjI+NVVEGAXjGWYHz/vv0pBqfGoUH0IGZ0cICTn7kB9PyjrATSkX+8WkguNjWoj2qSr1im/+tTGRaY+4/PdcQw== + +"@rollup/rollup-win32-ia32-msvc@4.22.4": + version "4.22.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.22.4.tgz#a6fc39a15db618040ec3c2a24c1e26cb5f4d7422" + integrity sha512-SiWG/1TuUdPvYmzmYnmd3IEifzR61Tragkbx9D3+R8mzQqDBz8v+BvZNDlkiTtI9T15KYZhP0ehn3Dld4n9J5g== + +"@rollup/rollup-win32-x64-msvc@4.22.4": + version "4.22.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.22.4.tgz#3dd5d53e900df2a40841882c02e56f866c04d202" + integrity sha512-j8pPKp53/lq9lMXN57S8cFz0MynJk8OWNuUnXct/9KCpKU7DgU3bYMJhwWmcqC0UU29p8Lr0/7KEVcaM6bf47Q== "@rushstack/node-core-library@4.0.2": version "4.0.2" @@ -2841,27 +2894,27 @@ resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.0.0.tgz#109fb595021de285f05a7db6806f2f48296fcee7" integrity sha512-gIVaYhUsy+9s58m/ETjSJVKHhKTBMmcRb9cEV5/5dwvfDlfORjKrFsDeDHWRrm6RjcPvCLZFwGJjAjLj1gg4HA== -"@scure/base@~1.1.4": - version "1.1.5" - resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.5.tgz#1d85d17269fe97694b9c592552dd9e5e33552157" - integrity sha512-Brj9FiG2W1MRQSTB212YVPRrcbjkv48FoZi/u4l/zds/ieRrqsh7aUf6CLwkAq61oKXr/ZlTzlY66gLIj3TFTQ== +"@scure/base@~1.1.6": + version "1.1.8" + resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.8.tgz#8f23646c352f020c83bca750a82789e246d42b50" + integrity sha512-6CyAclxj3Nb0XT7GHK6K4zK6k2xJm6E4Ft0Ohjt4WgegiFUHEtFb2CGzmPmGBwoIhrLsqNLYfLr04Y1GePrzZg== -"@scure/bip32@1.3.3": - version "1.3.3" - resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.3.3.tgz#a9624991dc8767087c57999a5d79488f48eae6c8" - integrity sha512-LJaN3HwRbfQK0X1xFSi0Q9amqOgzQnnDngIt+ZlsBC3Bm7/nE7K0kwshZHyaru79yIVRv/e1mQAjZyuZG6jOFQ== +"@scure/bip32@1.4.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.4.0.tgz#4e1f1e196abedcef395b33b9674a042524e20d67" + integrity sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg== dependencies: - "@noble/curves" "~1.3.0" - "@noble/hashes" "~1.3.2" - "@scure/base" "~1.1.4" + "@noble/curves" "~1.4.0" + "@noble/hashes" "~1.4.0" + "@scure/base" "~1.1.6" -"@scure/bip39@1.2.2": - version "1.2.2" - resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.2.2.tgz#f3426813f4ced11a47489cbcf7294aa963966527" - integrity sha512-HYf9TUXG80beW+hGAt3TRM8wU6pQoYur9iNypTROm42dorCGmLnFe3eWjz3gOq6G62H2WRh0FCzAR1PI+29zIA== +"@scure/bip39@1.3.0": + version "1.3.0" + resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.3.0.tgz#0f258c16823ddd00739461ac31398b4e7d6a18c3" + integrity sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ== dependencies: - "@noble/hashes" "~1.3.2" - "@scure/base" "~1.1.4" + "@noble/hashes" "~1.4.0" + "@scure/base" "~1.1.6" "@scure/bip39@^1.0.0": version "1.0.0" @@ -2905,6 +2958,11 @@ resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.27.8.tgz#6667fac16c436b5434a387a34dedb013198f6e6e" integrity sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA== +"@sindresorhus/fnv1a@^3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/fnv1a/-/fnv1a-3.1.0.tgz#f8e46597298f6fd4c12dc901cdd4e73beb4d24fa" + integrity sha512-KV321z5m/0nuAg83W1dPLy85HpHDk7Sdi4fJbwvacWsEhAh+rZUW4ZfGcXmUIvjZg4ss2bcwNlRhJ7GBEUG08w== + "@sindresorhus/is@^4.0.0": version "4.6.0" resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.6.0.tgz#3c7c9c46e678feefe7a2e5bb609d3dbd665ffb3f" @@ -3184,21 +3242,6 @@ resolved "https://registry.yarnpkg.com/@types/js-yaml/-/js-yaml-4.0.5.tgz#738dd390a6ecc5442f35e7f03fa1431353f7e138" integrity sha512-FhpRzf927MNQdRZP0J5DLIdTXhjLYzeUTmLAu69mnVksLH9CJY3IuSeEgbKUki7GQZm0WqDkGzyxju2EZGD2wA== -"@types/json-schema@^7.0.12": - version "7.0.13" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.13.tgz#02c24f4363176d2d18fc8b70b9f3c54aba178a85" - integrity sha512-RbSSoHliUbnXj3ny0CNFOoxrIDV6SUGyStHsvDqosw6CkdPV8TtWGlfecuK4ToyMEAql6pzNxgCFKanovUzlgQ== - -"@types/json-schema@^7.0.15": - version "7.0.15" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" - integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== - -"@types/json5@^0.0.29": - version "0.0.29" - resolved "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz" - integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4= - "@types/keyv@^3.1.4": version "3.1.4" resolved "https://registry.yarnpkg.com/@types/keyv/-/keyv-3.1.4.tgz#3ccdb1c6751b0c7e52300bcdacd5bcbf8faa75b6" @@ -3234,6 +3277,11 @@ "@types/dns-packet" "*" "@types/node" "*" +"@types/murmurhash3js-revisited@^3.0.3": + version "3.0.3" + resolved "https://registry.yarnpkg.com/@types/murmurhash3js-revisited/-/murmurhash3js-revisited-3.0.3.tgz#94e247168a18342477639126da8f01353437e8d0" + integrity sha512-QvlqvYtGBYIDeO8dFdY4djkRubcrc+yTJtBc7n8VZPlJDUS/00A+PssbvERM8f9bYRmcaSEHPZgZojeQj7kzAA== + "@types/mute-stream@^0.0.4": version "0.0.4" resolved "https://registry.yarnpkg.com/@types/mute-stream/-/mute-stream-0.0.4.tgz#77208e56a08767af6c5e1237be8888e2f255c478" @@ -3272,11 +3320,11 @@ undici-types "~5.26.4" "@types/node@^20.12.8": - version "20.12.8" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.12.8.tgz#35897bf2bfe3469847ab04634636de09552e8256" - integrity sha512-NU0rJLJnshZWdE/097cdCBbyW1h4hEg0xpovcoAQYHl8dnEyp/NAOiE45pvc+Bd1Dt+2r94v2eGFpQJ4R7g+2w== + version "20.16.7" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.16.7.tgz#0a245bf5805add998a22b8b5adac612ee70190bc" + integrity sha512-QkDQjAY3gkvJNcZOWwzy3BN34RweT0OQ9zJyvLCU0kSK22dO2QYh/NHGfbEAYylPYzRB1/iXcojS79wOg5gFSw== dependencies: - undici-types "~5.26.4" + undici-types "~6.19.2" "@types/node@^20.14.11": version "20.14.11" @@ -3322,15 +3370,10 @@ resolved "https://registry.npmjs.org/@types/retry/-/retry-0.12.1.tgz" integrity sha512-xoDlM2S4ortawSWORYqsdU+2rxdh4LRW9ytc3zmT37RIKQh6IHyKwwtKhKis9ah8ol07DCkZxPt8BBvPjC6v4g== -"@types/semver@^7.5.0": - version "7.5.2" - resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.2.tgz#31f6eec1ed7ec23f4f05608d3a2d381df041f564" - integrity sha512-7aqorHYgdNO4DM36stTiGO3DvKoex9TQRwsJU6vMaFGyqpBA1MNZkz+PG3gaNUPpTAOYhT1WR7M1JyA3fbS9Cw== - -"@types/semver@^7.5.8": - version "7.5.8" - resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.8.tgz#8268a8c57a3e4abd25c165ecd36237db7948a55e" - integrity sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ== +"@types/retry@0.12.2": + version "0.12.2" + resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.2.tgz#ed279a64fa438bb69f2480eda44937912bb7480a" + integrity sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow== "@types/sinon@^17.0.3": version "17.0.3" @@ -3447,145 +3490,6 @@ dependencies: "@types/node" "*" -"@typescript-eslint/eslint-plugin@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.2.0.tgz#5a5fcad1a7baed85c10080d71ad901f98c38d5b7" - integrity sha512-mdekAHOqS9UjlmyF/LSs6AIEvfceV749GFxoBAjwAv0nkevfKHWQFDMcBZWUiIC5ft6ePWivXoS36aKQ0Cy3sw== - dependencies: - "@eslint-community/regexpp" "^4.5.1" - "@typescript-eslint/scope-manager" "7.2.0" - "@typescript-eslint/type-utils" "7.2.0" - "@typescript-eslint/utils" "7.2.0" - "@typescript-eslint/visitor-keys" "7.2.0" - debug "^4.3.4" - graphemer "^1.4.0" - ignore "^5.2.4" - natural-compare "^1.4.0" - semver "^7.5.4" - ts-api-utils "^1.0.1" - -"@typescript-eslint/parser@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-7.2.0.tgz#44356312aea8852a3a82deebdacd52ba614ec07a" - integrity sha512-5FKsVcHTk6TafQKQbuIVkXq58Fnbkd2wDL4LB7AURN7RUOu1utVP+G8+6u3ZhEroW3DF6hyo3ZEXxgKgp4KeCg== - dependencies: - "@typescript-eslint/scope-manager" "7.2.0" - "@typescript-eslint/types" "7.2.0" - "@typescript-eslint/typescript-estree" "7.2.0" - "@typescript-eslint/visitor-keys" "7.2.0" - debug "^4.3.4" - -"@typescript-eslint/scope-manager@7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-7.2.0.tgz#cfb437b09a84f95a0930a76b066e89e35d94e3da" - integrity sha512-Qh976RbQM/fYtjx9hs4XkayYujB/aPwglw2choHmf3zBjB4qOywWSdt9+KLRdHubGcoSwBnXUH2sR3hkyaERRg== - dependencies: - "@typescript-eslint/types" "7.2.0" - "@typescript-eslint/visitor-keys" "7.2.0" - -"@typescript-eslint/scope-manager@7.7.0": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-7.7.0.tgz#3f0db079b275bb8b0cb5be7613fb3130cfb5de77" - integrity sha512-/8INDn0YLInbe9Wt7dK4cXLDYp0fNHP5xKLHvZl3mOT5X17rK/YShXaiNmorl+/U4VKCVIjJnx4Ri5b0y+HClw== - dependencies: - "@typescript-eslint/types" "7.7.0" - "@typescript-eslint/visitor-keys" "7.7.0" - -"@typescript-eslint/type-utils@7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-7.2.0.tgz#7be5c30e9b4d49971b79095a1181324ef6089a19" - integrity sha512-xHi51adBHo9O9330J8GQYQwrKBqbIPJGZZVQTHHmy200hvkLZFWJIFtAG/7IYTWUyun6DE6w5InDReePJYJlJA== - dependencies: - "@typescript-eslint/typescript-estree" "7.2.0" - "@typescript-eslint/utils" "7.2.0" - debug "^4.3.4" - ts-api-utils "^1.0.1" - -"@typescript-eslint/types@7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-7.2.0.tgz#0feb685f16de320e8520f13cca30779c8b7c403f" - integrity sha512-XFtUHPI/abFhm4cbCDc5Ykc8npOKBSJePY3a3s+lwumt7XWJuzP5cZcfZ610MIPHjQjNsOLlYK8ASPaNG8UiyA== - -"@typescript-eslint/types@7.7.0": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-7.7.0.tgz#23af4d24bf9ce15d8d301236e3e3014143604f27" - integrity sha512-G01YPZ1Bd2hn+KPpIbrAhEWOn5lQBrjxkzHkWvP6NucMXFtfXoevK82hzQdpfuQYuhkvFDeQYbzXCjR1z9Z03w== - -"@typescript-eslint/typescript-estree@7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-7.2.0.tgz#5beda2876c4137f8440c5a84b4f0370828682556" - integrity sha512-cyxS5WQQCoBwSakpMrvMXuMDEbhOo9bNHHrNcEWis6XHx6KF518tkF1wBvKIn/tpq5ZpUYK7Bdklu8qY0MsFIA== - dependencies: - "@typescript-eslint/types" "7.2.0" - "@typescript-eslint/visitor-keys" "7.2.0" - debug "^4.3.4" - globby "^11.1.0" - is-glob "^4.0.3" - minimatch "9.0.3" - semver "^7.5.4" - ts-api-utils "^1.0.1" - -"@typescript-eslint/typescript-estree@7.7.0": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-7.7.0.tgz#b5dd6383b4c6a852d7b256a37af971e8982be97f" - integrity sha512-8p71HQPE6CbxIBy2kWHqM1KGrC07pk6RJn40n0DSc6bMOBBREZxSDJ+BmRzc8B5OdaMh1ty3mkuWRg4sCFiDQQ== - dependencies: - "@typescript-eslint/types" "7.7.0" - "@typescript-eslint/visitor-keys" "7.7.0" - debug "^4.3.4" - globby "^11.1.0" - is-glob "^4.0.3" - minimatch "^9.0.4" - semver "^7.6.0" - ts-api-utils "^1.3.0" - -"@typescript-eslint/utils@7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-7.2.0.tgz#fc8164be2f2a7068debb4556881acddbf0b7ce2a" - integrity sha512-YfHpnMAGb1Eekpm3XRK8hcMwGLGsnT6L+7b2XyRv6ouDuJU1tZir1GS2i0+VXRatMwSI1/UfcyPe53ADkU+IuA== - dependencies: - "@eslint-community/eslint-utils" "^4.4.0" - "@types/json-schema" "^7.0.12" - "@types/semver" "^7.5.0" - "@typescript-eslint/scope-manager" "7.2.0" - "@typescript-eslint/types" "7.2.0" - "@typescript-eslint/typescript-estree" "7.2.0" - semver "^7.5.4" - -"@typescript-eslint/utils@^7.1.1": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-7.7.0.tgz#3d2b6606a60ac34f3c625facfb3b3ab7e126f58d" - integrity sha512-LKGAXMPQs8U/zMRFXDZOzmMKgFv3COlxUQ+2NMPhbqgVm6R1w+nU1i4836Pmxu9jZAuIeyySNrN/6Rc657ggig== - dependencies: - "@eslint-community/eslint-utils" "^4.4.0" - "@types/json-schema" "^7.0.15" - "@types/semver" "^7.5.8" - "@typescript-eslint/scope-manager" "7.7.0" - "@typescript-eslint/types" "7.7.0" - "@typescript-eslint/typescript-estree" "7.7.0" - semver "^7.6.0" - -"@typescript-eslint/visitor-keys@7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-7.2.0.tgz#5035f177752538a5750cca1af6044b633610bf9e" - integrity sha512-c6EIQRHhcpl6+tO8EMR+kjkkV+ugUNXOmeASA1rlzkd8EPIriavpWoiEz1HR/VLhbVIdhqnV6E7JZm00cBDx2A== - dependencies: - "@typescript-eslint/types" "7.2.0" - eslint-visitor-keys "^3.4.1" - -"@typescript-eslint/visitor-keys@7.7.0": - version "7.7.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-7.7.0.tgz#950148cf1ac11562a2d903fdf7acf76714a2dc9e" - integrity sha512-h0WHOj8MhdhY8YWkzIF30R379y0NqyOHExI9N9KCzvmu05EgG4FumeYa3ccfKUSphyWkWQE1ybVrgz/Pbam6YA== - dependencies: - "@typescript-eslint/types" "7.7.0" - eslint-visitor-keys "^3.4.3" - -"@ungap/structured-clone@^1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz#756641adb587851b5ccb3e095daf27ae581c8406" - integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ== - "@vitest/browser@^2.0.4": version "2.0.4" resolved "https://registry.yarnpkg.com/@vitest/browser/-/browser-2.0.4.tgz#6569258b4a8085f348007acd5ecf61db4eec4340" @@ -3853,16 +3757,24 @@ abstract-level@^1.0.0, abstract-level@^1.0.2, abstract-level@^1.0.3: module-error "^1.0.1" queue-microtask "^1.2.3" +abstract-level@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/abstract-level/-/abstract-level-1.0.4.tgz#3ad8d684c51cc9cbc9cf9612a7100b716c414b57" + integrity sha512-eUP/6pbXBkMbXFdx4IH2fVgvB7M0JvR7/lIL33zcs0IBcwjdzSSl31TOJsaCzmKSSDF9h8QYSOJux4Nd4YJqFg== + dependencies: + buffer "^6.0.3" + catering "^2.1.0" + is-buffer "^2.0.5" + level-supports "^4.0.0" + level-transcoder "^1.0.1" + module-error "^1.0.1" + queue-microtask "^1.2.3" + abstract-logging@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/abstract-logging/-/abstract-logging-2.0.1.tgz#6b0c371df212db7129b57d2e7fcf282b8bf1c839" integrity sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA== -acorn-jsx@^5.3.2: - version "5.3.2" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" - integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== - acorn-walk@^8.1.1: version "8.2.0" resolved "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz" @@ -3873,11 +3785,6 @@ acorn@^8.4.1: resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.1.tgz#0197122c843d1bf6d0a5e83220a788f278f63c30" integrity sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A== -acorn@^8.9.0: - version "8.10.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" - integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== - add-stream@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/add-stream/-/add-stream-1.0.0.tgz#6a7990437ca736d5e1288db92bd3266d5f5cb2aa" @@ -3931,16 +3838,6 @@ ajv-formats@^3.0.1: dependencies: ajv "^8.0.0" -ajv@^6.12.4, ajv@~6.12.6: - version "6.12.6" - resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz" - integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== - dependencies: - fast-deep-equal "^3.1.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" - uri-js "^4.2.2" - ajv@^8.0.0, ajv@^8.12.0: version "8.12.0" resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.12.0.tgz#d1a0527323e22f53562c567c00991577dfbe19d1" @@ -3961,6 +3858,16 @@ ajv@^8.6.0: require-from-string "^2.0.2" uri-js "^4.2.2" +ajv@~6.12.6: + version "6.12.6" + resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + ansi-colors@4.1.1: version "4.1.1" resolved "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz" @@ -4147,64 +4054,11 @@ array-ify@^1.0.0: resolved "https://registry.yarnpkg.com/array-ify/-/array-ify-1.0.0.tgz#9e528762b4a9066ad163a6962a364418e9626ece" integrity sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng== -array-includes@^3.1.7: - version "3.1.7" - resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.7.tgz#8cd2e01b26f7a3086cbc87271593fe921c62abda" - integrity sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - get-intrinsic "^1.2.1" - is-string "^1.0.7" - array-union@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== -array.prototype.filter@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/array.prototype.filter/-/array.prototype.filter-1.0.3.tgz#423771edeb417ff5914111fff4277ea0624c0d0e" - integrity sha512-VizNcj/RGJiUyQBgzwxzE5oHdeuXY5hSbbmKMlphj1cy1Vl7Pn2asCGbSrru6hSQjmCzqTBPVWAF/whmEOVHbw== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - es-array-method-boxes-properly "^1.0.0" - is-string "^1.0.7" - -array.prototype.findlastindex@^1.2.3: - version "1.2.4" - resolved "https://registry.yarnpkg.com/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.4.tgz#d1c50f0b3a9da191981ff8942a0aedd82794404f" - integrity sha512-hzvSHUshSpCflDR1QMUBLHGHP1VIEBegT4pix9H/Z92Xw3ySoy6c2qh7lJWTJnRJ8JCZ9bJNCgTyYaJGcJu6xQ== - dependencies: - call-bind "^1.0.5" - define-properties "^1.2.1" - es-abstract "^1.22.3" - es-errors "^1.3.0" - es-shim-unscopables "^1.0.2" - -array.prototype.flat@^1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz#1476217df8cff17d72ee8f3ba06738db5b387d18" - integrity sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - es-shim-unscopables "^1.0.0" - -array.prototype.flatmap@^1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz#c9a7c6831db8e719d6ce639190146c24bbd3e527" - integrity sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - es-shim-unscopables "^1.0.0" - arraybuffer.prototype.slice@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz#98bd561953e3e74bb34938e77647179dfe6e9f12" @@ -5471,7 +5325,7 @@ cross-spawn@^6.0.5: shebang-command "^1.2.0" which "^1.2.9" -cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: +cross-spawn@^7.0.0, cross-spawn@^7.0.3: version "7.0.3" resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz" integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== @@ -5547,15 +5401,14 @@ data-urls@^5.0.0: whatwg-mimetype "^4.0.0" whatwg-url "^14.0.0" -datastore-core@^9.0.0, datastore-core@^9.1.1, datastore-core@^9.2.9: - version "9.2.9" - resolved "https://registry.yarnpkg.com/datastore-core/-/datastore-core-9.2.9.tgz#74b4dd53d4597b59038488ba5f92a7f81769f8df" - integrity sha512-wraWTPsbtdE7FFaVo3pwPuTB/zXsgwGGAm8BgBYwYAuzZCTS0MfXmd/HH1vR9s0/NFFjOVmBkGiWCvKxZ+QjVw== +datastore-core@10.0.0, datastore-core@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/datastore-core/-/datastore-core-10.0.0.tgz#86abe346338e88c3326fb7aeb90eff3613cf542f" + integrity sha512-/b5KDmSAIFizS/ZzTTU+ZdfOcQc6mRmbc4/EK/WOzbEO5c0KWyjRLsZ3DWwh9wiPu93V7pX1oC+Or61k8UPPsg== dependencies: "@libp2p/logger" "^4.0.6" - err-code "^3.0.1" interface-datastore "^8.0.0" - interface-store "^5.0.0" + interface-store "6.0.0" it-drain "^3.0.5" it-filter "^3.0.4" it-map "^3.0.5" @@ -5565,18 +5418,19 @@ datastore-core@^9.0.0, datastore-core@^9.1.1, datastore-core@^9.2.9: it-sort "^3.0.4" it-take "^3.0.4" -datastore-level@*, datastore-level@^10.1.1: - version "10.1.1" - resolved "https://registry.yarnpkg.com/datastore-level/-/datastore-level-10.1.1.tgz#390dc6ca17dc691947a3e81c984b4b6064812e81" - integrity sha512-4fQPf/6fIXdcC0XZPGMiNuoOmF82Vhdz+LPTmbzR+CbbnCri6eOcFdzBPnDsAAuPOCV6Zld1EhgM2cRArw1+sQ== +datastore-level@*, datastore-level@^11.0.0: + version "11.0.0" + resolved "https://registry.yarnpkg.com/datastore-level/-/datastore-level-11.0.0.tgz#c0f7324bd74e15bec01f2911f5740fbf59c344f7" + integrity sha512-ATSEfGoWTAHgDeZaYukeHu0FgyhjW3FKUw3XtcIpfBl4UF2kLNnYRBfzCeH+3RA0QaZvbSWpgYk6Gwf7m1oCtg== dependencies: - datastore-core "^9.0.0" + datastore-core "10.0.0" interface-datastore "^8.0.0" - it-filter "^3.0.0" - it-map "^3.0.1" - it-sort "^3.0.1" - it-take "^3.0.1" - level "^8.0.0" + interface-store "6.0.0" + it-filter "^3.0.4" + it-map "^3.0.5" + it-sort "^3.0.4" + it-take "^3.0.4" + level "^8.0.1" dateformat@^3.0.3: version "3.0.3" @@ -5588,20 +5442,13 @@ de-indent@^1.0.2: resolved "https://registry.yarnpkg.com/de-indent/-/de-indent-1.0.2.tgz#b2038e846dc33baa5796128d0804b455b8c1e21d" integrity sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg== -debug@4, debug@4.3.4, debug@^4.1.0, debug@^4.1.1, debug@^4.2.0, debug@^4.3.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4: +debug@4, debug@4.3.4, debug@^4.1.0, debug@^4.1.1, debug@^4.2.0, debug@^4.3.1, debug@^4.3.3, debug@^4.3.4: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== dependencies: ms "2.1.2" -debug@^3.2.7: - version "3.2.7" - resolved "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz" - integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== - dependencies: - ms "^2.1.1" - debug@^4.3.5: version "4.3.5" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.5.tgz#e83444eceb9fedd4a1da56d671ae2446a01a6e1e" @@ -5609,6 +5456,13 @@ debug@^4.3.5: dependencies: ms "2.1.2" +debug@^4.3.6: + version "4.3.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.7.tgz#87945b4151a011d76d95a198d7111c865c360a52" + integrity sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ== + dependencies: + ms "^2.1.3" + decamelize-keys@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/decamelize-keys/-/decamelize-keys-1.1.0.tgz#d171a87933252807eb3cb61dc1c1445d078df2d9" @@ -5654,11 +5508,6 @@ deep-eql@^5.0.1: resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-5.0.2.tgz#4b756d8d770a9257300825d52a2c2cff99c3a341" integrity sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q== -deep-is@^0.1.3: - version "0.1.3" - resolved "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz" - integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= - deepmerge-ts@^5.0.0, deepmerge-ts@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/deepmerge-ts/-/deepmerge-ts-5.1.0.tgz#c55206cc4c7be2ded89b9c816cf3608884525d7a" @@ -5695,7 +5544,7 @@ define-lazy-prop@^2.0.0: resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== -define-properties@^1.1.3, define-properties@^1.1.4, define-properties@^1.2.0, define-properties@^1.2.1: +define-properties@^1.1.3, define-properties@^1.1.4, define-properties@^1.2.0: version "1.2.1" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.1.tgz#10781cc616eb951a80a034bafcaa7377f6af2b6c" integrity sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg== @@ -5870,20 +5719,6 @@ dockerode@^3.3.5: docker-modem "^3.0.0" tar-fs "~2.0.1" -doctrine@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz" - integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== - dependencies: - esutils "^2.0.2" - -doctrine@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz" - integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== - dependencies: - esutils "^2.0.2" - dom-accessibility-api@^0.5.9: version "0.5.16" resolved "https://registry.yarnpkg.com/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz#5a7429e6066eb3664d911e33fb0e45de8eb08453" @@ -6016,14 +5851,6 @@ end-of-stream@^1.1.0, end-of-stream@^1.4.1: dependencies: once "^1.4.0" -enhanced-resolve@^5.12.0: - version "5.15.0" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz#1af946c7d93603eb88e9896cee4904dc012e9c35" - integrity sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg== - dependencies: - graceful-fs "^4.2.4" - tapable "^2.2.0" - enquirer@~2.3.6: version "2.3.6" resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" @@ -6063,7 +5890,7 @@ error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" -es-abstract@^1.18.0-next.2, es-abstract@^1.22.1, es-abstract@^1.22.3: +es-abstract@^1.18.0-next.2, es-abstract@^1.22.1: version "1.22.3" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.22.3.tgz#48e79f5573198de6dee3589195727f4f74bc4f32" integrity sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA== @@ -6108,16 +5935,6 @@ es-abstract@^1.18.0-next.2, es-abstract@^1.22.1, es-abstract@^1.22.3: unbox-primitive "^1.0.2" which-typed-array "^1.1.13" -es-array-method-boxes-properly@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz#873f3e84418de4ee19c5be752990b2e44718d09e" - integrity sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA== - -es-errors@^1.0.0, es-errors@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f" - integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== - es-set-tostringtag@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz#338d502f6f674301d710b80c8592de8a15f09cd8" @@ -6127,20 +5944,6 @@ es-set-tostringtag@^2.0.1: has "^1.0.3" has-tostringtag "^1.0.0" -es-shim-unscopables@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz#702e632193201e3edf8713635d083d378e510241" - integrity sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w== - dependencies: - has "^1.0.3" - -es-shim-unscopables@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz#1f6942e71ecc7835ed1c8a83006d8771a63a3763" - integrity sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw== - dependencies: - hasown "^2.0.0" - es-to-primitive@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" @@ -6225,191 +6028,17 @@ escodegen@^2.1.0: optionalDependencies: source-map "~0.6.1" -eslint-import-resolver-node@^0.3.9: - version "0.3.9" - resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz#d4eaac52b8a2e7c3cd1903eb00f7e053356118ac" - integrity sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g== - dependencies: - debug "^3.2.7" - is-core-module "^2.13.0" - resolve "^1.22.4" - -eslint-import-resolver-typescript@^3.6.1: - version "3.6.1" - resolved "https://registry.yarnpkg.com/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.6.1.tgz#7b983680edd3f1c5bce1a5829ae0bc2d57fe9efa" - integrity sha512-xgdptdoi5W3niYeuQxKmzVDTATvLYqhpwmykwsh7f6HIOStGWEIL9iqZgQDF9u9OEzrRwR8no5q2VT+bjAujTg== - dependencies: - debug "^4.3.4" - enhanced-resolve "^5.12.0" - eslint-module-utils "^2.7.4" - fast-glob "^3.3.1" - get-tsconfig "^4.5.0" - is-core-module "^2.11.0" - is-glob "^4.0.3" - -eslint-module-utils@^2.7.4: - version "2.7.4" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.7.4.tgz#4f3e41116aaf13a20792261e61d3a2e7e0583974" - integrity sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA== - dependencies: - debug "^3.2.7" - -eslint-module-utils@^2.8.0: - version "2.8.0" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz#e439fee65fc33f6bba630ff621efc38ec0375c49" - integrity sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw== - dependencies: - debug "^3.2.7" - -eslint-plugin-es@^4.1.0: - version "4.1.0" - resolved "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-4.1.0.tgz" - integrity sha512-GILhQTnjYE2WorX5Jyi5i4dz5ALWxBIdQECVQavL6s7cI76IZTDWleTHkxz/QT3kvcs2QlGHvKLYsSlPOlPXnQ== - dependencies: - eslint-utils "^2.0.0" - regexpp "^3.0.0" - -eslint-plugin-import@^2.29.1: - version "2.29.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz#d45b37b5ef5901d639c15270d74d46d161150643" - integrity sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw== - dependencies: - array-includes "^3.1.7" - array.prototype.findlastindex "^1.2.3" - array.prototype.flat "^1.3.2" - array.prototype.flatmap "^1.3.2" - debug "^3.2.7" - doctrine "^2.1.0" - eslint-import-resolver-node "^0.3.9" - eslint-module-utils "^2.8.0" - hasown "^2.0.0" - is-core-module "^2.13.1" - is-glob "^4.0.3" - minimatch "^3.1.2" - object.fromentries "^2.0.7" - object.groupby "^1.0.1" - object.values "^1.1.7" - semver "^6.3.1" - tsconfig-paths "^3.15.0" - -eslint-plugin-prettier@^5.1.3: - version "5.1.3" - resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-5.1.3.tgz#17cfade9e732cef32b5f5be53bd4e07afd8e67e1" - integrity sha512-C9GCVAs4Eq7ZC/XFQHITLiHJxQngdtraXaM+LoUFoFp/lHNl2Zn8f3WQbe9HvTBBQ9YnKFB0/2Ajdqwo5D1EAw== - dependencies: - prettier-linter-helpers "^1.0.0" - synckit "^0.8.6" - -eslint-plugin-vitest@^0.3.26: - version "0.3.26" - resolved "https://registry.yarnpkg.com/eslint-plugin-vitest/-/eslint-plugin-vitest-0.3.26.tgz#0906893c1f8f7094614fc6ff255c0a369cfbf427" - integrity sha512-oxe5JSPgRjco8caVLTh7Ti8PxpwJdhSV0hTQAmkFcNcmy/9DnqLB/oNVRA11RmVRP//2+jIIT6JuBEcpW3obYg== - dependencies: - "@typescript-eslint/utils" "^7.1.1" - -eslint-scope@^7.2.2: - version "7.2.2" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.2.tgz#deb4f92563390f32006894af62a22dba1c46423f" - integrity sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg== - dependencies: - esrecurse "^4.3.0" - estraverse "^5.2.0" - -eslint-utils@^2.0.0: - version "2.1.0" - resolved "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz" - integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg== - dependencies: - eslint-visitor-keys "^1.1.0" - -eslint-visitor-keys@^1.1.0: - version "1.3.0" - resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz" - integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== - -eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.3: - version "3.4.3" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800" - integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== - -eslint@^8.57.0: - version "8.57.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.57.0.tgz#c786a6fd0e0b68941aaf624596fb987089195668" - integrity sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ== - dependencies: - "@eslint-community/eslint-utils" "^4.2.0" - "@eslint-community/regexpp" "^4.6.1" - "@eslint/eslintrc" "^2.1.4" - "@eslint/js" "8.57.0" - "@humanwhocodes/config-array" "^0.11.14" - "@humanwhocodes/module-importer" "^1.0.1" - "@nodelib/fs.walk" "^1.2.8" - "@ungap/structured-clone" "^1.2.0" - ajv "^6.12.4" - chalk "^4.0.0" - cross-spawn "^7.0.2" - debug "^4.3.2" - doctrine "^3.0.0" - escape-string-regexp "^4.0.0" - eslint-scope "^7.2.2" - eslint-visitor-keys "^3.4.3" - espree "^9.6.1" - esquery "^1.4.2" - esutils "^2.0.2" - fast-deep-equal "^3.1.3" - file-entry-cache "^6.0.1" - find-up "^5.0.0" - glob-parent "^6.0.2" - globals "^13.19.0" - graphemer "^1.4.0" - ignore "^5.2.0" - imurmurhash "^0.1.4" - is-glob "^4.0.0" - is-path-inside "^3.0.3" - js-yaml "^4.1.0" - json-stable-stringify-without-jsonify "^1.0.1" - levn "^0.4.1" - lodash.merge "^4.6.2" - minimatch "^3.1.2" - natural-compare "^1.4.0" - optionator "^0.9.3" - strip-ansi "^6.0.1" - text-table "^0.2.0" - esm@^3.2.25: version "3.2.25" resolved "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz" integrity sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA== -espree@^9.6.0, espree@^9.6.1: - version "9.6.1" - resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f" - integrity sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ== - dependencies: - acorn "^8.9.0" - acorn-jsx "^5.3.2" - eslint-visitor-keys "^3.4.1" - esprima@^4.0.0, esprima@^4.0.1: version "4.0.1" resolved "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== -esquery@^1.4.2: - version "1.5.0" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.5.0.tgz#6ce17738de8577694edd7361c57182ac8cb0db0b" - integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg== - dependencies: - estraverse "^5.1.0" - -esrecurse@^4.3.0: - version "4.3.0" - resolved "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz" - integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== - dependencies: - estraverse "^5.2.0" - -estraverse@^5.1.0, estraverse@^5.2.0: +estraverse@^5.2.0: version "5.2.0" resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz" integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ== @@ -6431,15 +6060,15 @@ esutils@^2.0.2: resolved "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== -ethereum-cryptography@^2.0.0, ethereum-cryptography@^2.1.3: - version "2.1.3" - resolved "https://registry.yarnpkg.com/ethereum-cryptography/-/ethereum-cryptography-2.1.3.tgz#1352270ed3b339fe25af5ceeadcf1b9c8e30768a" - integrity sha512-BlwbIL7/P45W8FGW2r7LGuvoEZ+7PWsniMvQ4p5s2xCyw9tmaDlpfsN9HjAucbF+t/qpVHwZUisgfK24TCW8aA== +ethereum-cryptography@^2.0.0, ethereum-cryptography@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ethereum-cryptography/-/ethereum-cryptography-2.2.1.tgz#58f2810f8e020aecb97de8c8c76147600b0b8ccf" + integrity sha512-r/W8lkHSiTLxUxW8Rf3u4HGB0xQweG2RyETjywylKZSzLWoWAijRz8WCuOtJ6wah+avllXBqZuk29HCCvhEIRg== dependencies: - "@noble/curves" "1.3.0" - "@noble/hashes" "1.3.3" - "@scure/bip32" "1.3.3" - "@scure/bip39" "1.2.2" + "@noble/curves" "1.4.2" + "@noble/hashes" "1.4.0" + "@scure/bip32" "1.4.0" + "@scure/bip39" "1.3.0" ethers@^5.7.1: version "5.7.2" @@ -6613,17 +6242,12 @@ fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== -fast-diff@^1.1.2: - version "1.2.0" - resolved "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz" - integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w== - fast-fifo@^1.1.0, fast-fifo@^1.2.0: version "1.3.2" resolved "https://registry.yarnpkg.com/fast-fifo/-/fast-fifo-1.3.2.tgz#286e31de96eb96d38a97899815740ba2a4f3640c" integrity sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ== -fast-glob@^3.2.9, fast-glob@^3.3.1: +fast-glob@^3.2.9: version "3.3.2" resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129" integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow== @@ -6652,11 +6276,6 @@ fast-json-stringify@^6.0.0: json-schema-ref-resolver "^1.0.1" rfdc "^1.2.0" -fast-levenshtein@^2.0.6: - version "2.0.6" - resolved "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz" - integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= - fast-querystring@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/fast-querystring/-/fast-querystring-1.1.1.tgz#f4c56ef56b1a954880cfd8c01b83f9e1a3d3fda2" @@ -6759,13 +6378,6 @@ figures@^5.0.0: escape-string-regexp "^5.0.0" is-unicode-supported "^1.2.0" -file-entry-cache@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" - integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== - dependencies: - flat-cache "^3.0.4" - file-stream-rotator@^0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/file-stream-rotator/-/file-stream-rotator-0.6.1.tgz#007019e735b262bb6c6f0197e58e5c87cb96cec3" @@ -6839,24 +6451,11 @@ find-up@^6.3.0: locate-path "^7.1.0" path-exists "^5.0.0" -flat-cache@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" - integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== - dependencies: - flatted "^3.1.0" - rimraf "^3.0.2" - flat@^5.0.2: version "5.0.2" resolved "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz" integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== -flatted@^3.1.0: - version "3.2.5" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.5.tgz#76c8584f4fc843db64702a6bd04ab7a8bd666da3" - integrity sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg== - fn.name@1.x.x: version "1.1.0" resolved "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz" @@ -7158,13 +6757,6 @@ get-symbol-description@^1.0.0: call-bind "^1.0.2" get-intrinsic "^1.1.1" -get-tsconfig@^4.5.0: - version "4.6.2" - resolved "https://registry.yarnpkg.com/get-tsconfig/-/get-tsconfig-4.6.2.tgz#831879a5e6c2aa24fe79b60340e2233a1e0f472e" - integrity sha512-E5XrT4CbbXcXWy+1jChlZmrmCwd5KGx502kDCXJJ7y898TtWW9FwoG5HfOLVRKmlmDGkWN2HM9Ho+/Y8F0sJDg== - dependencies: - resolve-pkg-maps "^1.0.0" - get-uri@^6.0.1: version "6.0.2" resolved "https://registry.yarnpkg.com/get-uri/-/get-uri-6.0.2.tgz#e019521646f4a8ff6d291fbaea2c46da204bb75b" @@ -7229,13 +6821,6 @@ glob-parent@5.1.2, glob-parent@^5.1.2, glob-parent@~5.1.2: dependencies: is-glob "^4.0.1" -glob-parent@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" - integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== - dependencies: - is-glob "^4.0.3" - glob@7.1.4: version "7.1.4" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.4.tgz#aa608a2f6c577ad357e1ae5a5c26d9a8d1969255" @@ -7351,13 +6936,6 @@ global-agent@^3.0.0: semver "^7.3.2" serialize-error "^7.0.1" -globals@^13.19.0: - version "13.20.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-13.20.0.tgz#ea276a1e508ffd4f1612888f9d1bad1e2717bf82" - integrity sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ== - dependencies: - type-fest "^0.20.2" - globalthis@^1.0.1, globalthis@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.3.tgz#5852882a52b80dc301b0660273e1ed082f0b6ccf" @@ -7365,7 +6943,7 @@ globalthis@^1.0.1, globalthis@^1.0.3: dependencies: define-properties "^1.1.3" -globby@11.1.0, globby@^11.1.0: +globby@11.1.0: version "11.1.0" resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== @@ -7428,11 +7006,6 @@ grapheme-splitter@^1.0.2: resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e" integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ== -graphemer@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" - integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== - graphql@^16.8.1: version "16.9.0" resolved "https://registry.yarnpkg.com/graphql/-/graphql-16.9.0.tgz#1c310e63f16a49ce1fbb230bd0a000e99f6f115f" @@ -7748,7 +7321,7 @@ ignore-walk@^6.0.0: dependencies: minimatch "^7.4.2" -ignore@^5.0.4, ignore@^5.1.1, ignore@^5.2.0, ignore@^5.2.4: +ignore@^5.0.4, ignore@^5.2.0: version "5.3.0" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.0.tgz#67418ae40d34d6999c95ff56016759c718c82f78" integrity sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg== @@ -7758,7 +7331,7 @@ immutable@^4.3.2: resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.3.5.tgz#f8b436e66d59f99760dc577f5c99a4fd2a5cc5a0" integrity sha512-8eabxkth9gZatlwl5TBuJnCsoTADlL6ftEr7A4qgdaTsPyreilDSnUk57SO+jfKcNtxPa22U5KK6DSeAYhpBJw== -import-fresh@^3.2.1, import-fresh@^3.3.0: +import-fresh@^3.3.0: version "3.3.0" resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz" integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== @@ -7882,18 +7455,18 @@ inquirer@^9.1.5: through "^2.3.6" wrap-ansi "^8.1.0" -interface-datastore@^8.0.0, interface-datastore@^8.2.11, interface-datastore@^8.2.7: - version "8.2.11" - resolved "https://registry.yarnpkg.com/interface-datastore/-/interface-datastore-8.2.11.tgz#1d555ce6218ab6cba6291fc361debe9713590207" - integrity sha512-9E0iXehfp/j0UbZ2mvlYB4K9pP7uQBCppfuy8WHs1EHF6wLQrM9+zwyX+8Qt6HnH4GKZRyXX/CNXm6oD4+QYgA== +interface-datastore@^8.0.0, interface-datastore@^8.2.11, interface-datastore@^8.3.0: + version "8.3.0" + resolved "https://registry.yarnpkg.com/interface-datastore/-/interface-datastore-8.3.0.tgz#0ce9a2f0f61f9fbe1c1734c6d10a0265193689f7" + integrity sha512-RM/rTSmRcnoCwGZIHrPm+nlGYVoT4R0lcFvNnDyhdFT4R6BuHHhfFP47UldVEjs98SfxLuMhaNMsyjI918saHw== dependencies: - interface-store "^5.0.0" + interface-store "6.0.0" uint8arrays "^5.0.2" -interface-store@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/interface-store/-/interface-store-5.1.0.tgz#1735cead844fe452d62c307fafbaaa1d261e6ff3" - integrity sha512-mjUwX3XSoreoxCS3sXS3pSRsGnUjl9T06KBqt/T7AgE9Sgp4diH64ZyURJKnj2T5WmCvTbC0Dm+mwQV5hfLSBQ== +interface-store@6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/interface-store/-/interface-store-6.0.0.tgz#8d8277a582f69d819134e125b686e147099a4728" + integrity sha512-HkjsDPsjA7SKkCr+TH1elUQApAAM3X3JPwrz3vFzaf614wI+ZD6GVvwKGZCHYcbSRqeZP/uzVPqezzeISeo5kA== internal-slot@^1.0.5: version "1.0.5" @@ -7984,7 +7557,7 @@ is-ci@3.0.1: dependencies: ci-info "^3.2.0" -is-core-module@^2.1.0, is-core-module@^2.11.0, is-core-module@^2.13.0, is-core-module@^2.13.1, is-core-module@^2.3.0, is-core-module@^2.5.0, is-core-module@^2.8.1: +is-core-module@^2.1.0, is-core-module@^2.13.0, is-core-module@^2.5.0, is-core-module@^2.8.1: version "2.13.1" resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.1.tgz#ad0d7532c6fea9da1ebdc82742d74525c6273384" integrity sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw== @@ -8023,7 +7596,7 @@ is-generator-function@^1.0.7: resolved "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.8.tgz" integrity sha512-2Omr/twNtufVZFr1GhxjOMFPAj2sjc/dKaIqBhvo4qciXfJmITGH6ZGd8eZYNHza8t1y0e01AuqRhJwfWp26WQ== -is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: +is-glob@^4.0.1, is-glob@~4.0.1: version "4.0.3" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== @@ -8079,6 +7652,11 @@ is-negative-zero@^2.0.2: resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150" integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA== +is-network-error@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-network-error/-/is-network-error-1.1.0.tgz#d26a760e3770226d11c169052f266a4803d9c997" + integrity sha512-tUdRRAnhT+OtCZR/LxZelH/C7QtjtFrTu5tXCA8pl55eTUElUHT+GPYV8MBMBvea/j+NxQqVt3LbWMRir7Gx9g== + is-node-process@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/is-node-process/-/is-node-process-1.2.0.tgz#ea02a1b90ddb3934a19aea414e88edef7e11d134" @@ -8106,11 +7684,6 @@ is-observable@^2.1.0: resolved "https://registry.npmjs.org/is-observable/-/is-observable-2.1.0.tgz" integrity sha512-DailKdLb0WU+xX8K5w7VsJhapwHLZ9jjmazqCJq4X12CTgqq73TKnbRcnSLuXYPOoLQgV5IrD7ePiX/h1vnkBw== -is-path-inside@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" - integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== - is-plain-obj@^1.0.0, is-plain-obj@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" @@ -8308,6 +7881,11 @@ it-all@^3.0.0, it-all@^3.0.4: resolved "https://registry.yarnpkg.com/it-all/-/it-all-3.0.4.tgz#08f2e3eb3df04fa4525a343dcacfbdf91ffee162" integrity sha512-UMiy0i9DqCHBdWvMbzdYvVGa5/w4t1cc4nchpbnjdLhklglv8mQeEYnii0gvKESJuL1zV32Cqdb33R6/GPfxpQ== +it-all@^3.0.6: + version "3.0.6" + resolved "https://registry.yarnpkg.com/it-all/-/it-all-3.0.6.tgz#30a4f922ae9ca0945b0f720d3478ae6f5b6707ab" + integrity sha512-HXZWbxCgQZJfrv5rXvaVeaayXED8nTKx9tj9fpBhmcUJcedVZshMMMqTj0RG2+scGypb9Ut1zd1ifbf3lA8L+Q== + it-byte-stream@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/it-byte-stream/-/it-byte-stream-1.0.0.tgz#07645e1c94444760bc7abecebf187b83777b0351" @@ -8317,29 +7895,38 @@ it-byte-stream@^1.0.0: it-stream-types "^2.0.1" uint8arraylist "^2.4.1" -it-drain@^3.0.3, it-drain@^3.0.5: +it-byte-stream@^1.0.12: + version "1.1.0" + resolved "https://registry.yarnpkg.com/it-byte-stream/-/it-byte-stream-1.1.0.tgz#f5b80b713fb71a34cbff2390b7232b103cf625bb" + integrity sha512-WWponBWdKEa6o2U3NX+wGMY8X1EkWXcQvpC+3CUqKb4ZzK30q3EPqiTjFxLf9tNVgdF/MNAtx/XclpVfgaz9KQ== + dependencies: + it-queueless-pushable "^1.0.0" + it-stream-types "^2.0.1" + uint8arraylist "^2.4.8" + +it-drain@^3.0.3, it-drain@^3.0.5, it-drain@^3.0.7: version "3.0.7" resolved "https://registry.yarnpkg.com/it-drain/-/it-drain-3.0.7.tgz#671a5d0220802c5bce9e68fc2b07088540fbc674" integrity sha512-vy6S1JKjjHSIFHgBpLpD1zhkCRl3z1zYWUxE14+kAYf+BL9ssWSFImJfhl361IIcwr0ofw8etzg11VqqB+ntUA== -it-filter@^3.0.0, it-filter@^3.0.4: +it-filter@^3.0.4: version "3.1.0" resolved "https://registry.yarnpkg.com/it-filter/-/it-filter-3.1.0.tgz#16e2914f7f54de44a19c03eb8289027643f33a1b" integrity sha512-FiYuzdsUhmMZJTJQ8YLdgX3ArjQmAtCG1lyrtZd+92/2eC6YO9UoybdrwVj/yyZkuXAPykrSipLuZ+KSKpt29A== dependencies: it-peekable "^3.0.0" -it-foreach@^2.0.6: - version "2.1.0" - resolved "https://registry.yarnpkg.com/it-foreach/-/it-foreach-2.1.0.tgz#37dd606d92d93ac82ee3fdeffeec7f9f8dd76cf8" - integrity sha512-nobWUecq9E2ED1kcXz2o27yN6KePauSdmxJNMwCduWByrF4WNB2UgBHjr9QV2jPXpEWPDuzxZas9fVhQj1Vovg== +it-foreach@^2.1.0, it-foreach@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/it-foreach/-/it-foreach-2.1.1.tgz#93e311a1057dd0ff7631f914dc9c2c963f27a4b8" + integrity sha512-ID4Gxnavk/LVQLQESAQ9hR6dR63Ih6X+8VdxEktX8rpz2dCGAbZpey/eljTNbMfV2UKXHiu6UsneoNBZuac97g== dependencies: it-peekable "^3.0.0" -it-length-prefixed-stream@^1.0.0, it-length-prefixed-stream@^1.1.6: - version "1.1.7" - resolved "https://registry.yarnpkg.com/it-length-prefixed-stream/-/it-length-prefixed-stream-1.1.7.tgz#de4fec7da005f9a593e3eccd901c183154be09f9" - integrity sha512-tH38h/wChpR6As/PD6yWZlpoMuB4wDW2Rxf3QbSt4+O1HTsLYbyZasNhTyIuvQqhebQ30OYrdM0yr9ig5qUvYQ== +it-length-prefixed-stream@^1.0.0, it-length-prefixed-stream@^1.1.7: + version "1.2.0" + resolved "https://registry.yarnpkg.com/it-length-prefixed-stream/-/it-length-prefixed-stream-1.2.0.tgz#1f6ad78c60dea3b16364f86a0b78058f4d66a04e" + integrity sha512-vX7dzSl/2UMYYsAr0FQdPNVR5xYEETaeboZ+eXxNBjgARuvxnWA6OedW8lC5/J3ebMTC98JhA3eH76eTijUOsA== dependencies: it-byte-stream "^1.0.0" it-stream-types "^2.0.1" @@ -8358,14 +7945,14 @@ it-length-prefixed@^9.0.1, it-length-prefixed@^9.0.4: uint8arraylist "^2.0.0" uint8arrays "^5.0.1" -it-map@^3.0.1, it-map@^3.0.5: +it-map@^3.0.5: version "3.1.0" resolved "https://registry.yarnpkg.com/it-map/-/it-map-3.1.0.tgz#a66e5447d2ed8167ff90d19b183f6a3f8ae6e1b9" integrity sha512-B7zNmHYRE0qes8oTiNYU7jXEF5WvKZNAUosskCks1JT9Z4DNwRClrQyd+C/hgITG8ewDbVZMGx9VXAx3KMY2kA== dependencies: it-peekable "^3.0.0" -it-merge@^3.0.0, it-merge@^3.0.3: +it-merge@^3.0.0, it-merge@^3.0.3, it-merge@^3.0.5: version "3.0.5" resolved "https://registry.yarnpkg.com/it-merge/-/it-merge-3.0.5.tgz#2b0d1d07c825b9d20c4c2889aab8e07322fd803e" integrity sha512-2l7+mPf85pyRF5pqi0dKcA54E5Jm/2FyY5GsOaN51Ta0ipC7YZ3szuAsH8wOoB6eKY4XsU4k2X+mzPmFBMayEA== @@ -8380,12 +7967,12 @@ it-pair@^2.0.6: it-stream-types "^2.0.1" p-defer "^4.0.0" -it-parallel@^3.0.6: - version "3.0.6" - resolved "https://registry.yarnpkg.com/it-parallel/-/it-parallel-3.0.6.tgz#d8f9efa56dac5f960545b3a148d2ca171694d228" - integrity sha512-i7UM7I9LTkDJw3YIqXHFAPZX6CWYzGc+X3irdNrVExI4vPazrJdI7t5OqrSVN8CONXLAunCiqaSV/zZRbQR56A== +it-parallel@^3.0.7: + version "3.0.8" + resolved "https://registry.yarnpkg.com/it-parallel/-/it-parallel-3.0.8.tgz#fb4a5344732ddae9eff7c7b21908aa1f223638d4" + integrity sha512-URLhs6eG4Hdr4OdvgBBPDzOjBeSSmI+Kqex2rv/aAyYClME26RYHirLVhZsZP5M+ZP6M34iRlXk8Wlqtezuqpg== dependencies: - p-defer "^4.0.0" + p-defer "^4.0.1" it-peekable@^3.0.0: version "3.0.1" @@ -8401,10 +7988,10 @@ it-pipe@^3.0.1: it-pushable "^3.1.2" it-stream-types "^2.0.1" -it-protobuf-stream@^1.1.1, it-protobuf-stream@^1.1.2: - version "1.1.3" - resolved "https://registry.yarnpkg.com/it-protobuf-stream/-/it-protobuf-stream-1.1.3.tgz#66d95ad55b66827fbd057e45bd411917437bc116" - integrity sha512-96n+e6X8CXL0JerxTJuEnfivmfLzGKpIGAlJLoH7HEGo2nPRrMe+HxeWGwDF4Un3FphI/Z62JNxSvq/5DxfiQw== +it-protobuf-stream@^1.1.3: + version "1.1.5" + resolved "https://registry.yarnpkg.com/it-protobuf-stream/-/it-protobuf-stream-1.1.5.tgz#70da43abfb6beaaf7c53262d8cfd176d463b08f0" + integrity sha512-H70idW45As3cEbU4uSoZ9IYHUIV3YM69/2mmXYR7gOlPabWjuyNi3/abK11geiiq3la27Sos/mXr68JljjKtEQ== dependencies: it-length-prefixed-stream "^1.0.0" it-stream-types "^2.0.1" @@ -8417,6 +8004,14 @@ it-pushable@^3.1.2, it-pushable@^3.2.0, it-pushable@^3.2.3: dependencies: p-defer "^4.0.0" +it-queueless-pushable@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/it-queueless-pushable/-/it-queueless-pushable-1.0.0.tgz#917b52964cd6465d6436f923552c407c5ee3d11c" + integrity sha512-HbcAbcuQj7a9EBxiRCZ+77FxWutgs/pY5ZvEyQnylWPGNFojCLAUwhcZjf5OuEQ9+y+vSa7w1GQBe8xJdmIn5A== + dependencies: + p-defer "^4.0.1" + race-signal "^1.0.2" + it-reader@^6.0.1: version "6.0.4" resolved "https://registry.yarnpkg.com/it-reader/-/it-reader-6.0.4.tgz#439cb88225dcd15116be0ffde9e846a928c3871a" @@ -8425,7 +8020,7 @@ it-reader@^6.0.1: it-stream-types "^2.0.1" uint8arraylist "^2.0.0" -it-sort@^3.0.1, it-sort@^3.0.4: +it-sort@^3.0.4: version "3.0.5" resolved "https://registry.yarnpkg.com/it-sort/-/it-sort-3.0.5.tgz#7209710c64e83e130659e00b2e42df4b36643f7e" integrity sha512-vFo3wYR+aRDwklp8iH8LKeePmWqXGQrS8JqEdZmbJ58DIGj67n0RT/t5BR8iYps/C/v5IdWsbow1bOCEUfY+hA== @@ -8437,7 +8032,7 @@ it-stream-types@^2.0.1: resolved "https://registry.yarnpkg.com/it-stream-types/-/it-stream-types-2.0.1.tgz#69cb4d7e79e707b8257a8997e02751ccb6c3af32" integrity sha512-6DmOs5r7ERDbvS4q8yLKENcj6Yecr7QQTqWApbZdfAUTEC947d+PEha7PCqhm//9oxaLYL7TWRekwhoXl2s6fg== -it-take@^3.0.1, it-take@^3.0.4: +it-take@^3.0.4: version "3.0.5" resolved "https://registry.yarnpkg.com/it-take/-/it-take-3.0.5.tgz#c5a82cb160d5d7767954d84c6ce30d680f884b77" integrity sha512-4CzqXzx7FAeXsRYBTH0GhkxerH8Sv0nEGIXrO0ZIpECHth59Dm9ZYZ161VPrCQccWIL/Vu6M9YptlbMiEpCIlQ== @@ -8616,23 +8211,11 @@ json-schema-traverse@^1.0.0: resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz" integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== -json-stable-stringify-without-jsonify@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz" - integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= - json-stringify-safe@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA== -json5@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.2.tgz#63d98d60f21b313b77c4d6da18bfa69d80e1d593" - integrity sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA== - dependencies: - minimist "^1.2.0" - json5@^2.2.2: version "2.2.3" resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" @@ -8810,13 +8393,14 @@ level@^8.0.0: browser-level "^1.0.1" classic-level "^1.2.0" -levn@^0.4.1: - version "0.4.1" - resolved "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz" - integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== +level@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/level/-/level-8.0.1.tgz#737161db1bc317193aca4e7b6f436e7e1df64379" + integrity sha512-oPBGkheysuw7DmzFQYyFe8NAia5jFLAgEnkgWnK3OXAuJr8qFT+xBQIwokAZPME2bhPFzS8hlYcL16m8UZrtwQ== dependencies: - prelude-ls "^1.2.1" - type-check "~0.4.0" + abstract-level "^1.0.4" + browser-level "^1.0.1" + classic-level "^1.2.0" libnpmaccess@7.0.2: version "7.0.2" @@ -8840,32 +8424,37 @@ libnpmpublish@7.3.0: sigstore "^1.4.0" ssri "^10.0.1" -libp2p@1.4.3: - version "1.4.3" - resolved "https://registry.yarnpkg.com/libp2p/-/libp2p-1.4.3.tgz#830453eec2982e5c0faf79558a0aaa87d1e5b150" - integrity sha512-/J+bqE+bYw6iiyPBlBZk1PrZo182f9W1zSzWcMrNy+CQCG/WdJllft/WxvhNKHK1KuIS/JsL9gvhuRhtpqmMKg== - dependencies: - "@libp2p/crypto" "^4.1.0" - "@libp2p/interface" "^1.3.0" - "@libp2p/interface-internal" "^1.1.1" - "@libp2p/logger" "^4.0.11" - "@libp2p/multistream-select" "^5.1.8" - "@libp2p/peer-collections" "^5.1.11" - "@libp2p/peer-id" "^4.1.0" - "@libp2p/peer-id-factory" "^4.1.0" - "@libp2p/peer-store" "^10.0.16" - "@libp2p/utils" "^5.3.2" - "@multiformats/dns" "^1.0.5" - "@multiformats/multiaddr" "^12.2.1" - "@multiformats/multiaddr-matcher" "^1.2.0" +libp2p@2.1.7: + version "2.1.7" + resolved "https://registry.yarnpkg.com/libp2p/-/libp2p-2.1.7.tgz#e0d921cba459c78c63d783aafea6ead98a75e57f" + integrity sha512-nUxws8eHeI4jREZJFNdif20c8jYnqPkmvioI3y/hICgXchkhcKzgT1E3jEd2CVT+isskr5LnJ1n70aw6bt0m6w== + dependencies: + "@libp2p/crypto" "^5.0.4" + "@libp2p/interface" "^2.1.2" + "@libp2p/interface-internal" "^2.0.7" + "@libp2p/logger" "^5.1.0" + "@libp2p/multistream-select" "^6.0.5" + "@libp2p/peer-collections" "^6.0.7" + "@libp2p/peer-id" "^5.0.4" + "@libp2p/peer-store" "^11.0.7" + "@libp2p/utils" "^6.1.0" + "@multiformats/dns" "^1.0.6" + "@multiformats/multiaddr" "^12.2.3" + "@multiformats/multiaddr-matcher" "^1.2.1" any-signal "^4.1.1" - datastore-core "^9.2.9" - interface-datastore "^8.2.11" - it-merge "^3.0.3" - it-parallel "^3.0.6" + datastore-core "^10.0.0" + interface-datastore "^8.3.0" + it-byte-stream "^1.0.12" + it-merge "^3.0.5" + it-parallel "^3.0.7" merge-options "^3.0.4" multiformats "^13.1.0" - uint8arrays "^5.0.3" + p-defer "^4.0.1" + p-retry "^6.2.0" + progress-events "^1.0.0" + race-event "^1.3.0" + race-signal "^1.0.2" + uint8arrays "^5.1.0" light-my-request@^6.0.0: version "6.0.0" @@ -8999,11 +8588,6 @@ lodash.isplainobject@^4.0.6: resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" integrity sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA== -lodash.merge@^4.6.2: - version "4.6.2" - resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" - integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== - lodash.some@^4.6.0: version "4.6.0" resolved "https://registry.npmjs.org/lodash.some/-/lodash.some-4.6.0.tgz" @@ -9422,13 +9006,6 @@ minimatch@5.0.1: dependencies: brace-expansion "^2.0.1" -minimatch@9.0.3, minimatch@^9.0.0, minimatch@^9.0.1: - version "9.0.3" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.3.tgz#a6e00c3de44c3a542bfaae70abfc22420a6da825" - integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== - dependencies: - brace-expansion "^2.0.1" - minimatch@^10.0.0: version "10.0.1" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-10.0.1.tgz#ce0521856b453c86e25f2c4c0d03e6ff7ddc440b" @@ -9436,7 +9013,7 @@ minimatch@^10.0.0: dependencies: brace-expansion "^2.0.1" -minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: +minimatch@^3.0.4, minimatch@^3.1.1: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== @@ -9464,13 +9041,27 @@ minimatch@^8.0.2: dependencies: brace-expansion "^2.0.1" -minimatch@^9.0.3, minimatch@^9.0.4: +minimatch@^9.0.0, minimatch@^9.0.1: + version "9.0.3" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.3.tgz#a6e00c3de44c3a542bfaae70abfc22420a6da825" + integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== + dependencies: + brace-expansion "^2.0.1" + +minimatch@^9.0.3: version "9.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.4.tgz#8e49c731d1749cbec05050ee5145147b32496a51" integrity sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw== dependencies: brace-expansion "^2.0.1" +minimatch@^9.0.4: + version "9.0.5" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.5.tgz#d74f9dd6b57d83d8e98cfb82133b03978bc929e5" + integrity sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow== + dependencies: + brace-expansion "^2.0.1" + minimatch@~3.0.3: version "3.0.8" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.8.tgz#5e6a59bd11e2ab0de1cfb843eb2d82e546c321c1" @@ -9686,11 +9277,16 @@ ms@2.1.2: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== -ms@2.1.3, ms@^2.0.0, ms@^2.1.1: +ms@2.1.3, ms@^2.0.0, ms@^2.1.1, ms@^2.1.3: version "2.1.3" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== +ms@^3.0.0-canary.1: + version "3.0.0-canary.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-3.0.0-canary.1.tgz#c7b34fbce381492fd0b345d1cf56e14d67b77b80" + integrity sha512-kh8ARjh8rMN7Du2igDRO9QJnqCb2xYTJxyQYK7vJJS4TvLLmsbyhiKpSW+t+y26gyOyMd0riphX0GeWKU3ky5g== + msw@^2.3.1: version "2.3.2" resolved "https://registry.yarnpkg.com/msw/-/msw-2.3.2.tgz#ea4f45b51f833fa3b2215c4093bcda28dbe25a83" @@ -9732,10 +9328,10 @@ multiformats@^11.0.1: resolved "https://registry.yarnpkg.com/multiformats/-/multiformats-11.0.2.tgz#b14735efc42cd8581e73895e66bebb9752151b60" integrity sha512-b5mYMkOkARIuVZCpvijFj9a6m5wMVLC7cf/jIPd5D/ARDOfLC5+IFkbgDXQgcU2goIsTD/O9NY4DI/Mt4OGvlg== -multiformats@^13.0.0, multiformats@^13.0.1, multiformats@^13.1.0: - version "13.1.0" - resolved "https://registry.yarnpkg.com/multiformats/-/multiformats-13.1.0.tgz#5aa9d2175108a448fc3bdb54ba8a3d0b6cab3ac3" - integrity sha512-HzdtdBwxsIkzpeXzhQ5mAhhuxcHbjEHH+JQoxt7hG/2HGFjjwyolLo7hbaexcnhoEuV4e0TNJ8kkpMjiEYY4VQ== +multiformats@^13.0.0, multiformats@^13.0.1, multiformats@^13.1.0, multiformats@^13.2.2: + version "13.2.2" + resolved "https://registry.yarnpkg.com/multiformats/-/multiformats-13.2.2.tgz#16da153ee8b68d8c9da31b52176e90b3cd8b43ef" + integrity sha512-RWI+nyf0q64vyOxL8LbKtjJMki0sogRL/8axvklNtiTM0iFCVtHwME9w6+0P1/v4dQvsIg8A45oT3ka1t/M/+A== multimatch@5.0.0: version "5.0.0" @@ -9748,6 +9344,11 @@ multimatch@5.0.0: arrify "^2.0.1" minimatch "^3.0.4" +murmurhash3js-revisited@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/murmurhash3js-revisited/-/murmurhash3js-revisited-3.0.0.tgz#6bd36e25de8f73394222adc6e41fa3fac08a5869" + integrity sha512-/sF3ee6zvScXMb1XFJ8gDsSnY+X8PbOyjIuBhtgis10W2Jx4ZjIhikUCIF9c4gpJxVnQIsPAFrSwTCuAjicP6g== + mute-stream@0.0.8: version "0.0.8" resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" @@ -9788,11 +9389,6 @@ native-fetch@^4.0.2: resolved "https://registry.yarnpkg.com/native-fetch/-/native-fetch-4.0.2.tgz#75c8a44c5f3bb021713e5e24f2846750883e49af" integrity sha512-4QcVlKFtv2EYVS5MBgsGX5+NWKtbDbIECdUXDBGDMAZXq3Jkv9zf+y8iS7Ub8fEdga3GpYeazp9gauNqXHJOCg== -natural-compare@^1.4.0: - version "1.4.0" - resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz" - integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= - negotiator@^0.6.2, negotiator@^0.6.3: version "0.6.3" resolved "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz" @@ -10240,35 +9836,6 @@ object.assign@^4.1.4: has-symbols "^1.0.3" object-keys "^1.1.1" -object.fromentries@^2.0.7: - version "2.0.7" - resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.7.tgz#71e95f441e9a0ea6baf682ecaaf37fa2a8d7e616" - integrity sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - -object.groupby@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/object.groupby/-/object.groupby-1.0.2.tgz#494800ff5bab78fd0eff2835ec859066e00192ec" - integrity sha512-bzBq58S+x+uo0VjurFT0UktpKHOZmv4/xePiOA1nbB9pMqpGK7rUPNgf+1YC+7mE+0HzhTMqNUuCqvKhj6FnBw== - dependencies: - array.prototype.filter "^1.0.3" - call-bind "^1.0.5" - define-properties "^1.2.1" - es-abstract "^1.22.3" - es-errors "^1.0.0" - -object.values@^1.1.7: - version "1.1.7" - resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.7.tgz#617ed13272e7e1071b43973aa1655d9291b8442a" - integrity sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - obliterator@^2.0.1: version "2.0.4" resolved "https://registry.yarnpkg.com/obliterator/-/obliterator-2.0.4.tgz#fa650e019b2d075d745e44f1effeb13a2adbe816" @@ -10331,18 +9898,6 @@ openapi-types@^12.1.3: resolved "https://registry.yarnpkg.com/openapi-types/-/openapi-types-12.1.3.tgz#471995eb26c4b97b7bd356aacf7b91b73e777dd3" integrity sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw== -optionator@^0.9.3: - version "0.9.3" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.3.tgz#007397d44ed1872fdc6ed31360190f81814e2c64" - integrity sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg== - dependencies: - "@aashutoshrathi/word-wrap" "^1.2.3" - deep-is "^0.1.3" - fast-levenshtein "^2.0.6" - levn "^0.4.1" - prelude-ls "^1.2.1" - type-check "^0.4.0" - ora@^5.4.1: version "5.4.1" resolved "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz" @@ -10502,6 +10057,15 @@ p-reduce@2.1.0, p-reduce@^2.0.0, p-reduce@^2.1.0: resolved "https://registry.yarnpkg.com/p-reduce/-/p-reduce-2.1.0.tgz#09408da49507c6c274faa31f28df334bc712b64a" integrity sha512-2USApvnsutq8uoxZBGbbWM0JIYLiEMJ9RlaN7fAzVNb9OZN0SHjjTTfIcb667XynS5Y1VhwDJVDa72TnPzAYWw== +p-retry@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-6.2.0.tgz#8d6df01af298750009691ce2f9b3ad2d5968f3bd" + integrity sha512-JA6nkq6hKyWLLasXQXUrO4z8BUZGUt/LjlJxx8Gb2+2ntodU/SS63YZ8b0LUTbQ8ZB9iwOfhEPhg4ykKnn2KsA== + dependencies: + "@types/retry" "0.12.2" + is-network-error "^1.0.0" + retry "^0.13.1" + p-timeout@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-3.2.0.tgz#c7e17abc971d2a7962ef83626b35d635acf23dfe" @@ -10854,18 +10418,6 @@ postcss@^8.4.39: picocolors "^1.0.1" source-map-js "^1.2.0" -prelude-ls@^1.2.1: - version "1.2.1" - resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz" - integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== - -prettier-linter-helpers@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz" - integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w== - dependencies: - fast-diff "^1.1.2" - prettier@^3.2.5: version "3.2.5" resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.2.5.tgz#e52bc3090586e824964a8813b09aba6233b28368" @@ -10924,10 +10476,10 @@ progress@^2.0.3: resolved "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz" integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== -prom-client@^15.1.0, prom-client@^15.1.1: - version "15.1.2" - resolved "https://registry.yarnpkg.com/prom-client/-/prom-client-15.1.2.tgz#78d79f12c35d395ca97edf7111c18210cf07f815" - integrity sha512-on3h1iXb04QFLLThrmVYg1SChBQ9N1c+nKAjebBjokBqipddH3uxmOUcEkTnzmJ8Jh/5TSUnUqS40i2QB2dJHQ== +prom-client@^15.1.0, prom-client@^15.1.2: + version "15.1.3" + resolved "https://registry.yarnpkg.com/prom-client/-/prom-client-15.1.3.tgz#69fa8de93a88bc9783173db5f758dc1c69fa8fc2" + integrity sha512-6ZiOBfCywsD4k1BN9IX0uZhF+tJkV8q8llP64G5Hajs4JOeVLPCwpPVcpXy3BwYiUGgyJzsJJQeOIv7+hDSq8g== dependencies: "@opentelemetry/api" "^1.4.0" tdigest "^0.1.1" @@ -10973,10 +10525,10 @@ protocols@^2.0.0, protocols@^2.0.1: resolved "https://registry.yarnpkg.com/protocols/-/protocols-2.0.1.tgz#8f155da3fc0f32644e83c5782c8e8212ccf70a86" integrity sha512-/XJ368cyBJ7fzLMwLKv1e4vLxOju2MNAIokcr7meSaNcVbWz/CPcW22cP04mwxOErdA5mwjA8Q6w/cdAQxVn7Q== -protons-runtime@5.4.0, protons-runtime@^5.0.0, protons-runtime@^5.4.0: - version "5.4.0" - resolved "https://registry.yarnpkg.com/protons-runtime/-/protons-runtime-5.4.0.tgz#2751ce22cae6c35eebba89acfd9d783419ae3726" - integrity sha512-XfA++W/WlQOSyjUyuF5lgYBfXZUEMP01Oh1C2dSwZAlF2e/ZrMRPfWonXj6BGM+o8Xciv7w0tsRMKYwYEuQvaw== +protons-runtime@^5.4.0, protons-runtime@^5.5.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/protons-runtime/-/protons-runtime-5.5.0.tgz#ea06d9ef843aad77ea5de3e1ebafa81b58c24570" + integrity sha512-EsALjF9QsrEk6gbCx3lmfHxVN0ah7nG3cY7GySD4xf4g8cr7g543zB88Foh897Sr1RQJ9yDCUsoT1i1H/cVUFA== dependencies: uint8-varint "^2.0.2" uint8arraylist "^2.4.3" @@ -11125,7 +10677,7 @@ quick-lru@^5.1.1: resolved "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz" integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA== -race-event@^1.2.0: +race-event@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/race-event/-/race-event-1.3.0.tgz#854f34118c31addf877898bd9f8e4dcfac9de7a2" integrity sha512-kaLm7axfOnahIqD3jQ4l1e471FIFcEGebXEnhxyLscuUzV8C94xVHtWEqDDXxll7+yu/6lW0w1Ff4HbtvHvOHg== @@ -11320,11 +10872,6 @@ regexp.prototype.flags@^1.5.1: define-properties "^1.2.0" set-function-name "^2.0.0" -regexpp@^3.0.0: - version "3.1.0" - resolved "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz" - integrity sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q== - require-directory@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" @@ -11362,12 +10909,7 @@ resolve-from@^4.0.0: resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== -resolve-pkg-maps@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz#616b3dc2c57056b5588c31cdf4b3d64db133720f" - integrity sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw== - -resolve@^1.10.0, resolve@^1.10.1, resolve@^1.17.0, resolve@^1.22.4, resolve@~1.22.1: +resolve@^1.10.0, resolve@^1.17.0, resolve@~1.22.1: version "1.22.8" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== @@ -11431,6 +10973,11 @@ retry@^0.12.0: resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" integrity sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow== +retry@^0.13.1: + version "0.13.1" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.13.1.tgz#185b1587acf67919d63b357349e03537b2484658" + integrity sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg== + reusify@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" @@ -11519,28 +11066,28 @@ rollup-plugin-visualizer@^5.12.0: yargs "^17.5.1" rollup@^4.13.0: - version "4.16.1" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.16.1.tgz#5a60230987fe95ebe68bab517297c116dbb1a88d" - integrity sha512-5CaD3MPDlPKfhqzRvWXK96G6ELJfPZNb3LHiZxTHgDdC6jvwfGz2E8nY+9g1ONk4ttHsK1WaFP19Js4PSr1E3g== + version "4.22.4" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.22.4.tgz#4135a6446671cd2a2453e1ad42a45d5973ec3a0f" + integrity sha512-vD8HJ5raRcWOyymsR6Z3o6+RzfEPCnVLMFJ6vRslO1jt4LO6dUo5Qnpg7y4RkZFM2DMe3WUirkI5c16onjrc6A== dependencies: "@types/estree" "1.0.5" optionalDependencies: - "@rollup/rollup-android-arm-eabi" "4.16.1" - "@rollup/rollup-android-arm64" "4.16.1" - "@rollup/rollup-darwin-arm64" "4.16.1" - "@rollup/rollup-darwin-x64" "4.16.1" - "@rollup/rollup-linux-arm-gnueabihf" "4.16.1" - "@rollup/rollup-linux-arm-musleabihf" "4.16.1" - "@rollup/rollup-linux-arm64-gnu" "4.16.1" - "@rollup/rollup-linux-arm64-musl" "4.16.1" - "@rollup/rollup-linux-powerpc64le-gnu" "4.16.1" - "@rollup/rollup-linux-riscv64-gnu" "4.16.1" - "@rollup/rollup-linux-s390x-gnu" "4.16.1" - "@rollup/rollup-linux-x64-gnu" "4.16.1" - "@rollup/rollup-linux-x64-musl" "4.16.1" - "@rollup/rollup-win32-arm64-msvc" "4.16.1" - "@rollup/rollup-win32-ia32-msvc" "4.16.1" - "@rollup/rollup-win32-x64-msvc" "4.16.1" + "@rollup/rollup-android-arm-eabi" "4.22.4" + "@rollup/rollup-android-arm64" "4.22.4" + "@rollup/rollup-darwin-arm64" "4.22.4" + "@rollup/rollup-darwin-x64" "4.22.4" + "@rollup/rollup-linux-arm-gnueabihf" "4.22.4" + "@rollup/rollup-linux-arm-musleabihf" "4.22.4" + "@rollup/rollup-linux-arm64-gnu" "4.22.4" + "@rollup/rollup-linux-arm64-musl" "4.22.4" + "@rollup/rollup-linux-powerpc64le-gnu" "4.22.4" + "@rollup/rollup-linux-riscv64-gnu" "4.22.4" + "@rollup/rollup-linux-s390x-gnu" "4.22.4" + "@rollup/rollup-linux-x64-gnu" "4.22.4" + "@rollup/rollup-linux-x64-musl" "4.22.4" + "@rollup/rollup-win32-arm64-msvc" "4.22.4" + "@rollup/rollup-win32-ia32-msvc" "4.22.4" + "@rollup/rollup-win32-x64-msvc" "4.22.4" fsevents "~2.3.2" rrweb-cssom@^0.6.0: @@ -11674,7 +11221,7 @@ semver@7.5.3: dependencies: lru-cache "^6.0.0" -semver@^6.1.0, semver@^6.2.0, semver@^6.3.1: +semver@^6.1.0, semver@^6.2.0: version "6.3.1" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== @@ -12124,7 +11671,7 @@ stream-http@^3.2.0: readable-stream "^3.6.0" xtend "^4.0.2" -stream-to-it@^1.0.0: +stream-to-it@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/stream-to-it/-/stream-to-it-1.0.1.tgz#7d5e1b04bab70facd48273279bfa49f0d0165950" integrity sha512-AqHYAYPHcmvMrcLNgncE/q0Aj/ajP6A4qGhxP6EVn7K3YTNs0bJpJyk57wc2Heb7MUL64jurvmnmui8D9kjZgA== @@ -12289,7 +11836,7 @@ strip-indent@^3.0.0: dependencies: min-indent "^1.0.0" -strip-json-comments@3.1.1, strip-json-comments@^3.1.1, strip-json-comments@~3.1.1: +strip-json-comments@3.1.1, strip-json-comments@~3.1.1: version "3.1.1" resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== @@ -12360,6 +11907,11 @@ supports-color@^7.1.0: dependencies: has-flag "^4.0.0" +supports-color@^9.4.0: + version "9.4.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-9.4.0.tgz#17bfcf686288f531db3dea3215510621ccb55954" + integrity sha512-VL+lNrEoIXww1coLPOmiEmK/0sGigko5COxI09KzHc2VJXJsQ37UaQ+8quuxjDeA7+KnLGTWRyOXSLLR2Wb4jw== + supports-preserve-symlinks-flag@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" @@ -12370,25 +11922,12 @@ symbol-tree@^3.2.4: resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== -synckit@^0.8.6: - version "0.8.8" - resolved "https://registry.yarnpkg.com/synckit/-/synckit-0.8.8.tgz#fe7fe446518e3d3d49f5e429f443cf08b6edfcd7" - integrity sha512-HwOKAP7Wc5aRGYdKH+dw0PRRpbO841v2DENBtjnR5HFWoiNByAl7vrx3p0G/rCyYXQsrxqtX48TImFtPcIHSpQ== - dependencies: - "@pkgr/core" "^0.1.0" - tslib "^2.6.2" - systeminformation@^5.22.9: version "5.22.9" resolved "https://registry.yarnpkg.com/systeminformation/-/systeminformation-5.22.9.tgz#68700a895a48cbf96e2cd6a34c5027d1fe58f053" integrity sha512-qUWJhQ9JSBhdjzNUQywpvc0icxUAjMY3sZqUoS0GOtaJV9Ijq8s9zEP8Gaqmymn1dOefcICyPXK1L3kgKxlUpg== -tapable@^2.2.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" - integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== - -tar-fs@^3.0.4, tar-fs@^3.0.5, tar-fs@^3.0.6: +tar-fs@^3.0.4, tar-fs@^3.0.6: version "3.0.6" resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-3.0.6.tgz#eaccd3a67d5672f09ca8e8f9c3d2b89fa173f217" integrity sha512-iokBDQQkUyeXhgPYaZxmczGPhnhXZ0CmrqI+MOb/WFGS9DW5wnfrLgtjUJBvz50vQ3qfRwJ62QVoCFu8mPVu5w== @@ -12399,6 +11938,17 @@ tar-fs@^3.0.4, tar-fs@^3.0.5, tar-fs@^3.0.6: bare-fs "^2.1.1" bare-path "^2.1.0" +tar-fs@^3.0.5: + version "3.0.5" + resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-3.0.5.tgz#f954d77767e4e6edf973384e1eb95f8f81d64ed9" + integrity sha512-JOgGAmZyMgbqpLwct7ZV8VzkEB6pxXFBVErLtb+XCOqzc6w1xiWKI9GVd6bwk68EX7eJ4DWmfXVmq8K2ziZTGg== + dependencies: + pump "^3.0.0" + tar-stream "^3.1.5" + optionalDependencies: + bare-fs "^2.1.1" + bare-path "^2.1.0" + tar-fs@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.0.1.tgz#e44086c1c60d31a4f0cf893b1c4e155dabfae9e2" @@ -12504,11 +12054,6 @@ text-hex@1.0.x: resolved "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz" integrity sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg== -text-table@^0.2.0: - version "0.2.0" - resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz" - integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= - thread-stream@^2.6.0: version "2.7.0" resolved "https://registry.yarnpkg.com/thread-stream/-/thread-stream-2.7.0.tgz#d8a8e1b3fd538a6cca8ce69dbe5d3d097b601e11" @@ -12660,16 +12205,6 @@ triple-beam@^1.3.0: resolved "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz" integrity sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw== -ts-api-utils@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.0.1.tgz#8144e811d44c749cd65b2da305a032510774452d" - integrity sha512-lC/RGlPmwdrIBFTX59wwNzqh7aR2otPNPR/5brHZm/XKFYKsfqxihXUe9pU3JI+3vGkl+vyCoNNnPhJn3aLK1A== - -ts-api-utils@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.3.0.tgz#4b490e27129f1e8e686b45cc4ab63714dc60eea1" - integrity sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ== - ts-node@^10.8.1: version "10.9.1" resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.1.tgz#e73de9102958af9e1f0b168a6ff320e25adcff4b" @@ -12708,16 +12243,6 @@ ts-node@^10.9.2: v8-compile-cache-lib "^3.0.1" yn "3.1.1" -tsconfig-paths@^3.15.0: - version "3.15.0" - resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz#5299ec605e55b1abb23ec939ef15edaf483070d4" - integrity sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg== - dependencies: - "@types/json5" "^0.0.29" - json5 "^1.0.2" - minimist "^1.2.6" - strip-bom "^3.0.0" - tsconfig-paths@^4.1.2: version "4.2.0" resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz#ef78e19039133446d244beac0fd6a1632e2d107c" @@ -12747,7 +12272,7 @@ tslib@^1.10.0: resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== -tslib@^2.0.0, tslib@^2.0.1, tslib@^2.1.0, tslib@^2.2.0, tslib@^2.3.0, tslib@^2.4.0, tslib@^2.6.1, tslib@^2.6.2: +tslib@^2.0.0, tslib@^2.0.1, tslib@^2.1.0, tslib@^2.2.0, tslib@^2.3.0, tslib@^2.4.0, tslib@^2.6.1: version "2.6.2" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== @@ -12781,13 +12306,6 @@ tweetnacl@^0.14.3: resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" integrity sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA== -type-check@^0.4.0, type-check@~0.4.0: - version "0.4.0" - resolved "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz" - integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== - dependencies: - prelude-ls "^1.2.1" - type-fest@2.13.0: version "2.13.0" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-2.13.0.tgz#d1ecee38af29eb2e863b22299a3d68ef30d2abfb" @@ -12803,11 +12321,6 @@ type-fest@^0.18.0: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.18.1.tgz#db4bc151a4a2cf4eebf9add5db75508db6cc841f" integrity sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw== -type-fest@^0.20.2: - version "0.20.2" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" - integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== - type-fest@^0.21.3: version "0.21.3" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" @@ -12930,10 +12443,10 @@ uint8arraylist@^2.0.0, uint8arraylist@^2.4.1, uint8arraylist@^2.4.3, uint8arrayl dependencies: uint8arrays "^5.0.1" -uint8arrays@^5.0.0, uint8arrays@^5.0.1, uint8arrays@^5.0.2, uint8arrays@^5.0.3: - version "5.0.3" - resolved "https://registry.yarnpkg.com/uint8arrays/-/uint8arrays-5.0.3.tgz#92b894d9c4269ba97c51544d6e1f279fe6f80d1f" - integrity sha512-6LBuKji28kHjgPJMkQ6GDaBb1lRwIhyOYq6pDGwYMoDPfImE9SkuYENVmR0yu9yGgs2clHUSY9fKDukR+AXfqQ== +uint8arrays@^5.0.0, uint8arrays@^5.0.1, uint8arrays@^5.0.2, uint8arrays@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/uint8arrays/-/uint8arrays-5.1.0.tgz#14047c9bdf825d025b7391299436e5e50e7270f1" + integrity sha512-vA6nFepEmlSKkMBnLBaUMVvAC4G3CTmO58C12y4sq6WPDOR7mOFYOi7GlrQ4djeSbP6JG9Pv9tJDM97PedRSww== dependencies: multiformats "^13.0.0" @@ -12960,6 +12473,11 @@ undici-types@~5.26.4: resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== +undici-types@~6.19.2: + version "6.19.8" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.19.8.tgz#35111c9d1437ab83a7cdc0abae2f26d88eda0a02" + integrity sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw== + undici@^5.12.0: version "5.28.4" resolved "https://registry.yarnpkg.com/undici/-/undici-5.28.4.tgz#6b280408edb6a1a604a9b20340f45b422e373068" @@ -13293,6 +12811,14 @@ wcwidth@^1.0.0, wcwidth@^1.0.1: dependencies: defaults "^1.0.3" +weald@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/weald/-/weald-1.0.2.tgz#a51fb3a8dbf5fa2b71ef09f9a267c86a46742238" + integrity sha512-iG5cIuBwsPe1ZcoGGd4X6QYlepU1vLr4l4oWpzQWqeJPSo9B8bxxyE6xlnj3TCmThtha7gyVL+uuZgUFkPyfDg== + dependencies: + ms "^3.0.0-canary.1" + supports-color "^9.4.0" + web-streams-polyfill@^3.0.3: version "3.2.1" resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz#71c2718c52b45fd49dbeee88634b3a60ceab42a6"